将事件侦听器添加到 vanilla javascript 中尚不存在的元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30601620/
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
Adding an event listener to an element that doesn't exist yet in vanilla javascript
提问by Johnston
In JQuery I can do:
在 JQuery 中,我可以这样做:
$(document).on("click","a.someBtn",function(e){
console.log("hi");
});
to add an event listener to an element that doesn't exist yet. I cannot seem to figure out how to add an event listener to an element that does not exist yet in vanilla javascript.
The following does not work obviously:
向尚不存在的元素添加事件侦听器。我似乎无法弄清楚如何将事件侦听器添加到 vanilla javascript 中尚不存在的元素。
以下显然不起作用:
query.addEventListener( "click", someListener );
Edit
编辑
What I would like to do is compare the item by query selectors. I am selecting the element that does not exist yet with querySelectorAll
. It is a little more dynamic than just checking the tag name.
我想做的是通过查询选择器比较项目。我正在选择尚不存在的元素querySelectorAll
。它比仅检查标签名称更具动态性。
回答by AmmarCSE
Use the targetproperty in the event
object to get the clicked element. Then, manually test for type/attributes/ids
使用对象中的target属性event
来获取被点击的元素。然后,手动测试类型/属性/ID
document.addEventListener( "click", someListener );
function someListener(event){
var element = event.target;
if(element.tagName == 'A' && element.classList.contains("someBtn")){
console.log("hi");
}
}
回答by Satpal
You can use event.target
您可以使用event.target
A reference to the object that dispatched the event.
对调度事件的对象的引用。
Code
代码
(function () {
"use strict";
document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
if (e.target.tagName == 'A' && e.target.classList.contains("someBtn")) {
alert('Clicked');
}
}, false);
})();
(function() {
"use strict";
var a = document.createElement('a');
a.textContent = 'Click Me';
a.href = '#';
document.body.appendChild(a);
document.getElementsByTagName('body')[0].addEventListener('click', function(e) {
if (e.target.tagName == 'A') {
alert('Clicked');
}
}, false);
})();
回答by martynasma
Here's a function that will let you add "live" events like jQuery's .on
. It can be invoked like this:
这是一个函数,可以让您添加“实时”事件,如 jQuery 的.on
. 可以这样调用:
addLiveListener(scope, selector, event, function reference);
Take a look at the function comment for the description of each of those parameters.
查看函数注释以了解每个参数的描述。
/**
* Adds a istener for specific tags for elements that may not yet
* exist.
* @param scope a reference to an element to look for elements in (i.e. document)
* @param selector the selector in form [tag].[class] (i.e. a.someBtn)
* @param event and event (i.e. click)
* @param funct a function reference to execute on an event
*/
function addLiveListener(scope, selector, event, funct) {
/**
* Set up interval to check for new items that do not
* have listeners yet. This will execute every 1/10 second and
* apply listeners to
*/
setInterval(function() {
var selectorParts = selector.split('.');
var tag = selectorParts.shift();
var className;
if (selectorParts.length)
className = selectorParts.shift();
if (tag != "") {
tag = tag.toUpperCase();
var elements = scope.getElementsByTagName(tag);
} else
var elements = scope.getElementsByClassName(className);
for (var i = 0; i < elements.length; i++) {
if (elements[i][event + '_processed'] === undefined && (tag == "" || elements[i].tagName == tag)) {
elements[i].addEventListener(event, funct);
}
}
}, 1000);
}
And here's a full working demo:
这是一个完整的工作演示:
/**
* Adds another anchor with no events attached and lets
* our other code auto-attach events
*/
var currentAnchor = 3;
function addAnchor() {
currentAnchor++;
var element = document.createElement('a');
element.href = "#";
element.innerHTML = "Anchor " + currentAnchor;
element.className = "someBtn";
document.getElementById("holder").appendChild(element);
}
/**
* Adds a istener for specific tags for elements that may not yet
* exist.
* @param scope a reference to an element to look for elements in (i.e. document)
* @param selector the selector in form [tag].[class] (i.e. a.someBtn)
* @param event and event (i.e. click)
* @param funct a function reference to execute on an event
*/
function addLiveListener(scope, selector, event, funct) {
/**
* Set up interval to check for new items that do not
* have listeners yet. This will execute every 1/10 second and
* apply listeners to
*/
setInterval(function() {
var selectorParts = selector.split('.');
var tag = selectorParts.shift();
var className;
if (selectorParts.length)
className = selectorParts.shift();
if (tag != "") {
tag = tag.toUpperCase();
var elements = scope.getElementsByTagName(tag);
} else
var elements = scope.getElementsByClassName(className);
for (var i = 0; i < elements.length; i++) {
if (elements[i][event + '_processed'] === undefined && (tag == "" || elements[i].tagName == tag)) {
elements[i].addEventListener(event, funct);
}
}
}, 1000);
}
/**
* Now let's add live listener for "a" tags
*/
addLiveListener(document, "a.someBtn", "click", function() {
alert('Clicked ' + this.innerHTML);
});
a {
margin-right: 10px;
}
<!-- Add some pre-existing anchors -->
<p id="holder">
<a href="#" class="someBtn">Anchor 1</a><a href="#" class="someBtn">Anchor 2</a><a href="#" class="someBtn">Anchor 3</a>
</p>
<!-- A button to add dynamic new anchors -->
<input type="button" value="Add anchor" onclick="addAnchor();" />
回答by Volfegan
What you want is to use DOM MutationObserver Events to apply the addEventListener. This DOM API is available on all major browser since 2012 I think.
您想要的是使用 DOM MutationObserver Events 来应用 addEventListener。我认为自 2012 年以来,这个 DOM API 可在所有主要浏览器上使用。
I use this on to lower the google translator bar created by their snippet (https://www.w3schools.com/howto/howto_google_translate.asp). Since it creates the element dynamically (an iframe), it is the same problem you have. Just change the callback function and variables for your need.
我用它来降低由他们的片段(https://www.w3schools.com/howto/howto_google_translate.asp)创建的谷歌翻译栏。由于它动态创建元素(iframe),因此与您遇到的问题相同。只需根据需要更改回调函数和变量即可。
//Observer for Google translator bar creation and action to move to bottom
// Select the nodetree that will be observed for mutations
var nodetree = document.getElementsByTagName("body")[0];
// Select the target node atributes (CSS selector)
var targetNode = "iframe.goog-te-banner-frame";
// Options for the observer (which mutations to observe)
var config = { attributes: false, childList: true };
// Callback function to execute when mutations of DOM tree are observed
var lowerGoogleTranslateBar = function(mutations_on_DOMtree) {
for(var mutation of mutations_on_DOMtree) {
if (mutation.type == 'childList') {
console.log(mutation);
if (document.querySelector(targetNode) != null) {
//40px is the height of the bar
document.querySelector(targetNode).style.setProperty("top", "calc(100% - 40px)");
//after action is done, disconnect the observer from the nodetree
observerGoogleTranslator.disconnect();
}
}
}
};
// Create an observer instance linked to the callback function
var observerGoogleTranslator = new MutationObserver(lowerGoogleTranslateBar);
// Start observing the target node for configured mutations
observerGoogleTranslator.observe(nodetree, config);
You can learn more about this here: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
您可以在此处了解更多信息:https: //developer.mozilla.org/en-US/docs/Web/API/MutationObserver