79 lines
2.1 KiB
JavaScript
79 lines
2.1 KiB
JavaScript
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;
|