【问题标题】:Replace multiple <br>'s with only one <br>用一个 <br> 替换多个 <br>
【发布时间】:2013-06-08 08:30:56
【问题描述】:

如何使用 JavaScript 进行检测

<br>
<br>
<br>

成为一个人

<br>

?

我试过了:

jQuery('body').html().replace(/(\<br\>\r\n){3, }/g,"\n");

但这对我不起作用。

【问题讨论】:

  • 我很惊讶没有人建议使用正则表达式:(
  • @LescaiIonel 真的吗?阅读答案。但无论如何我们都有 DOM,那么为什么还要使用正则表达式呢? (有些日子我们会看到Tony the pony。)另外,替换 HTML 会导致浏览器重新解析 HTML,效率不高。
  • 如果你不想拥有多个&lt;br&gt;,为什么一开始就在那里?
  • 这个问答是如何在如此短的时间内获得如此多的观点和投票的......?
  • @mskfisher:更令人好奇的是,这个问题最初是如何成为热门问题的。

标签: javascript jquery html replace line-breaks


【解决方案1】:

CSS 解决方案

如果你想在页面上禁用多个&lt;br&gt;的效果,你可以不使用JavaScript,通过CSS来实现:

br + br { display: none; }

但是,当您使用标签时,这种方法是理想的,如下所示:

<div>Text</div><br /><br /><br />
<div>Text</div><br /><br /><br />
<div>Text</div><br /><br /><br />

在其他情况下,像这样:

Hello World<br />   <br />
Hello World<br />   <br />
Hello World<br />   <br />

它将失败(因为 CSS 通过文本节点)。相反,请使用 JavaScript 解决方案。


JavaScript 解决方案

// It's better to wait for document ready instead of window.onload().
window.onload = function () {
    // Get all `br` tags, defined needed variables
    var br = document.getElementsByTagName('br'),
        l = br.length,
        i = 0,
        nextelem, elemname, include;
        
    // Loop through tags
    for (i; i < l - 1; i++) {
        // This flag indentify we should hide the next element or not
        include = false;
        
        // Getting next element
        nextelem = br[i].nextSibling;
        
        // Getting element name
        elemname = nextelem.nodeName.toLowerCase();
        
        // If element name is `br`, set the flag as true.
        if (elemname == 'br') {
            include = true;
        }
        
        // If element name is `#text`, we face text node
        else if (elemname == '#text') {
            // If text node is only white space, we must pass it.
            // This is because of something like this: `<br />   <br />`
            if (! nextelem.data.replace(/\s+/g, '').length) {
                nextelem = br[i+1];
                include = true;
            }
        }
        
        // If the element is flagged as true, hide it
        if (include) {
            nextelem.style.display = 'none';
        }
    }
};

【讨论】:

  • @Joseph "br + br" 的定义是一个 br 元素直接放在另一个 br 元素之后。它只匹配一个元素,而不是同时匹配两个。选择器将匹配除第一个之外的所有连续 br 元素。
  • 此解决方案也可以删除比预期更多的&lt;br&gt;,如果两者之间没有标签:jsfiddle.net/ahMMv/13
  • 这些新奇的jigga mahoo是什么?自从我还是初学者以来,情况发生了变化。
  • @0x499602D2 你的意思是 CSS 中的 + 标记吗?它已经成为标准有一段时间了,>
  • (抱歉最后一条不正确的评论)这是解决@zch 发现问题的方法:jsfiddle.net/ahMMv/17
【解决方案2】:

以您不想要的形式将 HTML 发送到客户端浏览器并使其运行JavaScript 代码来清理它有什么意义?这看起来是个糟糕的设计。

如何修复所有静态 HTML 和 HTML 生成,以使这些多余的 &lt;br&gt; 元素一开始就不会出现?

如果您使用 JavaScript 修改文档对象,请为其他任何方式都无法实现的动态效果这样做。

【讨论】:

  • 可能多个&lt;br&gt;标签已经被Javascript创建了。
  • @w4rumu 或者 HTML 可能来自不同的站点。 Javascript 并不总是带有特定网站的软件包。可以在浏览器中运行 Javascript 作为浏览器扩展,为用户编辑 HTML。
  • 虽然您的建议总体上是好的(所以 +1),但它并不能直接回答问题。有时您必须处理 html,而您完全无法控制由谁生成它或为什么以这种方式生成它 - 在这种情况下,直接解决此类问题会变得有益,而“从一开始就修复它”之类的事情变得不可能。 (另一方面,通常这种你无法控制的 html 转换无论如何都发生在服务器端,在这种情况下,它们可以在服务器端进行修复——javascript 可能是错误的地方在做这件事任何情况下)。
  • 但是,我仍然可以看到,只有客户端才能控制不受控制的 html 操作是有正当理由的——这并不典型。
  • 哇,不知道上下文也没有答案,但仍然需要说“它的设计很糟糕”。
【解决方案3】:

更简单:

var newText = oldText.replace(/(&lt;br\s*\/?&gt;){3,}/gi, '&lt;br&gt;');

这将允许可选的标签终止符 (/>) 以及标签结束前的空格(例如 &lt;br /&gt; 或 &lt;br &gt;)。

【讨论】:

  • 但是我怎么能确保它只有在找到超过 3 个
    的时候才能工作呢?
  • 它将任何 2 个或多个替换为仅 1 个。
  • 但是像在其他示例中那样将量词 + 更改为 {3,} 将使其以这种方式工作。更新答案...
  • 我把它改成了 jQuery('body').html().replace(/(
    ){3,}/gi, '
    ') ;但它不适合我
  • 只执行.replce() 不会改变原始值。您必须将替换方法的返回值分配给原始变量。
【解决方案4】:

这样的做法不正确吗:

$("br~br").remove()

编辑:不,这是错误的,因为根据 BoltClock 对“连续”的定义过于宽松。

【讨论】:

  • 详细来说,就是jQuery“下一个兄弟姐妹”选择器:api.jquery.com/next-siblings-selector
  • 这会杀死&lt;br&gt;&lt;hr&gt;&lt;br&gt;&lt;hr&gt; 中的第二个&lt;br&gt;,尽管&lt;br&gt; 元素不连续。根据用例,这可能是不可取的。
  • 你太客气了。谢谢。 :)
  • @BoltClock 应该改用相邻的选择器吧?
【解决方案5】:

此解决方案仅适用于 jQuery + DOM,不将 HTML 作为字符串操作,适用于文本节点,仅忽略空白文本节点:

$('br').each(function () {
  const {nodeName} = this;

  let node = this;

  while (node = node.previousSibling) {
    if (node.nodeType !== Node.TEXT_NODE || node.nodeValue.trim() !== '') {
      break;
    };
  }

  if (node && node !== this && node.nodeName === nodeName) {
    $(node).remove();
  }
});

见:https://jsfiddle.net/kov35jct/

【讨论】:

    【解决方案6】:

    试试这个

    $('body').html($('body').html().replace(/(<br>)+/g,"<br>"));
    

    它将n个&lt;br&gt;替换为一个。

    Demo

    【讨论】:

    • 该解决方案会在不同
      标签之间出现空格或换行符等内容时中断。
    • 最好的正则表达式是:.replace(/(&lt;br\s*/?&gt;\s*)+/g, "&lt;br&gt;\n") 它可以处理各种间距的各种中断。此外,替换之后也打破了界限。我建议用&lt;br /&gt;\n 替换,但他的明显偏好不是自动关闭的。
    • @lonesomeday:您需要遍历每个元素,我认为这比转换为 HTML 的字符串形式、操作字符串然后将其更改回DOM 表单 - 虽然我不会放弃看到它的实现的机会!
    • @Qantas94Heavy 问题更多的是你这样做会丢失信息。例如。绑定在body 中的任何事件处理程序都将被删除。在我看来,这不是一个好主意。
    【解决方案7】:

    我会选择这个:

    $('body').html($('body').html().replace(/<br\W?\\?>(\W?(<br\W?\\?>)+)+/g,"<br>"));
    

    但是,在阅读了此处另一篇文章中的 cmets 后,我确实认为您应该尽量避免这样做,以防您可以在后端进行更正。

    【讨论】:

      【解决方案8】:

      这个问题的许多其他答案只会替换最多一定数量的元素,或者使用复杂的循环。我想出了一个简单的正则表达式,它可以用来用单个标签替换 any 数量的&lt;br&gt; 标签。这适用于字符串中多个标签的多个实例。

      /(<br>*)+/g
      

      要在 JavaScript 中实现这一点,您可以使用 String.replace 方法:

      myString.replace(/(<br>*)+/g, "<br/>");
      

      要替换多个&lt;br/&gt; 标签,请在正则表达式中添加/:

      /(<br\/>*)+/g
      

      【讨论】:

        【解决方案9】:

        试试这个:

        jQuery('body').html(
              jQuery('body').html().replace(/(?:<br>\s+){3,}/ig,"\n"));
        );
        

        演示: jsfiddle

        【讨论】:

        • 不要-1她!她的建议很好,只是她用换行符\n 替换所有&lt;br&gt;s。将其更改为 &lt;br&gt; 就可以了。
        • 这是一项很好的工作,但使用正则表达式而不是 DOM 可以保证未来的问题和边缘情况。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-15
        • 2013-11-27
        • 2015-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多