简体   繁体   English

如何检查可见 DOM 中是否存在元素?

[英]How can I check if an element exists in the visible DOM?

How do you test an element for existence without the use of the getElementById method?如何在不使用getElementById方法的情况下测试元素是否存在?

I have set up a live demo for reference.我已经设置了一个现场演示以供参考。 I will also print the code on here as well:我还将在此处打印代码:

<!DOCTYPE html>
<html>
<head>
    <script>
    var getRandomID = function (size) {
            var str = "",
                i = 0,
                chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
            while (i < size) {
                str += chars.substr(Math.floor(Math.random() * 62), 1);
                i++;
            }
            return str;
        },
        isNull = function (element) {
            var randomID = getRandomID(12),
                savedID = (element.id)? element.id : null;
            element.id = randomID;
            var foundElm = document.getElementById(randomID);
            element.removeAttribute('id');
            if (savedID !== null) {
                element.id = savedID;
            }
            return (foundElm) ? false : true;
        };
    window.onload = function () {
        var image = document.getElementById("demo");
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false
        console.log('null', (image === null) ? true : false); // false
        console.log('find-by-id', isNull(image)); // false
        image.parentNode.removeChild(image);
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
        console.log('null', (image === null) ? true : false); // false ~ should be true?
        console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
    };
    </script>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

Basically the above code demonstrates an element being stored into a variable and then removed from the DOM.基本上,上面的代码演示了一个元素被存储到一个变量中,然后从 DOM 中移除。 Even though the element has been removed from the DOM, the variable retains the element as it was when first declared.即使该元素已从 DOM 中删除,该变量仍会保留该元素,因为它是第一次声明时的样子。 In other words, it is not a live reference to the element itself, but rather a replica.换句话说,它不是对元素本身的实时引用,而是一个副本。 As a result, checking the variable's value (the element) for existence will provide an unexpected result.因此,检查变量的值(元素)是否存在将提供意想不到的结果。

The isNull function is my attempt to check for an elements existence from a variable, and it works, but I would like to know if there is an easier way to accomplish the same result. isNull function 是我尝试从变量中检查元素是否存在,并且它有效,但我想知道是否有更简单的方法来实现相同的结果。

PS: I'm also interested in why JavaScript variables behave like this if anyone knows of some good articles related to the subject. PS:如果有人知道与该主题相关的一些好文章,我也对为什么 JavaScript 变量的行为如此感兴趣。

It seems some people are landing here, and simply want to know if an element exists (a little bit different to the original question).似乎有些人在这里登陆,只是想知道一个元素是否存在(与原始问题有点不同)。

That's as simple as using any of the browser's selecting method, and checking it for a truthy value (generally).这就像使用任何浏览器的选择方法一样简单,并检查它的真实值(通常)。

For example, if my element had an id of "find-me" , I could simply use...例如,如果我的元素的id"find-me" ,我可以简单地使用...

var elementExists = document.getElementById("find-me");

This is specified to either return a reference to the element or null .这被指定为返回对元素的引用或null If you must have a Boolean value, simply toss a !!如果你必须有一个布尔值,只需扔一个!! before the method call.在方法调用之前。

In addition, you can use some of the many other methods that exist for finding elements, such as (all living off document ):此外,您可以使用现有的许多其他方法中的一些来查找元素,例如(全部脱离document ):

  • querySelector() / querySelectorAll() querySelector() / querySelectorAll()
  • getElementsByClassName()
  • getElementsByName()

Some of these methods return a NodeList , so be sure to check its length property, because a NodeList is an object, and therefore truthy .其中一些方法返回一个NodeList ,所以一定要检查它的length属性,因为NodeList是一个对象,因此是真实的


For actually determining if an element exists as part of the visible DOM (like the question originally asked), Csuwldcat provides a better solution than rolling your own (as this answer used to contain).为了实际确定一个元素是否作为可见 DOM 的一部分存在(就像最初提出的问题), Csuwldcat 提供了比滚动你自己的更好的解决方案(因为这个答案曾经包含)。 That is, to use the contains() method on DOM elements.也就是说,在 DOM 元素上使用contains()方法。

You could use it like so...你可以像这样使用它...

document.body.contains(someReferenceToADomElement);

Use getElementById() if it's available.如果可用,请使用getElementById()

Also, here's an easy way to do it with jQuery:此外,这里有一个简单的方法来使用 jQuery:

if ($('#elementId').length > 0) {
  // Exists.
}

And if you can't use third-party libraries, just stick to base JavaScript:如果你不能使用第三方库,就坚持使用基础 JavaScript:

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}

Using the Node.contains DOM API , you can check for the presence of any element in the page (currently in the DOM) quite easily:使用Node.contains DOM API ,您可以非常轻松地检查页面中(当前在 DOM 中)是否存在任何元素:

document.body.contains(YOUR_ELEMENT_HERE);

CROSS-BROWSER NOTE : the document object in Internet Explorer does not have a contains() method - to ensure cross-browser compatibility, use document.body.contains() instead. CROSS-BROWSER 注意:Internet Explorer 中的document对象没有contains()方法 - 为确保跨浏览器兼容性,请改用document.body.contains()

