jQuery: how to change tag name?
For example:
$1
I need
$1
<
JS to change the tag name
/**
* This function replaces the DOM elements's tag name with you desire
* Example:
* replaceElem('header','ram');
* replaceElem('div.header-one','ram');
*/
function replaceElem(targetId, replaceWith){
$(targetId).each(function(){
var attributes = concatHashToString(this.attributes);
var replacingStartTag = '<' + replaceWith + attributes +'>';
var replacingEndTag = '</' + replaceWith + '>';
$(this).replaceWith(replacingStartTag + $(this).html() + replacingEndTag);
});
}
replaceElem('div','span');
/**
* This function concats the attributes of old elements
*/
function concatHashToString(hash){
var emptyStr = '';
$.each(hash, function(index){
emptyStr += ' ' + hash[index].name + '="' + hash[index].value + '"';
});
return emptyStr;
}
Related fiddle is in this link
You could go a little basic. Works for me.
var oNode = document.getElementsByTagName('tr')[0];
var inHTML = oNode.innerHTML;
oNode.innerHTML = '';
var outHTML = oNode.outerHTML;
outHTML = outHTML.replace(/tr/g, 'div');
oNode.outerHTML = outHTML;
oNode.innerHTML = inHTML;
Jquery plugin to make "tagName" editable :
(function($){
var $newTag = null;
$.fn.tagName = function(newTag){
this.each(function(i, el){
var $el = $(el);
$newTag = $("<" + newTag + ">");
// attributes
$.each(el.attributes, function(i, attribute){
$newTag.attr(attribute.nodeName, attribute.nodeValue);
});
// content
$newTag.html($el.html());
$el.replaceWith($newTag);
});
return $newTag;
};
})(jQuery);
See : http://jsfiddle.net/03gcnx9v/3/
The above solutions wipe out the existing element and re-create it from scratch, destroying any event bindings on children in the process.
short answer: (loses 's attributes)
$("p").wrapInner("<div/>").children(0).unwrap();
longer answer: (copies 's attributes)
$("p").each(function (o, elt) {
var newElt = $("<div class='p'/>");
Array.prototype.slice.call(elt.attributes).forEach(function(a) {
newElt.attr(a.name, a.value);
});
$(elt).wrapInner(newElt).children(0).unwrap();
});
fiddle with nested bindings
It would be cool to copy any bindings from the at the same time, but getting current bindings didn't work for me.
Today (2014) no browser understand the new DOM3 renameNode method (see also W3C) check if run at your bowser: http://jsfiddle.net/k2jSm/1/
So, a DOM solution is ugly and I not understand why (??) jQuery not implemented a workaround?
createElement(new_name)
replaceChild()
is something like this,
function rename_element(node,name) {
var renamed = document.createElement(name);
foreach (node.attributes as a) {
renamed.setAttribute(a.nodeName, a.nodeValue);
}
while (node.firstChild) {
renamed.appendChild(node.firstChild);
}
return node.parentNode.replaceChild(renamed, node);
}
... wait review and jsfiddle ...
The @ilpoldo algorithm is a good start point,
$from.replaceWith($('<'+newname+'/>').html($from.html()));
As others commented, it need a attribute copy ... wait generic ...
specific for class
, preserving the attribute, see http://jsfiddle.net/cDgpS/
See also https://stackoverflow.com/a/9468280/287948
You can use this function
var renameTag = function renameTag($obj, new_tag) {
var obj = $obj.get(0);
var tag = obj.tagName.toLowerCase();
var tag_start = new RegExp('^<' + tag);
var tag_end = new RegExp('<\\/' + tag + '>$');
var new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
};
ES6
const renameTag = function ($obj, new_tag) {
let obj = $obj.get(0);
let tag = obj.tagName.toLowerCase();
let tag_start = new RegExp('^<' + tag);
let tag_end = new RegExp('<\\/' + tag + '>$');
let new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
};
Sample code
renameTag($(tr),'div');