使用javascript制作文字突出显示

时间:2013-04-15 03:02:04

标签: javascript html regex

我想在给定段落中加粗。这是一个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>  

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

2 个答案:

答案 0 :(得分:0)

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

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处的代码示例。

<强>更新

  • Passerby指出应谨慎使用innerHTML。在处理之前转义文本nodeValue。

答案 1 :(得分: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. 如果我们还有文字,请将其添加回来。
  5. 我首先需要缓存TEXT_NODE的原因是,如果我们在walkElement中直接修改它,它将更改其父级的childNodes.length,并打破该过程。