元素添加到页面时的事件

这是之前在这里讨论的: 如何使用Jquery将一个元素添加到页面时执行一个操作?

响应者build议每当div添加到页面时触发一个自定义事件。 不过,我正在编写Chrome扩展程序,无法访问页面源代码。 我在这里有什么select? 我想在理论上,我可以使用setTimeout来持续search元素的存在,并添加我的动作,如果元素在那里。

由于DOM突变事件现在已被弃用 (请参见底部的注释)和最新的规范,你不能控制插入的元素,因为它们是由别人的代码添加的,唯一的select是不断地检查它们。

 function checkDOMChange() { // check for any new element being inserted here, // or a particular node being modified // call the function again after 100 milliseconds setTimeout( checkDOMChange, 100 ); } 

一旦调用这个函数,它将每xxx毫秒运行一次。 我select100次,这是每秒10次。 除非你需要实时的元素捕捉,否则应该就够了。

编辑

正如Ben Davis所说,DOM Level 4规范引入了Mutation观察者 (也在Mozilla文档上 ),它取代了被弃用的突变事件。

实际的答案是“使用突变观察者”(在这个问题中概述: 确定HTML元素是否已经dynamic添加到DOM ),但支持(特别是在IE)是有限的( http://caniuse.com/mutationobserver ) 。

所以实际的实际答案是“最终使用突变观察者……但是现在就和Jose Faeti的答案一起”:)

你可以使用jQuery的livequery插件。 您可以提供一个select器expression式,例如:

 $("input[type=button].removeItemButton").livequery(function () { $("#statusBar").text('You may now remove items.'); }); 

每次添加removeItemButton类的button时,都会在状态栏中显示一条消息。

就效率而言,您可能想要避免这种情况,但无论如何,您都可以利用插件而不是创build自己的事件处理程序。

重新回答

上面的答案只是为了检测一个项目是否已经通过插件添加到了DOM中

然而,最有可能的是,一个jQuery.on()方法更合适,例如:

 $("#myParentContainer").on('click', '.removeItemButton', function(){ alert($(this).text() + ' has been removed'); } 

例如,如果您的dynamic内容应该对点击做出响应,最好使用jQuery.on将事件绑定到父容器。

您也可以利用CSS3animation事件,以便在将特定元素添加到DOM时得到通知: http : //www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/

ETA 24 Apr 17我想用一些async / await魔法简化一下,因为它使得它更加简洁:

使用相同的promisified-observable:

 const startObservable = (domNode) => { var targetNode = domNode; var observerConfig = { attributes: true, childList: true, characterData: true }; return new Promise((resolve) => { var observer = new MutationObserver(function (mutations) { // For the sake of...observation...let's output the mutation to console to see how this all works mutations.forEach(function (mutation) { console.log(mutation.type); }); resolve(mutations) }); observer.observe(targetNode, observerConfig); }) } 

您的调用函数可以像下面这样简单:

 const waitForMutation = async () => { const button = document.querySelector('.some-button') if (button !== null) button.click() try { const results = await startObservable(someDomNode) return results } catch (err) { console.error(err) } } 

如果你想添加一个超时,你可以使用一个简单的Promise.race模式, 如下所示 :

 const waitForMutation = async (timeout = 5000 /*in ms*/) => { const button = document.querySelector('.some-button') if (button !== null) button.click() try { const results = await Promise.race([ startObservable(someDomNode), // this will throw after the timeout, skipping // the return & going to the catch block new Promise((resolve, reject) => setTimeout( reject, timeout, new Error('timed out waiting for mutation') ) ]) return results } catch (err) { console.error(err) } } 

原版的

你可以在没有库的情况下做到这一点,但是你必须使用一些ES6的东西,所以要认识到兼容性问题(例如,如果你的用户主要是阿米什语,luddite或者更糟的是IE8用户)

首先,我们将使用MutationObserver API构build观察者对象。 我们将这个对象包装在一个promise中,并resolve()时,callback被激发(h / t davidwalshblog) 大卫沃尔什博客文章突变 :

 const startObservable = (domNode) => { var targetNode = domNode; var observerConfig = { attributes: true, childList: true, characterData: true }; return new Promise((resolve) => { var observer = new MutationObserver(function (mutations) { // For the sake of...observation...let's output the mutation to console to see how this all works mutations.forEach(function (mutation) { console.log(mutation.type); }); resolve(mutations) }); observer.observe(targetNode, observerConfig); }) } 

然后,我们将创build一个generator function 。 如果你还没有使用过,那么你就错过了 – 但是一个简短的概要是:它像一个同步函数一样运行,当它find一个yield <Promise>expression式时,它以非阻塞的方式等待要实现的承诺( 发电机做得比这更多,但这是我们在这里感兴趣的 )。

 // we'll declare our DOM node here, too let targ = document.querySelector('#domNodeToWatch') function* getMutation() { console.log("Starting") var mutations = yield startObservable(targ) console.log("done") } 

关于发电机的一个棘手的部分是他们不像一个正常的function“返回”。 所以,我们将使用一个辅助函数来像普通函数那样使用生成器。 (再次, h / t到DWB )

 function runGenerator(g) { var it = g(), ret; // asynchronously iterate over generator (function iterate(val){ ret = it.next( val ); if (!ret.done) { // poor man's "is it a promise?" test if ("then" in ret.value) { // wait on the promise ret.value.then( iterate ); } // immediate value: just send right back in else { // avoid synchronous recursion setTimeout( function(){ iterate( ret.value ); }, 0 ); } } })(); } 

然后,在预期的DOM突变可能发生之前的任何时候,只需运行runGenerator(getMutation)

现在,您可以将DOM突变整合到同步风格的控制stream程中。 怎么回事

有一个名为Arrive的有前途的JavaScript库,一旦浏览器支持变得平常,看起来像是一个很好的开始利用变异观察者的方法。

https://github.com/uzairfarooq/arrive/

看看这个插件,做到了 – jquery.initialize

它的function非常像.eachfunction,不同之处在于它需要您select的select器,并在以后添加的新项目中匹配此select器并初始化它们

初始化看起来像这样

 $(".some-element").initialize( function(){ $(this).css("color", "blue"); }); 

但是现在,如果新的元素匹配.some-elementselect器将出现在页面上,它将立即初始化。

添加新项目的方式并不重要,你不需要关心任何callback等。

所以如果你想添加新的元素,如:

 $("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color! 

它会被立即初始化。

插件基于MutationObserver