为非标记文本添加CSS样式

时间:2016-05-11 12:26:03

标签: javascript jquery css

有没有办法为没有标签的文本添加CSS样式?也许它可以用CSS完成,或者我可能需要使用JS?

<html>
<body>

    <p>Foo</p>

    Bar

    Bar

    Bar

    <p>Foo</p>

    <div>

        <p>Foo</p>

        Bar

        Bar

        Bar

        <p>Foo</p>

    </div>

</body>
</html>

换句话说,我想让所有“酒吧”的红色。有办法吗?

修改

我的问题含糊不清。 T.J.克劳德的回答非常好,但我必须注意,实际的任务是匹配任意文本。因此,在下面的示例中,它应与所有关于动物的文本相匹配:

<html>
<body>

    <p>Foo</p>

    Cat

    Cat and elephant are going through the jungle

    Elephant

    <p>Foo</p>

    <div>

        <p>Foo</p>

        Green parrot

        Red parrot

        Yellow parrot

        <p>Foo</p>

    </div>

</body>
</html>

2 个答案:

答案 0 :(得分:3)

您的示例有点模棱两可,因为Bar实例是body直接包含的唯一内容。如果我假设您在该部分中可能有Bar以外的其他内容,则不能,您不能仅将CSS应用于Bar部分而不应用于其他部分。

在JavaScript中,您可以将Bar文本包装在元素中(例如,span),然后设置该元素的样式。简单朴素的方法是使用replace

// Simple, but naive, and probably not what you want
document.body.innerHTML = document.body.innerHTML.replace(/\bBar\b/g, '<span class="wrapper">Bar</span>');

以下是一个例子,但请继续阅读:

&#13;
&#13;
document.body.innerHTML = document.body.innerHTML.replace(/\bBar\b/g, '<span class="wrapper">Bar</span>');
&#13;
.wrapper {
  font-weight: bold;
  color: green;
}
&#13;
<p>Foo</p>

Bar

Glarb

Bar

Glarb

Bar

<p>Foo</p>

<div>

  <p>Foo</p>

  Bar
  
  Glarb

  Bar
  
  Glarb

  Bar

  <p>Foo</p>

</div>
&#13;
&#13;
&#13;

这样做的问题是:

  • Bar将在任何地方匹配,即使在属性和
  • 中也是如此
  • 它将完全吹掉页面,并用 new 元素替换页面上的所有元素。例如,这将断开事件处理程序。

相反,你可以做一些更精致的事情,在文本节点中找到文本,只在找到文本节点时将其包裹起来,A)在错误的地方找不到它,并且B)没有&#39; t影响现有元素的事件处理程序。

我的回答here演示了如何将文本节点中的一部分文本包装在另一个元素中。这里适用于您的具体情况:

&#13;
&#13;
walk(document.body, "Bar");

function walk(node, targetString) {
  var child;

  switch (node.nodeType) {
    case 1: // Element
      for (child = node.firstChild; child; child = child.nextSibling) {
        walk(child, targetString);
      }
      break;

    case 3: // Text node
      handleText(node, targetString);
      break;
  }
}

function handleText(node, targetString) {
  var start, targetNode, followingNode, wrapper;

  // Does the text contain our target string?
  // (This would be a regex test in your http://... case)
  start = node.nodeValue.indexOf(targetString);
  if (start >= 0) {
    // Split at the beginning of the match
    targetNode = node.splitText(start);

    // Split at the end of the match
    followingNode = targetNode.splitText(targetString.length);

    // Wrap the target in an element; in this case, we'll
    // use a `span` with a class, but you'd use an `a`.
    // First we create the wrapper and insert it in front
    // of the target text.
    wrapper = document.createElement('span');
    wrapper.className = "wrapper";
    targetNode.parentNode.insertBefore(wrapper, targetNode);

    // Now we move the target text inside it
    wrapper.appendChild(targetNode);

    // Clean up any empty nodes (in case the target text
    // was at the beginning or end of a text ndoe)
    if (node.nodeValue.length == 0) {
      node.parentNode.removeChild(node);
    }
    if (followingNode.nodeValue.length == 0) {
      followingNode.parentNode.removeChild(followingNode);
    }
  }
}
&#13;
.wrapper {
  font-weight: bold;
  color: green;
}
&#13;
<p>Foo</p>

Bar

Glarb

Bar

Glarb

Bar

<p>Foo</p>

<div>

  <p>Foo</p>

  Bar
  
  Glarb

  Bar
  
  Glarb

  Bar

  <p>Foo</p>

</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果您只想要body中的文字,则可以为body设置与所有元素不同的样式:

body {
    color: red;
} 

body * {
    color: green;
}

这也适用于任何其他给定元素,只需用您的父元素替换body

编辑完成后,此答案不再符合问题。请记住,“条形图”不是“标记之外的文本”,它们是标记内的文本,只是它们直接位于其父标记内,而不是堆叠在另外的标记中标签。
因此,您尝试使用CSS选择的节点类型不存在。

好消息是,如果您为body和新div设置了这些规则,我的代码仍可用于您的新示例。