Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 检测DOM元素的父元素何时更改_Javascript_Html_Dom - Fatal编程技术网

Javascript 检测DOM元素的父元素何时更改

Javascript 检测DOM元素的父元素何时更改,javascript,html,dom,Javascript,Html,Dom,元素的parentElement发生更改时是否会触发DOM事件?如果没有,还有什么方法比超时轮询更好吗 我特别感兴趣的是知道parentElement何时从null变为某个已定义的元素。也就是说,当DOM元素附加到文档树的某个位置时 编辑 鉴于注释中的问题,下面是一个示例,演示如何使用null parentElement创建元素: 父级仅在添加到DOM后设置: document.body.appendChild(element); console.assert(element.parentEl

元素的parentElement发生更改时是否会触发DOM事件?如果没有,还有什么方法比超时轮询更好吗

我特别感兴趣的是知道parentElement何时从null变为某个已定义的元素。也就是说,当DOM元素附加到文档树的某个位置时

编辑

鉴于注释中的问题,下面是一个示例,演示如何使用null parentElement创建元素:

父级仅在添加到DOM后设置:

document.body.appendChild(element);

console.assert(element.parentElement != null);
还请注意,使用jQuery创建的元素在创建时也将具有空父元素:

console.assert($('<div></div>').get(0).parentElement == null);

恐怕没有这样的家长听众

然而,我发现了一个可能有用的黑客。至少值得一读,因为这个想法很聪明

他在插入过程中使用CSS@keyframes,并侦听生成的动画事件,该事件告诉他元素已插入。

1这样的parentElementHasChanged事件不存在

2 PISquared指出的变通方法会起作用,但我觉得很奇怪

3实际上,没有必要举办这样的活动。parentChange只有在元素在DOM中的位置发生变化时才会出现在元素中。要实现这一点,必须在元素上运行一些代码,所有这些代码都必须使用native parent.removeChild, parent.appendChild、parent.insertBefore或parent.replaceChild。相同的代码可以在之后运行回调,因此回调将成为事件

4您正在构建库代码。该库可以为所有DOM插入/删除提供一个函数,它封装了四个本机函数并触发事件。这是我想到的避免频繁查找parentElement的最后一个也是唯一一个方法

5如果需要包含本机事件API,可以使用创建parentChanged事件


您正在尝试侦听一个元素是否被另一个元素包装?如果子元素已经在DOM中,parentElement怎么可能为null?我在这里遗漏了什么吗?是的,这也是我的问题,所有元素都将至少有html元素作为父元素?@Krumia@enguerranws新创建元素的父元素为null。OP对它连接到DOM和父元素从null更改为someElement的时刻很感兴趣。请参阅我的编辑以获得澄清。请在此处添加该外部资源的摘要,否则当“如果”该页面不存在时,您的答案将立即无效。感谢您的回答。这绝对是一个有趣的想法。但是,不得不求助于此是一种耻辱。欢迎来到SO顺便说一句:为侦听器误用动画计时器是个坏主意,并且会导致糟糕的代码。我不可能用这个。
console.assert($('<div></div>').get(0).parentElement == null);
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);