Domanda .prop () vs .attr ()


Così jQuery 1.6 ha la nuova funzione prop().

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

o in questo caso fanno la stessa cosa?

E se io fare devono passare all'utilizzo prop(), tutto il vecchio attr() le chiamate si interromperanno se passo a 1.6?

AGGIORNARE

selector = '#id'

$(selector).click(function() {
    //instead of:
    var getAtt = this.getAttribute('style');
    //do i use:
    var thisProp = $(this).prop('style');
    //or:
    var thisAttr = $(this).attr('style');

    console.log(getAtt, thisProp, thisAttr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>

(guarda anche questo violino: http://jsfiddle.net/maniator/JpUF2/)

La console registra il getAttribute come una stringa, e il attr come una stringa, ma il prop come un CSSStyleDeclaration, Perché? E in che modo ciò influenza la mia codifica in futuro?


2053
2018-05-03 19:33


origine


risposte:


Aggiornamento 1 novembre 2012

La mia risposta originale si applica specificamente a jQuery 1.6. Il mio consiglio rimane lo stesso, ma jQuery 1.6.1 ha cambiato leggermente le cose: di fronte al mucchio previsto di siti Web non funzionanti, il team di jQuery ritornati attr() a qualcosa di simile a (ma non esattamente uguale a) il suo vecchio comportamento per gli attributi booleani. Anche John Resig bloggato su di esso. Riesco a vedere la difficoltà in cui si trovavano, ma non sono ancora d'accordo con la raccomandazione di preferire attr().

Risposta originale

Se hai sempre usato jQuery e non direttamente il DOM, questo potrebbe essere un cambiamento confuso, anche se è sicuramente un miglioramento concettualmente. Non così buono per i miliardi di siti che utilizzano jQuery che si romperà come risultato di questo cambiamento però.

Riassumerò i principali problemi:

  • Di solito lo vuoi prop() piuttosto che attr().
  • Nella maggior parte dei casi, prop() fa cosa attr() era solito fare. Sostituire le chiamate a attr() con prop() nel tuo codice funzionerà generalmente.
  • Le proprietà sono generalmente più semplici da gestire rispetto agli attributi. Un valore di attributo può essere solo una stringa mentre una proprietà può essere di qualsiasi tipo. Ad esempio, il checked la proprietà è un booleano, il style proprietà è un oggetto con proprietà individuali per ogni stile, il size la proprietà è un numero
  • Dove esiste sia una proprietà che un attributo con lo stesso nome, in genere l'aggiornamento di uno aggiornerà l'altro, ma questo non è il caso per alcuni attributi di input, come value e checked: per questi attributi, la proprietà rappresenta sempre lo stato corrente mentre l'attributo (tranne nelle versioni precedenti di IE) corrisponde al valore / controllo predefinito dell'input (riflesso nel defaultValue / defaultChecked proprietà).
  • Questa modifica rimuove alcuni dei livelli di magia bloccati da jQuery di fronte a attributi e proprietà, il che significa che gli sviluppatori di jQuery dovranno imparare un po 'sulla differenza tra proprietà e attributi. Questa è una buona cosa.

Se sei uno sviluppatore di jQuery e sei confuso da tutta questa faccenda su proprietà e attributi, devi fare un passo indietro e imparare un po 'su di esso, dal momento che jQuery non sta cercando così tanto di proteggerti da questa roba. Per la parola autorevole ma un po 'secca sull'argomento, ci sono le specifiche: DOM4, DOM HTML, DOM livello 2, DOM livello 3. La documentazione DOM di Mozilla è valida per la maggior parte dei browser moderni ed è più facile da leggere rispetto alle specifiche, quindi potresti trovarne la loro Riferimento DOM utile. C'è un sezione sulle proprietà degli elementi.

Come esempio di come le proprietà sono più semplici da gestire rispetto agli attributi, prendi in considerazione una casella di controllo inizialmente verificata. Ecco due possibili parti di codice HTML valido per fare ciò:

<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">

Quindi, come fai a sapere se la casella è selezionata con jQuery? Guarda su Stack Overflow e troverai comunemente i seguenti suggerimenti:

  • if ( $("#cb").attr("checked") === true ) {...}
  • if ( $("#cb").attr("checked") == "checked" ) {...}
  • if ( $("#cb").is(":checked") ) {...}

Questa è in realtà la cosa più semplice del mondo con il checked Proprietà booleana, che è esistita e funzionava perfettamente in tutti i principali browser scriptable dal 1995:

if (document.getElementById("cb").checked) {...}

La proprietà effettua anche il controllo o la deselezione della casella di controllo banale:

document.getElementById("cb").checked = false

In jQuery 1.6, questo diventa inequivocabilmente

$("#cb").prop("checked", false)

L'idea di usare il checked l'attributo per lo scripting di una casella di controllo è inutile e non necessario. La proprietà è ciò di cui hai bisogno.

  • Non è ovvio quale sia il modo corretto di selezionare o deselezionare la casella di controllo checked attributo
  • Il valore dell'attributo riflette il valore predefinito piuttosto che lo stato visibile corrente (tranne in alcune versioni precedenti di IE, rendendo le cose ancora più difficili). L'attributo non ti dice nulla se la casella di controllo sulla pagina è selezionata. Vedere http://jsfiddle.net/VktA6/49/.

1734
2018-05-03 23:06



credo Tim lo disse abbastanza bene, ma facciamo un passo indietro:

Un elemento DOM è un oggetto, una cosa nella memoria. Come la maggior parte degli oggetti in OOP, ha proprietà. Inoltre, ha separatamente una mappa degli attributi definiti sull'elemento (in genere provenienti dal markup letto dal browser per creare l'elemento). Alcuni degli elementi proprietà prendi il loro iniziale valori da attributi con nomi uguali o simili (value ottiene il suo valore iniziale dall'attributo "valore"; href ottiene il suo valore iniziale dall'attributo "href", ma non è esattamente lo stesso valore; className dall'attributo "class"). Altre proprietà ottengono i loro valori iniziali in altri modi: ad esempio, il parentNode la proprietà ottiene il suo valore in base a quale è l'elemento principale; un elemento ha sempre un style proprietà, se ha o meno un attributo "stile".

Consideriamo questo ancoraggio in una pagina a http://example.com/testing.html:

<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>

Qualche arte ASCII gratuita (e tralasciando un sacco di cose):

+ ------------------------------------------- +
| HTMLAnchorElement |
+ ------------------------------------------- +
| href: "http://example.com/foo.html" |
| nome: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| attributi: |
| href: "foo.html" |
| nome: "fooAnchor" |
| id: "fooAnchor" |
| classe: "prova uno" |
+ ------------------------------------------- +

Si noti che le proprietà e gli attributi sono distinti.

Ora, sebbene siano distinti, poiché tutto questo si è evoluto invece di essere progettato da zero, un certo numero di proprietà riscrive l'attributo da cui sono derivate se le si imposta. Ma non tutti lo fanno, e come puoi vedere da hrefsopra, la mappatura non è sempre una scala "passa il valore su", a volte c'è un'interpretazione coinvolta.

Quando parlo di proprietà che sono proprietà di un oggetto, non sto parlando in astratto. Ecco alcuni codici non jQuery:

var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"

(Questi valori sono come per la maggior parte dei browser, c'è qualche variazione.)

Il link l'oggetto è una cosa reale, e puoi vedere che c'è una vera distinzione tra l'accesso a proprietà su di esso e accedendo a attributo.

Come ha detto Tim, il grande maggioranza del tempo, vogliamo lavorare con le proprietà. In parte è perché i loro valori (anche i loro nomi) tendono ad essere più coerenti tra i vari browser. Per lo più desideriamo lavorare con gli attributi solo quando non ci sono proprietà ad essi correlate (attributi personalizzati), o quando sappiamo che per quel particolare attributo, l'attributo e la proprietà non sono 1: 1 (come con href e "href" sopra).

Le proprietà standard sono definite nelle varie specifiche del DOM:

Queste specifiche hanno indici eccellenti e consiglio di tenere i collegamenti a portata di mano; Li uso sempre.

Gli attributi personalizzati includono, ad esempio, qualsiasi data-xyz attributi che potresti mettere su elementi per fornire metadati al tuo codice (ora che è valido come HTML5, a patto che tu rimanga fedele al data- prefisso). (Le versioni recenti di jQuery ti danno accesso data-xyz elementi tramite il data funzione, ma quella funzione è non solo un accessorio per data-xyz attributi [fa entrambi più e meno di quello]; a meno che tu non abbia effettivamente bisogno delle sue funzionalità, userei il attr funzione per interagire con data-xyz attributo.)

Il attr la funzione era usata per avere una logica complessa attorno a ottenere ciò che pensavano di volere, piuttosto che ottenere letteralmente l'attributo. Ha fuso i concetti. Trasferirsi a prop e attr era destinato a de-conflate loro. Brevemente in v1.6.0 jQuery è andato troppo oltre a riguardo, ma funzionalità è stato rapidamente aggiunto a attr per gestire le situazioni comuni in cui le persone usano attr quando tecnicamente dovrebbero usare prop.


621
2018-05-04 14:27



Questo cambiamento ha richiesto molto tempo per jQuery. Per anni si sono accontentati di una funzione chiamata attr() che ha recuperato le proprietà DOM per lo più, non il risultato che ti aspetteresti dal nome. La segregazione di attr() e prop() dovrebbe contribuire ad alleviare parte della confusione tra attributi HTML e proprietà DOM. $.fn.prop() afferra la proprietà DOM specificata, mentre $.fn.attr() afferra l'attributo HTML specificato.

Per comprendere appieno il loro funzionamento, ecco una spiegazione estesa sulla differenza tra attributi HTML e proprietà DOM .:

Attributi HTML

Sintassi:

<body onload="foo()">

Scopo: Consente al markup di avere dati associati ad esso per eventi, rendering e altri scopi.

visualizzazione: HTML AttributesL'attributo della classe è mostrato qui sul corpo. È accessibile attraverso il seguente codice:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

Gli attributi vengono restituiti in forma stringa e possono essere incoerenti dal browser al browser. Tuttavia, possono essere di vitale importanza in alcune situazioni. Come esemplificato sopra, IE 8 Quirks Mode (e sotto) si aspetta il nome di una proprietà DOM in get / set / removeAttribute al posto del nome dell'attributo. Questo è uno dei tanti motivi per cui è importante conoscere la differenza.

Proprietà DOM

Sintassi:

document.body.onload = foo;

Scopo: Fornisce l'accesso alle proprietà che appartengono ai nodi elemento. Queste proprietà sono simili agli attributi, ma sono accessibili solo tramite JavaScript. Questa è una differenza importante che aiuta a chiarire il ruolo delle proprietà DOM. Si noti che gli attributi sono completamente diversi dalle proprietà, poiché questa assegnazione del gestore eventi è inutile e non riceverà l'evento (il corpo non ha un evento onload, solo un attributo onload).

visualizzazione: DOM Properties

Qui, noterai un elenco di proprietà nella scheda "DOM" di Firebug. Queste sono proprietà DOM. Ne vedrai immediatamente alcuni, visto che li avresti usati prima senza saperlo. I loro valori sono ciò che riceverete tramite JavaScript.

Documentazione

Esempio

HTML: <textarea id="test" value="foo"></textarea>

JavaScript: alert($('#test').attr('value'));

Nelle versioni precedenti di jQuery, restituisce una stringa vuota. In 1.6, restituisce il valore corretto, foo.

Senza aver guardato il nuovo codice per entrambe le funzioni, posso dire con certezza che la confusione ha più a che fare con la differenza tra attributi HTML e proprietà DOM, piuttosto che con il codice stesso. Spero che questo abbia chiarito alcune cose per te.

-Opaco


234
2018-05-03 20:05



Una proprietà è nel DOM; un attributo è nell'HTML che viene analizzato nel DOM.

Maggiori dettagli

Se modifichi un attributo, la modifica si rifletterà nel DOM (a volte con un nome diverso).

Esempio: modifica del class l'attributo di un tag cambierà il className proprietà di quel tag nel DOM. Se non si dispone di un attributo su un tag, si ha comunque la proprietà DOM corrispondente con un valore vuoto o predefinito.

Esempio: mentre il tag ha no class attributo, la proprietà DOM className esiste con un valore stringa vuoto.

modificare

Se si modifica uno, l'altro verrà modificato da un controller e viceversa. Questo controller non è in jQuery, ma nel codice nativo del browser.


232
2017-09-27 16:55



È solo la distinzione tra attributi HTML e oggetti DOM che crea confusione. Per coloro che sono a loro agio agendo sulle proprietà native degli elementi DOM come this.src  this.value  this.checked eccetera, .prop è un caloroso benvenuto alla famiglia. Per gli altri, è solo un ulteriore strato di confusione. Chiariamolo.

Il modo più semplice per vedere la differenza tra .attr e .prop è il seguente esempio:

<input blah="hello">
  1. $('input').attr('blah'): ritorna 'hello'come previsto. Nessuna sorpresa qui.
  2. $('input').prop('blah'): ritorna undefined - perché sta cercando di fare [HTMLInputElement].blah - e nessuna proprietà di questo tipo su questo oggetto DOM esiste. Esiste solo nell'ambito come attributo di quell'elemento, ad esempio [HTMLInputElement].getAttribute('blah')

Ora cambiamo alcune cose in questo modo:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): ritorna 'apple' eh? Perché non "pera" come questo è stato impostato per ultimo su quell'elemento. Poiché la proprietà è stata modificata sull'attributo di input, non sull'elemento di input DOM stesso, praticamente funzionano indipendentemente l'uno dall'altro.
  2. $('input').prop('blah'): ritorna 'pear'

La cosa di cui hai veramente bisogno di stare attento è solo non mescolare l'utilizzo di questi per la stessa proprietà in tutta l'applicazione per la ragione di cui sopra.

Guarda un violino dimostrando la differenza:  http://jsfiddle.net/garreh/uLQXc/


.attr vs .prop:

Round 1: stile

<input style="font:arial;"/>
  • .attr('style') - restituisce gli stili in linea per l'elemento corrispondente, ad es. "font:arial;"
  • .prop('style') - restituisce un oggetto di dichiarazione di stile, ad es. CSSStyleDeclaration

Round 2: valore

<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');
  • .attr('value') -- ritorna 'hello' *
  • .prop('value') -- ritorna 'i changed the value'

* Nota: jQuery per questo motivo ha un .val() metodo, che internamente è equivalente a .prop('value')


131
2018-05-19 10:18



TL; DR

Uso prop() al di sopra di attr() nella maggior parte dei casi.

UN proprietà è lo stato corrente dell'elemento di input. Un attributo è il valore predefinito.

Una proprietà può contenere cose di diverso tipo. Un attributo può contenere solo stringhe


48
2017-07-16 09:45



Controllo sporco

Questo concetto è un esempio in cui la differenza è osservabile: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Provalo:

  • fare clic sul pulsante. Entrambe le caselle sono state controllate.
  • deseleziona entrambe le caselle di controllo.
  • clicca di nuovo il pulsante. Solo il prop la casella di controllo è stata selezionata. SCOPPIO!

$('button').on('click', function() {
  $('#attr').attr('checked', 'checked')
  $('#prop').prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>

Per alcuni attributi come disabled sopra button, aggiunta o rimozione dell'attributo content disabled="disabled" commuta sempre la proprietà (chiamato attributo IDL in HTML5) perché http://www.w3.org/TR/html5/forms.html#attr-fe-disabled dice:

L'attributo IDL disabilitato deve riflettere l'attributo del contenuto disabilitato.

quindi potresti farla franca, anche se è brutta dato che modifica l'HTML senza necessità.

Per altri attributi come checked="checked" sopra input type="checkbox", le cose si rompono, perché una volta cliccato su di esso, diventa sporco, e quindi aggiungendo o rimuovendo il checked="checked" attributo di contenuto non commuta più il controllo.

Questo è il motivo per cui dovresti usare soprattutto .prop, poiché influenza direttamente la proprietà effettiva, invece di fare affidamento su effetti collaterali complessi.


34
2017-07-06 11:43



Tutto è nel documento:

La differenza tra attributi e proprietà può essere importante in situazioni specifiche. Prima di jQuery 1.6, il metodo .attr () a volte prendeva in considerazione i valori delle proprietà quando recuperava alcuni attributi, il che poteva causare un comportamento incoerente. A partire da jQuery 1.6, il metodo .prop () fornisce un modo per recuperare esplicitamente i valori delle proprietà, mentre .attr () recupera solo gli attributi.

Quindi usa il sostegno!


32
2018-05-03 19:35



attributi sono nel tuo codice HTML documento / file di testo (== Immagina che questo sia il risultato del tuo markup html analizzato), mentre
proprietàsono in HTML Albero DOM (== fondamentalmente una proprietà effettiva di alcuni oggetti in senso JS).

È importante sottolineare che molti di loro sono sincronizzati (se si aggiorna class proprietà, class anche l'attributo in html verrà aggiornato; e in altro modo). Ma alcuni attributi possono essere sincronizzati con proprietà inaspettate, ad es. attributo  checked corrisponde a proprietà  defaultChecked, così che

  • il controllo manuale di una casella di controllo cambierà .prop('checked') valore, ma non cambierà .attr('checked') e .prop('defaultChecked') valori
  • ambientazione $('#input').prop('defaultChecked', true) cambierà anche .attr('checked'), ma questo non sarà visibile su un elemento.

La regola generale è: .prop() il metodo dovrebbe essere usato per attributi / proprietà booleane e per proprietà che non esistono in html   (come window.location). Tutti gli altri attributi (quelli che puoi vedere in   l'html) può e dovrebbe continuare a essere manipolato con .attr()   metodo. (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)

E qui c'è un tavolo che mostra dove .prop() è preferito (anche se .attr() può ancora essere usato).

  table with preferred usage


Perché a volte vorresti usare .prop () invece di .attr () dove quest'ultimo è ufficialmente consigliato?

  1. .prop() può restituire qualsiasi tipo - stringa, intero, booleano; mentre .attr() restituisce sempre una stringa.
  2. .prop() si dice che sia circa 2,5 volte più veloce di .attr().

26
2018-06-12 05:56



.attr():

  • Ottieni il valore di un attributo per il primo elemento nel set di elementi abbinati.
  • Fornisce il valore dell'elemento come era definito nel caricamento html a pagina

.prop():

  • Ottieni il valore di a proprietà per il primo elemento nel set di elementi abbinati.
  • Fornisce i valori aggiornati degli elementi che vengono modificati tramite javascript / jquery

18
2017-12-08 09:14