js 事件绑定的一些方式 笔记

 看了网上的一些资料,发现有一下几种比较牛的:

john resig的 <!---->Flexible Javascript Events(The code, itself, is very short and simple - only 15 lines long:

function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
  obj['e'+type+fn] = fn;
  obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
  obj.attachEvent( 'on'+type, obj[type+fn] );
} else
  obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
  obj.detachEvent( 'on'+type, obj[type+fn] );
  obj[type+fn] = null;
} else
  obj.removeEventListener( type, fn, false );
}

  dean.edwards 发表了自己的意见:

<!---->My solution is very different.

  • it performs no object detection
  • it does not use the addeventListener/attachEvent methods
  • it keeps the correct scope (the this keyword)
  • it passes the event object correctly
  • it is entirely cross-browser (it will probably work on IE4 and NS4)
  • and from what I can tell it does not leak memory
// written by Dean Edwards, 2005
// with input from Tino Zijdel, Matthias Miller, Diego Perini

// http://dean.edwards.name/weblog/2005/10/add-event/

function addEvent(element, type, handler) {
        if (element.addEventListener) {
                element.addEventListener(type, handler, false);
        } else {
                // assign each event handler a unique ID
                if (!handler.$$guid) handler.$$guid = addEvent.guid++;
                // create a hash table of event types for the element
                if (!element.events) element.events = {};
                // create a hash table of event handlers for each element/event pair
                var handlers = element.events[type];
                if (!handlers) {
                        handlers = element.events[type] = {};
                        // store the existing event handler (if there is one)
                        if (element["on" + type]) {
                                handlers[0] = element["on" + type];
                        }
                }
                // store the event handler in the hash table
                handlers[handler.$$guid] = handler;
                // assign a global event handler to do all the work
                element["on" + type] = handleEvent;
        }
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
        if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
        } else {
                // delete the event handler from the hash table
                if (element.events && element.events[type]) {
                        delete element.events[type][handler.$$guid];
                }
        }
};

function handleEvent(event) {
        var returnValue = true;
        // grab the event object (IE uses a global event object)
        event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
        // get a reference to the hash table of event handlers
        var handlers = this.events[event.type];
        // execute each event handler
        for (var i in handlers) {
                this.$$handleEvent = handlers[i];
                if (this.$$handleEvent(event) === false) {
                        returnValue = false;
                }
        }
        return returnValue;
};

function fixEvent(event) {
        // add W3C standard event methods
        event.preventDefault = fixEvent.preventDefault;
        event.stopPropagation = fixEvent.stopPropagation;
        return event;
};
fixEvent.preventDefault = function() {
        this.returnValue = false;
};
fixEvent.stopPropagation = function() {
        this.cancelBubble = true;
};

 最后 dean.edwards 推荐了一种:

/**
  * Crossbrowser event handling functions.
  *
  * A set of functions to easily attach and detach event handlers to HTML elements.
  * These functions work around the shortcomings of the traditional method ( element.onevent = function; )
  * where only 1 handler could be attached for a certain event on the object, and mimic the DOM level 2
  * event methods addEventListener and removeEventListener for browsers that do not support these
  * methods (e.g. Internet Explorer) without resorting to propriety methods such as attachEvent and detachEvent
  * that have a whole set of their own shortcomings.
  * Created as an entry for the 'contest' at quirksmode.org: http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html
  *
  * @author Tino Zijdel ( crisp@xs4all.nl )
  * @version 1.2
  * @date 2005-10-21
  */


/**
  * addEvent
  *
  * Generic function to attach event listeners to HTML elements.
  * This function does NOT use attachEvent but creates an own stack of function references
  * in the DOM space of the element. This prevents closures and therefor possible memory leaks.
  * Also because of the way the function references are stored they will get executed in the
  * same order as they where attached - matching the behavior of addEventListener.
  *
  * @param obj The object to which the event should be attached.
  * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
  * @param fn The function to be executed when the event fires.
  * @param useCapture (optional) Whether to use event capturing, or event bubbling (default).
  */
function addEvent(obj, evType, fn, useCapture)
{
 //-- Default to event bubbling
 if (!useCapture) useCapture = false;

 //-- DOM level 2 method
 if (obj.addEventListener)
 {
  obj.addEventListener(evType, fn, useCapture);
 }
 else
 {
  //-- event capturing not supported
  if (useCapture)
  {
   alert('This browser does not support event capturing!');
  }
  else
  {
   var evTypeRef = '__' + evType;

   //-- create function stack in the DOM space of the element; seperate stacks for each event type
   if (obj[evTypeRef])
   {
    //-- check if handler is not already attached, don't attach the same function twice to match behavior of addEventListener
    if (array_search(fn, obj[evTypeRef]) > -1) return;
   }
   else
   {
    //-- create the stack if it doesn't exist yet
    obj[evTypeRef] = [];

    //-- if there is an inline event defined store it in the stack
    if (obj['on'+evType]) obj[evTypeRef][0] = obj['on'+evType];

    //-- attach helper function using the DOM level 0 method
    obj['on'+evType] = IEEventHandler;
   }

   //-- add reference to the function to the stack
   obj[evTypeRef][obj[evTypeRef].length] = fn;
  }
 }
}

