библиотека jQuery: как изменить имя тега?
библиотека jQuery: как изменить имя тега?
например:
<tr>
</tr>
мне нужно
<div>
</div>
Да, я могу
- создать элемент DOM
- скопируйте содержимое tr в div
- удалить tr из dom
но могу ли я сделать это напрямую?
PS:
$(tr).get(0).tagName = "div";результаты
DOMException.
16 ответов:
вы можете заменить любую разметку HTML с помощью jQuery в
.replaceWith()метод.пример:http://jsfiddle.net/JHmaV/
Ref.: .replaceWith
Если вы хотите сохранить существующую разметку, вы можете использовать такой код:
$('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
нет, это невозможно в соответствии со спецификацией W3C: "tagName типа DOMString, только для чтения"
где метод 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/
вышеуказанные решения уничтожают существующий элемент и воссоздают его с нуля, уничтожая любые привязки событий на дочерних элементах в процессе.
короткий ответ: (проигрывает с атрибутами)
$("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(); });возиться с вложенными привязками
было бы здорово скопировать любые привязки из того же времени, но получение текущего привязки не работает для меня.
для сохранения внутреннего содержимого тега можно использовать аксессоры
.html()в сочетании с.replaceWith()раздвоенный пример:http://jsfiddle.net/WVb2Q/1/
вы могли бы пойти немного простой. Работать на меня.
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;
для замены внутреннего содержимого несколько теги, каждый со своим оригинальным контентом, вы должны использовать
.replaceWith()и.html()иначе:
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; }связанная скрипка находится в этом ссылке
простое изменение значений свойств не сделает этого (как говорили другие, некоторые
HTMLElementсвойства доступны только для чтения; также некоторые содержат прототипический контекст для более примитивных элементов). Самое близкое, что вы можете получить, чтобы имитировать API DOM, - это имитировать также процесс прототипного наследования в 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.
С
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);
возьмите его за слово
взял вопрос по слову "как изменить имя тега?"Я бы предложил такое решение:
Если это имеет смысл или нет, должно быть решено в каждом конкретном случае.мой пример будет "переименовать" все 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. Есть и другие способы, которыми люди пытаются скопировать все атрибуты в новый элемент, но они не совместимы со всеми браузерами.
хотя я думаю, что это довольно дорого, чтобы сделать это таким образом.
плагин 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);
еще один скрипт для изменения имени узла
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 в новый элемент, а затем заменит старый.
$(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>
вы можете использовать эту функцию
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');
вдохновленный 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')