библиотека 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')