getAttribute () rispetto alle proprietà dell'oggetto Element?


92

Espressioni come Element.getAttribute("id")e Element.idrestituiscono la stessa cosa.

Quale dovrebbe essere usato quando abbiamo bisogno degli attributi di un oggetto HTMLElement?

C'è qualche problema cross browser con questi metodi come getAttribute()e setAttribute()?

O qualche impatto sulle prestazioni tra l'accesso diretto alle proprietà degli oggetti e l'utilizzo di questi metodi di attributo?


Risposte:


126

getAttributerecupera l' attributo di un elemento DOM, mentre el.idrecupera la proprietà di questo elemento DOM. Non sono la stessa cosa.

La maggior parte delle volte, le proprietà DOM sono sincronizzate con gli attributi.

Tuttavia, la sincronizzazione non garantisce lo stesso valore . Un classico esempio è tra el.hrefe el.getAttribute('href')per un elemento di ancoraggio.

Per esempio:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Questo comportamento si verifica perché secondo il W3C , la proprietà href deve essere un collegamento ben formato. La maggior parte dei browser rispetta questo standard (indovina chi non lo fa?).

C'è un altro caso per il input's checkedproprietà. La proprietà DOM restituisce trueo falsementre l'attributo restituisce la stringa "checked"o una stringa vuota.

E poi, ci sono alcune proprietà che sono sincronizzate solo unidirezionali . Il miglior esempio è la valueproprietà di un inputelemento. Cambiare il suo valore tramite la proprietà DOM non cambierà l'attributo (modifica: controlla il primo commento per maggiore precisione).

Per questi motivi, ti suggerirei di continuare a utilizzare le proprietà DOM e non gli attributi, poiché il loro comportamento differisce tra i browser.

In realtà, ci sono solo due casi in cui è necessario utilizzare gli attributi:

  1. Un attributo HTML personalizzato, perché non è sincronizzato con una proprietà DOM.
  2. Per accedere a un attributo HTML integrato, che non è sincronizzato dalla proprietà, e sei sicuro di aver bisogno dell'attributo (ad esempio, l'originale valuedi un inputelemento).

Se vuoi una spiegazione più dettagliata, ti consiglio caldamente di leggere questa pagina . Ci vorranno solo pochi minuti, ma rimarrai deliziato dalle informazioni (che ho riassunto qui).


9
+1 per un consiglio generalmente buono. La cosa di sincronizzazione è però leggermente fuori luogo: la valueproprietà di un input ottiene il suo valore iniziale dall'attributo ma per il resto non è affatto legata ad esso. L' valueattributo è invece completamente sincronizzato con la defaultValueproprietà. Allo stesso modo checkede defaultChecked. Tranne che nel vecchio IE (<= 7 e modalità di compatibilità successive), che ha rotto getAttribute()e setAttribute().
Tim Down

Aggiunto il tuo commento come "ulteriore spiegazione" :-)
Florian Margaine

2
Penso che tu abbia sbagliato il primo esempio. a.hrefrestituisce l'URL completo, a.getAttribute("href")restituisce l'attributo esattamente come definito nel sorgente HTML.
Salman A

Se stai cercando di capire se un valore non è predefinito, è meglio usare gli attributi. Molti browser moderni restituiranno un valore predefinito (ad esempio input.formAction) o una stringa vuota (ad esempio a.download), il che rende le cose ambigue. L'unica eccezione sono i valori che non sono sincronizzati a 2 vie, come value.
Kevin Li

Se id non è impostato affatto nel dominio, getAttribute restituirà null e element.id restituirà una stringa vuota. È uno standard?
Maciej Krawczyk

11

getAttribute('attribute') normalmente restituisce il valore dell'attributo come una stringa, esattamente come definito nel sorgente HTML della pagina.

Tuttavia, element.attributepotrebbe restituire un valore normalizzato o calcolato dell'attributo. Esempi:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href conterrà l' URL completo
  • <input type="checkbox" checked>
    • input.checked sarà vero (booleano)
  • <input type="checkbox" checked="bleh">
    • input.checked sarà vero (booleano)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width sarà 0 (numero) prima che l'immagine venga caricata
    • img.width sarà 64 (numero) quando viene caricata l'immagine (oi primi pochi byte di essa)
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img. larghezza sarà il 50% calcolato
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img. larghezza sarà 50 (numero)
  • <div style='background: lime;'></div>
    • div.style sarà un oggetto

3

.idsalva l'overhead della chiamata di funzione. (che è molto piccolo, ma hai chiesto.)


Ciao gdoron, solo per curiosità: ho provato a trovare una spiegazione 'ufficiale' di questo (oltre il test empirico, che è abbastanza chiaro;)) ma senza successo. Hai qualche collegamento a riguardo?
mamoo

3

Secondo questo jsPerf il test getAttribute è più lento diid proprietà.

PS

Stranamente, entrambe le istruzioni si comportano molto male su IE8 (rispetto ad altri browser).


3

Usa sempre le proprietà a meno che tu non abbia un motivo specifico per non farlo.

  • getAttribute()e setAttribute()sono danneggiati nella vecchia IE (e modalità di compatibilità nelle versioni successive)
  • le proprietà sono più convenienti (in particolare, quelle corrispondenti agli attributi booleani)

Ci sono alcune eccezioni :

  • accedere agli attributi degli <form>elementi
  • accedere agli attributi personalizzati (anche se sconsiglierei di utilizzare attributi personalizzati)

Ho scritto su questo argomento alcune volte su SO:


Prima di IE 8, le proprietà e gli attributi venivano trattati in modo identico . Come hai accennato in precedenza, le proprietà sono la strada da percorrere.

@ MattMcDonald: Sì, questa è la frattura a cui stavo alludendo. Non l'ho ampliato in questa risposta perché sentivo di averlo fatto abbastanza in altre risposte a cui ho collegato :)
Tim Down

0

Prova sotto l'esempio per capirlo completamente. Per il DIV di seguito

<div class="myclass"></div>

Il Element.getAttribute('class')torneranno myclass, ma è necessario utilizzare Element.classNameche recupera dalla proprietà DOM.


0

Un'area in cui questo fa una grande differenza è con lo stile CSS basato sugli attributi.

Considera quanto segue:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

Il div con la proprietà personalizzata impostata direttamente non riflette il valore dell'attributo e non è selezionato dal nostro selettore di attributi ( div[custom]) nel css.

Il div con l'attributo personalizzato impostato utilizzando setAttribute, tuttavia, può essere selezionato utilizzando un selettore di attributi css e con uno stile di conseguenza.

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.