如何在不使用getElementById方法的情况下测试元素的存在性?

我已经设置了一个现场演示供参考。我也将在这里打印代码:

<!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>

基本上,上面的代码演示了一个元素被存储到一个变量中,然后从DOM中删除。即使元素已经从DOM中删除,变量仍然保留第一次声明时的元素。换句话说,它不是对元素本身的动态引用,而是一个副本。因此,检查变量的值(元素)是否存在将会得到一个意想不到的结果。

isNull函数是我试图从变量中检查元素的存在,它可以工作,但我想知道是否有更简单的方法来实现相同的结果。

PS:如果有人知道一些与这个主题相关的好文章,我还对JavaScript变量为什么会这样表现感兴趣。


当前回答

csuwldcat的解决方案似乎是最好的,但需要做一些轻微的修改,以使它能够正确地处理与JavaScript代码运行在不同文档中的元素,例如iframe:

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

注意元素的ownerDocument属性的使用,而不是简单的旧文档(可能引用也可能不引用元素的所有者文档)。

torazaburo发布了一个更简单的方法,它也适用于非本地元素,但不幸的是,它使用了baseURI属性,这个属性目前还没有在所有浏览器中统一实现(我只能让它在基于webkit的浏览器中工作)。我找不到任何其他可以以类似方式使用的元素或节点属性,所以我认为目前上述解决方案是最好的。

其他回答

而不是迭代父元素,当元素从DOM中分离出来时,你可以得到一个全为0的边界矩形:

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

如果你想处理宽度和高度都为零的元素的边缘情况,你可以通过迭代父元素直到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;
}

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

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

节点使用。包含DOM API,你可以检查页面中任何元素的存在(当前在DOM中)非常容易:

document.body.contains(YOUR_ELEMENT_HERE);

跨浏览器注意:Internet Explorer中的文档对象没有contains()方法——为了确保跨浏览器兼容性,请使用document.body.contains()代替。

简单的方法:

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

如果需要在严格可见的DOM中,这意味着不是在整个页面上,使用像view-js这样的东西(我的lib因此尽可能多地击败它)


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

函数测试(){ pt = document.querySelector('#result') iv = document.querySelector('#f') cond = document.querySelector('#'+iv.value) || false If (cond) { pt.innerText = '发现!' }其他{ pt.innerText = '未找到!' } } 输入一个id,看看它是否存在:<input id='f'></input> <按钮onclick = '测试()' >测试!< /按钮> < br / > <p id='result'>我是一个p标签。我会根据结果来改变 < br / > <div id='demo'>我是一个div.我的id是demo

我更喜欢使用节点。isConnected属性(访问MDN)。

注意:如果元素被附加到暗影根,这将返回true,这可能不是每个人都想要的行为。

例子:

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