Obviously, the tagName of an element is readonly – however, you can fake it with a little trickery. Just swapping with replaceWith and copying over the product of .html() won’t get data or events. Here’s an ugly little hack that should do the trick:

POC: http://jsfiddle.net/moagrius/3TRtc/1/

Note that the clone() isn’t necessary in all cases, but for unknown reasons certain event handlers weren’t being passed under certain circumstances.

Of course, you can easily create problems if you do something like replacing a <tr> with an <input />, but for certain cases this should be enough (in my case, I only had access to JS while working on browser app for another company, who had some content wrapped in a label – with the extended functionality I had to create, the label’s default behavior was conflicting with child form controls, and event.preventDefault would have stymied the mouse events of those controls – I used this homely little nugget to change it to a div, conditionally, and just in the relevant module).