当元素添加到页面时如何通知我?
我希望在 DOM 元素添加到页面时运行我选择的函数。这是在浏览器扩展的上下文中,因此该网页独立于我运行,我无法修改其源。我在这里有什么选择?
我想,理论上,我可以使用 setInterval() 来不断搜索元素是否存在,并在元素存在时执行我的操作,但我需要更好的方法。
I want a function of my choosing to run when a DOM element is added to the page. This is in the context of a browser extension, so the webpage runs independently of me and I cannot modify its source. What are my options here?
I guess that, in theory, I could just use setInterval()
to continually search for the element's presence and perform my action if the element is there, but I need a better approach.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于突变事件已于 2012 年被弃用,因此您已经无法控制插入的元素,因为它们是由其他人的代码添加的,您唯一的选择就是不断检查它们。
一旦调用该函数,它将每 100 毫秒运行一次,即 1/10(十分之一)秒。除非你需要实时元素观察,否则应该足够了。
Since mutation events were deprecated in 2012, and you have no control over the inserted elements because they are added by someone else's code, your only option is to continuously check for them.
Once this function is called, it will run every 100 milliseconds, which is 1/10 (one tenth) of a second. Unless you need real-time element observation, it should be enough.
实际答案是“使用突变观察者”(如本问题所述:确定 HTML 元素是否已动态添加到 DOM ),但是支持(特别是在 IE 上)是有限的 (http://caniuse.com/mutationobserver)。
所以实际的实际答案是“最终使用突变观察者……但现在就使用 Jose Faeti 的答案”:)
The actual answer is "use mutation observers" (as outlined in this question: Determining if a HTML element has been added to the DOM dynamically), however support (specifically on IE) is limited (http://caniuse.com/mutationobserver).
So the actual ACTUAL answer is "Use mutation observers.... eventually. But go with Jose Faeti's answer for now" :)
在突变事件的弃用和< a href="https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver" rel="noreferrer">
MutationObserver
,当特定元素添加到 DOM 时收到通知的有效方法是 利用 CSS3 动画事件。引用博文:
Between the deprecation of mutation events and the emergence of
MutationObserver
, an efficent way to be notified when a specific element was added to the DOM was to exploit CSS3 animation events.To quote the blog post:
预计到达时间 2017 年 4 月 24 日
我想用一些
async
/await
魔法来简化一下,因为它使它更加简洁:使用相同的promisified-observable:
您的调用函数可以是简单如下:
如果您想添加超时,您可以使用简单的
Promise.race
模式 如此处演示:原始
您可以在没有库的情况下执行此操作,但是您' d 必须使用一些 ES6 的东西,所以要认识到兼容性问题(即,如果你的受众主要是阿米什人、勒德分子或更糟糕的是 IE8 用户)
首先,我们将使用 MutationObserver API 用于构造观察者对象。我们将这个对象包装在一个承诺中,并在回调被触发时
resolve()
(h/t davidwalshblog)david walsh 关于突变的博客文章:然后,我们将创建一个
生成器函数
。如果您还没有使用过这些,那么您就错过了 - 但简单的概要是:它像同步函数一样运行,当它找到yield
表达式时,它以非阻塞方式等待承诺的履行(生成器的作用远不止于此,但这正是我们感兴趣的)。关于生成器的一个棘手的部分是它们不会像普通函数那样“返回”。因此,我们将使用辅助函数来像常规函数一样使用生成器。 (同样,h/t 到 dwb)
然后,在预期的 DOM 突变可能发生之前的任何时候,只需运行runGenerator(getMutation)。
现在您可以将 DOM 突变集成到同步式控制流中。怎么样。
ETA 24 Apr 17
I wanted to simplify this a bit with some
async
/await
magic, as it makes it a lot more succinct:Using the same promisified-observable:
Your calling function can be as simple as:
If you wanted to add a timeout, you could use a simple
Promise.race
pattern as demonstrated here:Original
You can do this without libraries, but you'd have to use some ES6 stuff, so be cognizant of compatibility issues (i.e., if your audience is mostly Amish, luddite or, worse, IE8 users)
First, we'll use the MutationObserver API to construct an observer object. We'll wrap this object in a promise, and
resolve()
when the callback is fired (h/t davidwalshblog)david walsh blog article on mutations:Then, we'll create a
generator function
. If you haven't used these yet, then you're missing out--but a brief synopsis is: it runs like a sync function, and when it finds ayield <Promise>
expression, it waits in a non-blocking fashion for the promise to be fulfilled (Generators do more than this, but this is what we're interested in here).A tricky part about generators is they don't 'return' like a normal function. So, we'll use a helper function to be able to use the generator like a regular function. (again, h/t to dwb)
Then, at any point before the expected DOM mutation might happen, simply run
runGenerator(getMutation)
.Now you can integrate DOM mutations into a synchronous-style control flow. How bout that.
(请参阅底部重新访问的答案)
您可以使用
livequery
jQuery 插件。您可以提供一个选择器表达式,例如:
每次添加
removeItemButton
类的按钮时,状态栏中都会显示一条消息。就效率而言,您可能希望避免这种情况,但无论如何您可以利用该插件而不是创建自己的事件处理程序。
重新访问答案
上面的答案只是为了检测是否已通过插件将项目添加到 DOM。
但是,最有可能的是,
jQuery.on()
方法更合适,例如:如果您有应响应点击的动态内容,则最好使用以下方法将事件绑定到父容器:
jQuery.on
。(see revisited answer at the bottom)
You can use
livequery
plugin for jQuery. You can provide a selector expression such as:Every time a button of a
removeItemButton
class is added a message appears in a status bar.In terms of efficiency you might want avoid this, but in any case you could leverage the plugin instead of creating your own event handlers.
Revisited answer
The answer above was only meant to detect that an item has been added to the DOM through the plugin.
However, most likely, a
jQuery.on()
approach would be more appropriate, for example:If you have dynamic content that should respond to clicks for example, it's best to bind events to a parent container using
jQuery.on
.看看这个插件,它确实做到了这一点 - jquery.initialize
它的工作原理与 .each 函数完全相同,区别在于它需要您输入的选择器并监视将来添加的与此选择器匹配的新项目并初始化它们
初始化看起来像这样
但是现在如果与
.some-element
选择器匹配的新元素将出现在页面上,它将立即初始化。添加新项目的方式并不重要,您不需要关心任何回调等。
因此,如果您添加新元素,例如:
它将立即初始化。
插件基于
MutationObserver
Check out this plugin that does exacly that - jquery.initialize
It works exacly like .each function, the difference is it takes selector you've entered and watch for new items added in future matching this selector and initialize them
Initialize looks like this
But now if new element matching
.some-element
selector will appear on page, it will be instanty initialized.The way new item is added is not important, you dont need to care about any callbacks etc.
So if you'd add new element like:
it will be instantly initialized.
Plugin is based on
MutationObserver
纯 JavaScript 解决方案(没有
jQuery
):A pure javascript solution (without
jQuery
):使用 jQuery,你可以做 -
该函数递归搜索节点,直到找到它,然后针对文档触发一个事件
然后你可以使用它来实现它
With jQuery you can do -
The function search recursively for the node until it finds it then trigger an event against the document
Then you can use this to implement it