Creación de un nuevo elemento DOM a partir de una cadena HTML utilizando métodos DOM integrados o prototipo

9 minutos de lectura

Creacion de un nuevo elemento DOM a partir de una
Ömer Bokhari

Tengo una cadena HTML que representa un elemento: '<li>text</li>'. Me gustaría agregarlo a un elemento en el DOM (un ul en mi caso). ¿Cómo puedo hacer esto con Prototype o con métodos DOM?

(Sé que podría hacer esto fácilmente en jQuery, pero desafortunadamente no estamos usando jQuery).

  • Lo siento, ¿qué estás tratando de lograr exactamente? Cadena HTML -> elemento dom?

    – Media Luna Fresca

    30 de enero de 2009 a las 2:28

  • Es lamentable que estas soluciones sean tan indirectas. Me gustaría que el comité de estándares especificara algo similar como: var nodes = document.fromString("<b>Hello</b> <br>");

    – Sridhar Sarnobat

    27/02/2015 a las 19:32

  • Tuve un problema con lo anterior, porque tenía atributos que debían pasarse y no tenía ganas de analizarlos: “

    ” entonces, simplemente usé: $(“

    “)

    – stevenlacerda

    14/09/2017 a las 18:03

Creacion de un nuevo elemento DOM a partir de una
media luna fresca

Nota: la mayoría de los navegadores actuales admiten HTML <template> elementos, que proporcionan una forma más confiable de convertir la creación de elementos a partir de cadenas. Consulte la respuesta de Mark Amery a continuación para obtener más detalles.

Para navegadores más antiguos y node/jsdom: (que aún no es compatible <template> elementos en el momento de la escritura), utilice el siguiente método. Es lo mismo que hacen las bibliotecas para obtener elementos DOM de una cadena HTML (con algo de trabajo adicional para que IE solucione los errores con su implementación de innerHTML):

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes.
  return div.firstChild;
}

Tenga en cuenta que, a diferencia de las plantillas HTML, esta no lo haré trabajar para algunos elementos que legalmente no pueden ser hijos de un <div>tal como <td>s.

Si ya está utilizando una biblioteca, le recomendaría que siga el método aprobado por la biblioteca para crear elementos a partir de cadenas HTML:

  • Cómo configurar innerHTML al div creado usando jQuery sin usar esta asignación insegura de innerHTML (div.innerHTML = “algún valor”)

    – Shivanshu Goyal

    6 de marzo de 2018 a las 3:59

  • El nombre de la función createElementFromHTML es engañoso ya que div.firstChild devuelve un Node que no es un HTMLElement por ejemplo, no puede node.setAttribute. Para crear un Element regreso div.firstElementChild de la función en su lugar.

    – Semmel

    3 abr 2018 a las 18:22

  • gracias, el <div> envolviendo el HTML que agregué con .innerHTML me estaba molestando Nunca pensé en usar .firstChild.

    – Iván

    17 de mayo de 2018 a las 8:19


  • Tenga en cuenta, por cierto, que este no trabajo para etiquetas de script. Etiquetas de script agregadas al DOM usando innerHTML no se ejecutará. Para esos casos, mejor ir con var script = document.createElement('script')y luego usar script.src o script.textContent dependiendo de si el script está en línea. Luego, agregue el script con document.body.appendChild(script).

    – ethan.roday

    27 de junio de 2018 a las 22:33


  • Usaría firstElementChild en lugar de firstChild (ver w3schools.com/jsref/prop_element_firstelementchild.asp ), porque si hay espacio al frente o al final de la plantilla, firstChild devolvería textNode vacío

    – Chris Panayotoff

    12 de noviembre de 2018 a las 9:46

Creacion de un nuevo elemento DOM a partir de una
marca amery

HTML 5 introdujo el <template> elemento que puede ser utilizado para este propósito (como ahora se describe en el Qué especificaciones de WG y documentos de MDN).

A <template> El elemento se utiliza para declarar fragmentos de HTML que se pueden utilizar en secuencias de comandos. El elemento se representa en el DOM como un HTMLTemplateElement que tiene un .content propiedad de DocumentFragment tipo, para proporcionar acceso a los contenidos de la plantilla. Esto significa que puede convertir una cadena HTML en elementos DOM configurando el innerHTML de un <template> elemento, luego alcanzando el template‘s .content propiedad.

Ejemplos:

/**
 * @param {String} HTML representing a single element
 * @return {Element}
 */
function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild;
}

var td = htmlToElement('<td>foo</td>'),
    div = htmlToElement('<div><span>nested</span> <span>stuff</span></div>');

/**
 * @param {String} HTML representing any number of sibling elements
 * @return {NodeList} 
 */
function htmlToElements(html) {
    var template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

var rows = htmlToElements('<tr><td>foo</td></tr><tr><td>bar</td></tr>');

Tenga en cuenta que los enfoques similares que utilizan un elemento contenedor diferente, como un div no trabajo del todo. HTML tiene restricciones sobre qué tipos de elementos pueden existir dentro de qué otros tipos de elementos; por ejemplo, no puedes poner un td como hijo directo de un div. Esto hace que estos elementos desaparezcan si intenta configurar el innerHTML de un div para contenerlos. Ya que <template>s no tienen tales restricciones en su contenido, esta deficiencia no se aplica cuando se usa una plantilla.

Sin embargo, template no es compatible con algunos navegadores antiguos. A partir de abril de 2021, Puedo usar… estimados El 96 % de los usuarios en todo el mundo utilizan un navegador que admite templates. En particular, ninguna versión de Internet Explorer los admite; Microsoft no implementó template soporte hasta el lanzamiento de Edge.

Si tiene la suerte de estar escribiendo código que solo está dirigido a usuarios en navegadores modernos, continúe y utilícelos ahora mismo. De lo contrario, es posible que deba esperar un tiempo para que los usuarios se pongan al día.

  • Este es un enfoque efectivo y muy limpio; sin embargo, (al menos en Chrome 50) esto rompe el manejo de etiquetas de secuencias de comandos. En otras palabras, usar este método para crear una etiqueta de secuencia de comandos y luego agregarla al documento (cuerpo o encabezado) no da como resultado que se evalúe la etiqueta y, por lo tanto, evita que se ejecute la secuencia de comandos. (Esto puede deberse al diseño si la evaluación ocurre al adjuntar; no podría decirlo con certeza).

    – Shanef22

    26 mayo 2016 a las 21:23

  • ¡ENCANTADOR! incluso puede consultar elementos haciendo algo como: template.content.querySelector(“img”);

    -Roger Gajraj

    13 de junio de 2016 a las 6:27

  • No veo innerHTML definido como una propiedad de los objetos de fragmento DOM (de <template>.content) en MDN: developer.mozilla.org/en-US/docs/Web/API/DocumentFragment

    – Dai

    29/03/2017 a las 20:53


  • @Dai, de hecho, no, ya que no existe tal propiedad. Has leído mal mi respuesta; puse el innerHTML de la propia plantilla (que es un Element), no su .content (el cual es un DocumentFragment).

    –Mark Amery

    21/09/2017 a las 10:55


  • Hay un problema con eso. Si tiene una etiqueta con espacios adentro (!) al principio o al final, ¡se eliminarán! No me malinterpreten, no se trata de los espacios eliminados por html.trim pero mediante el análisis interno de la configuración de innerHTML. En mi caso, elimina espacios importantes que forman parte de un textNode. 🙁

    – e-motivo

    24/04/2018 a las 15:50

1646971511 616 Creacion de un nuevo elemento DOM a partir de una
Christian d’Heureuse

Utilizar insertAdjacentHTML(). Funciona con todos los navegadores actuales, incluso con IE11.

var mylist = document.getElementById('mylist');
mylist.insertAdjacentHTML('beforeend', '<li>third</li>');
<ul id="mylist">
 <li>first</li>
 <li>second</li>
</ul>

  • Primero, insertAdjacentHTML funciona con todos los navegadores desde IE 4.0.

    – Jonas Appelgran

    10 de abril de 2018 a las 17:37

  • En segundo lugar, ¡es genial! Una gran ventaja en comparación con innerHTML += ... es que las referencias a elementos anteriores siguen intactas usando este método.

    – Jonas Appelgran

    10/04/2018 a las 17:40

  • En tercer lugar, los valores posibles para el primer argumento son: beforebegin, afterbegin, beforeend, afterend. Ver el artículo de MDN.

    – Jonas Appelgran

    10 de abril de 2018 a las 17:44

  • Lástima que no devuelve el HTML insertado como un elemento

    – Mojimi

    1 de julio de 2019 a las 13:21

  • Esto tiene un soporte de navegador fantástico y es completamente sencillo. No es extraño crear un elemento ficticio solo para obtener su Nodo secundario.

    – Dylan Reile

    29 de octubre de 2019 a las 1:15

1646971512 647 Creacion de un nuevo elemento DOM a partir de una
matemáticas2001

No hay necesidad de ningún ajuste, tienes una API nativa:

const toNodes = html =>
    new DOMParser().parseFromString(html, 'text/html').body.childNodes[0]

1646971513 3 Creacion de un nuevo elemento DOM a partir de una
Munawwar

Para ciertos fragmentos html como <td>test</td>div.innerHTML, DOMParser.parseFromString y range.createContextualFragment (sin el contexto correcto) las soluciones mencionadas en otras respuestas aquí, no crearán el <td> elemento.

jQuery.parseHTML() los maneja correctamente (extraí La función parseHTML de jQuery 2 en una función independiente que se puede usar en bases de código que no sean jquery).

Si solo admite Edge 13+, es más sencillo usar la etiqueta de plantilla HTML5:

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content;
}

var documentFragment = parseHTML('<td>Test</td>');

1646971513 719 Creacion de un nuevo elemento DOM a partir de una
Neithan Max

Las implementaciones DOM más recientes tienen range.createContextualFragmentque hace lo que quiere de una manera independiente del marco.

Es ampliamente compatible. Sin embargo, para estar seguro, comprobar su compatibilidad abajo en el mismo enlace de MDN, ya que estará cambiando. A partir de mayo de 2017 esto es todo:

Feature         Chrome   Edge   Firefox(Gecko)  Internet Explorer   Opera   Safari
Basic support   (Yes)    (Yes)  (Yes)           11                  15.0    9.1.2

1646971514 730 Creacion de un nuevo elemento DOM a partir de una
william malo

Aquí hay una manera simple de hacerlo:

String.prototype.toDOM=function(){
  var d=document
     ,i
     ,a=d.createElement("div")
     ,b=d.createDocumentFragment();
  a.innerHTML=this;
  while(i=a.firstChild)b.appendChild(i);
  return b;
};

var foo="<img src="https://placekitten.com/100/100">foo<i>bar</i>".toDOM();
document.body.appendChild(foo);

  • @MarkAmery, la diferencia aquí es que usa un fragmento para permitir que se agreguen múltiples elementos raíz en el DOM, lo cual es un beneficio adicional. Si tan solo William mencionara esa es su respuesta…

    – Koen.

    23 de marzo de 2016 a las 11:32

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad