检查HTML元素是否包含原始文本?

时间:2014-01-17 17:54:12

标签: javascript html dom

拿这个HTML:

<div id="el1">
  <div id="el2">
    <div id="el3">
      Hello
      <div id="el4">
        World
      </div>
    </div>
  </div>
</div>

请注意el3el4包含原始文字;即“你好”和“世界”。其他元素(el1el2)仅包含其他元素。

然而,使用纯JavaScript,他们的所有innerHTML属性都表明它们包含某种形式的文本。

如何使用纯JavaScript来确定特定元素是否包含原始文本作为子元素。在这种情况下,该方法还会将el3识别为包含原始文本(即使此后它还包含另一个元素)。

这样的事情:

var els = getElementByTagName("*");

for(var i = 0; i < els.length; i++){

  if( /* element contains text */ ){

    // do something

  }
}

这真的只是RegEx的工作吗?有了HTMLElement的所有属性,你会认为会有更好的方法。

没有jQuery,谢谢。

3 个答案:

答案 0 :(得分:2)

innerHTML获取HTML,除了最后一个元素之外的所有元素都包含HTML,因为它们是嵌套的。

例如,#el2的innerHTML将是

  <div id="el3">
      Hello
      <div id="el4">
          World
      </div>
  </div>

要获得文字,现代浏览器支持innerTexttextContent(firefox)。
然后是空白,所以你应该修剪()文本,所以像这样

var els = document.querySelectorAll("#wrapper *");

for(var i = 0; i < els.length; i++){
    var el = els[i].cloneNode(true);
    var children = el.children;

    for (var j=children.length; j--;) el.removeChild(children[j]);
    var content = el.innerText ? el.innerText  : el.textContent;

    if( content.trim().length ){
        // do something
        console.log(els[i].getAttribute('id') + ' has text');
    }
}

FIDDLE

或者检查文本节点的nodeType和nodeValue

var els = document.querySelectorAll("#wrapper *");

for(var i = 0; i < els.length; i++){
    var el = els[i];
    var children = el.childNodes;

    for (var j=children.length; j--;) {
        if( children[j].nodeType === 3 && children[j].nodeValue.trim().length) {
            // do something
            console.log(els[i].getAttribute('id') + ' has text');
        }
    }
}

FIDDLE

答案 1 :(得分:2)

以下是如何使用nodeType帮助您获得答案的示例:

var els = document.getElementsByTagName("*");

for (var i = 0; i < els.length; i++) {
    var hasTextNode = false;
    var currChildren = els[i].childNodes;

    for (var j = 0; j < currChildren.length; j++) {
        if ((currChildren[j].nodeType === Node.TEXT_NODE) &&
            (!(/^\s*$/.test(currChildren[j].textContent)))) {
                hasTextNode = true;
                break;
        }
    }

    window.console.log(els[i].id + ((hasTextNode) ? " has" : " does not have") + " a Text Node");
}

将其应用于您提供的HTML会在控制台中生成此内容:

el1 does not have a Text Node
el2 does not have a Text Node
el3 has a Text Node
el4 has a Text Node

注意:检查找到的“仅限空间”内容的文本节点非常重要,因为DOM会将源代码中的所有缩进和换行符视为“文本节点” 。显然,你会想忽略这些。

答案 2 :(得分:1)

通过nodeType属性告诉元素节点和文本节点之间的区别。 myelementnode.nodeType将返回1,mytextnode.nodeType将返回3.

顾名思义,getElementsByTagName只会为您提供元素节点。您要做的是使用根节点的childNodes属性,该属性将使该节点的所有直接子节点成为节点列表。因此,对于el1,您将只获得一个子节点el2。

然后,您必须递归遍历每个子节点以获取其子节点,直到您点击类型为3的节点 - 文本。

因此对于el3,它将返回2个子节点。第一个是你的文字,第二个是你的el4元素。然后,您需要进入el4以获取其子节点。

innerHTML返回一个字符串(一大块html转换为字符串),而不是节点。你可以使用它和正则表达式来丢弃位于&lt;和&gt;,但这有点粗糙,而且大量的html将是一个昂贵的过程。