4

How to replace <b></b> tag with <strong></strong> tag to a specific div?

ex:

<div id="aaa">hello<b>wow</b>!</div>

using javascript to replace with

<div id="aaa">hello<strong>wow</strong>!</div>

please help! thanks in advance.

enter image description here

***** Why I'm try to do is change the output HTML code <b></b> to <strong></strong> , in order to get W3C validation. Can I do that? **

Or Is there any solution that can use ASP.NET+C# to do that?

user951581
  • 83
  • 1
  • 4
  • 10
  • 1
    http://stackoverflow.com/questions/918792/use-jquery-to-change-an-html-tag – Samich Sep 18 '11 at 19:34
  • 2
    Just out of interest, why? `` and `` do the same thing, other than the former is interpreted by screenreaders. – Bojangles Sep 18 '11 at 19:35
  • 1
    @Samich The OP didn't specify jQuery... – Šime Vidas Sep 18 '11 at 19:42
  • Why I'm doing this is because of W3C. – user951581 Sep 18 '11 at 19:52
  • @Šime Vidas maybe OP don't know yet jQuery, but it's a good chance to learn it – Samich Sep 18 '11 at 19:56
  • @JamWaffles, both `` and `` render the same in a browser **by default**, but `` provides more meaning (strong emphasis), whereas `` is simply a visual styling. A subtle difference, but sometimes an important one. – Chris Calo Sep 18 '11 at 19:56
  • 1
    **Note**: the W3C validator will not execute your JavaScript so if you're doing this just to validate your document, then keep in mind that the validator will only see the original source, not the modified DOM. – Andrew Vit Sep 18 '11 at 20:11
  • or you can do this using server-side language to write the HTML/CSS of your page. – Kakashi Sep 18 '11 at 20:23
  • In the image you posted, your script is running before the document is loaded. (That is, `
    ` doesn't exist yet.) You need to put the script after the content you want to modify (just before the closing `

    ` tag will do. There are other ways to fix it, but this is the simplest.

    – Chris Calo Sep 19 '11 at 01:08

5 Answers5

5

Here you go:

var root, elems;

root = document.getElementById( 'test' );
elems = root.getElementsByTagName( 'b' );

toArray( elems ).forEach( function ( elem ) {
    var newElem = document.createElement( 'strong' );
    newElem.textContent = elem.textContent;
    elem.parentNode.replaceChild( newElem, elem );    
});

where toArray is your preferred array-like to array converter function. I use this one:

function toArray( arrayLike ) { return [].slice.call( arrayLike ); }

Live demo: http://jsfiddle.net/mJSyH/3/

Note: this code doesn't work in IE8.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Why doesn't it work in IE? Nice answer nevertheless, learned a thing or two :) – fresskoma Sep 18 '11 at 19:47
  • `forEach` is new in JS, see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach – Lekensteyn Sep 18 '11 at 19:50
  • 2
    @x3ro IE8 doesn't implement `forEach` and `textContent`. One could use `innerHTML` instead of `textContent`, and `forEach` can easily be manually implemented in IE8, so with some additional effort, this can work in IE8, too. – Šime Vidas Sep 18 '11 at 19:50
  • can I change the output HTML code ` ` to ` `? – user951581 Sep 18 '11 at 21:05
  • @user In the browsers (where JavaScript is executed), there is no "output HTML". The HTML source code is used as an input to create the DOM tree. If you need this change to be made on the HTML source code (before sending it to the browsers), you'll need to do it on the server... – Šime Vidas Sep 18 '11 at 21:12
5

You can grab all <b> elements under a certain element, move all child nodes to a new <strong> element, and then replace the <b> with the <strong>.

<div id="aaa">hello<b>wow</b><b>2</b><b>3</b>!</div>

<script>
  var container = document.getElementById("aaa")
  var find = container.getElementsByTagName("b");
  var bold, strong;

  while (bold = find[0]) {
    strong = document.createElement("strong");

    while (bold.firstChild) {
      strong.appendChild(bold.firstChild);
    }

    bold.parentNode.replaceChild(strong, bold);
  }
</script>

The reason you can set bold = find[0] every time is that as the <b> elements are removed from the document, they are also removed from the NodeList find.

See the latest version at http://jsbin.com/eqikaj/13/edit.

Chris Calo
  • 7,518
  • 7
  • 48
  • 64
  • +1 This is a good way to do it. You could even get rid of the `i`, and do a `while (bold = find[0]) {` since your `find` list will update with each removal. – user113716 Sep 18 '11 at 20:42
  • Great point, @Patrick. Those dynamic `NodeList`s will get you every time. Updating the solution now. – Chris Calo Sep 19 '11 at 01:32
  • 1
    Ah, I wasn't even thinking about the fact that you were walking forward through the updating list. Still, I'd personally keep it as a NodeList and [just assign to `find[0]`](http://jsbin.com/eqikaj/10/edit) without updating the index. That'll get you through the list without any skips, it'll be much faster, and more browser compatible since you can't place a NodeList (or any Host Object) as the *thisArg* of `.slice()` in IE8 or lower. – user113716 Sep 19 '11 at 02:22
2

Using jQuery you can find all b tags in scope of your parent div container element and then replace each of them with strong and copy inner text of the source tag:

$('#aaa b').each(function() {
  $(this).replaceWith($('<strong>' + this.html() + '</strong>');
});
Samich
  • 29,157
  • 6
  • 68
  • 77
1

If you use jQuery, you can simply go like this:

$('b').replaceWith(function() {
        return $('<strong>').html($(this).html());
});

Just download or include the jQuery library somehow, and you can use the snippet. http://docs.jquery.com/Downloading_jQuery

Sunjay Varma
  • 5,007
  • 6
  • 34
  • 51
1

A solution using regular expressions:

var e = document.getElementById("aaa");
e.innerHTML = e.innerHTML.replace(/<b[^>]*>(.*?)<\/b>/ig, '<strong>$1</strong>');

perhaps is not more fast that the versions above. but the perfomace difference is very little(irrelevant in real applications). Use whichever you think best

note: you don't need use a function as toArray, you can do this:

Array.forEach(elems, function() {  ... })
Kakashi
  • 2,165
  • 14
  • 19