jQuery查找/替换而不更改原始文本

时间:2010-10-30 18:19:03

标签: javascript jquery

jQuery中是否有一种方法可以在jQuery中查找文本字符串,而不是用其他内容替换它,但是将该文本用元素包装起来,这样当脚本完成后,它会将原始文本用文本字符串包装出来。

示例:

原始文字

"Hello world to all people"

搜索字符串

"world to"

替换为<i></i>

最终输出

"Hello <i>World to</i> all people"

提前感谢您的帮助!

一种有效的代码:

function highlightChild(child) {
        $(childElements[child]).text("");
        console.log(child);
        $('.child_element_' + child).bind('textselect', function(e){
            var selection = e.text;
            var str = $("#construct_version").text();
            var wrap = jQuery(childElements[child]).text(selection);
            var re = new RegExp("" + selection + "", "g");

            console.log(str.replace(selection, function(match, key, val){
                console.log(match);
                console.log(key);
                console.log(val);
                jQuery(childElements[child]).text(val)
            }));
        });
    }

上面的代码执行替换,但实际上替换它显示为undefined。

因此,如果原始字符串对所有人都是Hello world,并且我希望将world替换为<b>world to</b>,则它在console.log中显示为Hello undefined all

5 个答案:

答案 0 :(得分:13)

通常,更改页面内容与使用正则表达式替换html()标记一样简单。如果标记本身存在匹配的文本,所有这些尝试都将失败,当浏览器选择以不符合您期望的方式序列化其DOM时可能会失败,并且充其量,当它确实有效时,仍会强制您序列化并重新解析所有搜索到的文本,这些文本很慢并且会破坏所有不可序列化的信息,例如表单字段值,JavaScript引用和事件处理程序。对于简单的低级元素,您可以使用它,但对于像<body>这样的容器,它会很糟糕。

更好:不是黑客攻击HTML字符串,而是坚持使用实时DOM节点,搜索符合您要求的Text个节点,并对直接文本节点数据进行替换。这里有一些简单的JS代码(如果你愿意,我想你可以将它放在一个插件中。)

// Utility function to find matches in an element's descendant Text nodes,
// calling back a function with (node, match) arguments. The `pattern` can
// be a string, for direct string matching, or a RegExp object (which must
// be a `g`lobal regex.
//
function findText(element, pattern, callback) {
    for (var childi= element.childNodes.length; childi-->0;) {
        var child= element.childNodes[childi];
        if (child.nodeType==1) {
            var tag= child.tagName.toLowerCase();
            if (tag!=='script' && tag!=='style' && tag!=='textarea')
                findText(child, pattern, callback);
        } else if (child.nodeType==3) {
            var matches= [];
            if (typeof pattern==='string') {
                var ix= 0;
                while (true) {
                    ix= child.data.indexOf(pattern, ix);
                    if (ix===-1)
                        break;
                    matches.push({index: ix, '0': pattern});
                }
            } else {
                var match;
                while (match= pattern.exec(child.data))
                    matches.push(match);
            }
            for (var i= matches.length; i-->0;)
                callback.call(window, child, matches[i]);
        }
    }
}

使用纯字符串搜索词的示例:

// Replace “World to” string in element text with <i>-wrapped version
//
var element= $('#construct_version')[0];
findText(element, 'World to', function(node, match) {
    var wrap= document.createElement('i');
    node.splitText(match.index+match[0].length);
    wrap.appendChild(node.splitText(match.index));
    node.parentNode.insertBefore(span, node.nextSibling);
});

答案 1 :(得分:9)

您可以使用.replace(),例如:

var str = "Hello world to all people";
str = str.replace(/(world to all)/g, "<i>$1</i>");

You can give it a try here适用于说明元素的html:

$("span").html(function(i, t) {
    return t.replace(/(world to all)/g, "<i>$1</i>");
});

答案 2 :(得分:0)

我想你可能会使用javascript:

var t= "Hello world to all people";
var output = t.replace("world to", "<i>world to</i>"));
alert(output);

答案 3 :(得分:0)

这很简单。只需执行jQuery .replace()函数。

这是一个jsFiddle

http://jsfiddle.net/HZVs8/

此方法的唯一问题是,如果您在其中包含任何其他带有字符串“id”的单词,它也会转换它们。如果单词类似于“项目ID”,带有空格,而不是“Project-id”或“ProjectId”,则此方法可以像这样使用:

$("body").html(function(i, x) {
return x.replace(/( id)/g, "ID");
});​

确保在第一个ID之前有空格,或者它会选择每个单词中包含字母“id”的单词。

答案 4 :(得分:-1)

我在下面写了这个函数,但它可能效率不高但效果很好。

categoryname是字符串,userinput是要突出显示的字符串,我想将其换成粗体,您可以更改为li

function GetHighlightedString(categoryname,userinput) {
    userinput=TrimSS(userinput);
    var tempToSearch=categoryname.toLowerCase(); // to take care of case issue.
    var mysearchTemp=userinput;
    var mytemppos = tempToSearch.indexOf(mysearchTemp.toLowerCase());
    var finalstring=categoryname;
    var str1,str2,str3;
    str1=tempToSearch.substring(0,mytemppos);

    str2=tempToSearch.substring(mytemppos, mytemppos+userinput.length);

    if(userinput.toLowerCase()==str2) 
    {
        finalstring=str1 + '<b>';
        finalstring=finalstring+str2+'</b>';
    }
    else
    {
        finalstring= str1+str2;
    } 

    str3=tempToSearch.substring(mytemppos+userinput.length);
    finalstring=finalstring+str3;
    return finalstring;
}