如何获取至少具有一个直接子文本节点的元素

时间:2015-10-09 00:19:15

标签: javascript

我试图编写一个函数,返回带有直接子文本节点的所有元素 -

function getAllElementsWithDirectTextNode() {
    var matchingElements = [];
    var allElements = document.body.getElementsByTagName('*');
    for (var i = 0, n = allElements.length; i < n; i++) {
         if (allElements[i].childNodes !== null) {
             matchingElements.push(allElements[i]);
         }
    }
    console.log(allElements);           
}

但是,这不起作用。我认为这与第5行(if语句)有关。如果元素没有直接文本节点子节点,但确实有一个直接元素子节点具有自己的子文本,我不想包含它。

编辑:我使用以下DOM尝试了Praveen Kumar的解决方案,控制台打印出正文中的所有元素。但是,我期待只看到div.div1,span.span2,div.div3和按钮。我做错了吗?

<div class="div1">
   this is direct text
   <span class="span1"></span>
</div>
<div class="div2">
    <span class="span2">this is span text</span>
</div>
<article></article>
<div class="div3">
    <span class="span3"></span>
    this is direct text, child #2
</div>

4 个答案:

答案 0 :(得分:3)

您需要检查他们是否childNode nodeType Node.TEXT_NODE

function getAllElementsWithDirectTextNode() {
  var matchingElements = [];
  var allElements = document.body.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++) {
    if (allElements[i].childNodes !== null) {
      for (var j in allElements[i].childNodes)
        if (allElements[i].childNodes[j].nodeType == Node.TEXT_NODE) {
          matchingElements.push(allElements[i]);
          break;
        }
    }
  }
  console.log(allElements);           
}

答案 1 :(得分:0)

您需要测试是否有任何子节点是文本节点。因此,您需要遍历所有孩子,测试他们的类型。

function getAllElementsWithDirectTextNode() {
  var matchingElements = [];
  var allElements = document.body.getElementsByTagName('*');
  for (var i = 0, n = allElements.length; i < n; i++) {
    if (allElements[i].childNodes !== null) {
      var children = allElements[i].childNodes;
      for (var j = 0, m = children.length; j < m; j++) {
        if (children[j].nodeType == Node.TEXT_NODE) {
          matchingElements.push(allElements[i]);
          break; // don't need to check the remaining children
        }
      }
    }
  }
  console.log(allElements);
}

答案 2 :(得分:0)

jsfiddle with NodeIterator

MDN Reference

GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed

答案 3 :(得分:0)

jsfiddle with a for loop solution

 function getAllElementsWithDirectTextNode() {
    var matchingElements = [];
    var allElements = document.body.getElementsByTagName('*');
    for (var i = 0; i < allElements.length; i++) {
        for (var j=0; j < allElements[i].childNodes.length; j++) {
            if (allElements[i].childNodes[j].nodeType === Node.TEXT_NODE) {
                if (is_all_ws(allElements[i].childNodes[j])) continue;
                matchingElements.push(allElements[i]);
                break;
            }
        }
    }
    console.log(matchingElements);
}

function is_all_ws(nod) {
   // Use ECMA-262 Edition 3 String and RegExp features
   return !(/[^\t\n\r ]/.test(nod.textContent));
}