2

以下代码不起作用,结果被破坏,因为 HTML 标记中有空格。

HTML:

<div>Lorem ipsum <a id="demo" href="demo" rel="demo">dolor sit amet</a>, consectetur adipiscing elit.</div>

Javascript:

var div = document.getElementsByTagName('div')[0];
div.innerHTML = div.innerHTML.replace(/\s/g, '<span class="space"> </span>');


如何替换不在 HTML 标签中的空格?

4

3 回答 3

1

实际使用 DOM 函数而不是使用正则表达式进行一些不可靠的字符串操作会是一个更好的主意。splitText是文本节点的功能,允许您拆分文本节点。它在这里派上用场,因为它允许您在空格处拆分并<span>在它们之间插入一个元素。这是一个演示:http: //jsfiddle.net/m5Qe8/2/

var div = document.querySelector("div");

// generates a space span element
function space() {
    var elem = document.createElement("span");
    elem.className = "space";
    elem.textContent = " ";
    return elem;
}

// this function iterates over all nodes, replacing spaces
// with space span elements
function replace(elem) {
    for(var i = 0; i < elem.childNodes.length; i++) {
        var node = elem.childNodes[i];
        if(node.nodeType === 1) {
            // it's an element node, so call recursively
            // (e.g. the <a> element)
            replace(node);
        } else {
            var current = node;
            var pos;
            while(~(pos = current.nodeValue.indexOf(" "))) {
                var next = current.splitText(pos + 1);
                current.nodeValue = current.nodeValue.slice(0, -1);
                current.parentNode.insertBefore(space(), next);
                current = next;
                i += 2;  // childNodes is a live array-like object
                         // so it's necessary to advance the loop
                         // cursor as well
            }
        }
    }
}
于 2012-06-03T16:56:07.083 回答
0

首先在每次出现>or时拆分字符串<。然后通过仅在偶数部分替换空格再次将所有部分组合成一个字符串:

var div = document.getElementsByTagName('div')[0];
var parts = div.innerHTML.split(/[<>]/g);
var newHtml = '';
for (var i = 0; i < parts.length; i++) {
    newHtml += (i % 2 == 0 ? parts[i].replace(/\s/g, '<span class="space"> </span>') : '<' + parts[i] + '>');
}
div.innerHTML = newHtml;

另请参阅此示例

=== 更新 ===

好的,IE 拆分的结果可能与所有其他浏览器的拆分结果不同。通过以下解决方法,它应该可以工作:

var div = document.getElementsByTagName('div')[0];
var sHtml = ' ' + div.innerHTML;
var sHtml = sHtml.replace(/\>\</g, '> <');
var parts = sHtml.split(/[<>]/g);
var newHtml = '';
for (var i = 0; i < parts.length; i++) {
    if (i == 0) {
        parts[i] = parts[i].substr(1);
    }
    newHtml += (
        i % 2 == 0 ? 
        parts[i].replace(/\s/g, '<span class="space"> </span>') : 
        '<' + parts[i] + '>'
    );
}
div.innerHTML = newHtml;

另请参阅此更新示例

=== 更新 ===

好的,我已经完全改变了我的脚本。它已经过 IE8 和当前的 firefox 测试。

function parseNodes(oElement) {
    for (var i = oElement.childNodes.length - 1; i >= 0; i--) {
        var oCurrent = oElement.childNodes[i];
        if (oCurrent.nodeType != 3) {
            parseNodes(oElement.childNodes[i]);
        } else {
            var sText = (typeof oCurrent.nodeValue != 'undefined' ? oCurrent.nodeValue : oCurrent.textContent);
            var aParts = sText.split(/\s+/g);
            for (var j = 0; j < aParts.length; j++) {
                var oNew = document.createTextNode(aParts[j]);
                oElement.insertBefore(oNew, oCurrent);
                if (j < aParts.length - 1) {
                    var oSpan = document.createElement('span');
                    oSpan.className = 'space';
                    oElement.insertBefore(oSpan, oCurrent);
                    var oNew = document.createTextNode(' ');
                    oSpan.appendChild(oNew);
                }
            }
            oElement.removeChild(oCurrent);
        }
    }
}

var div = document.getElementsByTagName('div')[0];
parseNodes(div);

另请参阅新示例

于 2012-06-03T14:10:23.053 回答
0

您可以处理容器的文本内容,而忽略标记。

var div = document.getElementsByTagName('div')[0];
if(div.textContent){
    div.textContent=div.textContent.replace(/(\s+)/g,'<span class="space"> </span>';
}
else if(div.innerText){
    div.innerText=div.innerText.replace(/(\s+)/g,'<span class="space"> </span>';
}
于 2012-06-03T14:23:41.967 回答