Как проверить, находится ли элемент jQuery в DOM?
предположим, что я определяю элемент
$foo = $('#foo');
и
$foo.remove()
из какого-то события. Мой вопрос в том, как проверить, был ли $foo удален из DOM или нет? Я нашел это $foo.is(':hidden')
работает, но это, конечно, также вернет true, если я просто позвоню $foo.hide()
.
11 ответов
такой:
if (!jQuery.contains(document, $foo[0])) {
//Element is detached
}
Это будет работать, если один из родителей элемент был удален (в этом случае сам элемент будет родителем).
Я только что понял ответ, когда я набирал свой вопрос: Call
$foo.parent()
если $f00
был удален из DOM, то $foo.parent().length === 0
. В противном случае его длина будет не менее 1.
[Edit: это не совсем правильно, потому что удаленный элемент все еще может иметь родителя; например, если вы удалите <ul>
, каждый из своих детей <li>
s по-прежнему будет иметь родителя. Вместо этого используйте ответ Слакса.
поскольку я не могу ответить как комментарий (слишком низкая карма, я думаю), вот полный ответ. Самый быстрый способ-легко развернуть проверку jQuery для поддержки браузера и свести постоянные факторы к минимуму.
Как видно также здесь -http://jsperf.com/jquery-element-in-dom/28 - код будет выглядеть так:
var isElementInDOM = (function($) {
var docElt = document.documentElement, find,
contains = docElt.contains ?
function(elt) { return docElt.contains(elt); } :
docElt.compareDocumentPosition ?
function(elt) {
return docElt.compareDocumentPosition(elt) & 16;
} :
((find = function(elt) {
return elt && (elt == docElt || find(elt.parentNode));
}), function(elt) { return find(elt); });
return function(elt) {
return !!(elt && ((elt = elt.parent) == docElt || contains(elt)));
};
})(jQuery);
это семантически эквивалентно jQuery.содержит(документ.documentElement, elt[0]).
Мне понравился этот подход. Нет jQuery и нет поиска DOM. Сначала найдите верхнего родителя (предка). Затем посмотрите, является ли это documentElement.
function ancestor(HTMLobj){
while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement}
return HTMLobj;
}
function inTheDOM(obj){
return ancestor(obj)===document.documentElement;
}
согласен с комментарием Перро. Это также можно сделать следующим образом:
$foo.parents().last().is(document.documentElement);
jQuery.fn.isInDOM = function () {
if (this.length == 1) {
var element = this.get(0);
var rect = element.getBoundingClientRect();
if (rect.top + rect.bottom + rect.width + rect.height + rect.left + rect.right == 0)
return false;
return true;
}
return false;
};
вероятно, самый перформативный способ:
document.contains(node); // boolean
Это также работает с jQuery:
document.contains($element[0]); // var $element = $("#some-element")
document.contains(this[0]); // in contexts like $.each(), `this` is the jQ object
источник MDN
Примечание:
вместо итерации родителей вы можете просто получить ограничивающую прямую, которая является всеми нулями, когда элемент отделен от dom
function isInDOM(element) {
var rect=element.getBoundingClientRect();
return (rect.top || rect.bottom || rect.height || rect.width)?true:false;
}
Если вы хотите обработать крайний случай нулевого элемента ширины и высоты в нулевом верхнем и нулевом левом углу, вы можете дважды проверить, повторяя родителей до документа.тело