Last active
December 29, 2016 10:40
-
-
Save w3core/d4d59fcee33ac03faace568318fbdfbc to your computer and use it in GitHub Desktop.
"selector".on (events, listener, closest)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* on v.1.0.0 | |
* ========== | |
* This tiny extension allows to process events from elements that are added to the document at a later time. | |
* By picking an element that is guaranteed to be present at the time the delegated event handler is attached, | |
* you can use delegated events to avoid the need to frequently attach and remove event handlers. | |
* It's safe to attach events without waiting for the document to be ready. | |
* | |
* "selector".on (events, listener, closest) | |
* | |
* @param selector (String) A comma separated list of CSS selectors | |
* @param events (String) A comma or space separated list of events that should be handled by listener | |
* @param listener (Function) Listener function | |
* @param closest (Boolean) Optional. To handle events if any children node dispatched | |
* | |
* @returns (Function) Listener destructor | |
* | |
* @license MIT | |
* @author Max Chuhryaev | |
*/ | |
!new function (win, doc) { | |
var FUNCTION = "function", BLUR = "blur"; | |
String.prototype.on = function on (event, handler, closest) { | |
var that = this, event = event.match(/[^,\s]+/g) || [], offBlur = onBlur.call(that, event, handler, closest); | |
var on = function (e) { | |
var node = e.target; | |
if (typeof handler == FUNCTION && matchesSelector(node, that, closest)) return handler.call(that, e); | |
}; | |
listen(!0, event, win, on); | |
return function off () { | |
if (typeof offBlur == FUNCTION) offBlur(); | |
listen(!1, event, win, on); | |
}; | |
} | |
function onBlur (event, handler, closest) { | |
var that = this, idx = event.indexOf(BLUR), destruct = [], events = "click keyup"; | |
if (idx >= 0 && typeof handler == FUNCTION) { | |
event.splice(idx, 1); | |
var on = function (e) { | |
var node = e.target; | |
if (!node._hasBlurHandler && matchesSelector(node, that, closest)) { | |
node._hasBlurHandler = !0; | |
listen(!0, BLUR, node, handler); | |
destruct.push(function(){ | |
delete node._hasBlurHandler; | |
listen(!1, BLUR, node, handler); | |
}); | |
} | |
}; | |
listen(!0, events, win, on); | |
return function () { | |
listen(!1, events, win, on); | |
for (var i in destruct) destruct[i](); | |
}; | |
} | |
} | |
function listen (add, event, node, handler) { | |
var pfx = "EventListener", event = typeof event == "string" ? event.match(/[^,\s]+/g) || [] : event; | |
var fn = (add ? "add" : "remove") + pfx; | |
for (var i in event) node[fn](event[i], handler, !1); | |
} | |
function _matchesSelector(el, selector) { | |
if (el == win || el == doc) return !1; | |
var p = Element.prototype; | |
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { | |
return [].indexOf.call(doc.querySelectorAll(s), this) !== -1; | |
}; | |
return f.call(el, selector); | |
} | |
function matchesSelector (el, selector, closest) { | |
if (_matchesSelector(el, selector)) return !0; | |
if (!closest) return !1; | |
return el.parentNode ? matchesSelector (el.parentNode, selector, closest) : !1; | |
} | |
}(window, document); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!new function(h,l){function n(a,b,d){var e=this,c=a.indexOf("blur"),f=[];if(0<=c&&"function"==typeof b){a.splice(c,1);var m=function(a){var c=a.target;!c._hasBlurHandler&&k(c,e,d)&&(c._hasBlurHandler=!0,g(!0,"blur",c,b),f.push(function(){delete c._hasBlurHandler;g(!1,"blur",c,b)}))};g(!0,"click keyup",h,m);return function(){g(!1,"click keyup",h,m);for(var a in f)f[a]()}}}function g(a,b,d,e){b="string"==typeof b?b.match(/[^,\s]+/g)||[]:b;a=(a?"add":"remove")+"EventListener";for(var c in b)d[a](b[c],e,!1)}function p(a,b){if(a==h||a==l)return!1;var d=Element.prototype;return(d.matches||d.webkitMatchesSelector||d.mozMatchesSelector||d.msMatchesSelector||function(a){return-1!==[].indexOf.call(l.querySelectorAll(a),this)}).call(a,b)}function k(a,b,d){return p(a,b)?!0:d?a.parentNode?k(a.parentNode,b,d):!1:!1}String.prototype.on=function(a,b,d){var e=this;a=a.match(/[^,\s]+/g)||[];var c=n.call(e,a,b,d),f=function(a){var c=a.target;if("function"==typeof b&&k(c,e,d))return b.call(e,a)};g(!0,a,h,f);return function(){"function"==typeof c&&c();g(!1,a,h,f)}}}(window,document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
on v.1.0.0
This tiny extension allows to process events from elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. It's safe to attach events without waiting for the document to be ready.
selector
String
events
String
listener
Function
closest
Boolean
Usage example