【问题标题】:How to split and wrap lines in a span in each section?如何在每个部分的跨度中拆分和换行?
【发布时间】:2020-04-01 04:57:44
【问题描述】:

我使用“Detect browser wrapped lines via javascript”作为将每一行包装在<span> 中的一种方式。但是,如果要拆分和包装的元素不止一个,我就会遇到问题。

例如:如果我有多个部分要拆分和包装,例如:

<div class="emails">
<ul class="multi-items">
  <div class="message-contain">
   <div id="content">
       1 - Lorem Khaled Ipsum is a major key to success. They will try to close the door on you, just open it. Watch your back, but more importantly when you get out the shower, dry your back, it’s a cold world out there. 
   </div>
</div>
<div class="message-contain">
  <div id="content">
       2 - The key to more success is to get a massage once a week, very important, major key, cloth talk. Eliptical talk. 
  </div>
</div>
</ul>
</div>

它将获取.content 中的所有文本,将它们拆分并包装在&lt;span&gt; 中并复制它们。所以 put 看起来像这样;

<div class="emails">
<ul class="multi-items">
  <div class="message-contain">
   <div id="content">
       <span class="line_wrap">1 - Lorem Khaled Ipsum is a major key to success.</span>
       <span class="line_wrap">They will try to close the door on you, just open it.</span>
       <span class="line_wrap">Watch your back, but more importantly when you get out the</span>
       <span class="line_wrap">shower, dry your back, it’s a cold world out there.</span> 
       <span class="line_wrap">2 - The key to more success is to get a massage once</span>
       <span class="line_wrap">a week, very important, major key, cloth talk.</span>
       <span class="line_wrap">Eliptical talk.</span> 
   </div>
</div>
<div class="message-contain">
  <div id="content">
       <span class="line_wrap">1 - Lorem Khaled Ipsum is a major key to success.</span>
       <span class="line_wrap">They will try to close the door on you, just open it.</span>
       <span class="line_wrap">Watch your back, but more importantly when you get out the</span>
       <span class="line_wrap">shower, dry your back, it’s a cold world out there.</span> 
       <span class="line_wrap">2 - The key to more success is to get a massage once</span>
       <span class="line_wrap">a week, very important, major key, cloth talk.</span>
       <span class="line_wrap">Eliptical talk.</span>
  </div>
</div>
</ul>
</div>

我添加了 1 - 和 2 - 以表明它们重复。假设在不同的部分,而不是在所有部分。

无论如何如何在每个部分中将每一行拆分和包装在&lt;span&gt; 中并且不创建重复的内容?

工作示例:https://codepen.io/openbayou/pen/poJwaXv

JS代码:

$(".emails .multi-items").each(function (i) {
var $cont = $('.emails .multi-items .message-contain #content')
var text_arr = $cont.text().split(' ');
for (i = 0; i < text_arr.length; i++) {
  text_arr[i] = '<span>' + text_arr[i] + ' </span>';
}

$cont.html(text_arr.join(''));
$wordSpans = $cont.find('span');

var lineArray = [],
  lineIndex = 0,
  lineStart = true,
  lineEnd = false

  $wordSpans.each(function(idx) {
      var pos = $(this).position();
      var top = pos.top;

      if (lineStart) {
          lineArray[lineIndex] = [idx];
          lineStart = false;

      } else {
          var $next = $(this).next();

          if ($next.length) {
              if ($next.position().top > top) {
                  lineArray[lineIndex].push(idx);
                  lineIndex++;
                  lineStart = true
              }
          } else {
              lineArray[lineIndex].push(idx);
          }
      }

  });


 //console.log( lineArray)
 for (i = 0; i < lineArray.length; i++) {
  var start = lineArray[i][0],
      end = lineArray[i][1] + 1;

  /* no end value pushed to array if only one word last line*/
  if (!end) {
      $wordSpans.eq(start).wrap('<span class="line_wrap">')
  } else {
      $wordSpans.slice(start, end).wrapAll('<span class="line_wrap">');
  }

 };
});

【问题讨论】:

  • 所以你想把每一行都包裹在 span 中而不重复内容?
  • 是的。目前它拆分和包装,然后在两个元素中输出重复的内容,如链接中所示

标签: javascript jquery split


【解决方案1】:

我为此编写了一个原生 JavaScript 版本:

function wrapNewLines(targetSelector, wrapEl = 'span', wrapClass = 'new-line') {
  const content = document.querySelectorAll(targetSelector)
  content.forEach(section => {
    let sectionWidth = section.getBoundingClientRect().width
    let words = section.innerText.split(/( )/g)
    section.innerHTML = words.map(word =>`<span>${word}</span>`).join('')
    let lines = []
    let line = []
    let lineWidth = 0
    let spans = section.querySelectorAll('span')
    spans.forEach((span, i) => {
      let spanWidth = span.getBoundingClientRect().width
      if (lineWidth + spanWidth <= sectionWidth - 4) {
        line.push(span)
        lineWidth += spanWidth
      } else {
        lines.push(line)
        line = []
        lineWidth = 0
        line.push(span)
        lineWidth += spanWidth
      }
    })
    if (line.length) lines.push(line)
    let newLines = lines
      .map(
        line =>
          `<${wrapEl} class=${wrapClass}>${line
            .map(span => span.innerText)
            .join('')}</${wrapEl}>`
      )
      .join('')
    section.innerHTML = newLines
  })
}

wrapNewLines ('.emails .multi-items .message-contain #content');

Here is the gist

【讨论】:

  • 我不知道该怎么做。你把它放在哪里?提供的示例没有帮助。 function wrapNewLines('#content') { 没用。
  • 所有你需要做的就是复制上面的函数,并在下面这样调用它:codepen.io/brendan-c/pen/ZEGZbPm
  • 感谢您的澄清!现在它起作用了。编辑您的答案以包含wrapNewLines ('.emails .multi-items .message-contain #content');,它可以重置投票计数。
【解决方案2】:

试试下面的代码

$(".emails .multi-items").each(function(i) {
          var $cont = $(".message-contain #content");

          var text_arr = $cont.text().split(". ");

          for (i = 0; i < text_arr.length; i++) {
            text_arr[i] = "<span class='line_wrap'>" + text_arr[i] + ". </span>";
          }

          $cont.html(text_arr.join(""));
        });

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-25
  • 1970-01-01
  • 2010-11-27
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
相关资源
最近更新 更多