Come normalizzare l'HTML in JavaScript o jQuery?


84

I tag possono avere più attributi. L'ordine in cui gli attributi vengono visualizzati nel codice non ha importanza. Per esempio:

<a href="#" title="#">
<a title="#" href="#">

Come posso "normalizzare" l'HTML in Javascript, in modo che l'ordine degli attributi sia sempre lo stesso? Non mi interessa quale ordine viene scelto, purché sia ​​sempre lo stesso.

AGGIORNAMENTO : il mio obiettivo originale era di rendere più facile diff (in JavaScript) 2 pagine HTML con lievi differenze. Poiché gli utenti possono utilizzare software diversi per modificare il codice, l'ordine degli attributi potrebbe cambiare. Questo rende il diff troppo prolisso.

RISPOSTA : Bene, prima grazie per tutte le risposte. E SÌ, è possibile. Ecco come sono riuscito a farlo. Questa è una prova di concetto, sicuramente può essere ottimizzata:

function sort_attributes(a, b) {
  if( a.name == b.name) {
    return 0;
  }

  return (a.name < b.name) ? -1 : 1;
}

$("#original").find('*').each(function() {
  if (this.attributes.length > 1) {
    var attributes = this.attributes;
    var list = [];

    for(var i =0; i < attributes.length; i++) {
      list.push(attributes[i]);
    }

    list.sort(sort_attributes);

    for(var i = 0; i < list.length; i++) {
      this.removeAttribute(list[i].name, list[i].value);
    }

    for(var i = 0; i < list.length; i++) {
      this.setAttribute(list[i].name, list[i].value);
    }
  }
});

Stessa cosa per il secondo elemento del diff, $('#different'). Ora $('#original').html()e $('#different').html()mostra il codice HTML con attributi nello stesso ordine.


59
Qual è la necessità di questo?
rahul

40
@rahul: in realtà c'è un bisogno piuttosto interessante di questo: può migliorare notevolmente la compressione gzip delle tue pagine.
haylem

11
ah, in Javascript ... tanto per la compressione. Non ho idea di quale sia il bisogno allora.
haylem

13
@ Julien: nel momento in cui il codice JavaScript viene eseguito, la pagina è già stata inviata al client. Allora non vedo come possa aiutare nella compressione.
casablanca

22
In realtà c'è un uso valido per provare a fare ciò che chiede l'OP. Utilizzando un editor WYSIWYG per guidare un wiki. Il progetto su cui sto lavorando fa esattamente questo e l'editor inverte l'ordine degli attributi ogni volta che modifichi il wiki, generando differenze non necessarie. Finisco per ordinare alfabeticamente gli attributi nell'HTML inviato sul backend prima di salvare per evitare differenze; avrebbe potuto fare altrettanto facilmente questo tipo in javascript prima di inviare.
Frank Farmer

Risposte:


68

JavaScript in realtà non vede una pagina web sotto forma di HTML basato su testo, ma piuttosto come una struttura ad albero nota come DOM, o Document Object Model. L'ordine degli attributi degli elementi HTML nel DOM non è definito (infatti, come commenti di Svend, non fanno nemmeno parte del DOM), quindi l'idea di ordinarli nel punto in cui viene eseguito JavaScript è irrilevante.

Posso solo immaginare cosa stai cercando di ottenere. Se stai cercando di farlo per migliorare le prestazioni di JavaScript / pagina, la maggior parte dei renderizzatori di documenti HTML presumibilmente si è già impegnata molto nell'ottimizzazione dell'accesso agli attributi, quindi c'è poco da guadagnare.

Se stai cercando di ordinare gli attributi per rendere più efficace la compressione gzip delle pagine quando vengono inviate in rete, tieni presente che JavaScript viene eseguito dopo quel momento. Invece, potresti voler guardare le cose che girano invece sul lato server, anche se probabilmente è più un problema di quanto valga la pena.


8
JavaScript può essere eseguito sul lato server.
Matt Kantor

Gli attributi non sono considerati parte dell'albero del documento (che utilizza naturalmente l'ordinamento). Quindi, mentre Attr eredita l'interfaccia Node, DOM Core 2 specifica che questi campi sono nulli per gli attributi w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Svend

35

Prendi l'HTML e analizzalo in una struttura DOM. Quindi prendi la struttura DOM e riscrivila in HTML. Durante la scrittura, ordina gli attributi utilizzando un ordinamento stabile. Il tuo codice HTML verrà ora normalizzato per quanto riguarda gli attributi.

Questo è un modo generale per normalizzare le cose. (analizzare i dati non normalizzati, quindi riscriverli in forma normalizzata).

Non sono sicuro del motivo per cui vorresti normalizzare l'HTML, ma il gioco è fatto. I dati sono dati. ;-)


1
Hai un esempio di codice. Ho provato a fare qualcosa di simile, non ha funzionato.
Julien

12

Questa è una prova di concetto, sicuramente può essere ottimizzata:

function sort_attributes(a, b) {
  if( a.name == b.name) {
    return 0;
  }

  return (a.name < b.name) ? -1 : 1;
 }

$("#original").find('*').each(function() {
  if (this.attributes.length > 1) {
    var attributes = this.attributes;
    var list = [];

    for(var i =0; i < attributes.length; i++) {
      list.push(attributes[i]);
    }

     list.sort(sort_attributes);

    for(var i = 0; i < list.length; i++) {
      this.removeAttribute(list[i].name, list[i].value);
    }

     for(var i = 0; i < list.length; i++) {
       this.setAttribute(list[i].name, list[i].value);
    }
  }
 });

Stessa cosa per il secondo elemento del diff, $ ('# different'). Ora $ ('# original'). Html () e $ ('# different'). Html () mostrano il codice HTML con attributi nello stesso ordine.


Penso che sia meglio se generi i tuoi contenuti html in XML e poi renderli usando xslt. Otterrai sicuramente risultati migliori.
Nasaralla

8

puoi provare ad aprire la scheda HTML in Firebug, gli attributi sono sempre nello stesso ordine


4
Questo non è davvero utile da solo. Questo perché sta ricreando l'HTML dal DOM, e tuttavia questo accade ha un particolare ordine di iterazione degli attributi (o Firebug li ordina manualmente). Julien potrebbe trarne vantaggio e utilizzare lo stesso metodo per scrivere HTML.
Matt Kantor

5

In realtà, posso pensare ad alcune buone ragioni. Uno potrebbe essere il confronto per la corrispondenza dell'identità e per l'uso con strumenti di tipo "diff" in cui è abbastanza fastidioso che le linee semanticamente equivalenti possano essere contrassegnate come "diverse".

La vera domanda è "Perché in Javascript"?

Questa domanda "odora" di "Ho un problema e penso di avere una risposta ... ma ho anche un problema con la mia risposta".

Se l'OP spiegasse perché vuole farlo, le sue possibilità di ottenere una buona risposta aumenterebbero notevolmente.


2

La domanda "A cosa serve?" Risposta: rende il codice più leggibile e più facile da capire.

Perché la maggior parte dell'interfaccia utente fa schifo ... Molti programmatori non riescono a capire la necessità di semplificare il lavoro degli utenti. In questo caso, il lavoro dell'utente è leggere e comprendere il codice. Una ragione per ordinare gli attributi è per l'essere umano che deve eseguire il debug e mantenere il codice. Un elenco ordinato, con cui il programma acquisisce familiarità, facilita il suo lavoro. Può trovare più rapidamente gli attributi o rendersi conto di quali attributi mancano e modificare più rapidamente i valori degli attributi.


Mi sembra che tu non abbia riflettuto abbastanza a lungo sulla domanda; anche una soluzione funzionante alla domanda non affronterebbe quello che dici qui, per quanto vero possa essere.
issa marie tseng

Perché pensi che l'OP voglia farlo con Javascript? È possibile che fosse in mente una soluzione Javascript lato server (tempo di compilazione?), Ma è improbabile che qualcuno con sufficiente esperienza per farlo non abbia omesso di menzionarla in un post di Stackoverflow. È anche possibile che l'OP stia implementando un editor HTML nel browser, ma anche questo sembra dubbio.
Pointy

0

Questo importa solo quando qualcuno sta leggendo la fonte, quindi per me sono prima gli attributi semantici, poi quelli meno semantici ...

Ci sono ovviamente delle eccezioni, se hai ad esempio <li> consecutivi, tutti con un attributo su ciascuno e altri solo su alcuni, potresti voler assicurarti che quelli condivisi siano tutti all'inizio, seguiti da quelli individuali, ad es. .

<li a = "x"> A </li>
<li a = "y" b = "t"> B </li>
<li a = "z"> C </li>

(Anche se l'attributo "b" è più semanticamente utile di "a")

Hai l'idea.


0

in realtà è possibile, penso, se i contenuti html vengono passati come xml e renderizzati tramite xslt ... quindi il contenuto originale in XML può essere nell'ordine desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.