Tengo un componente personalizado en el que estoy trabajando y tomé prestado el código de un proyecto textualmente de otro. Aquí está el área problemática:
<style> #history tr:nth-child(even) {background-color: #f2f2f2;} </style> <div class="ce-card" style="height:280px;overflow:auto;" id="myscroller"> <table id="history" style="width:100%"> </table> </div>Luego, más tarde, la tabla se adjunta con esto:
this.shadowRoot.querySelector('#history').innerHTML += `<tr><td>Term ${this._term}: ${text}</td></tr>`; Todo funciona. Sin embargo, no obtengo mi resaltado alterno porque en el proyecto n. ° 2, la fila se envuelve con etiquetas <tbody></tbody> . No tengo uso de tbody en ninguna parte, pero aparece solo en la nueva página con la que estoy jugando. ¿Cómo suprimo la inserción de etiquetas <tbody> cuando configuro innerHTML para tener un <tr> ?
Sé que alguien preguntará qué sucede cuando se usa = en lugar de += . Tiene el mismo problema.
Resumen: xxx.innerHTML = `<tr><td>text</td></tr>` produce diferentes resultados en diferentes proyectos. Uno de los dos siguientes:
<table><tr><td>text</td></tr></table> <table><tbody><tr><td>text</td></tr></tbody></table>Editar:
De acuerdo con lo que estoy leyendo en los comentarios, si agrego varias filas agregando HTML, debería obtener lo siguiente: https://i.imgur.com/7PDaMxW.png
Pero no parece haber ninguna forma de no ponerlo entre paréntesis... excepto lo que parece suceder en otra página (y aparentemente por accidente).
Esta tabla se creó de manera idéntica: https://i.imgur.com/Wc9i18e.png Tal vez la mejor pregunta para hacer es "¿cómo logré hacerlo la primera vez? ¿Qué configuré en CSS o algo que está suprimiendo el inserción de un cuerpo?"
El navegador infiere la existencia de un <tbody> . No puedes quitarlo.
Una cosa a tener en cuenta es que la gente ha estado escribiendo HTML roto desde los albores de la web. Los fabricantes de navegadores han elegido manejar ese problema al hacer que los navegadores hagan más que cumplir con los autores de las páginas a mitad de camino.
Prueba este experimento.
<!DOCTYPE html> <html> <body> <table> <tr> <td>one</td> </tr> </table> </body> </html><tbody> . P: ¿Por qué se siguen agregando nuevos elementos <tbody> ?
Como se indicó anteriormente, el navegador infiere la existencia de un <tbody> . ¿Pero por qué?
Porque el DOM no permite que <tr> sea el descendiente directo de <table> .
Para mi sorpresa, la especificación DOM permite que <tr> sea un descendiente directo de <table> . Aquí está el texto exacto (énfasis mío):
modelo de contenido:
En este orden: opcionalmente un elemento
caption, seguido de cero o más elementoscolgroup, seguido opcionalmente de un elementothead, seguido de cero o más elementostbodyo uno o más elementostr, seguido opcionalmente de un elementotfoot, opcionalmente entremezclado con uno o más elementos de apoyo al script.
Mi lectura es que la especificación permite esto:
<!-- Snippet 1: row wrapped in tbody --> <table> <tbody> <tr> <td> cell </td> </tr> </tbody> </table>O esto:
<!-- Snippet 2: row as direct child of table --> <table> <tr> <td> cell </td> </tr> </table>Pero no esto:
<!-- Snippet 3: mixed-case, table with both tbody and row children --> <table> <tbody> <tr> <td> cell </td> </tr> </tbody> <tr> <td> cell </td> </tr> </table> Dado que está claro que los navegadores modernos infieren la existencia de un <tbody> , el fragmento n.° 2 se transforma automáticamente en el fragmento n.° 1. Y eso significa que cualquier <tr> adicional se incluirá automáticamente en <tbody> para evitar el Snippet #3.
Obtuve los mismos resultados que usted cuando probé esto en una página HTML simple con una tabla.
Es un comportamiento normal para la mayoría de los navegadores. Se inserta en el navegador durante el procesamiento de su DOM. Para obtener más detalles, consulteel MDN oficial . Es imposible suprimir <tbody> , tal vez puedas usarlo de otra manera. ¿Qué hay de usar en CSS #history > tbody > tr:nth-child(even) primero recopilar todos los tr en una cadena EN JAVASCRIPT y luego agregarlo usando innerHTML a #history
Respuesta actualizada:
Como la intención aquí es agregar continuamente a la tabla "historial", lo siguiente debería ser más apropiado:
<tbody> ).createElement() para crear un nuevo elemento <tr> ,.innerHTML necesario en este <tr> antes de eventualmente.append() -ing it to the <tbody> -target. const tbd=document.querySelector("#history tbody"); "abc".split("").forEach((v,i)=>appendEl(tbd,"tr", `<td>Term ${i+1}:</td><td>${v}</td>`)); function appendEl(trgt,type,html){ const el=document.createElement(type); el.innerHTML=html; trgt.append(el); } // And here is another "late" addition to the table: appendEl(tbd,"tr", `<td>last term:</td><td>"the end"</td>`); <table id="history"><tbody></tbody></table> appendEl() es una pequeña función de utilidad que me ayuda a realizar los pasos anteriores para cada <tr> . jQuery tiene un método integrado append() que sería ideal para este trabajo. Desafortunadamente, no existe un método equivalente directo de Vanilla JS, pero appendEl() funciona en la misma dirección.
Al hacerlo de esta manera, evitamos volver a analizar el contenido de la tabla ya existente. Esto debería hacer que todo el proceso sea más rápido y más estable (los detectores de eventos adjuntos previamente o los valores de entrada modificados no se verán afectados).