使用Javascript检查给定HTML元素中是否存在子元素

使用Javascript检查给定HTML元素中是否存在子元素,javascript,html,dom,xhtml,Javascript,Html,Dom,Xhtml,我正在尝试编写一个纯javascript函数,它将从页面(通常是a)中获取一个元素,并由此计算出它是否有任何特定的子元素。基本上是表示文本内容的任何标记,因此:或任何标题标记so(。)或列表等 我不想操纵这些元素,只是检查它们的存在 所以函数的形式是 /** * Takes an element and returns whether * the element contains content * @return boolean (true/false) */ var isConten

我正在尝试编写一个纯javascript函数,它将从页面(通常是a)中获取一个元素,并由此计算出它是否有任何特定的子元素。基本上是表示文本内容的任何标记,因此:
或任何标题标记so(
)或列表等

我不想操纵这些元素,只是检查它们的存在

所以函数的形式是

/**
 * Takes an element and returns whether
 * the element contains content
 * @return boolean (true/false)
 */
var isContent = function (elementToCheck) {

};
我目前正在使用
document.getElementsByTagName('div')
获取页面的所有
元素。然后,我将一次一个地将它们解析到函数中

我现在已经记下来了

var isContent = function (elementToCheck) {
    if (elementToCheck.hasChildNodes()) {
        var children = elementToCheck.childNodes;

        for (var i = 0; i < children.length; i++) {
            // handle children[i]
        }
   }
}
var isContent=function(elementToCheck){
if(elementToCheck.hasChildNodes()){
var children=elementToCheck.childNodes;
对于(变量i=0;i
我一直在尝试使用
chilren[I].nodeValue
和测试各种东西的平等性,但我无法让任何东西通过


进行这项工作的最佳方式是什么?我认为它变成了一个混乱的函数,因为我必须得到这个函数之外的所有元素,循环它们,并在这里解析它们,然后执行另一个循环。我开始想知道是否可以用正则表达式来实现这一点?

如果您想找到所有
元素,这些元素至少有一个子节点具有非空的内容模型,那么在所有浏览器中都可以使用类似的方法返回(包括)IE8:


我认为这可能更有效。(可能有必要在每个
中添加一个无意义的“类”标记,以避免多次将其添加到列表中。)

我对此感到非常痛心,尽管Pointy提到了一个新函数,名为
querySelectorAll()
,它可能会让您切断
containsTextElements
循环

var textTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p"];

var containsTextElements = function(elementToCheck) {

    for (var i = 0; i < textTags.length; i++) {
        if(elementToCheck.getElementsByTagName(textTags[i]).length > 0)
            return true;    
    }
    return false;
}

var doStuffToDivsWithText = function(callback) {

    var divs = document.getElementsByTagName("div");
    for(var i = 0; i < divs.length; i++ ) {
        if(containsTextElements(divs[i]))
            callback(divs[i]); 
    };
}

doStuffToDivsWithText(function(div) {
    console.log(div.id);
});
var textTags=[“h1”、“h2”、“h3”、“h4”、“h5”、“h6”、“p”];
var containsTextElements=函数(elementToCheck){
对于(var i=0;i0)
返回true;
}
返回false;
}
var doStuffToDivsWithText=函数(回调){
var divs=document.getElementsByTagName(“div”);
对于(变量i=0;i
通过这种方式,您不需要jQuery,不需要(但可以)指定您想要文本内容的标记,并且可以对找到的文本应用正则表达式

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
    function logTextContent(elem) {
    var childNodes = elem.childNodes;
    for(var i=0; i<childNodes.length; i++) {
        var nodex = childNodes[i];
        if(nodex.nodeType == 3 /* text node */) {
        var textContent = nodex.nodeValue;
        if(textContent.match(/\S+/) /* apply regex */) {
            console.log("found text: "+textContent);
        }
        }
        else if (nodex.nodeType == 1 /* element node*/) {
        logTextContent(nodex)
        }
    }
    }
    function findDocumentTexts() {
    var docElems = document.getElementsByTagName("body");
    for(var i=0; i<docElems.length; i++) {
        var elem = docElems[i];
        logTextContent(elem);
    }
    }
</script>
</head>
<body>
<button onclick="findDocumentTexts()">find document texts</button>
<!-- I will fail -->
<div>
    <!-- I will pass -->
    <div>
    <h1>Heading</h1>
    <p>
        I should be found straight away
    </p>
    </div>
    <!-- I will fail -->
    <div>
    <!-- I will pass -->
    <div>
        <p>
        I will be missed by the first div but found by the second
        </p>
    </div>
    </div>
</div>
</body>
</html>

函数logTextContent(elem){
var childNodes=elem.childNodes;
对于(var i=0;i
标题

我应该马上被找到

我将被第一个div错过,但被第二个div找到


你到底需要检查什么?一旦你调用了
.getElementsByTagName()
你只会得到你想要的类型的元素。除了标记名之外,你还需要找到什么?不,你不能用正则表达式。术语“parse”事实上,在这里不太合适,因为您使用的是DOM,而不是文档的原始字符串表示形式。浏览器已经解析了它来构建DOM。因此,您是否需要检查节点是否包含一些
p
div
等标记?不是文本内容,只是节点?因此我获得了所有
div
元素从这里,我想检查那些
div
中的哪些具有
或其他标记,这些标记表示内容是直接的后代。也许这个示例将有助于我混乱的解释:您可以调用
.getElementsByTagName()
从任何元素。因此,您可以找到一些
,然后从它的DOM节点调用
getElementsByTagName()
来查找所有的后代
标记。这太棒了。正是我要找的。我只是在正确地学习DOM遍历等等。
findTheDivs()
这条路看起来更优雅。谢谢你,我感谢你的帮助。
var textTags = ["h1", "h2", "h3", "h4", "h5", "h6", "p"];

var containsTextElements = function(elementToCheck) {

    for (var i = 0; i < textTags.length; i++) {
        if(elementToCheck.getElementsByTagName(textTags[i]).length > 0)
            return true;    
    }
    return false;
}

var doStuffToDivsWithText = function(callback) {

    var divs = document.getElementsByTagName("div");
    for(var i = 0; i < divs.length; i++ ) {
        if(containsTextElements(divs[i]))
            callback(divs[i]); 
    };
}

doStuffToDivsWithText(function(div) {
    console.log(div.id);
});
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
    function logTextContent(elem) {
    var childNodes = elem.childNodes;
    for(var i=0; i<childNodes.length; i++) {
        var nodex = childNodes[i];
        if(nodex.nodeType == 3 /* text node */) {
        var textContent = nodex.nodeValue;
        if(textContent.match(/\S+/) /* apply regex */) {
            console.log("found text: "+textContent);
        }
        }
        else if (nodex.nodeType == 1 /* element node*/) {
        logTextContent(nodex)
        }
    }
    }
    function findDocumentTexts() {
    var docElems = document.getElementsByTagName("body");
    for(var i=0; i<docElems.length; i++) {
        var elem = docElems[i];
        logTextContent(elem);
    }
    }
</script>
</head>
<body>
<button onclick="findDocumentTexts()">find document texts</button>
<!-- I will fail -->
<div>
    <!-- I will pass -->
    <div>
    <h1>Heading</h1>
    <p>
        I should be found straight away
    </p>
    </div>
    <!-- I will fail -->
    <div>
    <!-- I will pass -->
    <div>
        <p>
        I will be missed by the first div but found by the second
        </p>
    </div>
    </div>
</div>
</body>
</html>