javascript - texto - jQuery: ¿cómo cambiar el nombre de la etiqueta?
modificar html con javascript (15)
jQuery: ¿cómo cambiar el nombre de la etiqueta?
Por ejemplo:
<tr>
$1
</tr>
Necesito
<div>
$1
</div>
Si puedo
- Crear elemento DOM <div>
- Copie el contenido de tr en div
- Eliminar tr de dom
¿Pero puedo hacerlo directamente?
PD:
$(tr).get(0).tagName = "div";
resultados en DOMException
.
Tómelo por la palabra
¿Tomó la pregunta por Word "cómo cambiar el nombre de la etiqueta?" Sugeriría esta solución:
Si tiene sentido o no tiene que decidirse caso por caso.
Mi ejemplo "cambiará el nombre" de todas las etiquetas con hipervínculos por SMS con etiquetas de extensión. Mantenimiento de todos los atributos y contenido:
$(''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);
});
Como no tiene sentido tener una etiqueta span con un atributo href, también elimino eso. Hacerlo de esta manera es a prueba de balas y compatible con todos los navegadores compatibles con jquery. Hay otras formas en que las personas intentan copiar todos los Atributos al nuevo Elemento, pero esos no son compatibles con todos los navegadores.
Aunque creo que es bastante caro hacerlo de esta manera.
Donde el método DOM renameNode ()?
Hoy (2014) ningún navegador entiende el nuevo método DOM3 renameNode (ver también el W3C ), compruebe si se ejecuta en su bowser: http://jsfiddle.net/k2jSm/1/
Entonces, una solución DOM es fea y no entiendo por qué (??) jQuery no implementó una solución alternativa?
algoritmo DOM puro
-
createElement(new_name)
- copiar todo el contenido a un nuevo elemento;
- reemplace de viejo a nuevo por
replaceChild()
es algo como esto,
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);
}
... espera la revisión y jsfiddle ...
Algoritmo jQuery
El algoritmo @ilpoldo es un buen punto de partida
$from.replaceWith($(''<''+newname+''/>'').html($from.html()));
Como otros comentaron, necesita una copia de atributo ... espera genérico ...
específico para la class
, preservando el atributo , ver http://jsfiddle.net/cDgpS/
Ver también https://.com/a/9468280/287948
Como replaceWith()
no funcionó para mí sobre una base de elemento (tal vez porque lo usé dentro de map()
), lo hice creando un nuevo elemento y copiando los atributos según sea necesario.
$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);
Complemento Jquery para hacer que "tagName" sea editable:
(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);
JS para cambiar el nombre de la etiqueta
/**
* 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;
}
Fiddle relacionado está en este link
Las soluciones anteriores borran el elemento existente y lo vuelven a crear desde cero, destruyendo cualquier vinculación de eventos en los niños en el proceso.
respuesta corta: (pierde los atributos)
$("p").wrapInner("<div/>").children(0).unwrap();
respuesta más larga: (atributos de las copias)
$("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();
});
Sería genial copiar cualquier vinculación desde el, al mismo tiempo, pero obtener enlaces actuales no funcionó para mí.
No, no es posible de acuerdo con la especificación W3C: "tagName de tipo DOMString, readonly"
Otra secuencia de comandos para cambiar el nombre del nodo
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/
Copiará los atributos y html interno en un nuevo elemento y luego reemplazará el antiguo.
Para conservar el contenido interno de la etiqueta, puede usar el acceso .html()
junto con .replaceWith()
ejemplo bifurcado: http://jsfiddle.net/WVb2Q/1/
Para reemplazar los contenidos internos de varias etiquetas, cada una con su propio contenido original, debe usar .replaceWith()
y .html()
diferente:
Podrías ir un poco básico. Funciona para mi.
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;
Puede reemplazar cualquier .replaceWith()
HTML utilizando el método .replaceWith()
jQuery.
ejemplo: http://jsfiddle.net/JHmaV/
Ref .:. replaceWith
Si desea mantener el marcado existente, puede usar un código como este:
$(''#target'').replaceWith(''<newTag>'' + $(''target'').html() +''</newTag>'')
Puedes usar esta función
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);
};
Código de muestra
renameTag($(tr),''div'');
Simplemente cambiar los valores de las propiedades no lo hará (como otros han dicho, algunas propiedades de HTMLElement
son de solo lectura, y algunas mantienen el contexto del prototipo para elementos más primitivos). Lo más parecido a imitar a DOM API es imitar también el proceso de herencia prototípica en JavaScript.
''Configuración'' en el prototipo de un objeto a través de __proto__
es generalmente desaprobado. Además, podría considerar por qué cree que necesita duplicar todo el elemento DOM en primer lugar. Pero aquí va:
// 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"
Todos los elementos DOM funcionan de esta manera. Por ejemplo: <div></div>
es producido por HTMLDivElement
, que extiende HTMLElement
, que a su vez extiende Element
, que a su vez extiende Object
.
$(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>