Использование jQuery для замены одного тега другим

Цель:

Используя jQuery, я пытаюсь заменить все вхождения:

<code> ... </code>

с:

<pre> ... </pre>

Мое решение:

Я получил следующее:

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

Проблема с моим решением:

но проблема заключается в том, что он заменяет все теги (теги "второй, третий, четвертый и т.д." ) содержимым между тегами first "code".

например.

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

становится

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

Я думаю, мне нужно использовать "this" и какую-то функцию, но я боюсь, что я все еще участвую и не понимаю, как собрать решение вместе.

Ответ 1

Вы можете передать функцию .replaceWith [docs]:

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

Внутри функции this ссылается на текущий обработанный элемент code.

DEMO

Обновление: нет большой разницы в производительности, но в случае, если элементы code имеют другие дочерние элементы HTML, вместо этого вместо них добавляются дети сериализация их чувств будет более правильной:

$('code').replaceWith(function(){
    return $("<pre />").append($(this).contents());
});

Ответ 3

Правильно, что вы всегда получите первое содержимое code, потому что $('code').html() всегда будет ссылаться на первый элемент, где бы вы его ни использовали.

Вместо этого вы можете использовать .each для перебора всех элементов и изменения каждого из них по отдельности:

$('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.
});

Ответ 4

Попробуйте следующее:

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

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

});

http://jsfiddle.net/mTGhV/

Ответ 5

Как насчет этого?

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

Ответ 6

Настройтесь на ответ Феликса.

$('code').replaceWith(function() {
    var replacement = $('<pre>').html($(this).html());
    for (var i = 0; i < this.attributes.length; i++) {
        replacement.attr(this.attributes[i].name, this.attributes[i].value);
    }
    return replacement;
});

Это приведет к воспроизведению атрибутов тегов code в тегах замены pre.

Изменить: это заменит те теги code, которые находятся внутри innerHTML других тегов code.

function replace(thisWith, that) {
    $(thisWith).replaceWith(function() {
        var replacement = $('<' + that + '>').html($(this).html());
        for (var i = 0; i < this.attributes.length; i++) {
            replacement.attr(this.attributes[i].name, this.attributes[i].value);
        }
        return replacement;
    });
    if ($(thisWith).length>0) {
        replace(thisWith, that);
    }
}

replace('code','pre');

Ответ 8

Если вы использовали ванильный JavaScript, вы бы:

  • Создайте новый элемент
  • Переместите дочерние элементы старого элемента в новый элемент
  • Вставьте новый элемент перед старым
  • Удалить старый элемент

Здесь jQuery эквивалент этого процесса:

$("code").each(function () {
    $("<pre></pre>").append(this.childNodes).insertBefore(this);
    $(this).remove();
});

Вот URL-адрес jsperf:
http://jsperf.com/substituting-one-tag-for-another-with-jquery/7

PS: Все решения, которые используют .html() или .innerHTML, разрушают.

Ответ 9

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

Лучший и чистый способ.

Ответ 10

Вы можете использовать функцию jQuery html. Ниже приведен пример замены тега кода тегом pre, сохраняя все атрибуты кода.

    $('code').each(function() {
        var temp=$(this).html();
        temp=temp.replace("code","pre");
        $(this).html(temp);
    });

Это может работать с любым набором тегов элементов html, которые необходимо поменять местами, сохраняя все атрибуты предыдущего тега.

Ответ 11

Создан плагин jquery, поддерживающий также атрибуты.

$.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;
}

Использование:

$('code').renameTag('pre')

Ответ 12

Все приведенные здесь ответы предполагают (как указывает пример вопроса), что в теге нет атрибутов. Если принятый ответ выполняется по этому вопросу:

<code class='cls'>A</code>

если заменить на

<pre>A</pre>

Что делать, если вы хотите сохранить атрибуты, а это значит, что замена тега будет означать...? Это решение:

$("code").each( function(){
    var content = $( "<pre>" );

    $.each( this.attributes, function(){ 
         content.attr( this.name, this.value );
    } );

    $( this ).replaceWith( content );
} );

Ответ 13

Еще один короткий и простой способ:

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