/**
  * removeEvent
  *
  * Generic function to remove previously attached event listeners.
  *
  * @param obj The object to which the event listener was attached.
  * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
  * @param fn The listener function.
  * @param useCapture (optional) Whether event capturing, or event bubbling (default) was used.
  */
function removeEvent(obj, evType, fn, useCapture)
{
 //-- Default to event bubbling
 if (!useCapture) useCapture = false;

 //-- DOM level 2 method
 if (obj.removeEventListener)
 {
  obj.removeEventListener(evType, fn, useCapture);
 }
 else
 {
  var evTypeRef = '__' + evType;

  //-- Check if there is a stack of function references for this event type on the object
  if (obj[evTypeRef])
  {
   //-- check if function is present in the stack
   var i = array_search(fn, obj[evTypeRef]);
   if (i > -1)
   {
    try
    {
     delete obj[evTypeRef][i];
    }
    catch(e)
    {
     obj[evTypeRef][i] = null;
    }
   }
  }
 }
}

/**
  * IEEventHandler
  *
  * IE helper function to execute the attached handlers for events.
  * Because of the way this helperfunction is attached to the object (using the DOM level 0 method)
  * the 'this' keyword will correctely point to the element that the handler was defined on.
  *
  * @param e (optional) Event object, defaults to window.event object when not passed as argument (IE).
  */
function IEEventHandler(e)
{
 e = e || window.event;
 var evTypeRef = '__' + e.type, retValue = true;

 //-- iterate through the stack and execute each function in the scope of the object by using function.call
 for (var i = 0, j = this[evTypeRef].length; i < j; i++)
 {
  if (this[evTypeRef][i])
  {
   if (Function.call)
   {
    retValue = this[evTypeRef][i].call(this, e) && retValue;
   }
   else
   {
    //-- IE 5.0 doesn't support call or apply, so use this
    this.__fn = this[evTypeRef][i];
    retValue = this.__fn(e) && retValue;
   }
  }
 }

 if (this.__fn) try { delete this.__fn; } catch(e) { this.__fn = null; }

 return retValue;
}

/**
  * array_search
  *
  * Searches the array for a given value and returns the (highest) corresponding key if successful, -1 if not found.
  *
  * @param val The value to search for.
  * @param arr The array to search in.
  */
function array_search(val, arr)
{
 var i = arr.length;

 while (i--)
  if (arr[i] && arr[i] === val) break;

 return i;
}

 短的版本:

/**
  * Generic add/removeEvent functionality
  *
  * @author Tino Zijdel ( crisp@xs4all.nl )
  * @version 1.2 (short version)
  * @date 2005-10-21
  */
function addEvent(obj, evType, fn)
{
 var evTypeRef = '__' + evType;

 if (obj[evTypeRef])
 {
  if (array_search(fn, obj[evTypeRef]) > -1) return;
 }
 else
 {
  obj[evTypeRef] = [];
  if (obj['on'+evType]) obj[evTypeRef][0] = obj['on'+evType];
  obj['on'+evType] = handleEvent;
 }

 obj[evTypeRef][obj[evTypeRef].length] = fn;
}

function removeEvent(obj, evType, fn)
{
 var evTypeRef = '__' + evType;

 if (obj[evTypeRef])
 {
  var i = array_search(fn, obj[evTypeRef]);
  if (i > -1) delete obj[evTypeRef][i];
 }
}

function handleEvent(e)
{
 e = e || window.event;
 var evTypeRef = '__' + e.type, retValue = true;

 for (var i = 0, j = this[evTypeRef].length; i < j; i++)
 {
  if (this[evTypeRef][i])
  {
   this.__fn = this[evTypeRef][i];
   retValue = this.__fn(e) && retValue;
  }
 }

 if (this.__fn) try { delete this.__fn; } catch(e) { this.__fn = null; }

 return retValue;
}

function array_search(val, arr)
{
 var i = arr.length;

 while (i--)
  if (arr[i] && arr[i] === val) break;

 return i;
}

 不过我还是用了john resig 的。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值