A friend of mine needed a method to wrap the inner content of a tag with another tag, and after a bit of digging around I found that Brandon Aaron, author of the fantastic Dimensions plugin, has created just the thing.

“jQuery provides a method for wrapping an element with one or more elements. This is a really nice method but sometimes you need to wrap the contents of an element. Now you can do so with one method, innerWrap. The innerWrap method acts almost identical to the wrap method. The only real difference is that it wraps the contents of the element instead of the actual element.” – Brandon Aaron

Here’s the function itself:

jQuery.fn.innerWrap = function() {
    var a, args = arguments;
    return this.each(function() {
        if (!a) a = jQuery.clean(args, this.ownerDocument);
        // Clone the structure that we're using to wrap
        var b = a[0].cloneNode(true),
        c = b; 
        // Find the deepest point in the wrap structure
        while (b.firstChild) b = b.firstChild; 
        // append the child nodes to the wrapper
        jQuery.each(this.childNodes,
        function(i, node) {
            b.appendChild(node);
        });
        jQuery(this) 
        // clear the element
        .empty() 
        // add the new wrapper with the previous child nodes appended
        .append(c);
    });
};

And the example below will effectively turn
<h2>Title</h2>
into
<h2><span>Title</span></h2>

$(document).ready(function(){
      $('h2').innerWrap('<span></span>')
});