简体   繁体   中英

Smart text replacing with jQuery

I need to replace some part of text, eg mustache var {{myvar}}, on already loaded page. Example html:

<html>
   <head>
      <title>{{MYTITLE}}</title>
   </head>
   <body>
      <p><strong><ul><li>text {{TEXT}}</li></ul></strong></p>
      {{ANOTHER}}
   </body>
</html>

What's the problem? Use $(html).html(myrenderscript($(html).html())) !

It's ugly, slow and brokes <script> tags.

What do you want?

I want to get closest tag with {{}} and than render and replace.

Your researches?

Firstly, i tried: $('html :contains("{{")) . But it returns <title>, <p>, <strong> .... But i need <title> and <li> .

Than i tried to filter them:

$('html :contains("{{")').filter(function (i) {
   return $(this).find(':contains("{{")').length === 0
});

...but it WONT return {{ANOTHER}} . And that is my dead end. Your suggestions?

Using http://benalman.com/projects/jquery-replacetext-plugin/ you could do the following:

$('html *').replaceText(/{{([^}]+)}}/, function(fullMatch, key) {
    return key;
}, true);

See http://jsfiddle.net/4nvNy/

If all you want to do is replace that text - then surely the following works (or have I mis-understood)

usage is as follows: CONTAINER (body) - replaceTExt (search term (I have built the function to always include {{}} around the term), (replace - this will remove the {{}} as well)

$('body').replaceText("MYTITLE","WHATEVER YOU WANT IT REPLACING WITH");

$.fn.replaceText = function(search, replace, text_only) {  
return this.each(function(){  
    var v1, v2, rem = [];
    $(this).find("*").andSelf().contents().each(function(){
        if(this.nodeType === 3) {
            v1 = this.nodeValue;
            v2 = v1.replace("{{" + search + "}}", replace );
            if(v1!=v2) {
                if(!text_only && /<.*>/.test(v2)) {  
                    $(this).before( v2 );  
                    rem.push(this);  
                }
                else this.nodeValue = v2;  
            }
        }
    });
    if(rem.length) $(rem).remove();
});
};

You could avoid jQuery altogether if you wanted to with something like this:

<body>


<p><strong>
    <ul>
        <li>text {{TEXT}}</li>
    </ul>
</strong></p>
{{ANOTHER}}

<hr/>
<div id="showResult"></div>

<script>


    var body = document.getElementsByTagName('body')[0].innerHTML;
    var startIdx = 0, endIdx = 0, replaceArray = [];
    var scriptPos = body.indexOf('<script');
    while (startIdx != 1) {
        startIdx = body.indexOf('{{', endIdx) + 2;
        if(startIdx > scriptPos){
            break;
        }
        endIdx = body.indexOf('}}', startIdx);
        var keyText = body.substring(startIdx, endIdx);
        replaceArray.push({"keyText": keyText, 'startIdx': startIdx, 'endIdx': endIdx});

    }

    document.getElementById("showResult").innerHTML = JSON.stringify(replaceArray);


</script>

</body>

You can then do what you want with the replaceArray.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM