根据规范,只有BODY
和FRAMESET
元素提供了一个"onload"事件来附加,但我想知道什么时候动态创建的DOM元素已经添加到JavaScript中的DOM.
我目前正在使用的超级天真的启发式方法如下:
遍历元素的parentNode属性,直到找到最终的祖先(即parentNode.parentNode.parentNode.etc,直到parentNode为null)
如果最终祖先具有已定义的非空体属性
假设有问题的元素是dom的一部分
其他
在100毫秒内再次重复这些步骤
我所追求的是确认我正在做的事情是足够的(再次,它在IE7和FF3中工作)或更好的解决方案,无论出于何种原因,我完全忘记了; 也许我应该检查其他属性等.
编辑:我想要一个与浏览器无关的方法,不幸的是,我并不住在一个浏览器的世界里; 也就是说,浏览器特定的信息是值得赞赏的,但是请注意哪个浏览器知道它确实有效.谢谢!
更新:对于任何对它感兴趣的人,这是我最终使用的实现:
function isInDOMTree(node) { // If the farthest-back ancestor of our node has a "body" // property (that node would be the document itself), // we assume it is in the page's DOM tree. return !!(findUltimateAncestor(node).body); } function findUltimateAncestor(node) { // Walk up the DOM tree until we are at the top (parentNode // will return null at that point). // NOTE: this will return the same node that was passed in // if it has no ancestors. var ancestor = node; while(ancestor.parentNode) { ancestor = ancestor.parentNode; } return ancestor; }
我想要的原因是提供一种合成onload
DOM元素事件的方法.这是该函数(虽然我使用的东西略有不同,因为我将它与MochiKit结合使用):
function executeOnLoad(node, func) { // This function will check, every tenth of a second, to see if // our element is a part of the DOM tree - as soon as we know // that it is, we execute the provided function. if(isInDOMTree(node)) { func(); } else { setTimeout(function() { executeOnLoad(node, func); }, 100); } }
例如,此设置可以按如下方式使用:
var mySpan = document.createElement("span"); mySpan.innerHTML = "Hello world!"; executeOnLoad(mySpan, function(node) { alert('Added to DOM tree. ' + node.innerHTML); }); // now, at some point later in code, this // node would be appended to the document document.body.appendChild(mySpan); // sometime after this is executed, but no more than 100 ms after, // the anonymous function I passed to executeOnLoad() would execute
希望对某人有用.
注意:我最终得到这个解决方案而不是Darryl的答案的原因是因为getElementById技术只有在同一个文档中才有效.我在页面上有一些iframe,页面之间以某些复杂的方式进行通信 - 当我尝试这个时,问题是它无法找到元素,因为它是一个不同的文档的一部分而不是它在执行的代码.
最直接的答案是使用Node.contains
Chrome,Firefox(Gecko),Internet Explorer,Opera和Safari支持的方法.这是一个例子:
var el = document.createElement("div"); console.log(document.body.contains(el)); // false document.body.appendChild(el); console.log(document.body.contains(el)); // true document.body.removeChild(el); console.log(document.body.contains(el)); // false
理想情况下,我们会使用document.contains(el)
,但这在IE中不起作用,所以我们使用document.body.contains(el)
.
不幸的是,您仍然需要轮询,但检查元素是否在文档中却非常简单:
setTimeout(function test() { if (document.body.contains(node)) { func(); } else { setTimeout(test, 50); } }, 50);
如果您可以在页面中添加一些CSS,那么这是另一种使用动画检测节点插入的聪明技术:http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
你不能做一个document.getElementById('newElementId');
,看看是否返回true.如果没有,就像你说的那样,等待100毫秒再试一次?
而不是将DOM树走到文档元素只是使用element.ownerDocument
.请参阅此处:https://developer.mozilla.org/en-US/docs/DOM/Node.ownerDocument
并执行以下操作:
element.ownerDocument.body.contains(element)
而且你很好.