javascript綁定事件

本質:不一樣的庫或者工具中老是封裝了不一樣的事件綁定形式,可是究其根源,仍是IE事件模型和W3C事件模型不一樣的處理方式jquery

1)W3C事件模型:支持事件捕捉和冒泡 addEventListener('type',function(){},bool) removeEventListener ('type',function(){},bool)json

2)IE事件模型:僅支持事件冒泡 attachEvent('type',function(){}); detachEvent('type',fucntion(){});數組

*如何統一:設置W3C事件綁定函數的第三個參數爲false,那麼就不支持事件捕捉了。 框架

*原生的綁定形式:dom

obj.addEventListener('type',function(){},false);函數

obj.attachEvent('type',function(){});工具

*是否有注意的:性能

固然有,IE對同一個事件綁定2次會重複綁定2次,可是W3C只會綁定一次,會忽略後面的一個事件。這個要特別注意,特別是在開發的時候優化

我記得我在使用百度tangram的處理問題的時候,還碰到了,後面咱們來分析tangram的事件綁定形式。this

*是否有解決方案:

固然有,對對象綁定以class的形式就能夠解決。不會重複綁定事件了。實現方式也是多種多樣。

如今來看看一些框架中的事件綁定處理:

1)tangram:

 
baidu.event.on = function (element, type, listener) {
    type = type.replace(/^on/i, '');
    element = baidu.dom._g(element);
 
    var realListener = function (ev) {
            // 1. 這裏不支持EventArgument,  緣由是跨frame的事件掛載
            // 2. element是爲了修正this
            listener.call(element, ev);
        },
        lis = baidu.event._listeners,
        filter = baidu.event._eventFilter,
        afterFilter,
        realType = type;
    type = type.toLowerCase();
    // filter過濾
    if(filter && filter[type]){
        afterFilter = filter[type](element, type, realListener);
        realType = afterFilter.type;
        realListener = afterFilter.listener;
    }
    
    // 事件監聽器掛載
    if (element.addEventListener) {
        element.addEventListener(realType, realListener, false);
    } else if (element.attachEvent) {
        element.attachEvent('on' + realType, realListener);
    }
  
    // 將監聽器存儲到數組中
    lis[lis.length] = [element, type, listener, realListener, realType];
    return element;
};
 
baidu.event.un = function (element, type, listener) {
    element = baidu.dom._g(element);
    type = type.replace(/^on/i, '').toLowerCase();
    
    var lis = baidu.event._listeners, 
        len = lis.length,
        isRemoveAll = !listener,
        item,
        realType, realListener;
    
    //若是將listener的結構改爲json
    //能夠節省掉這個循環,優化性能
    //可是因爲un的使用頻率並不高,同時在listener很少的時候
    //遍歷數組的性能消耗不會對代碼產生影響
    //暫不考慮此優化
    while (len--) {
        item = lis[len];
        
        // listener存在時,移除element的全部以listener監聽的type類型事件
        // listener不存在時,移除element的全部type類型事件
        if (item[1] === type
            && item[0] === element
            && (isRemoveAll || item[2] === listener)) {
            realType = item[4];
            realListener = item[3];
            if (element.removeEventListener) {
                element.removeEventListener(realType, realListener, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + realType, realListener);
            }
            lis.splice(len, 1);
        }
    }
    
    return element;

}; 

能夠看出tangram不過是變了一個綁定的方式,其本質仍是同樣的。

2)jquery

// 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 );
  }

  } 

能夠看出也是對是否支持 addEventListener和attachEvent  按後進行綁定處理的。

3) prototype

 function observe(element, eventName, handler) {

    element = $(element);
 
    var responder = _createResponder(element, eventName, handler);
 
    if (!responder) return element;
 
    if (eventName.include(':')) {
      if (element.addEventListener)
        element.addEventListener("dataavailable", responder, false);
      else {
        element.attachEvent("ondataavailable", responder);
        element.attachEvent("onlosecapture", responder);
      }
    } else {
      var actualEventName = _getDOMEventName(eventName);
 
      if (element.addEventListener)
        element.addEventListener(actualEventName, responder, false);
      else
        element.attachEvent("on" + actualEventName, responder);
    }
 
    return element;
  }
 

能夠看出也是對IE和W3C支持的事件模型進行處理的。不過是處理的函數,方式不一樣而已。

相關文章
相關標籤/搜索