【发布时间】:2011-01-24 10:14:13
【问题描述】:
如何在 jquery 中检测何时将新元素添加到文档中?
说明: 我想知道何时将具有“列标题”类的元素添加到文档中。因为我计划在这些元素上运行一些 javascript。
我该怎么做?我使用 jQuery javascript 库。
【问题讨论】:
标签: javascript jquery html css
如何在 jquery 中检测何时将新元素添加到文档中?
说明: 我想知道何时将具有“列标题”类的元素添加到文档中。因为我计划在这些元素上运行一些 javascript。
我该怎么做?我使用 jQuery javascript 库。
【问题讨论】:
标签: javascript jquery html css
接受的答案使用 2011 年过时的插件,最高投票的答案使用 Mutation 事件,现在是 deprecated。
今天,您应该使用 MutationObserver 来检测元素何时添加到 DOM。 现在所有现代浏览器(Chrome 26+、Firefox 14+)都广泛支持 MutationObservers 、IE11、Edge、Opera 15+ 等)。
这是一个简单的示例,说明如何使用MutationObserver 来监听元素何时添加到 DOM。
为简洁起见,我使用 jQuery 语法来构建节点并将其插入到 DOM 中。
var myElement = $("<div>hello world</div>")[0];
var observer = new MutationObserver(function(mutations) {
if (document.contains(myElement)) {
console.log("It's in the DOM!");
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
$("body").append(myElement); // console.log: It's in the DOM!
只要在document 中添加或删除任何节点,observer 事件处理程序就会触发。在处理程序内部,我们然后执行contains 检查以确定myElement 现在是否在document 中。
您无需遍历存储在 mutations 中的每个 MutationRecord,因为您可以直接对 myElement 执行 document.contains 检查。
要提高性能,请将 document 替换为 DOM 中将包含 myElement 的特定元素。
【讨论】:
$(document).bind('DOMNodeInserted', function(e) {
console.log(e.target, ' was inserted');
});
DOMNodeInserted 是一个 DOM 级别 3 事件。这反过来意味着,您需要一个相当新的浏览器来支持这种事件。
参考:MDC
【讨论】:
如果你想在上面做一些jQuery,你也可以做类似livequery (extra plugin):
$('column-header').livequery(function()
{
// do things here with your column-header, like binding new events and stuff.
// this function is called when an object is added.
// check the API for the deletion function and so on.
});
更新: 似乎链接已断开。试试this link
【讨论】:
我会使用 setInterval 反复检查元素。例如。
var curLength=0;
setInterval(function(){
if ($('.column-header').length!=curLength){
curLength=$('.column-header').length;
// do stuff here
}
},100);
此代码将每 100 毫秒检查一次任何新的 .colum-header 元素
【讨论】:
我认为上面提到的 DOMNodeInserted 方法可能是最性感的选择,但是如果你需要一些可以在 IE8 及更低版本上运行的东西,你可以执行以下操作:
// wrap this up in en immediately executed function so we don't
// junk up our global scope.
(function() {
// We're going to use this to store what we already know about.
var prevFound = null;
setInterval(function() {
// get all of the nodes you care about.
var newFound = $('.yourSelector');
// get all of the nodes that weren't here last check
var diff = newFound.not(prevFound);
// do something with the newly added nodes
diff.addClass('.justGotHere');
// set the tracking variable to what you've found.
prevFound = newFound;
}, 100);
})();
这只是基本的想法,你可以随意改变它,用它创建一个方法,保留 setInterval 的返回值以便你可以停止它,或者你需要做的任何事情。但它应该可以完成工作。
【讨论】:
您应该查看jQuery Mutation Events。我相信这就是您正在寻找的。p>
【讨论】:
如果你想为类column-header的所有元素设置相同的功能
然后你可以使用 jquery live()
$(".column-header").live("click",function(){});
【讨论】:
如何使用投票 - 继续搜索具有“列标题”类的元素,直到找到它然后执行操作。看起来很简单。
【讨论】:
不推荐使用直到 2013 年的 MutationEvents。如果其他人在检测 dom 中的新元素时遇到问题,您可以使用 MutationObservers 代替: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
【讨论】:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
/* Observing Easy */
function observing(who, forWhat, callBack){
var observer = new MutationObserver(function(mutations) {
mutations.forEach(mutation => {
console.log(mutation.addedNodes[0])
if ( mutation.addedNodes[0].matches(forWhat)){
console.log('MATCH!');
if(callBack!==undefined){
callBack(mutation)
}
}else{
console.log('%cNOT match', 'color: #f00');
}
});
});
observer.observe($(who)[0], {attributes: false, childList: true, characterData: false, subtree:false});
}
$(document).ready(function(){
/* Observing Usage */
observing('div#application', 'div.viewContainer', function(mutation){
console.log('Mutation:', mutation)
})
/* Adding Elements for Test */
$("#application").append($("<div>Hello World</div>")[0]);
$("#application").append($("<div class='contentFake'>ContentClassFAKE</div>")[0])
$("#application").append($("<div class='contentFake'>ContentClass1</div>")[0])
$("#application").append($("<div class='viewContainer'>ContentClass2</div>")[0])
setTimeout(function(){
$("#application").append($("<div class='contentFake'>ContentClass3</div>")[0])
}, 1000)
setTimeout(function(){
$("#application").append($("<div class='viewContainer'>ContentClass4</div>")[0])
}, 1000)
})
</script>
</head>
<body>
<div id="application"></div>
</body>
</html>
【讨论】:
试试这个……
if($('.column-header')){
//do something...
}
或者你也可以做这样的事情..它会更通用
jQuery.exists = function(selector) { return ($(selector).length > 0); }
if ($(selector).exists()) {
// Do something
}
【讨论】: