javascript - How to wrap all text into unique span tag? - Stack Overflow

I want to wrap all body text(each word) into unique span tag.Before wrap :<body><div>&

I want to wrap all body text(each word) into unique span tag.

Before wrap :

<body>    
<div>
  <p>word word </p>
  <div>word word</div>
    <ul>
        <li>word word</li>
    </ul>
  </ul>
  <p>word word <strong>word</strong> </p>
</div>
</body>

After wrap :

<body>
<div>
    <p><span id="1">word</span> <span id="2">word</span> </p>
    <div><span id="3">word</span> <span id="4">word</span></div>
    <ul>
        <li><span id="5">word</span> <span id="6">word</span></li>
    </ul>
    </ul>
    <p><span id="7">word</span> <span id="8">word</span> <strong><span id="9">word</span></strong> </p>
</div>
</body>

I tried this in jquery but it doesn't give what i expect

$('body *').each(function(){

        var words = $(this).text().split(" ");

            $(this).empty();
            $t=$(this);
            $.each(words, function(i, v) {
                $t.append('<span>'+v+'</span>');
            });

});

Thanks in advance, Logan

I want to wrap all body text(each word) into unique span tag.

Before wrap :

<body>    
<div>
  <p>word word </p>
  <div>word word</div>
    <ul>
        <li>word word</li>
    </ul>
  </ul>
  <p>word word <strong>word</strong> </p>
</div>
</body>

After wrap :

<body>
<div>
    <p><span id="1">word</span> <span id="2">word</span> </p>
    <div><span id="3">word</span> <span id="4">word</span></div>
    <ul>
        <li><span id="5">word</span> <span id="6">word</span></li>
    </ul>
    </ul>
    <p><span id="7">word</span> <span id="8">word</span> <strong><span id="9">word</span></strong> </p>
</div>
</body>

I tried this in jquery but it doesn't give what i expect

$('body *').each(function(){

        var words = $(this).text().split(" ");

            $(this).empty();
            $t=$(this);
            $.each(words, function(i, v) {
                $t.append('<span>'+v+'</span>');
            });

});

Thanks in advance, Logan

Share Improve this question asked Aug 24, 2012 at 7:37 LoganLogan 1,6944 gold badges21 silver badges35 bronze badges 4
  • performance-wise, you're unnecessarily caling $(this) 3 times, while you could've had your $t=$(this) on top and then reuse that $t later on – Zathrus Writer Commented Aug 24, 2012 at 7:41
  • also, you're closing your unordered list twice (ul tag) – Zathrus Writer Commented Aug 24, 2012 at 7:42
  • you can give id, $t.append('<span id="'+i+'">'+v+'</span>') – Jitender Commented Aug 24, 2012 at 7:52
  • @amit <span id="n'+i+'">' better not to start with number\ – elclanrs Commented Aug 24, 2012 at 7:53
Add a ment  | 

2 Answers 2

Reset to default 11
(function (count) {
  'use strict';
  (function wrap(el) {
    $(el).contents().each(function () {
      // Node.* won't work in IE < 9, use `1`
      if (this.nodeType === Node.ELEMENT_NODE) {
        wrap(this);
      // and `3` respectively
      } else if (this.nodeType === Node.TEXT_NODE) {
        var val = $.trim(this.nodeValue);
        if (val.length > 0) {
          $(this).replaceWith($.map(val.split(/\s+/), function (w) {
            return $('<span>', {id: count = count + 1, text: w}).get();
          }));
        }
      }
    });
  }('body'));
}(0));

http://jsfiddle/LNLvg/3/

update: this version does not silently kill the whitspace ;)

(function (count) {
  'use strict';
  (function wrap(el) {
    $(el).filter(':not(script)').contents().each(function () {
      if (this.nodeType === Node.ELEMENT_NODE) {
        wrap(this);
      } else if (this.nodeType === Node.TEXT_NODE && !this.nodeValue.match(/^\s+$/m)) {
        $(this).replaceWith($.map(this.nodeValue.split(/(\S+)/), function (w) {
          return w.match(/^\s*$/) ? document.createTextNode(w) : $('<span>', {id: count = count + 1, text: w}).get();
        }));
      }
    });
  }('body'));
}(0));

http://jsfiddle/mtmqR/1/

Here's a solution using plain javascript that wraps the words in spans and preserves the spaces that were in the text, but leaves them outside the spans so only the words themselves are in the spans:

function splitWords(top) {
    var node = top.firstChild, words, newNode, idCntr = 1, skipChild;
    var re = /\S/;
    while(node && node != top) {
        skipChild = false;
        // if text node, check for our text
        if (node.nodeType == 3) {
            if (re.test(node.nodeValue)) {
                newNode = null;
                words = node.nodeValue.split(" ");
                for (var i = 0; i < words.length; i++) {
                    if (words[i] === "") {
                        newNode = document.createTextNode(" ");
                        node.parentNode.insertBefore(newNode, node);
                    } else {
                        newNode = document.createElement("span");
                        newNode.id = "word" + idCntr++;
                        newNode.innerHTML = words[i];
                        node.parentNode.insertBefore(newNode, node);
                        if (i < words.length - 1) {
                            newNode = document.createTextNode(" ");
                            node.parentNode.insertBefore(newNode, node);
                        }
                    }
                }
                if (newNode) {
                    node.parentNode.removeChild(node);
                    node = newNode;
                    // don't go into the children of this node
                    skipChild = true;
                }
            }
        } else if (node.nodeType == 1) {
            if (node.tagName == "SCRIPT") {
                skipChild = true;
            }
        }        

        if (!skipChild && node.firstChild) {
            // if it has a child node, traverse down into children
            node = node.firstChild;
        } else if (node.nextSibling) {
            // if it has a sibling, go to the next sibling
            node = node.nextSibling;
        } else {
            // go up the parent chain until we find a parent that has a nextSibling
            // so we can keep going
            while ((node = node.parentNode) != top) {
                if (node.nextSibling) {
                    node = node.nextSibling;
                    break;
                }
            }
        }
    }
}

And a working demo: http://jsfiddle/jfriend00/3mms7/

FYI, I made the id values be "word1", "word2", etc... since before HTML5, id values were not allowed to start with a number.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744094538a4557698.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信