如何仅设置没有文本节点作为兄弟节点的类型的元素?

时间:2016-12-17 15:53:10

标签: javascript nodes

我有这个标记:

<div class="wysiwyg">
  <em>It has to be red because is the only em element</em>
</div>


<div class="wysiwyg">
  Some text
  <em>Not to be red because has previous (and following) text node</em>
  Some text
</div>


<div class="wysiwyg">
  <em>It has to be red because its' a em in a div that has only ems and no text node / </em>
  <em>It has to be red because its' a em in a div that has only ems and no text node</em>

我想仅将element.style.color = "red";应用于<ems>元素,这些元素是其父级的唯一<em>子元素,或者其他<em> s为兄弟元素但是不是文本节点作为兄弟节点。

另外,我想知道如何仅使用node.style.color = blue;之类的方式设置文本节点的样式(我知道.style方法仅适用于元素...)。

谢谢!

1 个答案:

答案 0 :(得分:4)

假设您喜欢本机JavaScript解决方案,并且至少可以定位EcmaScript 5,这里有一个解决方案https://jsfiddle.net/pjhuptt3/

我使用childNodes来获取包括文本节点在内的所有子节点。另外,我检查nodeType是否等于3(文本节点),我必须检查文本节点是否不是空格。

请注意,该代码仅用于示例目的,并用于演示您拥有的工具。未经任何方式测试或优化。

function hasTextNodes(node) {
  if (!node || !node.childNodes.length) return false;

  for (var i=0;i<node.childNodes.length;++i) {
    var child = node.childNodes[i];
    // check if the node is text node and check if it's not a white space
    if (child.nodeType == 3 && child.textContent && child.textContent.trim().length)
      return true;
  }
  return false;    
}

document.querySelectorAll(".wysiwyg").forEach(function(node) { 
  if (!hasTextNodes(node))
    node.style.backgroundColor = "blue"; 
});

如果您想设置em元素的样式,可以执行以下操作。

document.querySelectorAll(".wysiwyg").forEach(function(node) { 
  if (!hasTextNodes(node)) {
    // query the em direct children
    node.querySelectorAll("> em").forEach(function(em) {
      em.style.backgroundColor = "blue"; 
    });
  }
});

为了完整起见,我应该告诉你,除非你需要这个确切的场景(例如它的一些教育练习),否则有几种更好的方法可以实现同样的目的。

  • 首先,任何时候你发现自己给出一些&#34;意思&#34;对于文本节点,您不应该再将其作为文本节点。您应该将它们包装到span并添加特定的类,如果您将来需要区分它们。因此,处理它们更容易,你可以选择它们,设计它们等等。
  • 其次,使用像jQuery这样的框架,这些任务更容易解决,而jQuery本身并没有增加太多开销,特别是如果您使用CDN引用它