【发布时间】:2012-09-28 22:44:59
【问题描述】:
假设我有一个 DOM 元素,作为事件的参数,例如 click。
$(document).click(function() {
myElement = $(this);
});
我以后如何检查 myElement 是否仍在 DOM 中? 我不能使用 .length 或任何其他类似的东西,因为它现在仍然引用保存的元素和 DOM 的状态,对吧?
【问题讨论】:
标签: javascript jquery
假设我有一个 DOM 元素,作为事件的参数,例如 click。
$(document).click(function() {
myElement = $(this);
});
我以后如何检查 myElement 是否仍在 DOM 中? 我不能使用 .length 或任何其他类似的东西,因为它现在仍然引用保存的元素和 DOM 的状态,对吧?
【问题讨论】:
标签: javascript jquery
您可以检查元素父级:
function isInDom(obj) {
var root = obj.parents('html')[0]
return !!(root && root === document.documentElement);
}
if(isInDom(myElement)) {
...
}
这是工作小提琴:http://jsfiddle.net/vnxhQ/7/
【讨论】:
myElement 需要是一个包装元素的 jQuery 对象,但是.. 但是,我不相信这与存储时有任何关系。
为了测试DOM中是否还存在一个元素,需要再次爬取DOM:
// store it in some shared scope
var myElement;
$(document).click(function() {
myElement = $(this);
});
// sometime later...
if ($('#' + myElement.attr('id')).length > 0) {
// it still exists
} else {
// it no longer exists
}
不过,您点击的元素都必须有 ids 才能正常工作。可以使用类或任何其他选择器。
编辑:请参阅this question,了解如何为任何给定的 DOM 元素获取唯一选择器。
【讨论】:
这是假设您设置了可能的“可点击”元素的 id
var idRef;
$(document).on('click', function() {
idRef = this.id;
});
稍后..
var exists = document.getElementById(idRef).length > 0;
【讨论】:
您可以使用 jQuery 对象的未记录的.selector 属性来查看元素是否仍在 DOM 中,前提是它使用唯一 ID。很明显
http://jsfiddle.net/mblase75/CC2Vn/
$two = $('#two');
console.log($($two.selector).length); // 1
$two.remove();
console.log($($two.selector).length); // 0
有关如何获取 jQuery 对象的选择器的更多信息,请参阅this question,该选择器可能会或可能不会唯一地描述它包含的 DOM 元素。
【讨论】:
到目前为止,我看到的唯一可靠的方法是检查元素是否在 document.getElementsByTagName('*') 中
function isInDoc(element)
{
var elements=document.getElementsByTagName(element.tagName);
for(var i=0;i<elements.length;++i)
{
if(elements[i]===element)return true;
}
return false;
}
演示:http://jsfiddle.net/doktormolle/hX8eN/
<edit>
Node.contains() 似乎所有主流浏览器都支持,所以我最后建议:
if(document.documentElement.contains(myElement))
【讨论】:
Node.contains() 对我来说很好。
只是为了添加一些东西:
这确实是 Inferpse 的回答,针对 Dr.Molle 的极端案例进行了微调,即创建另一个 body 元素,该元素可能包含从一般 DOM 树中删除的元素(或者,当然,也许该元素一开始就从未在 DOM 中.) 就像 Inferspe 的回答一样,它需要一个 jQuery 包装的对象,而不是元素本身。
function isInDom(jqobj) {
var someBody = jqobj.parents('body');
return someBody.length > 0 && someBody.get(0) === document.body;
}
我必须承认我无法弄清楚如何尝试打破它。
编辑:哦,是的... jsFiddle:http://jsfiddle.net/vnxhQ/5/
编辑二:当然,如果我们不是在谈论链接或脚本元素(任何可能进入head,而不是body,我想这可能会很好:-/
【讨论】:
也许实现 Inferpse 功能的更好方法是扩展 jQuery:
jQuery.fn.extend({
isInDom: function() {
var root = this.eq(0).parents('html')[0];
return !!(root && root === document.documentElement);
}
})
用法:
$("div").isInDom() //returns true if your dom contains a div
$("<div />").isInDom() //returns false
$().isInDom() //returns false
【讨论】:
您可能正在寻找Node.isConnected。
【讨论】: