拿这个HTML:
<div id="el1">
<div id="el2">
<div id="el3">
Hello
<div id="el4">
World
</div>
</div>
</div>
</div>
请注意el3
和el4
包含原始文字;即“你好”和“世界”。其他元素(el1
和el2
)仅包含其他元素。
然而,使用纯JavaScript,他们的所有innerHTML
属性都表明它们包含某种形式的文本。
如何使用纯JavaScript来确定特定元素是否包含原始文本作为子元素。在这种情况下,该方法还会将el3
识别为包含原始文本(即使此后它还包含另一个元素)。
这样的事情:
var els = getElementByTagName("*");
for(var i = 0; i < els.length; i++){
if( /* element contains text */ ){
// do something
}
}
这真的只是RegEx的工作吗?有了HTMLElement的所有属性,你会认为会有更好的方法。
没有jQuery,谢谢。
答案 0 :(得分:2)
innerHTML获取HTML,除了最后一个元素之外的所有元素都包含HTML,因为它们是嵌套的。
例如,#el2
的innerHTML将是
<div id="el3">
Hello
<div id="el4">
World
</div>
</div>
要获得文字,现代浏览器支持innerText
或textContent
(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');
}
}
或者检查文本节点的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');
}
}
}
答案 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将是一个昂贵的过程。