# Yahoo! UI Library

### Element Event Delegation Module 2.8.0r4

Yahoo! UI Library > element-delegate > Element-Delegate.js (source view)
Search:
Filters Show Private Show Protected Show Deprecated

    /**
     * Augments the Element Utility with a <code>delegate</code> method that
     * facilitates easy creation of delegated event listeners.  (Note: Using CSS
     * selectors as the filtering criteria for delegated event listeners requires
     * inclusion of the Selector Utility.)
     *
     * @module element-delegate
     * @title Element Event Delegation Module
     * @namespace YAHOO.util
     * @requires element, event-delegate
     */

    (function () {

    	var Event = YAHOO.util.Event,
    		delegates = [],
    		specialTypes = {
    			mouseenter: true,
    			mouseleave: true
    		};

    	YAHOO.lang.augmentObject(YAHOO.util.Element.prototype, {

    	    /**
             * Appends a delegated event listener.  Delegated event listeners
    		 * receive two arguments by default: the DOM event and the element
    		 * specified by the filtering function or CSS selector.
    		 * (Note: Using the delegate method requires the element-delegate
    		 * module.  Using CSS selectors as the filtering criteria for delegated
    		 * event listeners requires inclusion of the Selector Utility.)
    	     * @method delegate
    	     * @param {String} type The name of the event to listen for
    	     * @param {Function} fn The handler to call when the event fires
    		 * @param {Function|string} filter Function or CSS selector used to
    		 * determine for what element(s) the event listener should be called.
    		 * When a function is specified, the function should return an
    		 * HTML element.  Using a CSS Selector requires the inclusion of the
    		 * CSS Selector Utility.
    	     * @param {Any} obj A variable to pass to the handler
    	     * @param {Object} scope The object to use for the scope of the handler
             * @return {boolean} Returns true if the delegated event listener
    		 * was added successfully
             * @for Element
    	     */
    		delegate: function (type, fn, filter, obj, overrideContext) {

    			if (YAHOO.lang.isString(filter) && !YAHOO.util.Selector) {
    				YAHOO.log("Using a CSS selector to define the filtering criteria for a delegated listener requires the Selector Utility.", "error", "Element");
    		        return false;
    			}

    			if (!Event._createDelegate) {
    		        YAHOO.log("Using delegate functionality requires the event-delegate module.", "error", "Element");
    		        return false;
    			}

    			var sType = Event._getType(type),
    				el = this.get("element"),
    				fnDelegate,
    				fnMouseDelegate,

    				fnWrapper = function (e) {

    					return fnDelegate.call(el, e);

    				};

    			if (specialTypes[type]) {

    				if (!Event._createMouseDelegate) {
    			        YAHOO.log("Delegating a " + type + " event requires the event-mouseleave module.", "error", "Element");
    			        return false;
    				}

    				fnMouseDelegate = Event._createMouseDelegate(fn, obj, overrideContext);

    				fnDelegate = Event._createDelegate(function (event, matchedEl, container) {

    					return fnMouseDelegate.call(matchedEl, event, container);

    				}, filter, obj, overrideContext);

    			}
    			else {
    				fnDelegate = Event._createDelegate(fn, filter, obj, overrideContext);
    			}

    			delegates.push([el, sType, fn, fnWrapper]);

    			return this.on(sType, fnWrapper);

    		},

    	    /**
    	     * Remove a delegated event listener
    	     * @method removeDelegate
    	     * @param {String} type The name of the event to listen for
    	     * @param {Function} fn The function call when the event fires
             * @return {boolean} Returns true if the unbind was successful, false
             *  otherwise.
             * @for Element
    	     */
    		removeDelegate: function (type, fn) {

    			var sType = Event._getType(type),
    				index = Event._getCacheIndex(delegates, this.get("element"), sType, fn),
    				returnVal,
    				cacheItem;

    		    if (index >= 0) {
    		        cacheItem = delegates[index];
    		    }

    		    if (cacheItem) {

    		        returnVal = this.removeListener(cacheItem[1], cacheItem[3]);

    				if (returnVal) {
    		            delete delegates[index][2];
    		            delete delegates[index][3];
    		            delegates.splice(index, 1);
    				}

    			}

    			return returnVal;

    		}

    	});

    }());

Copyright © 2009 Yahoo! Inc. All rights reserved.