gabf Hahn
gabf Hahn

Reputation: 117

javascript: how to replace all the tag with something different

I want to replace all the tags with different tag using javascript.

Lets say I want to replace "asdf" tag with "xyz"

<asdf>
<asdf> First 
      <asdf> First nested </asdf>
</asdf>
<asdf> Second</asdf
</asdf>

This is what I am expecting:

<xyz>
<xyz>  First
   <xyz> First nested </xyz>
</xyz>
<xyz> Second </xyz>
</xyz>

i tried with using jquery

$('asdf').each(function() {
$(this).replaceWith("<xyz>"+$(this).html()+"</xyz>")
});

but it replaces only the first not all.

Upvotes: 0

Views: 126

Answers (2)

Jagdish Idhate
Jagdish Idhate

Reputation: 7742

Made simple jquery plugin

$.fn.renameTag = function(replaceWithTag){
  this.each(function(){
        var outerHtml = this.outerHTML;
        var tagName = $(this).prop("tagName");
        var regexStart = new RegExp("^<"+tagName,"i");
        var regexEnd = new RegExp("</"+tagName+">$","i")
        outerHtml = outerHtml.replace(regexStart,"<"+replaceWithTag)
        outerHtml = outerHtml.replace(regexEnd,"</"+replaceWithTag+">");
        $(this).replaceWith(outerHtml);
    });
    return this;
}

Usage:

$('asdf').renameTag('xyz')

Upvotes: -1

T.J. Crowder
T.J. Crowder

Reputation: 1074305

I'd do it in reverse document order so that we process descendant elements before ancestor ones, and I'd avoid making a round-trip through markup since that's unnecessary overhead and will wipe out event handlers we could avoid wiping out. (Not much we can do about the ones on the actual elements we're changing, at least not ones attached with modern techniques.)

See comments:

// Get all target elements, and then get a raw array for them
// and reverse it. Then loop through the reversed copy.
$("div").get().reverse().forEach(function(src) {
  // Get a jQuery wrapper for this element
  var $src = $(src);

  // Create the replacement
  var $dest = $("<span>");

  // Move all its contents over
  $dest.append($src.contents());

  // Copy its attributes
  Array.prototype.forEach.call(src.attributes, function(attr) {
    $dest[0].setAttribute(attr.nodeName, attr.nodeValue);
  });

  // Replace it
  $src.replaceWith($dest);
});

Live Example:

setTimeout(function() {
  // Get all target elements, and then get a raw array for them
  // and reverse it. Then loop through the reversed copy.
  $("div").get().reverse().forEach(function(src) {
    // Get a jQuery wrapper for this element
    var $src = $(src);

    // Create the replacement
    var $dest = $("<span>");

    // Move all its contents over
    $dest.append($src.contents());

    // Copy its attributes
    Array.prototype.forEach.call(src.attributes, function(attr) {
      $dest[0].setAttribute(attr.nodeName, attr.nodeValue);
    });

    // Replace it
    $src.replaceWith($dest);
  });
}, 500);
div {
  border: 1px solid red;
}
span {
  border: 1px solid green;
}
.test {
  color: blue;
  font-weight: bold;
}
<p>Divs will change to spans in a moment. "Second" is blue because it has a class on it, to check that we copy attributes correctly.</p>
<div>
  <div>First
    <div>First nested</div>
  </div>
  <div class="test">Second</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 2

Related Questions