简体   繁体   English

如何将每个字母包装在一个跨度中并保持正常的分词和子元素

[英]How to wrap each letter in a span and keep normal word breaks and subelements

I want to wrap each letter inside an HTML element into it's own span (for animation purposes).我想将 HTML 元素内的每个字母包装到它自己的跨度中(用于 animation 目的)。

This is doable by splitting the text into chars and creating multiple spans (See jQuery - How to wrap each character from a string in spans ).这可以通过将文本拆分为字符并创建多个跨度来实现(请参阅jQuery - 如何将字符串中的每个字符包装在跨度中)。

Only this way word wrapping will not work anymore since words/letters are broken up into spans.只有这样,文字换行将不再起作用,因为单词/字母被分解为跨度。 Also child elements (like strong) are removed.子元素(如强)也被删除。

Example:例子:

 $.fn.convertToSeperateLetters = function() { return this.each(function() { var html = $(this).text().replace(/\S/g, '<span class="letter">$&</span>'); return $(this).html(html) }); } $('p').convertToSeperateLetters();
 p, .word, .letter { padding: 3px 1px; } p { border: 1px solid red; }.word { display: inline-block; border: 1px solid green; margin-left: 2px; margin-right: 2px; }.letter { display: inline-block; border: 1px solid blue; }.word-wrapped { width: 360px; background: lightgrey; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p>Hello World</p> <p>Hello <strong>World</strong></p> <div class="word-wrapped"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p> </div>

I've made an solution that also wraps each word into a span.我制定了一个解决方案,该解决方案还将每个单词包装成一个跨度。 This way wrapping still works on whole words.这种换行方式仍然适用于整个单词。

Also (1 level) of sub-elements is preserved in the end result.最终结果中还保留了(1 级)子元素。 For example:例如:

a <strong>bc</strong> d

Is converted into:转换为:

<span class="word">
  <span class="letter">a</span>
</span>
<span class="word">
  <span class="letter">
    <strong>b</strong>
  </span>
  <span class="letter">
    <strong>c</strong>
  </span>
</span>
<span class="word">
  <span class="letter">d</span>
</span>

Known issues:已知的问题:

  • Only one level of sub-elements works (So <p>Hello <strong><u>W</u>orld</strong></p> won't)只有一级子元素有效(所以<p>Hello <strong><u>W</u>orld</strong></p>不会)
  • Text against another element create two separate words (So <p>User<strong>name</strong></p> are two words)针对另一个元素的文本创建两个单独的单词(所以<p>User<strong>name</strong></p>是两个单词)

The full solution:完整的解决方案:

 $.fn.convertToSeperateLetters = function() { return this.each(function() { var $el = $(this); var elements = convertToSeperateLetters($el, false); $el.empty().append(elements); return $el; }); } $('p').convertToSeperateLetters(); function convertToSeperateLetters($element, asSubNode) { var elements = []; var childNodes = $element.contents(); // Loop through all child nodes of selected element for (var c = 0; c < childNodes.length; c++) { var node = childNodes[c]; var type = node.nodeType; // Process a child element if (type == Node.ELEMENT_NODE) { Array.prototype.push.apply(elements, convertToSeperateLetters($(node), true)); } // Process a piece of text else if (type == Node.TEXT_NODE) { var text = node.nodeValue; // Process each word var words = text.split(' '); for (var w = 0; w < words.length; w++) { var word = words[w]; // Skip empty words if (word == '') continue; // Wrap each word into span var $word = $('<span/>').addClass('word'); for (var l = 0; l < word.length; l++) { var letter = word[l]; // Wrap each letter into span var $letter = $('<span/>').addClass('letter'); if (.asSubNode) { $letter;html(letter). } if (asSubNode) { var $subNode = $element.clone().empty();html(letter). $letter;append($subNode). } $word;append($letter). } elements;push($word); } } } return elements; }
 p, .word, .letter { padding: 3px 1px; } p { border: 1px solid red; }.word { display: inline-block; border: 1px solid green; margin-left: 2px; margin-right: 2px; }.letter { display: inline-block; border: 1px solid blue; }.word-wrapped { width: 360px; background: lightgrey; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p>Hello World</p> <p>Hello <strong>World</strong></p> <div class="word-wrapped"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM