Daniel Fischer
Daniel Fischer

Reputation: 3062

How could I wrap an area of a string with an html element?

If I had something like the following:

$400/week

$800/week

With jQuery being available, what would be an ideal method of wrapping the "/week" part in an html element like <span class='small'>/week</span>?

Upvotes: 2

Views: 55

Answers (2)

icktoofay
icktoofay

Reputation: 129019

It's not pretty, but the only safe way to do it (preserving event handlers and such) is to walk the tree, splitting text nodes where necessary. Unfortunately, jQuery does not like working with text nodes; it is very element-centric.

You can start by defining a helper function to do the recursion:

function recurse(node, fn) {
    if(node.nodeType === Node.TEXT_NODE) {
        fn(node);
    }else if(node.nodeType === Node.ELEMENT_NODE) {
        var children = Array.prototype.slice.call(node.childNodes);
        for(var i = 0, l = children.length; i < l; i++) {
            recurse(children[i], fn);
        }
    }
}

It walks every node in the tree, calling a given function for every text node. Then we can use that function to split the text nodes and insert a span in the middle:

recurse(document.documentElement, function(node) {
    var re = /(\$\d+)(\/week)/;
    var match;
    while(match = re.exec(node.nodeValue)) {
        var before = document.createTextNode(node.nodeValue.substring(0, match.index + match[1].length));
        node.parentNode.insertBefore(before, node);
        var span = document.createElement('span');
        span.className = 'week';
        span.textContent = node.nodeValue.substring(match.index + match[1].length, match.index + match[0].length);
        node.parentNode.insertBefore(span, node);
        node.nodeValue = node.nodeValue.substring(match.index + match[0].length);
    }
});

Try it.

Upvotes: 1

jfriend00
jfriend00

Reputation: 707536

You could do something like this:

var data = $("#text").html();
$("#text").html(data.replace(/\/\s*week/g, '<span class="small">/week</span>'));

Working example: http://jsfiddle.net/jfriend00/TKa8D/

Note: Replacing HTML will undo any event handlers assigned within that HTML so you should generally replace the HTML at the lowest level possible so you aren't replacing elements that already have event handlers on them. If you share your specific HTML, we could make more concrete recommendations for the easiest way.

Upvotes: 4

Related Questions