当元素parentElement
发生变化时,是否会触发DOM事件?如果没有,有没有比超时轮询更好的方法?
我非常有兴趣了解parentElement
何时从null
更改为某个已定义的元素。也就是说,当某个DOM元素附加到文档树的某个地方时。
修改
鉴于评论中的问题,以下是一个示例,说明如何使用null
parentElement
创建元素:
var element = document.createElement('div');
console.assert(element.parentElement == null);
父级只有在添加到DOM后才会设置:
document.body.appendChild(element);
console.assert(element.parentElement != null);
另请注意,使用jQuery创建的元素在创建时也将具有null
父级:
console.assert($('<div></div>').get(0).parentElement == null);
答案 0 :(得分:3)
Afaik那里没有这样的&#34;父母听众&#34;。
然而,我发现了一个可能有用的黑客攻击。至少它值得一读,因为这个想法很聪明。
http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
他在插入过程中使用CSS @keyframes并侦听生成的动画事件,告诉他该元素已被插入。
答案 1 :(得分:1)
1)这样的parentElementHasChanged event
不存在。
2)解决方法 PISquared 指向可行,但对我来说看起来很奇怪。
3)在实践中,不需要这样的事件。如果一个元素在DOM中的位置发生变化,那么parentChange只会出现在元素中。为了实现这一点,你必须在执行此操作的元素上运行一些代码,并且所有代码都必须使用本机parent.removeChild()
,
某处parent.appendChild
,parent.insertBefore()
或parent.replaceChild()
。之后相同的代码可以运行回调,因此回调将是事件。
4)您正在构建库代码。该库可以为所有DOM插入/删除提供单个函数,它包含四个本机函数,并且&#34;触发事件&#34;。这是最后一次,也是我唯一想要避免频繁查找parentElement的内容。
5)如果需要包含原生Event API
,您可以使用CustomEvent
element.addEventListener('parentChanged', handler); // only when Event API needed
function manipulateElementsDOMPosition(element, target, childIndex, callback, detail) {
if (!target.nodeType) {
if (arguments.length > 4) return element;
detail = callback; callback = childIndex; childIndex = target; target = null;
}
if (typeof childIndex === 'function') detail = callback, callback = childIndex;
var oldParent = element.parentElement,
newParent = target,
sameParent = oldParent === newParent,
children = newParent.children,
cl = children.length,
ix = sameParent && cl && [].indexOf.call(children, element),
validPos = typeof childIndex === 'number' && cl <= childIndex;
if (childIndex === 'replace') {
(newParent = target.parentElement).replaceChild(element, target);
if (sameParent) return element;
} else {
if (samePar) {
if (!oldParent || ix == childIndex ||
childIndex === 'first' && ix === 0 ||
childIndex === 'last' && ix === (cl - 1)) return element;
oldParent.removeChild(element);
} else if (oldParent) oldParent.removeChild(element);
if (!cl || childIndex === 'last') {
newParent.appendChild(element);
} else if (childIndex === 'first') {
newParent.insertBefore(element, children[0])
} else if (validPos) {
newParent.insertBefore(element, children[childIndex]);
} else return element;
}
console.log(element, 'parentElement has changed from: ', oldParent, 'to: ', newParent);
element.dispatchEvent(new CustomEvent('parentChanged', detail)); // only when Event API needed
if (typeof callback === 'function') callback.call(element, oldParent, newParent, detail);
return element;
}
一些示例用法(详细信息可能是您想要传递给事件/回调的任何内容)。函数总是返回元素。
// remove element
manipulateElementsDOMPosition(element /*optional:*/, callback, detail);
// prepend element in target
manipulateElementsDOMPosition(element, target, 'first' /*optional:*/, callback, detail);
// append element in target
manipulateElementsDOMPosition(element, target, 'last' /*optional:*/, callback, detail);
// add element as third child of target, do nothing when less than two children there
manipulateElementsDOMPosition(element, target, 3 /*optional:*/, callback, detail);
// replace a target-element with element
manipulateElementsDOMPosition(element, target, 'replace' /*optional:*/, callback, detail);