2

我想在给定的段落中加粗一个单词。这是一个javascript代码。

        var hlWord = "idm";
        var nregex = new RegExp(hlWord,"gi");
        var div = document.getElementById("SR").innerHTML;
        var rword = div.replace(nregex,"<b>"+hlWord+"</b>");
        document.getElementById("SR").innerHTML = rword;  

这是一个 HTML 代码。

<div id="SR">
Download here free idm.
<a href="http://www.anywebsite.com/idm">click here to download</a>
</div>  

这很好用,并使所有 idm 粗体,但这里有一个问题,它也将 url 更改为这样

<a href="http://www.anywebsite.com/<b>idm</b>">click here to download</a>  

这不是一个有效的 url。这是此代码使 url 损坏的问题。请告诉我如何避免这种情况。
谢谢...

4

2 回答 2

0

您可以使用此线程中的方法遍历所有文本节点,更改它们并用新的粗体替换它们。

var hlWord = "idm";
var nregex = new RegExp(hlWord,"gi");

var sr = document.getElementById('SR');

function escape_html(html) {
    return html.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

(function findTextNodes(current) {
    // make a shadow copy of the child nodes.
    var current_children = Array.prototype.slice.call(current.childNodes);
    for(var i = 0; i < current_children.length; i++) {
        var child = current.childNodes[i];
        // text node
        if(child.nodeType == 3) {
            var value = escape_html(child.nodeValue);
            var html = value.replace(nregex, '<b>' + hlWord + '</b>');
            if (html != value) {
                var node = document.createElement('div');
                node.innerHTML = html;
                // make a shadow copy of the child nodes.
                var childNodes = Array.prototype.slice.call(node.childNodes);
                // replace the plain text node with the bold segments
                for (var j = 0; j < childNodes.length; j++) {
                    var c = childNodes[j];
                    current.insertBefore(c, child);
                }
                current.removeChild(child);
            }
        }
        else {
            findTextNodes(child);
        }
    }
})(sr);

检查jsFiddle的代码示例。

更新

  • 路人指出,innerHTML应谨慎使用。处理前转义文本 nodeValue。
于 2013-04-15T03:52:55.193 回答
0

经过一些尝试和失败后,我做了一个工作演示,它可能比你想象的要复杂:

http://jsfiddle.net/4VKNk/

var cache=[];
var reg=/idm/gi;
var id=function(ID){return document.getElementById(ID);}
function walkElement(ele){
    if(ele.childNodes.length>0){
        for(var i=0;i<ele.childNodes.length;i++){
            walkElement(ele.childNodes[i]);
        }
    }else if(ele.nodeType==3){//text node
        if(reg.test(ele.nodeValue)){
            cache.push(ele);
        }
    }
}
id("test").onclick=function(){
    cache=[];
    walkElement(id("SR"));
    while(cache.length>0){
        var ele=cache.shift();
        var val=ele.nodeValue;
        var pnt=ele.parentNode;
        var nextSibling=ele.nextSibling;
        var i=0;
        var r,tmp;
        pnt.removeChild(ele);
        while(r=reg.exec(val)){
            tmp=document.createTextNode(val.substring(i,r.index));
            if(nextSibling){
                pnt.insertBefore(tmp,nextSibling);
                tmp=document.createElement("strong");
                tmp.appendChild(document.createTextNode("idm"));
                pnt.insertBefore(tmp,nextSibling);
            }else{
                pnt.appendChild(tmp);
                tmp=document.createElement("strong");
                tmp.appendChild(document.createTextNode("idm"));
                pnt.appendChild(tmp);
            }
            i=reg.lastIndex;
        }
        if(i<val.length-1){
            tmp=document.createTextNode(val.substring(i,val.length));
            if(nextSibling){
                pnt.insertBefore(tmp,nextSibling);
            }else{
                pnt.appendChild(tmp);
            }
        }
    }
};

我采用了 DOM 操作的方法。

解释:

  1. 遍历目标元素下的整个DOM树,并缓存所有TEXT_NODE( nodeType==3);
  2. 使用RegExp.exec()方法获取每个匹配的索引;
  3. 当您找到匹配项时,添加回它之前的文本,然后添加一个<strong>包含匹配项的突出显示元素 ( );继续这一步;
  4. 如果我们仍然有文本,请将其添加回来。

我需要先缓存 TEXT_NODE 的原因是,如果我们直接在 中修改它walkElement,它会改变childNodes.length它的父节点,并中断进程。

于 2013-04-15T03:53:56.487 回答