I simply do:我只是这样做:

if(document.getElementById("myElementId")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

It works for me and had no issues with it yet...它对我有用,而且还没有问题......

From Mozilla Developer Network :来自Mozilla 开发者网络

This function checks to see if an element is in the page's body.这个函数检查一个元素是否在页面的正文中。 As contains() is inclusive and determining if the body contains itself isn't the intention of isInPage, this case explicitly returns false.由于 contains() 是包含性的,并且确定正文是否包含自身不是 isInPage 的意图,因此这种情况显式返回 false。

function isInPage(node) {
  return (node === document.body) ? false : document.body.contains(node);
}

node is the node we want to check for in the <body>. node是我们要在 <body> 中检查的节点。

You could just check to see if the parentNode property is null.您可以只检查 parentNode 属性是否为空。

That is,那是,

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}

I prefer to use the node.isConnected property ( Visit MDN ).我更喜欢使用node.isConnected属性(访问 MDN )。

Note: This will return true if the element is appended to a ShadowRoot as well, which might not be everyone's desired behaviour.注意:如果元素也附加到 ShadowRoot 中,这将返回 true,这可能不是每个人都想要的行为。

Example:例子:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true

The easiest solution is to check the baseURI property, which is set only when the element is inserted in the DOM, and it reverts to an empty string when it is removed.最简单的解决方案是检查baseURI属性,该属性仅在元素插入 DOM 时设置,并在删除时恢复为空字符串。

 var div = document.querySelector('div'); // "div" is in the DOM, so should print a string console.log(div.baseURI); // Remove "div" from the DOM document.body.removeChild(div); // Should print an empty string console.log(div.baseURI);
 <div></div>

jQuery solution: jQuery 解决方案:

if ($('#elementId').length) {
    // element exists, do something...
}

This worked for me using jQuery and did not require $('#elementId')[0] to be used.这对我使用 jQuery 有效,并且不需要使用$('#elementId')[0]

A simple way to check if an element exist can be done through one-line code of jQuery.一种检查元素是否存在的简单方法可以通过 jQuery 的一行代码来完成。

Here is the code below:这是下面的代码:

if ($('#elementId').length > 0) {
    // Do stuff here if the element exists
} else {
    // Do stuff here if the element does not exist
}

This code works for me, and I didn't have any issues with it.这段代码对我有用,我没有任何问题。


    if(document.getElementById("mySPAN")) {
        // If the element exists, execute this code
        alert("Element exists");
    }
    else {
        // If the element does not exist execute this code
        alert("Element does not exists");
    }

csuwldcat's solution seems to be the best of the bunch, but a slight modification is needed to make it work correctly with an element that's in a different document than the JavaScript code is running in, such as an iframe: csuwldcat 的解决方案似乎是最好的解决方案,但需要稍作修改才能使其与运行 JavaScript 代码所在文档不同的元素(例如 iframe)正常工作:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

Note the use of the element's ownerDocument property, as opposed to just plain old document (which may or may not refer to the element's owner document).请注意元素的ownerDocument属性的使用,而不是简单的旧document (可能会也可能不会引用元素的所有者文档)。

torazaburo posted an even simpler method that also works with non-local elements, but unfortunately, it uses the baseURI property, which is not uniformly implemented across browsers at this time (I could only get it to work in the WebKit -based ones). torazaburo 发布了一个更简单的方法,它也适用于非本地元素,但不幸的是,它使用了baseURI属性,目前该属性在浏览器中并未统一实现(我只能让它在基于 WebKit的浏览器中工作)。 I couldn't find any other element or node properties that could be used in a similar fashion, so I think for the time being the above solution is as good as it gets.我找不到可以以类似方式使用的任何其他元素或节点属性,因此我认为目前上述解决方案已达到最佳效果。

Instead of iterating parents, you can just get the bounding rectangle which is all zeros when the element is detached from the DOM:当元素从 DOM 分离时,您可以只获得全零的边界矩形,而不是迭代父项:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    return (rect.top || rect.left || rect.height || rect.width)?true:false;
}

If you want to handle the edge case of a zero width and height element at zero top and zero left, you can double check by iterating parents till the document.body :如果您想处理零顶部和零左零宽度和高度元素的边缘情况,您可以通过迭代父级直到document.body来仔细检查:

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    if (element.top || element.left || element.height || element.width)
        return true;
    while(element) {
        if (element == document.body)
            return true;
        element = element.parentNode;
    }
    return false;
}

Easiest way:最简单的方法:

const cond = document.getElementById('elem') || false
if (cond) {
    //does
} else {
    //does not
}

If needed in strictly visible DOM, meaning not on entire page, use something like view-js (my lib so beat it up as much as you want)如果在严格可见的 DOM 中需要,这意味着不是在整个页面上,请使用 view-js 之类的东西(我的库因此可以根据需要进行优化)


