在纯Javascript中,如何获取body标签内的所有元素,不包括某个div及其子元素?

时间:2012-10-29 20:55:40

标签: javascript dom

我正在尝试查找body标签内的所有元素,但是有一个元素(div)具有某种类型的“hidden”,我想从它的元素数组中排除它和它的子元素。

这是我的var,其中包含正文中的所有元素:

allTagsInBody = document.body.getElementsByTagName('*');

以下是我要从此列表中排除的div:

<div class="myHiddenElement"> 
    <button>Click here</button>
    <div> <button>Click here</button> </div>
    <button>Click here</button>
</div>

问题是我不知道div里面有多少元素以及它们嵌套了多远。

4 个答案:

答案 0 :(得分:1)

document.querySelectorAll( '*:not(.myHiddenElement)' );

.querySelectorAll以及css2 :not()选择器会执行此操作。

答案 1 :(得分:1)

当您遍历每个元素时,您不仅需要检查它是否具有您的隐藏类,而且其任何父元素是否具有该类。因此,您需要递归检查每个元素的父元素。这可能非常昂贵,具体取决于页面上元素的数量以及它们的嵌套程度,但这是如何完成的:

var arr = [];
var len;
var i;
var nodes = document.querySelectorAll('body *');

function checkNode(node) {
    if (node.classList.contains('myHiddenElement')) {
        return true;        
    } else if (node.parentNode.nodeType === 1) {
        return checkNode(node.parentNode);
    }

    return false;
};

for (i = 0, len = nodes.length; i < len; i++) {
    if (checkNode(nodes[i])) {
        continue;
    } else {
        arr.push(nodes[i]);
    }
}

这是一个JSFiddle示例:http://jsfiddle.net/xzCfs/5/

不幸的是我认为有一种方法可以用CSS选择器来实现这一点,因为:not()选择器只接受简单的选择器,而不是复合的选择器(例如:not(.myHiddenClass *)&lt; - 将是如果有效的话真棒。)

答案 2 :(得分:0)

试试这个

​​var elems = document.body.childNodes;
var filtered = Array();  //holds elements that doesn't have 'myHiddenElement' class

​for(var i=0; i<elems.length; i++)
{
    if(elems[i].className != 'myHiddenElement')
      filtered.push(elems[i]);
}

答案 3 :(得分:0)

如果所有其他方法都失败了,你总是可以递归遍历DOM(这就是所有库所做的事情):

这是一个通用的DOM遍历函数:

# Note: Even though this function accepts a callback it is synchronous:

function traverse (node, callback) {
    // The callback function must return true to continue processing
    // otherwise stop processing down this branch:
    if (callback(node)) {
        for (var i=0;i < node.childNodes.length; i++) {
            traverse(node.childNodes[i],callback);
        }
    }
}

所以,要建立你的收藏品:

var elements = [];
traverse(document,function(node){
    // We only care about element nodes, ignore comments, attributes etc:
    if (node.nodeType == 1 && node.className != "myHiddenElement") {
        elements.push(node);
        return true; // continue parsing this branch
    }
    return false; // ignore this branch and its children
});