Javascript 检查HTML元素是否包含基本文本?

Javascript 检查HTML元素是否包含基本文本?,javascript,html,dom,Javascript,Html,Dom,以HTML为例: <div id="el1"> <div id="el2"> <div id="el3"> Hello <div id="el4"> World </div> </div> </div> </div> 这真的只是RegEx的工作吗?有了HTMLElement的所有属性,您会认为有更好的方法 不用jQuery,

以HTML为例:

<div id="el1">
  <div id="el2">
    <div id="el3">
      Hello
      <div id="el4">
        World
      </div>
    </div>
  </div>
</div>
这真的只是RegEx的工作吗?有了HTMLElement的所有属性,您会认为有更好的方法


不用jQuery,谢谢。

innerHTML获取HTML,除最后一个元素外的所有元素都包含嵌套的HTML

例如,
#el2
的innerHTML将是

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

或者检查文本节点的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');
        }
    }
}
var els=document.querySelectorAll(“#wrapper*”);
对于(变量i=0;i

可以通过nodeType属性区分元素节点和文本节点。MyLementNode.nodeType将返回1,mytextnode.nodeType将返回3

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

然后,您必须递归地遍历每个子节点以获取其子节点,直到找到类型为3-text的节点为止

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


innerHTML返回字符串(转换为字符串的html块),而不是节点。您可以使用它和正则表达式来丢弃中的所有内容,但这有点粗糙,使用大块html将是一个昂贵的过程。

下面是一个示例,说明如何使用
节点类型来帮助您获得答案:

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");
}

<强>注:对于“仅空间”内容检查所找到的文本节点是很重要的,因为DOM会将源代码中的所有缩进和断线视为“文本节点”。显然,您希望忽略这些。

这是行不通的。我知道
innerHTML
包含所选元素下面的所有内容,但是
innerText
textContent
不能替代,因为它们仍然指示DOM树的下一层有文本,即使元素本身不包含文本。然后只需删除子元素,然后检查元素是否包含文本。感谢您更新代码。为了记录在案,我认为你的第二个例子(受Dawn关于检查
节点类型
属性的建议启发)是一个更好的方法。@shennan-这是检查文本内容的一种常见方法,因此没有什么神奇之处,我同意,检查节点比克隆和删除子节点要好。是的,试图避免复杂的正则表达式。我的答案是+1,但如果你能给我一个dom遍历示例来澄清,我会给你答案?与问题中概述的HTML相关的内容。:-)我喜欢将您与常量
节点进行比较。TEXT\u节点
中断
子句可以提高效率。你能描述一下你对正则表达式的用法吗?当然。regex模式基本上从节点中文本的开始到结束(
^
-start,
$
-end)进行查看,查看整个文本是否由0或更多(
*
-0或更多)空格字符(
\s
-whitespace characters)组成。如果全部为空白,则假定文本节点只是源代码格式化的结果。如果不是所有的空白字符,那么假设它包含有意的文本内容。Fab,再次感谢+一丁点儿。我将给出答案@adeneo,因为他是第一个给出工作示例的人。但我也会运用你的一些技巧。干杯。这不是亚迪尼奥第一次击败我有趣的是,使用正则表达式测试和使用
trim
方法之间有什么区别吗?定义“原始文本”。示例中的所有元素都包含文本节点。您应该定义您希望执行的测试,而不是在没有定义的情况下使用像“原始文本”这样的虚构表达式。也许您希望测试一个元素是否包含除空格字符以外的内容的文本节点?然后你只需要定义哪些字符应该被视为空白字符,剩下的只是简单的编码。你来晚了一点。考虑到已经提出的三个答案,都是有能力的,这表明大多数人理解我的“发明表达”。如果我知道DOM的来龙去脉,那么也许我能够清楚地表达“文本节点的内容不是空白”。但是,我决定试着描述一下我所追求的,并希望更有想象力的人能够理解我的意思。谢天谢地,他们做到了。
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');
        }
    }
}
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");
}
el1 does not have a Text Node
el2 does not have a Text Node
el3 has a Text Node
el4 has a Text Node