1) таких parentElementHasChanged event
не существует.
2) Обходной путь PISquared указал, что это сработает, но выглядит очень странно для меня.
3) На практике нет необходимости в таком событии. Элемент parentChange будет отображаться только в элементе, если это позиция в изменениях DOM. Чтобы это произошло, вам нужно запустить некоторый код для элемента, который делает это, и весь этот код должен использовать родные parent.removeChild()
, parent.appendChild
, parent.insertBefore()
или parent.replaceChild()
где-то. Один и тот же код может выполнить обратный вызов после этого, поэтому обратный вызов будет событием.
4) Вы создаете код библиотеки. Библиотека может предоставить одну функцию для всех DOM-вставок/абстракций, которая обертывает четыре родные функции и «запускает событие». Это последнее и единственное, что приходит мне на ум, чтобы избежать частого поиска родительского элемента.
5) Если есть необходимость включать нативную Event API
, вы можете создать ParentChanged событие с 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);
Вы пытаетесь выслушать, если элемент обернут в другой? – enguerranws
Как родительский элемент может быть нулевым, если дочерний объект уже находится в DOM? Я что-то упустил? – Krumia
Да, это тоже мой вопрос, все элементы будут иметь хотя бы элемент html в качестве родителя? – enguerranws