JQuery: как изменить имя тега?
jQuery: как изменить имя тега?
Например:
<tr>
$1
</tr>
Мне нужно
<div>
$1
</div>
Да, я могу
- Создать элемент DOM <div>
- Скопировать tr-контент в div
- Удалить tr из dom
Но могу ли я сделать это напрямую?
PS:
$(tr).get(0).tagName = "div";
приводит к DOMException
.
Ответы
Ответ 1
Вы можете заменить любую HTML-разметку, используя метод jQuery .replaceWith()
.
пример: http://jsfiddle.net/JHmaV/
Ref.:.replaceWith
Если вы хотите сохранить существующую разметку, вы можете использовать такой код:
$('#target').replaceWith('<newTag>' + $('#target').html() +'</newTag>')
Ответ 2
Нет, это невозможно по спецификации W3C: "tagName типа DOMString, readonly"
http://www.w3.org/TR/DOM-Level-2-Core/core.html
Ответ 3
Где метод DOM renameNode()?
Сегодня (2014) ни один браузер не понимает новый метод DOM3 renameNode (см. также W3C)
проверьте, не запускается ли у вас доза:http://jsfiddle.net/k2jSm/1/
Итак, решение DOM безобразно, и я не понимаю, почему (??) jQuery не реализовал обходной путь?
алгоритм чистого DOM
createElement(new_name)
- скопировать весь контент в новый элемент;
- заменить старое на новое
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()));
Как прокомментировали другие, для этого нужна копия атрибута... ждать общего...
специально для class
, с сохранением атрибута, см. http://jsfiddle.net/cDgpS/
Смотрите также fooobar.com/questions/111486/...
Ответ 4
Приведенные выше решения стирают существующий элемент и воссоздают его с нуля, уничтожая любые привязки событий к дочерним процессам.
краткий ответ: (теряет атрибуты)
$("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();
});
возиться с вложенными привязками
Было бы неплохо скопировать любые привязки одновременно, но получение текущих привязок мне не помогло.
Ответ 5
Чтобы сохранить внутренний контент тега, вы можете использовать accessor .html()
в сочетании с .replaceWith()
forked example: http://jsfiddle.net/WVb2Q/1/
Ответ 6
Вы можете пойти немного базовым. Работает для меня.
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;
Ответ 7
Вдохновленный ответом 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')
Ответ 8
Чтобы заменить внутреннее содержимое нескольких тегов, каждое из которых имеет свой собственный исходный контент, вы должны использовать .replaceWith()
и .html()
иначе:
http://jsfiddle.net/kcrca/VYxxG/
Ответ 9
JS, чтобы изменить имя тега
/**
* This function replaces the DOM elements 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;
}
Связанный скрипт находится в этой ссылке
Ответ 10
Простое изменение значений свойств не будет делать это (как говорили другие, некоторые свойства HTMLElement
доступны только для чтения, а некоторые содержат прототипный контекст для более примитивных элементов). Самое близкое, что вы можете подражать DOM API, - это подражать процессу прототипного наследования в JavaScript.
"Настройка" прототипа объекта через __proto__
обычно не одобряется. Кроме того, вы можете подумать, почему, по-вашему, вам нужно дублировать весь элемент DOM. Но здесь идет:
// Define this at whatever scope you'll need to access it
// Most of these kinds of constructors are attached to the `window` object
window.HTMLBookElement = function() {
function HTMLBookElement() {
var book = document.createElement('book');
book.__proto__ = document.createElement('audio');
return book;
}
return new HTMLBookElement();
}
// Test your new element in a console (I'm assuming you have Chrome)
var harryPotter = new HTMLBookElement();
// You should have access to your new `HTMLBookElement` API as well as that
// of its prototype chain; since I prototyped `HTMLAudioElement`, you have
// some default properties like `volume` and `preload`:
console.log(harryPotter); // should log "<book></book>"
console.log(harryPotter.volume); // should log "1"
console.log(harryPotter.preload); // should log "auto"
Все элементы DOM работают таким образом. Например:
<div></div>
создается HTMLDivElement
,
который распространяется на HTMLElement
,
которая, в свою очередь, расширяет Element
,
который, в свою очередь, распространяется на Object
.
Ответ 11
Так как replaceWith()
не работал у меня на основе элемента (возможно, потому, что я использовал его внутри map()
), я сделал это, создав новый элемент и скопировав атрибуты по мере необходимости.
$items = $('select option').map(function(){
var
$source = $(this),
$copy = $('<li></li>'),
title = $source.text().replace( /this/, 'that' );
$copy
.data( 'additional_info' , $source.val() )
.text(title);
return $copy;
});
$('ul').append($items);
Ответ 12
Возьмите его под словом
Возник вопрос по слову "как изменить имя тега?" Я бы предложил это решение:
Если это имеет смысл или нет, это необходимо решить в каждом конкретном случае.
Мой пример будет "переименовывать" все a-теги с гиперссылками для SMS с тегами span. Поддержание всех атрибутов и содержимого:
$('a[href^="sms:"]').each(function(){
var $t=$(this);
var $new=$($t.wrap('<div>')
.parent()
.html()
.replace(/^\s*<\s*a/g,'<span')
.replace(/a\s*>\s*$/g,'span>')
).attr('href', null);
$t.unwrap().replaceWith($new);
});
Как не имеет смысла иметь тег span с атрибутом href, я также удаляю его.
Выполнение этого способа является пуленепробиваемым и совместимым со всеми браузерами, поддерживаемыми jquery.
Существуют и другие способы, с помощью которых люди пытаются скопировать все атрибуты в новый элемент, но они не совместимы со всеми браузерами.
Хотя я считаю, что это так дорого.
Ответ 13
Плагин JQuery для редактирования "tagName":
(function($){
var $newTag = null;
$.fn.tagName = function(newTag){
this.each(function(i, el){
var $el = $(el);
$newTag = $("<" + newTag + ">");
// attributes
$.each(el.attributes, function(i, attribute){
$newTag.attr(attribute.nodeName, attribute.nodeValue);
});
// content
$newTag.html($el.html());
$el.replaceWith($newTag);
});
return $newTag;
};
})(jQuery);
Смотрите: http://jsfiddle.net/03gcnx9v/3/
Ответ 14
Еще один script, чтобы изменить имя node
function switchElement() {
$element.each(function (index, oldElement) {
let $newElement = $('<' + nodeName + '/>');
_.each($element[0].attributes, function(attribute) {
$newElement.attr(attribute.name, attribute.value);
});
$element.wrapInner($newElement).children().first().unwrap();
});
}
http://jsfiddle.net/rc296owo/5/
Он скопирует атрибуты и внутренний html в новый элемент, а затем заменит старый.
Ответ 15
$(function(){
$('#switch').bind('click', function(){
$('p').each(function(){
$(this).replaceWith($('<div/>').html($(this).html()));
});
});
});
p {
background-color: red;
}
div {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hello</p>
<p>Hello2</p>
<p>Hello3</p>
<button id="switch">replace</button>
Ответ 16
Вы можете использовать эту функцию
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');
Ответ 17
Работает чистый алгоритм DOM
function rename_element(node, name) {
let renamed = document.createElement(name);
Array.from(node.attributes).forEach(attr => {
renamed.setAttribute(attr.name, attr.value);
})
while (node.firstChild) {
renamed.appendChild(node.firstChild);
}
node.parentNode.replaceChild(renamed, node);
return renamed;
}