如何在span标记中包含元素的每个单词?

时间:2011-12-22 20:07:55

标签: javascript jquery

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

我是新手并且认为代码可以完成这个技巧,但它会像<span>一样包装所有内容:

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

应该看起来像这样:

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

9 个答案:

答案 0 :(得分:25)

这会比那复杂一点。你将不得不找出所有的单词并将它们重新附加到你的元素中,包裹在一个跨度中。

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

Live example

答案 1 :(得分:25)

对于这个简单的任务,你不需要需要 jQuery。 String.prototype.replace和正则表达式可以解决问题。

我刚刚制作了一些简单的实用函数,包装了字母,单词和行:

/**
 * 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>");
}

用法非常简单。只需传入字符串作为第一个参数包装。如果需要自定义标记,请将其作为第二个参数传入,而$&替换为每个字符/单词/行。

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

答案 2 :(得分:2)

这是你想要实现的目标吗?

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

如果是这样的话:

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

或者你想要得到这个:

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

这样的事情可以解决问题:

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

dateInner.html(wraps.join(''));

答案 3 :(得分:2)

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

然后

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

变为

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

答案 4 :(得分:2)

如果元素内容包含子元素(HTML),则上述解决方案无效。

这是我提出的一个保留HTML(元素及其属性)的jsfiddle。这个小片段的缺点是,如果你有事件绑定到元素的内容,那么它们将丢失,因为innerHTML被重新分配给其他东西。

此代码不需要任何特殊库(如jQuery)。

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

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

答案 5 :(得分:2)

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

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

答案 6 :(得分:1)

如果您使用jQuery,请尝试this

具体来说,您可以找到如何拆分为单词here

的示例

引用:

  

以下是.lettering(&#39; words&#39;)方法的示例:

<p class="word_split">Don't break my heart.</p>

<script>
$(document).ready(function() {
  $(".word_split").lettering('words');
});
</script>
     

将生成:

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

答案 7 :(得分:1)

我需要给每个单词一个特定的id,因此,作为一个新手,我研究了之前发布的答案代码。从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]));
      }
    })

输出:

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

从:

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

它完全符合我的需求。 也许一些专家程序员可以更好地调整它!

答案 8 :(得分:0)

基于Xeon06的优秀答案。

我必须在同一页面上为同一元素的多个执行此操作。

    $('.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]));
        }
    })