<script src='https://view-js.glitch.me/view-main.js'></script>
<script>
elem = $sel('#myelem');
if (isVis(elem)) { //yes } else { //no }
</script>

 function test() { pt = document.querySelector('#result') iv = document.querySelector('#f') cond = document.querySelector('#'+iv.value) || false if (cond) { pt.innerText = 'Found!' } else { pt.innerText = 'Not found!' } }
 Enter an id to see if it exists: <input id='f'></input> <button onclick='test()'>Test!</button> <br /> <p id='result'>I am ap tag. I will change depending on the result.</p> <br /> <div id='demo'>I am a div. My id is demo.</div>

另一种选择是element.closest

element.closest('body') === null

一个简单的 jQuery 解决方案:

$('body').find(yourElement)[0] != null

You can also use jQuery.contains , which checks if an element is a descendant of another element.您还可以使用jQuery.contains ,它检查一个元素是否是另一个元素的后代。 I passed in document as the parent element to search because any elements that exist on the page DOM are a descendant of document .我传入document作为要搜索的父元素,因为页面 DOM 上存在的任何元素都是document的后代。

jQuery.contains( document, YOUR_ELEMENT)
  • If an element is in the DOM , its parents should also be in如果一个元素在DOM ,它的父元素也应该在
  • And the last grandparent should be the document最后的祖父母应该是document

So to check that we just loop unto the element's parentNode tree until we reach the last grandparent所以为了检查我们是否只是循环到元素的parentNode树,直到我们到达最后一个祖父母

Use this:用这个:

/**
 * @param {HTMLElement} element - The element to check
 * @param {boolean}     inBody  - Checks if the element is in the body
 * @return {boolean}
 */
var isInDOM = function(element, inBody) {
    var _ = element, last;

    while (_) {
        last = _;
        if (inBody && last === document.body) { break;}
        _ = _.parentNode;
    }

    return inBody ? last === document.body : last === document;
};

Check if the element is a child of <html> via Node::contains() :通过Node::contains()检查元素是否是<html>的子元素:

const div = document.createElement('div');
document.documentElement.contains(div); //-> false

document.body.appendChild(div);
document.documentElement.contains(div); //-> true

I've covered this and more in is-dom-detached .我已经在is-dom-detached 中介绍了这一点以及更多内容。

// This will work prefectly in all :D
function basedInDocument(el) {

    // This function is used for checking if this element in the real DOM
    while (el.parentElement != null) {
        if (el.parentElement == document.body) {
            return true;
        }
        el = el.parentElement; // For checking the parent of.
    } // If the loop breaks, it will return false, meaning
      // the element is not in the real DOM.

    return false;
}

All existing elements have parentElement set, except the HTML element!所有现有元素都设置了 parentElement,除了 HTML 元素!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};

this condition chick all cases.这种情况小鸡所有情况。

 function del() { //chick if dom has this element //if not true condition means null or undifind or false . if (!document.querySelector("#ul_list ")===true){ // msg to user alert("click btn load "); // if console chick for you and show null clear console. console.clear(); // the function will stop. return false; } // if its true function will log delet . console.log("delet"); }

使用下面的这个命令返回元素是否存在于 DOM 中:

return !!document.getElementById('myElement');

Check element exist or not检查元素是否存在

const elementExists = document.getElementById("find-me");
if(elementExists){
    console.log("have this element");
}else{
    console.log("this element doesn't exist");
}

I liked this approach:我喜欢这种方法:

var elem = document.getElementById('elementID');

if (elem)
    do this
else
    do that

Also

var elem = ((document.getElementById('elemID')) ? true:false);

if (elem)
    do this
else
    do that

Use querySelectorAll with forEach ,querySelectorAllforEach一起forEach

document.querySelectorAll('.my-element').forEach((element) => {
  element.classList.add('new-class');
});

as the opposite of:相反:

const myElement = document.querySelector('.my-element');
if (myElement) {
  element.classList.add('new-class');
}

Try the following.请尝试以下操作。 It is the most reliable solution:这是最可靠的解决方案:

window.getComputedStyle(x).display == ""

For example,例如,

var x = document.createElement("html")
var y = document.createElement("body")
var z = document.createElement("div")
x.appendChild(y);
y.appendChild(z);

z.style.display = "block";

console.log(z.closest("html") == null); // 'false'
console.log(z.style.display); // 'block'
console.log(window.getComputedStyle(z).display == ""); // 'true'

As I landed up here due to the question.由于这个问题,我来到这里。 Few of the solutions from above don't solve the problem.上面的解决方案很少能解决问题。 After a few lookups, I found a solution on the internet that provided if a node is present in the current viewport where the answers I tried solves of it's present in the body or not.经过几次查找后,我在互联网上找到了一个解决方案,该解决方案提供了当前视口中是否存在节点,我尝试解决的答案是否存在于正文中。

function isInViewport(element) {
    const rect = element.getBoundingClientRect();
    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
}

isInViewport(document.querySelector('.selector-i-am-looking-for'));

The snippet is taken from HERE to keep as a backup as the links may be unavailable after some time.该片段取自HERE以作为备份保存,因为链接可能会在一段时间后不可用。 Check the link for an explanation.检查链接以获取解释。

And, didn't intend to post in the comment, as in most cases, they are ignored.而且,不打算在评论中发帖,因为在大多数情况下,它们会被忽略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM