JQuery: как изменить имя тега? - PullRequest
       12

JQuery: как изменить имя тега?

55 голосов
/ 09 августа 2010

jQuery: как изменить имя тега?

Например:

<tr>
    $1
</tr>

Мне нужно

<div>
    $1
</div>

Да, я могу

  1. Создать элемент DOM
  2. Копирование содержимого tr в div
  3. Удалить tr из dom

Но можно ли сделать это напрямую?

PS:

    $(tr).get(0).tagName = "div"; 

приводит к DOMException.

Ответы [ 16 ]

44 голосов
/ 09 августа 2010

Нет, это невозможно в соответствии со спецификацией W3C: "tagName типа DOMString, только для чтения"

http://www.w3.org/TR/DOM-Level-2-Core/core.html

35 голосов
/ 09 августа 2010

Вы можете заменить любую HTML-разметку с помощью метода jQuery .replaceWith().

пример: http://jsfiddle.net/JHmaV/

Ref .:. replaceWith

Если вы хотите сохранить существующую разметку, вы можете использовать код, подобный следующему:

$('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
13 голосов
/ 12 февраля 2014

Где метод DOM renameNode ()?

Сегодня (2014) ни один браузер не понимает новый метод переименования DOM3 (см. также W3C ) проверьте, работает ли ваш дозаправка: http://jsfiddle.net/k2jSm/1/

Итак, решение DOM безобразно, и я не понимаю почему (??) jQuery не реализовал обходной путь?

Алгоритм чистого DOM

  1. createElement(new_name)
  2. копировать весь контент в новый элемент;
  3. заменить старое на новое replaceChild()

это что-то вроде этого,

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);
}

... ждать обзора и jsfiddle ...

алгоритм jQuery

Алгоритм @ilpoldo является хорошей отправной точкой,

   $from.replaceWith($('<'+newname+'/>').html($from.html()));

Как прокомментировали другие, для этого нужен атрибут copy ... wait generic ...

специфично для class, с сохранением атрибута , см. http://jsfiddle.net/cDgpS/

См. Также https://stackoverflow.com/a/9468280/287948

10 голосов
/ 05 мая 2015

Приведенные выше решения уничтожают существующий элемент и воссоздают его с нуля, уничтожая любые привязки событий к дочерним процессам в процессе.

короткий ответ: (теряет атрибуты)

$("p").wrapInner("<div/>").children(0).unwrap();

более длинный ответ: (атрибуты копий)

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

скрипка с вложенными привязками

Itбыло бы здорово скопировать любые привязки из, но получение текущих привязок не сработало для меня.

7 голосов
/ 24 ноября 2010

Для сохранения внутреннего содержимого тега вы можете использовать аксессор .html() в сочетании с .replaceWith()

раздвоенный пример: http://jsfiddle.net/WVb2Q/1/

2 голосов
/ 04 октября 2018

Вдохновлен ответом ericP , отформатирован и преобразован в плагин jQuery:

$.fn.replaceWithTag = function(tagName) {
    var result = [];
    this.each(function() {
        var newElem = $('<' + tagName + '>').get(0);
        for (var i = 0; i < this.attributes.length; i++) {
            newElem.setAttribute(
                this.attributes[i].name, this.attributes[i].value
            );
        }
        newElem = $(this).wrapInner(newElem).children(0).unwrap().get(0);
        result.push(newElem);
    });
    return $(result);
};

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

$('div').replaceWithTag('span')
2 голосов
/ 31 января 2014

Вы могли бы пойти немного базовым.У меня работает.

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;
1 голос
/ 04 января 2015

JS для изменения имени тега

/**
 * 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;
}

Связанная скрипта находится в этой ссылке

1 голос
/ 21 июля 2011

Чтобы заменить внутреннее содержимое нескольких тегов , каждый со своим собственным оригинальным содержимым, необходимо использовать .replaceWith() и .html() по-разному:

http://jsfiddle.net/kcrca/VYxxG/

0 голосов
/ 21 декабря 2017

Вы можете использовать эту функцию

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);
};

Пример кода

renameTag($(tr),'div');
...