简体   繁体   English

如何将元素的每个单词包装在 span 标签中?

[英]How to wrap each word of an element in a span tag?

$("div.date")
    .contents()
    .filter(
        function(){
            return this.nodeType != 1; 
        })
    .wrap("<span/>");

I am new and thought that code would have done the trick, but it wraps everything in the <span> like so:我是新手,认为代码可以解决问题,但它将所有内容都包装在<span>中,如下所示:

<div class='date'><span> Dec 22, 2011 </span></div> <div class='date'><span> 2011 年 12 月 22 日</span></div>

It is supposed to look like this:它应该看起来像这样:

<div class='date'>
  <span>Dec</span>
  <span>22,</span>
  <span>2011</span>
</div>

You don't need jQuery for this simple task.不需要jQuery 来完成这个简单的任务。 String.prototype.replace and regex should do the trick. String.prototype.replace和 regex 应该可以解决问题。

I just made some simple utility functions, that wraps letters, words and lines:我刚刚制作了一些简单的实用函数,用于包装字母、单词和线条:

/**
 * Wraps a string around each character/letter
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input as splitted by chars/letters
 */
function wrapChars(str, tmpl) {
  return str.replace(/\w/g, tmpl || "<span>$&</span>");
}

/**
 * Wraps a string around each word
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input splitted by words
 */
function wrapWords(str, tmpl) {
  return str.replace(/\w+/g, tmpl || "<span>$&</span>");
}

/**
 * Wraps a string around each line
 *
 * @param {string} str The string to transform
 * @param {string} tmpl Template that gets interpolated
 * @returns {string} The given input splitted by lines
 */
function wrapLines(str, tmpl) {
  return str.replace(/.+$/gm, tmpl || "<span>$&</span>");
}

The usage is pretty simple.用法很简单。 Just pass in the string to wrap as first argument.只需传入要包装的字符串作为第一个参数。 If you need custom markup, pass it in as the second argument, while $& is replaced by each char/word/line.如果您需要自定义标记,请将其作为第二个参数传入,而$&将替换为每个字符/单词/行。

var str = "Foo isn't equal\nto bar.";
wrapChars(str); // => "<span>F</span><span>o</span><span>o</span> <span>i</span><span>s</span><span>n</span>'<span>t</span> <span>e</span><span>q</span><span>u</span><span>a</span><span>l</span> <span>t</span><span>o</span> <span>b</span><span>a</span><span>r</span>."
wrapWords(str); // => "<span>Foo</span> <span>isn</span>'<span>t</span> <span>equal</span> <span>to</span> <span>bar</span>."
wrapLines(str); // => "<span>Foo isn't equal</span> <span>to bar.</span>"

It's gonna be a little more complicated than that.它会比那更复杂一点。 You're gonna have to find out all the words and re-append them to your element, wrapped in a span.您将不得不找出所有单词并将它们重新附加到您的元素中,包裹在一个跨度中。

var words = $("p").text().split(" ");
$("p").empty();
$.each(words, function(i, v) {
    $("p").append($("<span>").text(v));
});

Live example活生生的例子

If your element contents contains child elements (HTML) then the above solutions are not useful.如果您的元素内容包含子元素 (HTML),则上述解决方案没有用。

Here's a jsfiddle I've come up with that preserves HTML (elements and their attributes).这是我提出的一个 jsfiddle,它保留了 HTML(元素及其属性)。 The shortcoming of this small snippet is that if you have events binded to the element's contents then they will be lost since innerHTML is being reassigned to something else.这个小片段的缺点是,如果您将事件绑定到元素的内容,那么它们将丢失,因为 innerHTML 被重新分配给其他内容。

This code does not require any special libraries (like jQuery).此代码不需要任何特殊库(如 jQuery)。

https://jsfiddle.net/4b5j0wjo/3/ https://jsfiddle.net/4b5j0wjo/3/

var e = document.getElementById('words');
e.innerHTML = e.innerHTML.replace(/(^|<\/?[^>]+>|\s+)([^\s<]+)/g, '$1<span class="word">$2</span>');

I needed to give each word a specific id, so, being a newbie, I studied the previously published answers code.我需要给每个单词一个特定的 id,所以,作为一个新手,我研究了以前发布的答案代码。 Starting from Brad Christie's and Daniel Tonon's code I used .addClass to achieve this result:从 Brad Christie 和 Daniel Tonon 的代码开始,我使用 .addClass 来实现这个结果:

    $('.mydiv').each(function(){ 
    var words = $(this).text().split(/\s+/);
    var total = words.length;
    $(this).empty();
    for (index = 0; index < total; index ++){
      $(this).append($("<span /> ").addClass("myclass_" + index).text(words[index]));
      }
    })

which outputs:输出:

    <div class="mydiv">
       <span class="myclass_0">bla</span>
       <span class="myclass_1">bla</span>
       <span class="myclass_2">bla</span>
    </div>

starting from:从...开始:

    <div class="mydiv">bla bla bla</div>

It works perfectly for my needs.它非常适合我的需求。 Maybe some expert programmers could tune up that better!也许一些专家程序员可以更好地调整它!

经过大量研究,我能够通过使用正则表达式的负后视功能安全地做到这一点。

htmlStr.replace(/(?<!(<\/?[^>]*|&[^;]*))([^\s<]+)/g, '$1<span class="word">$2</span>')

Is this what you are trying to achieve?这是你想要达到的目标吗?

<span><div class="date">Dec 22, 2011</div></span>

If so:如果是这样的话:

$('div.date').wrap('<span/>');

Or are you trying to get this:或者你想得到这个:

<span>Dec</span> <span>22,</span> <span>2011</span>

Something like this shoul do the trick:像这样的事情应该可以解决问题:

var dateInner = $('div.date');
var wraps = [];
$.each(dateInner.text().split(' '), function (key, value) {
  wraps.push = '<span>' + value + '</span>';
});

dateInner.html(wraps.join(''));
var $div = $('.words');
var divWords = $div.text().split(/\s+/);
$div.empty();
$.each(divWords, function(i,w){
  $('<span/>').text(w).appendTo($div);
});

Then然后

<div class="words">Why hello there, world!</div>

becomes变成

<div class="words">
  <span>Why</span>
  <span>hello</span>
  <span>there,</span>
  <span>World!</span>
</div>

If you use jQuery, try this .如果你使用 jQuery,试试这个

Specifically, you can find an example of how to split to words here具体来说,您可以在此处找到如何拆分为单词的示例

Quote:引用:

Here's an example of the .lettering('words') method:下面是 .lettering('words') 方法的一个例子:

 <p class="word_split">Don't break my heart.</p> <script> $(document).ready(function() { $(".word_split").lettering('words'); }); </script>

Which will generate:这将生成:

 <p class="word_split"> <span class="word1">Don't</span> <span class="word2">break</span> <span class="word3">my</span> <span class="word4">heart.</span> </p>

Just building on Xeon06 excellent answer.只是建立在 Xeon06 上的优秀答案。

I had to do this for a multiple of the same element on the same page.我必须为同一页面上的多个相同元素执行此操作。

    $('.element').each(function(){
        var words = $(this).text().split(" ");
        var total = words.length;
        $(this).empty();
        for (index = 0; index < total; index ++){
            $(this).append($("<span /> ").text(words[index]));
        }
    })

It is a simple one-line answer if you want it for each word:如果您想要每个单词,这是一个简单的单行答案:

str.split(' ').replace(/\w+/g,"<span>$&</span>").join(' ');

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

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