将跨度添加到字符串中的字符(在HTML元素中)

Add spans to characters in a string (in an HTML element)

本文关键字:HTML 元素 字符 添加 字符串      更新时间:2023-09-26

我想循环遍历元素中文本的字符,并将spans添加到这些字符中。使用jQuery.map():非常容易

$elem = $('h1');
var chars = jQuery.map($elem.text().split(''), function(c) {
  return '<span>' + c + '</span>';
});
$elem.html(chars.join('')); 

上面的内容适用于一个简单的字符串,但现在我想更改函数,使其也能处理更"复杂"的内容,如:<h1>T<em>e</em><b>st</b></h1>。应翻译为:<h1><span>T</span><em><span>e</span></em><b><span>s</span><span>t</span></b></h1>

这意味着我不能再简单地循环遍历元素中的所有字符了。有什么东西可以用来循环遍历元素的内容(字符)以及所有子元素吗?或者还有其他方法可以实现我想要的吗?

总体思路:

您可以递归地迭代子节点。如果遇到元素节点,则迭代其子节点等。如果遇到文本节点,则用一系列span元素替换它。


jQuery

function wrapCharacters(element) {
    $(element).contents().each(function() {
        if(this.nodeType === 1) {
            wrapCharacters(this);
        }
        else if(this.nodeType === 3) {
            $(this).replaceWith($.map(this.nodeValue.split(''), function(c) {
               return '<span>' + c + '</span>';
            }).join(''));
        }
    });
}    
wrapCharacters($('h1')[0]);

演示


JavaScript(不带jQuery)

想法保持不变,即使没有jQuery,包装每个字符也不是很困难:

var d_ = document.createDocumentFragment();
for(var i = 0, len = this.nodeValue.length; i < len; i++) {
    var span = document.createElement('span');
    span.innerHTML = this.nodeValue.charAt(i);
    d_.appendChild(span);
}
// document fragments are awesome :)
this.parentNode.replaceChild(d_, this);

只需要小心地迭代子节点,因为在迭代过程中会删除文本节点。

普通JavaScript示例

尝试类似(未经测试)的东西:

function recursivelyWrapTextNodes($node) {
  $node.contents().each(function() {
    var $this = $(this);
    if (this.nodeType === 3) { //Node.TEXT_NODE (IE...)
        var spans = $.each($this.text().split(""), function(index, element) {
            var $span = $("<span></span>");
            $span.text(element);
            $span.insertBefore($this);
        });
        $this.remove();
    }
    else if (this.nodeType === 1) //Node.ELEMENT_NODE
    recursivelyWrapTextNodes($this);
}

示例:http://jsfiddle.net/Ymcha/

这是一个纯javascript解决方案

/**
 * Enclose every character of a string into a span
 * @param text Text whose characters will be spanned
 * @returns {string} The "spanned" string
 */
function spanText(text) {
    return "<span class='char'>" +
        text.split("").join("<'/span><span class='char'>") + "<'/span>";
}
var text = "Every character will be in a span";
document.getElementById("testContent").innerHTML = spanText(text);
document.getElementById("showSpans").textContent = spanText(text);
.char{background-color: grey;}
<! --- Demo for spanning all characters -->
<h3> Spanned text is highlighted grey </h3>
<p id="testContent"> Spanned material here</p>
<h3> This is how the above Highlighted text looks </h3>
<p id="showSpans"></p>