As somebody who (unfortunately) learned more of jQuery
than raw javascript
I am just now taking the time to replace all of my code with raw javascript
. No, it's not needed, but it's an easier way for me to learn. A problem I am facing is converting all of my $(document).on
with raw javascript
. My website is a "single-page application" and most of my actual HTML
is in different files which are called via Ajax
requests. So, my question is, how would I look for an event
fired from dynamically loaded content? I am assuming I would have to add an onclick
event to them, but how is it that jQuery
does it without needing an onclick
event
?
Binding handlers in native API is done using addEventListener()
.
To emulate jQuery's event delegation, you could fairly easily create a system that uses the .matches()
method to test the selector you give.
function delegate(el, evt, sel, handler) {
el.addEventListener(evt, function(event) {
var t = event.target;
while (t && t !== this) {
if (t.matches(sel)) {
handler.call(t, event);
}
t = t.parentNode;
}
});
}
There are probably some tweaks to be made, but basically it's a function that takes the element to bind to, like document
, the event type, a selector and the handler.
It starts on the e.target
and traverses up the parents until it gets to the bound element. Each time, it checks to see if the current element matches the selector, and if so, it invokes the handler.
So you'd call it like this:
delegate(document, "click", ".some_elem", function(event) {
this.style.border = "2px dashed orange";
});
Here's a live demo that also adds dynamic elements to show that new elements are picked up as well.
function delegate(el, evt, sel, handler) {
el.addEventListener(evt, function(event) {
var t = event.target;
while (t && t !== this) {
if (t.matches(sel)) {
handler.call(t, event);
}
t = t.parentNode;
}
});
}
delegate(document, "click", ".some_elem", function(event) {
this.parentNode.appendChild(this.cloneNode(true));
this.style.border = "2px dashed orange";
});
<div>
<p class="some_elem">
<span>
CLICK ME
</span>
</p>
</div>
Here's a shim to add a bit more support for .matches()
.
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.webkitMatchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments