2012-03-19 66 views
7

我喜欢在不拥有或控制的页面上运行自定义脚本。很多时候,这些网页都有动态创建的内容,我想应用一个功能。插入动态创建DOM节点的处理程序

这可能吗?如果是这样,我该怎么做?理想情况下,我正在寻找一些实时jQuery的live方法,除了代替绑定像click这样的事件,它更像是在DOM中加载元素时发生的事件。 load事件可能适用于某些元素,但我不认为所有...

对于此问题,假设您无法查看或更改插入DOM节点的代码。我想要一种技巧,可以在可以跨多个不相关网站使用的用户脚本或书签中使用。

编辑:我寻找的东西在我的反色书签使用:JavaScript: Invert color on all elements of a page

+0

你打算申请什么样的功能?您可以监听DOMNodeInsertedIntoDocument事件,但这可能适用于许多您不感兴趣的插入节点。 – nrabinowitz 2012-03-19 22:41:53

+0

我对每个节点都感兴趣。我正在改变页面上所有内容的颜色。 – Muhd 2012-03-19 22:42:46

回答

6

假设你正在运行像Firefox或Chrome浏览器,你可以监听DOMNodeInserted事件:

$(document).on('DOMNodeInserted', function(e) { 
    $(e.target).css({ color : '#c00' }); 
}); 

$('body').append('<div>test</div>');​ 

小提琴:http://jsfiddle.net/VeF6g/(可能失败在IE)

+1

为了随机读者的缘故,我只想说明一下:如果可以避免,请不要使用突变事件。详细信息:http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html – Nickolay 2012-03-20 00:53:41

+1

@Nickolay - 感谢您的参考。我知道使用这些通常是一个糟糕的主意,但对于OP的用例似乎是合理的(除此之外,讨论关于用户脚本,因此他将是唯一受慢速或崩溃影响的人)。 – nrabinowitz 2012-03-20 03:55:27

1

这是相当难以实现,因为对于反应DOM没有可行的事件变化。我宁愿坚持事件转授。

但是,有些事件可能会让您觉得有用或有趣。在Mozilla Developer Network's list of DOM events你可以看到例如:

  • DOMNodeInserted
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemoved
  • DOMElementNameChanged

他们的所有但是被标记为W3C草案。

+0

这些实现了哪些浏览器?理想情况下,我希望在Chrome中使用某些功能。 – Muhd 2012-03-19 22:47:07

+0

“草稿”标记是部分MDC编辑的疏忽。这些事件也在DOML2 Events中,这是“推荐”。事实是,这些事件中的大部分都适用于除IE之外的所有事件;但如果可以的话,你应该避免使用它们,因为它们有很大的缺点(详细信息:http://lists.w3.org/Archives/Public/public-webapps/2011JulSep/0779.html) – Nickolay 2012-03-20 00:51:55

1

检测节点插入的通用方法是使用DOMNodeInserted突变事件。

我对每个节点都有兴趣。我正在改变页面上所有内容的颜色。

为此,更好的解决方案是注入一个动态样式表,该标志符合!important标志。如果你只想改变颜色,我推荐使用Stylish扩展名(Stylish for Chrome)而不是GreaseMonkey。

+0

对,但是'!重要的“国旗会毁掉很多页面。我正在创建一个智能脚本,可以在很多不同的页面上工作,并且看起来不错。 – Muhd 2012-03-19 22:46:17

+0

@Muhd您可以选择智能选择器来仅选择特定元素。 Stylish使用RegExes通过'@ -moz-document regexp()'支持域选择 - 另见['@ document'](https://developer.mozilla.org/en/CSS/@document)。 – 2012-03-19 22:48:39

1

如果没有获得像jQuery的库,这里是only- 的JavaScript语法:

document.addEventListener('DOMNodeInserted', nodeInsert) 

function nodeInsert() { 
    event.srcElement.style.color = '#ffffff' 
} 

我认为它应该适用于大多数浏览器。

3

下面是处理节点插入事件的一个好方法。为要使用css添加的元素设置动画。

<style type="text/css"> 

/* set up the keyframes; remember to create prefixed keyframes too! */ 

@keyframes nodeInserted { 
from { opacity: 0.99; } 
to { opacity: 1; } 
} 

#parent > button { 
animation-duration: 0.001s; 
animation-name: nodeInserted; 
} 

</style> 

#parent是股利,其中我要去追加按钮的 动态的ID。

<script type="text/javascript"> 

    var insertListener = function(event){ 
     if (event.animationName == "nodeInserted") { 
      // This is the debug for knowing our listener worked! 
      // event.target is the new node! 
      console.warn("Another node has been inserted! ", event, event.target); 
     } 
    } 

    document.addEventListener("animationstart", insertListener, false); // standard + firefox 
    document.addEventListener("MSAnimationStart", insertListener, false); // IE 
    document.addEventListener("webkitAnimationStart", insertListener, false); // Chrome + Safari 

    setInterval(function(){ 

     var btn = document.createElement("BUTTON"); 

     var t = document.createTextNode("CLICK ME");  // Create a text node 

     btn.appendChild(t);   

     document.getElementById("parent").appendChild(btn); 

    }, 2000); 

</script> 
+0

我已经实现了这个方法,并在'insertListener'方法内编写了一个'iframe'的响应大小调整。奇怪的是,调整自定义行为只发生在向下滚动到iframe之前,而不是之前。任何想法可能会发生在这里? – 2017-02-11 17:21:35