How to wrap all text into unique span tag?

后端 未结 2 1112
心在旅途
心在旅途 2021-01-03 07:37

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

Before wrap :

    

word word

相关标签:
2条回答
  • 2021-01-03 08:06
    (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.net/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.net/mtmqR/1/

    0 讨论(0)
  • 2021-01-03 08:13

    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.net/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.

    0 讨论(0)
提交回复
热议问题