什么時候要用到自定義函數(shù)?有些瀏覽器并不兼容某類型的事件,如IE6~8不支持hashchange事件,你無法通過jQuery(window).bind('hashchange',
callback)來綁定這個事件,這個時候你就可以通過jQuery自定義事件接口來模擬這個事件,做到跨瀏覽器兼容。
原理
jQuery(elem).bind(type, callbakc)實際上是映射到 jQuery.event.add(elem,
types, handler, data)這個方法,每一個類型的事件會初始化一次事件處理器,而傳入的回調(diào)函數(shù)會以數(shù)組的方式緩存起來,當事件觸發(fā)的時候處理器將依次執(zhí)行這個數(shù)組。
jQuery.event.add方法在第一次初始化處理器的時候會檢查是否為自定義事件,如果存在則將會把控制權(quán)限交給自定義事件的事件初始化函數(shù),同樣事件卸載的jQuery.event.remove方法在刪除處理器前也會檢查此。
如jQuery源碼:
初始化處事件處理器
- // Check for a special event handler
- // Only use addEventListener/attachEvent if the special
- // events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
卸載處理器:
- if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
入口
- <pre name="code" class="javascript">jQuery.event.special[youEvent] = {
- /**
- * 初始化事件處理器 - this指向元素
- * @param 附加的數(shù)據(jù)
- * @param 事件類型命名空間
- * @param 回調(diào)函數(shù)
- */
- setup: function (data, namespaces, eventHandle) {
- },
- /**
- * 卸載事件處理器 - this指向元素
- * @param 事件類型命名空間
- */
- teardown: function (namespaces) {
- }
- };
事實上jQuery自定義事件那些接收的參數(shù)有點雞肋,需要hack與能hack的事件就那么一點點,且限制頗多,一般情況下很少使用到。
接下來我們做一個最簡單的自定義插件,給jQuery提供input跨瀏覽器事件支持。input事件不同于keydown與keyup,它不依賴鍵盤響應,只要值改變都會觸發(fā)input事件,比如粘貼文字、使用在線軟鍵盤等。
范例
- /*
- * jQuery input event
- * Author: tangbin
- * Blog: http://www.
- * Date: 2011-08-18 15:15
- */
- (function ($) {
-
- // IE6\7\8不支持input事件,但支持propertychange事件
- if ('onpropertychange' in document) {
- // 檢查是否為可輸入元素
- var rinput = /^INPUT|TEXTAREA$/,
- isInput = function (elem) {
- return rinput.test(elem.nodeName);
- };
-
- $.event.special.input = {
- setup: function () {
- var elem = this;
- if (!isInput(elem)) return false;
-
- $.data(elem, '@oldValue', elem.value);
- $.event.add(elem, 'propertychange', function (event) {
- // 元素屬性任何變化都會觸發(fā)propertychange事件
- // 需要屏蔽掉非value的改變,以便接近標準的onput事件
- if ($.data(this, '@oldValue') !== this.value) {
- $.event.trigger('input', null, this);
- };
-
- $.data(this, '@oldValue', this.value);
- });
- },
- teardown: function () {
- var elem = this;
- if (!isInput(elem)) return false;
- $.event.remove(elem, 'propertychange');
- $.removeData(elem, '@oldValue');
- }
- };
- };
-
- // 聲明快捷方式:$(elem).input(function () {});
- $.fn.input = function (callback) {
- return this.bind('input', callback);
- };
-
- })(jQuery);
調(diào)用:
- jQuery(elem).bind('input', function () {});
|