Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

got a quandary i was hoping you kind folks could help me out with...

 

goal:

Using jQuery, I'm trying to replace all the occurrences of:

<code> ... </code>

with:

<pre> ... </pre>

 

my solution:

I got as far as the following,

$('code').replaceWith( "<pre>" + $('code').html() + "</pre>" );

 

the problem with my solution:

but the issues is that it's replacing everything between the (second, third, fourth, etc)"code" tags with the content between the first "code" tags.

e.g.

<code> A </code>
<code> B </code>
<code> C </code>

becomes

<pre> A </pre>
<pre> A </pre>
<pre> A </pre>

I think I need to use "this" and some sort of function but I'm afraid I'm still learning and don't really understand how to piece a solution together.

  Thanks for your time and help! :)

Jon

share|improve this question
Fixed the wrap-unwrap solution now jon - check it out ;) – Jens Roland Aug 17 '11 at 13:34

6 Answers

up vote 56 down vote accepted

This is much nicer:

$('code').contents().unwrap().wrap('<pre/>');

Though admittedly Felix Kling's solution is approximately twice as fast:

share|improve this answer
3  
worked like a charm, to my lay eyes this seems to be the most efficient solution. :) – jon Aug 17 '11 at 13:26
3  
didn't work for me: jsfiddle.net/ET6nu – JKirchartz Aug 17 '11 at 13:26
1  
FWIW, $('code').children() will return an empty jQuery object for the example above, because the code elements have no child element nodes. Though it works if there are child elements. – Felix Kling Aug 17 '11 at 13:30
1  
Fixed - true, when the contents consist of a single text node, children() won't work. Using contents() instead works perfectly. jsfiddle.net/7Yne9 – Jens Roland Aug 17 '11 at 13:31
2  
+1, good idea... (now that it works ;)) – Felix Kling Aug 17 '11 at 13:35
show 7 more comments

You can pass a function to .replaceWith [docs]:

$('code').replaceWith(function(){
    return $("<pre />", {html: $(this).html()});
});

Inside the function, this refers to the currently processed code element.

DEMO

Update: There is no big performance difference, but in case the code elements have other HTML children, appending the children instead of serializing them feels to be more correct:

$('code').replaceWith(function(){
    return $("<pre />").append($(this).contents());
});
share|improve this answer
1  
I didn't know this. +1. – Kokos Aug 17 '11 at 13:15
1  
+1, same as Kokos. However is jsFiddle a little slow today? – pimvdb Aug 17 '11 at 13:25
1  
this seems to be the most elegant solution, tho i'll admit i don't understand what's going on inside the replaceWith function. would love to hear more. i.e. how is assigning the opening AND closing tags? does the space in <pre /> accomplish that? – jon Aug 17 '11 at 13:32
2  
@jon: It is a short hand for creating new elements. More information can be found here: api.jquery.com/jQuery/#jQuery2. jQuery loops over all the elements and executes the function for each of them (same what .each is doing). – Felix Kling Aug 17 '11 at 13:33
1  
+1 for a nice trick - this can be used for a lot more than just simple tag-for-tag substitution. – Jens Roland Aug 17 '11 at 14:02
show 2 more comments

It's correct that you'll always obtain the first code's contents, because $('code').html() will always refer to the first element, wherever you use it.

Instead, you could use .each to iterate over all elements and change each one individually:

$('code').each(function() {
    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
    // this function is executed for all 'code' elements, and
    // 'this' refers to one element from the set of all 'code'
    // elements each time it is called.
});
share|improve this answer
this solution makes the most sense to me. – jon Aug 17 '11 at 13:33

Try this:

$('code').each(function(){

    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );

});

http://jsfiddle.net/mTGhV/

share|improve this answer
wow. you guys came up with the exact same solution within 2 seconds of each other. there are tiny formatting differences. I'm not sure which one to upvote - I really don't like the space between function and () in thomas' answer and the 2 lines of empty space in kokos answer are pretty pointlness + there should be a space between the () and the { – Michael Bylstra Feb 13 at 7:17

How about this?

$('code').each(function () {
    $(this).replaceWith( "<pre>" + $(this).html() + "</pre>" );
});
share|improve this answer

As of jQuery 1.4.2:

$('code').replaceWith(function(i,html) {
  return $('<pre />').html(html);
});​

You can then select the new elements:

$('pre').css('color','red');

Source: http://api.jquery.com/replaceWith/#comment-45493689

jsFiddle: http://jsfiddle.net/k2swf/16/

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.