Saltar al contenido

Cómo comparar dos elementos HTML

Te damos el resultado a este conflicto, o por lo menos eso pensamos. Si continuas con alguna duda puedes dejarlo en el apartado de comentarios, para nosotros será un gusto responderte

Solución:

Puedes usar:

element1.isEqualNode(element2);

En su ejemplo específico:

var divs = $(".a");
if ( divs.get(0).isEqualNode(divs.get(1)) ) alert("Same");

El DOM Level 3 Core Spec tiene todos los detalles. Esencialmente esto regresa true de los dos nodos tienen correspondencia attributesdescendientes, y los descendientes’ attributes.

Hay un .isSameNode() similar que devuelve true sólo si ambos elementos son el mismo nodo. En su ejemplo, estos no son los mismos nodos, pero son nodos iguales.

Actualizar

Consulte la respuesta de Keen y también la respuesta de ccproj a una pregunta estrechamente relacionada. hay isEqualNode para esto, pero se compara class y style attributes como texto, por lo que el mismo conjunto de clases o el mismo conjunto de propiedades de estilo en diferentes órdenes hará pensar que los nodos no son equivalentes. La respuesta de ccprog maneja eso.

Respuesta Original

(Consulte a continuación para obtener una solución improvisada completa, en gran parte no probada y ciertamente no refactorizada. Pero primero, los fragmentos).

Comparando sus innerHTML es fácil:

if (divs[0].innerHTML === divs[1].innerHTML)
// or if you prefer using jQuery
if (divs.html() === $(divs[1]).html()) // The first one will just be the HTML from div 0

…aunque hay que preguntarse si estos dos elementos son equivalentes según su criterio:

x
x

… porque su innerHTML sera diferente (al menos en Chrome, y sospecho que en la mayoría, si no en todos los navegadores). (Más sobre eso a continuación).

Entonces necesita comparar todos sus attributes. Hasta donde yo sé, jQuery no le brinda un medio para enumerar el attributespero el DOM sí:

function getAttributeNames(node) 
  var index, rv, attrs;

  rv = [];
  attrs = node.attributes;
  for (index = 0; index < attrs.length; ++index) 
    rv.push(attrs[index].nodeName);
  
  rv.sort();
  return rv;

Luego

var names = [getAttributeNames(div[0]), getAttributeNames(div[1])];
if (names[0].length === names[1].length) 
    // Same number, loop through and compare names and values
    ...

Tenga en cuenta que al ordenar las matrices anteriores, asumo el orden de sus attributes no es significativo en su definición de "equivalente". Espero que ese sea el caso, porque parece que no se conserva, ya que obtengo diferentes resultados de diferentes navegadores cuando ejecuto esta prueba. Siendo ese el caso, tenemos que volver a la innerHTML pregunta, porque si el orden de attributes en los elementos mismos no es significativo, entonces presumiblemente el orden de attributes en los elementos descendientes no debería ser significativo. Si eso es el caso, necesitará una función recursiva que verifique los descendientes de acuerdo con su definición de equivalente, y no use innerHTML en absoluto.

Luego está la preocupación planteada por esta pregunta posterior: ¿Qué pasa si los elementos tienen diferentes pero equivalentes? style attributes? P.ej:

TEST A
TEST B

Mi respuesta allí lo aborda recorriendo el contenido de los elementos. style objetos, como este:

const astyle = div[0].style;
const bstyle = div[1].style;
const rexDigitsOnly = /^d+$/;
for (const key of Object.keys(astyle)) 
    if (!rexDigitsOnly.test(key) && astyle[key] !== bstyle[key]) 
        // Not equivalent, stop
    

// Equivalent

Lamentablemente, como digo en esa respuesta:

Tenga en cuenta que lo anterior fallará si (uno de ellos tiene color: red y el otro tiene color: #ff0000)al menos en algunos navegadores, porque cuando una propiedad de estilo usa un string valor, por lo general obtiene el valor de la forma en que se suministró, no normalizado. podrías usar getComputedStyle para obtener el valor calculado (ish) en su lugar, pero luego nos encontramos con problemas relacionados con la aplicabilidad de CSS: dos elementos con exactamente el mismo marcado puede tener diferentes valores de getComputedStyle debido a dónde se encuentran en el DOM y, como resultado, se les aplicó el CSS. Y getComputedStyle no funciona en nodos que no están en un documento, por lo que no puede simplemente clonar los nodos para eliminar ese problema.

Pero debería poder juntar algo de las piezas anteriores para comparar dos elementos de acuerdo con sus criterios.

Más para explorar:

  • Núcleo DOM2
  • HTML DOM2
  • Núcleo DOM3
  • API de aplicaciones web HTML5

La pregunta me interesó extrañamente, así que le di vueltas un rato y se me ocurrió lo siguiente. En su mayoría no se ha probado, podría usar alguna refactorización, etc., pero debería llevarlo la mayor parte del camino allí. De nuevo, asumo el orden de attributes no es significativo Lo siguiente asume incluso la más mínima diferencia en el texto. es significativo.

function getAttributeNames(node) 
  var index, rv, attrs;

  rv = [];
  attrs = node.attributes;
  for (index = 0; index < attrs.length; ++index) 
    rv.push(attrs[index].nodeName);
  
  rv.sort();
  return rv;


function equivElms(elm1, elm2) 
  var attrs1, attrs2, name, node1, node2;

  // Compare attributes without order sensitivity
  attrs1 = getAttributeNames(elm1);
  attrs2 = getAttributeNames(elm2);
  if (attrs1.join(",") !== attrs2.join(",")) 
    display("Found nodes with different sets of attributes; not equiv");
    return false;
  

  // ...and values
  // unless you want to compare DOM0 event handlers
  // (onclick="...")
  for (index = 0; index < attrs1.length; ++index) 
    name = attrs1[index];
    if (elm1.getAttribute(name) !== elm2.getAttribute(name)) 
      display("Found nodes with mis-matched values for attribute '" + name + "'; not equiv");
      return false;
    
  

  // Walk the children
  for (node1 = elm1.firstChild, node2 = elm2.firstChild;
       node1 && node2;
       node1 = node1.nextSibling, node2 = node2.nextSibling) 
     if (node1.nodeType !== node2.nodeType) 
       display("Found nodes of different types; not equiv");
       return false;
     
     if (node1.nodeType === 1)  // Element
       if (!equivElms(node1, node2)) 
         return false;
       
     
     else if (node1.nodeValue !== node2.nodeValue) 
       display("Found nodes with mis-matched nodeValues; not equiv");
       return false;
     
  
  if (node1 

Ejemplos en vivo:

  • divisiones equivalentes
  • diferencia de valor attr
  • diferencia attr
  • diferencia de texto

Reseñas y puntuaciones

Más adelante puedes encontrar los comentarios de otros administradores, tú todavía tienes la opción de mostrar el tuyo si dominas el tema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *