相当于 $.on 的 Javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30880757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript equivalent to $.on
提问by Polarize
As somebody who (unfortunately) learned more of jQuery
than rawjavascript
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
?
作为一个(不幸)学到的jQuery
不仅仅是raw 的人,javascript
我现在正在花时间用 raw 替换我的所有代码javascript
。不,它不是必需的,但对我来说这是一种更简单的学习方式。我面临的一个问题是将我的所有内容转换为$(document).on
raw javascript
。我的网站是一个“单页应用程序”,我的大部分内容HTML
都在通过Ajax
请求调用的不同文件中。所以,我的问题是,我将如何寻找event
从动态加载的内容中触发的内容?我假设我必须向onclick
它们添加一个事件,但是它是如何在jQuery
不需要onclick
event
?
回答by
Binding handlers in native API is done using addEventListener()
.
本机 API 中的绑定处理程序是使用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.
要模拟 jQuery 的事件委托,您可以相当轻松地创建一个系统,该系统使用该.matches()
方法来测试您提供的选择器。
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.
可能需要进行一些调整,但基本上它是一个将元素绑定到的函数,例如document
事件类型、选择器和处理程序。
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.
它从 开始e.target
并向上遍历父元素,直到到达绑定元素。每次,它都会检查当前元素是否与选择器匹配,如果匹配,则调用处理程序。
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()
.
这里有一个 shim 来增加对.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;
};
}
回答by AmmarCSE
Here is a javascript equivalentto on()
这里是JavaScript中的等价于on()
jQuery
jQuery
$(document).on('click', '#my-id', callback);
function callback(){
...handler code here
}
Javascript
Javascript
document.addEventListener('click', function(event) {
if (event.target.id == 'my-id') {
callback();
}
});
function callback(){
...handler code here
}
With this approach, the idea is to make use of event.target. Of course, as the selector changes, your code will have to get more involved
通过这种方法,我们的想法是利用event.target。当然,随着选择器的变化,你的代码将不得不更多地参与
回答by benvc
In modern browsers, you can use Element.closest()
to simplify replication of jQuery's .on()
method as well as ensure that you capture event bubbling from children of the targeted element (a nuance that some other implementations overlook). Older browsers, including IE, would require a polyfillfor this to work.
在现代浏览器中,您可以使用Element.closest()
来简化 jQuery.on()
方法的复制,并确保您捕获来自目标元素的子元素的事件冒泡(其他一些实现忽略的细微差别)。旧的浏览器,包括 IE,需要一个polyfill才能工作。
const on = (element, event, selector, handler) => {
element.addEventListener(event, e => {
if (e.target.closest(selector)) {
handler(e);
}
});
}
on(document, 'click', '#test', e => {
console.log('click');
});
<button id="test">
Clickable
<i>Also Clickable</i>
</button>
回答by Peter Darmis
Another approach for modern browsers would be something like this:
现代浏览器的另一种方法是这样的:
const on = (selector, event, handler, element=document) => {
element.addEventListener(event, (e) => { if(e.target.matches(selector)) handler(e); });
};
// click will work for each selector
on('[type="button"], .test, #test','click', e => {
alert(e.target.innerHTML);
});
// click event will work for nested .test3 element only
on('.test3','click', e => {
alert(e.target.innerHTML);
},document.querySelector('.test2'));
<div id="test">
test
</div>
<div class="test">
test 1
</div>
<div class="test">
test 2
</div>
<button type="button">
go
</button>
<div class="test3">
test 3 outer
</div>
<div class="test2">
<div class="test3">
test 3 inner
</div>
test 2
</div>