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

时间:2012-06-03 13:47:12

标签: javascript replace tags space

以下代码不起作用,结果因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标签中的替换空格?

3 个答案:

答案 0 :(得分: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
            }
        }
    }
}

答案 1 :(得分:0)

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

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;

另见this example

=== UPDATE ===

好的,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;

另见this updated example

=== UPDATE ===

好的,我完全改变了我的脚本。它已经过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);

另见the new example

答案 2 :(得分: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>';
}