You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.1 KiB
78 lines
2.1 KiB
var closest = require('./closest'); |
|
|
|
/** |
|
* Delegates event to a selector. |
|
* |
|
* @param {Element} element |
|
* @param {String} selector |
|
* @param {String} type |
|
* @param {Function} callback |
|
* @param {Boolean} useCapture |
|
* @return {Object} |
|
*/ |
|
function _delegate(element, selector, type, callback, useCapture) { |
|
var listenerFn = listener.apply(this, arguments); |
|
|
|
element.addEventListener(type, listenerFn, useCapture); |
|
|
|
return { |
|
destroy: function() { |
|
element.removeEventListener(type, listenerFn, useCapture); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Delegates event to a selector. |
|
* |
|
* @param {Element|String|Array} [elements] |
|
* @param {String} selector |
|
* @param {String} type |
|
* @param {Function} callback |
|
* @param {Boolean} useCapture |
|
* @return {Object} |
|
*/ |
|
function delegate(elements, selector, type, callback, useCapture) { |
|
// Handle the regular Element usage |
|
if (typeof elements.addEventListener === 'function') { |
|
return _delegate.apply(null, arguments); |
|
} |
|
|
|
// Handle Element-less usage, it defaults to global delegation |
|
if (typeof type === 'function') { |
|
// Use `document` as the first parameter, then apply arguments |
|
// This is a short way to .unshift `arguments` without running into deoptimizations |
|
return _delegate.bind(null, document).apply(null, arguments); |
|
} |
|
|
|
// Handle Selector-based usage |
|
if (typeof elements === 'string') { |
|
elements = document.querySelectorAll(elements); |
|
} |
|
|
|
// Handle Array-like based usage |
|
return Array.prototype.map.call(elements, function (element) { |
|
return _delegate(element, selector, type, callback, useCapture); |
|
}); |
|
} |
|
|
|
/** |
|
* Finds closest match and invokes callback. |
|
* |
|
* @param {Element} element |
|
* @param {String} selector |
|
* @param {String} type |
|
* @param {Function} callback |
|
* @return {Function} |
|
*/ |
|
function listener(element, selector, type, callback) { |
|
return function(e) { |
|
e.delegateTarget = closest(e.target, selector); |
|
|
|
if (e.delegateTarget) { |
|
callback.call(element, e); |
|
} |
|
} |
|
} |
|
|
|
module.exports = delegate;
|
|
|