0

I have written a basic script to search the DOM for strings and replace. But in it's current state, it will affect URLs of links too.

For example replacing "example" with "my example" would break the following example;

<a href="http://my example.com/my example">My Example</a>

How could I stop this for happening, so the result would in fact return like this?

<a href="http://example.com/example">My Example</a>

Is there a way to automatically account for CAPs or would this require a separate search string?

Here is my code;

$(document).ready(function(){

    $("body").children().each(function() {           

        $(this).html($(this).html().replace(/example/g,"my example"));

    })

});

There will be approximately 80 words to find/replace, from a perfromace point of view, is there a better method of handling this? Short of separate pages per languages of course.

1 Answer 1

3

If you use .text() instead of .html() it will not change the hrefs.

$(document).ready(function(){
    $("body").children().each(function() {           
        $(this).text($(this).text().replace(/example/g,"my example"));
    });
});

UPDATE: I should add that this may cause unintended side effects as currently written. I would suggest restricting the .replace operation to atomic elements as follows:

$(document).ready(function() {
    replaceText($("body"));

    function replaceText(object) {
        var children = object.children();
        if (children.length > 0) {
            children.each(function() {
                replaceText($(this));
            });
        } else {
            object.text(object.text().replace(/example/g, "my example"));
        };
    };
});

UPDATE: Here is an alternative approach that works for free-floating text nodes.

$(document).ready(function() {
    replaceText($("body"));

    function replaceText(object) {

        //first we handle text nodes inside the element itself
        handleTextNodes(object); 

        //then we iterate down into the child elements 
        var children = object.children();
        children.each(function() {
            replaceText($(this));
        });
    };

    function handleTextNodes(object) {
        object.contents().filter(function() {
            return this.nodeType == 3;
        }).each(function() {
            textNodeReplace(this);
        });
    };

    function textNodeReplace(node) {
        var text = node.nodeValue;
        node.nodeValue = text.replace(/example/g, "my example");
    };
});
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the quick reply. Using this code, I get an error... Uncaught TypeError: Cannot read property 'createDocumentFragment' of undefined
Oops - I had forgotten to update the last line. Should work now.
Perfect! Works a treat! Thank you so much!
Actually, just noticed this method only replaces the first instance in each of the children. Any ideas how to get it to target all instances within a particular child?
It should work for all instances, but will not work for text nodes (i.e. text that is free-floating inside a div). So that may be the issue. If so, I've added an alternative approach.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.