【问题标题】:Add CSS styles for non-tagged text [closed]为非标记文本添加 CSS 样式 [关闭]
【发布时间】:2016-05-11 12:26:02
【问题描述】:

有没有办法为没有标签的文本添加 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>

换句话说,我想让所有“Bar”的颜色变成红色。有办法吗?


编辑

我的问题表述得模棱两可。 T.J. Crowder 回答得很好,但我必须注意,实际任务是匹配任意文本。所以,在下面的例子中,它应该匹配所有关于动物的文本:

<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>

【问题讨论】:

  • 你还有什么其他东西,比如上面的Bars,也直接包含在body 中吗?您的示例有点模棱两可,因为 Bar 实例是 body 直接包含的唯一内容。
  • 没有“没有标签的文字”
  • 再次:Bars 旁边还有其他内容吗?例如,Bar Foo Bar?
  • @T.J.Crowder Crowder 谢谢你的回答,我读了。我正在考虑适当的修改

标签: javascript jquery css


【解决方案1】:

您的示例有点模棱两可,因为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>');

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

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

Bar

Glarb

Bar

Glarb

Bar

<p>Foo</p>

<div>

  <p>Foo</p>

  Bar
  
  Glarb

  Bar
  
  Glarb

  Bar

  <p>Foo</p>

</div>

这样做的问题是:

  • Bar 将在任何地方匹配,即使在属性等中也是如此
  • 它将彻底清除页面,并将页面上的所有元素替换为 new 元素。例如,这将断开事件处理程序。

因此,您可以做一些更精细的事情,在文本节点中查找文本,并仅在找到时将其包装起来,A) 不会在错误的位置找到它,并且 B) 不会影响事件处理程序在现有元素上。

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

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);
    }
  }
}
.wrapper {
  font-weight: bold;
  color: green;
}
<p>Foo</p>

Bar

Glarb

Bar

Glarb

Bar

<p>Foo</p>

<div>

  <p>Foo</p>

  Bar
  
  Glarb

  Bar
  
  Glarb

  Bar

  <p>Foo</p>

</div>

【讨论】:

  • 非常感谢。是的,它确实有效,但我的问题是模棱两可的。我试图找到一种将 CSS 应用于 any 非标记文本的方法。所以,它可能是 bar,也可能是 abcefg——任何没有标签的文本。据我了解,您的正则表达式脚本(发布在链接上)可以完成这项工作吗?
  • @johnc.j.:以上内容可以让您对任何特定文本执行此操作,如果这就是您的意思的话;只需更改您搜索的内容。如果这不是你的意思,我不明白“任何没有标签的文本”。 HTML 页面中的 no 文本不包含在元素中(例如,在标签中)。在您的问题中,四个p 元素中包含四个“Foo”实例,一个body 元素中包含三个“Bar”实例,div 元素中包含三个“Bar”实例。
  • 这里是带有编辑示例的 jsfiddle:jsfiddle.net/0ovcu4u4/1。所以,在这个例子中,所有关于动物的文本都应该匹配。那是我寻找的。希望,现在不是模棱两可了
  • @johnc.j.:如果需要可运行的示例(例如 jsFiddle),请使用 Stack Snippets(&lt;&gt; 工具栏按钮)将其编辑到您的问题中。问题的内容必须完全包含在现场,而不仅仅是链接。
  • @johnc.j.:见my question above:什么“它”?
【解决方案2】:

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

body {
    color: red;
} 

body * {
    color: green;
}

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


编辑后,此答案不再适合该问题。请记住,“Bar”不是“标签外的文本”,它们是文本 inside 标签,只是它们直接位于其父标签内,而不是堆叠在另一个附加标签内标记。
因此,您尝试使用 CSS 选择的节点类型不存在。

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

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多