.prop () vs .attr ()

2300

So jQuery 1.6 hat die neue Funktion prop().

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

oder machen sie in diesem Fall dasselbe?

Und wenn ich sie zu Schalter müssen mit prop(), alle alten attr()Anrufe brechen , wenn ich auf 1,6 wechseln?

AKTUALISIEREN

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>

(Siehe auch diese Geige: http://jsfiddle.net/maniator/JpUF2/ )

Die Konsole protokolliert die getAttributeals Zeichenfolge und die attrals Zeichenfolge, aber die propals CSSStyleDeclaration, warum? Und wie wirkt sich das in Zukunft auf meine Codierung aus?

Naftali alias Neal
quelle
17
Dies wird von definitivem Interesse sein: books.google.ca/…
28
@Neal, weil diese Änderung jQuery übersteigt. Der Unterschied zwischen HTML-Attributen und DOM-Eigenschaften ist enorm.
7
Es macht mich traurig zu sehen, dass jQuery die Änderungen rückgängig gemacht hat. Sie gehen in die falsche Richtung.
4
@Neal. Ja, und es macht das Problem nur noch komplizierter, anstatt die beiden Methoden zu trennen.
6
@BritishDeveloper Die Antwort ist komplizierter als die bloße Angabe, immer x oder y zu verwenden, da dies davon abhängt, was Sie erhalten möchten. Möchten Sie das Attribut oder möchten Sie die Eigenschaft? Das sind zwei sehr unterschiedliche Dinge.
Kevin B

Antworten:

1876

Update 1. November 2012

Meine ursprüngliche Antwort gilt speziell für jQuery 1.6. Mein Rat bleibt das gleiche , aber jQuery 1.6.1 Dinge etwas geändert: angesichts des vorhergesagten Haufen zerbrochener Websites, die jQuery - Team zurückgekehrt , attr()um etwas in der Nähe (aber nicht genau das gleiche wie) sein altes Verhalten für Boolesche Attribute . John Resig hat auch darüber gebloggt . Ich kann die Schwierigkeit sehen, in der sie sich befanden, bin aber immer noch nicht mit seiner Empfehlung einverstanden attr().

Ursprüngliche Antwort

Wenn Sie bisher nur jQuery und nicht direkt das DOM verwendet haben, kann dies eine verwirrende Änderung sein, obwohl dies konzeptionell definitiv eine Verbesserung darstellt. Nicht so gut für die Unmengen von Websites, die jQuery verwenden und die aufgrund dieser Änderung nicht mehr funktionieren.

Ich werde die Hauptprobleme zusammenfassen:

  • Sie wollen normalerweise prop()eher als attr().
  • In den meisten Fällen wird prop()das getan , was attr()früher getan wurde. Das Ersetzen von Anrufen attr()durch prop()in Ihrem Code funktioniert im Allgemeinen.
  • Eigenschaften sind im Allgemeinen einfacher zu handhaben als Attribute. Ein Attributwert kann nur eine Zeichenfolge sein, während eine Eigenschaft von einem beliebigen Typ sein kann. Beispielsweise ist die checkedEigenschaft ein Boolescher Wert, die styleEigenschaft ist ein Objekt mit individuellen Eigenschaften für jeden Stil, die sizeEigenschaft ist eine Zahl.
  • Wenn sowohl eine Eigenschaft als auch ein Attribut mit demselben Namen vorhanden sind, wird beim Aktualisieren eines Attributs normalerweise das andere aktualisiert. Dies ist jedoch bei bestimmten Attributen von Eingaben nicht der Fall, z. B. valueund checked: Bei diesen Attributen repräsentiert die Eigenschaft immer den aktuellen Status, während das Attribut (außer in alten Versionen von IE) entspricht den Standardwert / checkedness des Eingangs (im reflektierten defaultValue/ defaultCheckedImmobilien).
  • Diese Änderung entfernt einen Teil der magischen jQuery-Ebene, die vor Attributen und Eigenschaften steckt, was bedeutet, dass jQuery-Entwickler etwas über den Unterschied zwischen Eigenschaften und Attributen lernen müssen. Das ist eine gute Sache.

Wenn Sie ein jQuery-Entwickler sind und von diesem ganzen Geschäft über Eigenschaften und Attribute verwirrt sind, müssen Sie einen Schritt zurücktreten und ein wenig darüber lernen, da jQuery nicht mehr so ​​sehr versucht, Sie vor diesen Dingen zu schützen. Für das maßgebliche, aber etwas trockene Wort zu diesem Thema gibt es die Spezifikationen: DOM4 , HTML DOM , DOM Level 2 , DOM Level 3 . Die DOM-Dokumentation von Mozilla ist für die meisten modernen Browser gültig und leichter zu lesen als die technischen Daten. Daher ist die DOM-Referenz möglicherweise hilfreich. Es gibt einen Abschnitt über Elementeigenschaften .

Betrachten Sie als Beispiel dafür, wie Eigenschaften einfacher zu handhaben sind als Attribute, ein Kontrollkästchen, das zunächst aktiviert ist. Hier sind zwei mögliche Teile von gültigem HTML, um dies zu tun:

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

Wie finden Sie heraus, ob das Kontrollkästchen mit jQuery aktiviert ist? Schauen Sie sich den Stapelüberlauf an und Sie werden häufig die folgenden Vorschläge finden:

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

Dies ist tatsächlich die einfachste Sache der Welt, die mit der checkedBooleschen Eigenschaft zu tun hat, die seit 1995 in allen wichtigen skriptfähigen Browsern existiert und einwandfrei funktioniert:

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

Die Eigenschaft macht auch das Aktivieren oder Deaktivieren des Kontrollkästchens trivial:

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

In jQuery 1.6 wird dies eindeutig

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

Die Idee, das checkedAttribut zum Erstellen von Skripten für ein Kontrollkästchen zu verwenden, ist nicht hilfreich und unnötig. Die Eigenschaft ist, was Sie brauchen.

  • Es ist nicht offensichtlich, wie das Kontrollkästchen mithilfe des checkedAttributs richtig aktiviert oder deaktiviert wird
  • Der Attributwert spiegelt eher den Standardwert als den aktuell sichtbaren Status wider (außer in einigen älteren Versionen des IE, wodurch die Dinge noch schwieriger werden). Das Attribut sagt nichts darüber aus, ob das Kontrollkästchen auf der Seite aktiviert ist. Siehe http://jsfiddle.net/VktA6/49/ .
Tim Down
quelle
2
@TJCrowder, welche dann?
Naftali aka Neal
9
@Neal: Wenn Sie wissen möchten, welche Eigenschaften DOM-Elemente haben und wie Attribute ihre Werte festlegen können, halten Sie diese Links bereit : Die DOM2-HTML-Spezifikation , die DOM2- Spezifikation und die DOM3- Spezifikation. Die Indizes sind jeweils ausgezeichnet und führen Sie direkt zu einer gründlichen Beschreibung der Immobilie, woher ihr Wert stammt usw.
TJ Crowder
4
@Neal: Was macht es anders: Die Quelle und Art der Informationen. Schauen Sie sich zum valueBeispiel Tims Beispiel an. Eine aufgerufene Funktion attr, die die Eigenschaft value und nicht das Attribut "Wert" abruft , ist wenig sinnvoll (und sie können unterschiedlich sein). In Zukunft wird es klarer sein, attrAttribute und propEigenschaften auszuführen, obwohl der Übergang für einige schmerzhaft sein wird. Verstehen Sie das nicht falsch, es gibt nichts Schöneres, als zurückzutreten und die technischen Daten zu lesen, um eine Vorstellung von den Eigenschaften zu bekommen.
TJ Crowder
54
@Neal: Ein DOM-Element ist ein Objekt. Eigenschaften sind Eigenschaften dieses Objekts, genau wie jedes andere Programmierobjekt. Einige dieser Requisiten erhalten ihre Anfangswerte aus den Attributen im Markup, die auch im DOM-Objekt in einer separaten Zuordnung von Attributen gespeichert sind . In den meisten Fällen ändert das Schreiben in eine Requisite nur die Requisite, obwohl es leider einige Requisiten gibt, die Änderungen an den zugrunde liegenden attr ( valuezum Beispiel) durchschreiben , aber versuchen wir, dies größtenteils zu ignorieren. In 99% der Fälle möchten Sie mit Requisiten arbeiten. Wenn Sie mit einem tatsächlichen Attribut arbeiten müssen, wissen Sie das wahrscheinlich.
TJ Crowder
4
@Tim: "Das Ändern der valueEigenschaft einer Eingabe ändert ihr valueAttribut in modernen Browsern nicht." Ich habe nicht gedacht, dass dies der Fall ist. Deshalb habe ich angefangen, es als Beispiel zu verwenden, aber als ich anfing, das Beispiel zu codieren, verdammt Wenn es nicht auf Chrome, Firefox, Opera, IE ... aktualisiert wurde - jsbin.com/ahire4 Es stellte sich heraus, dass ich ein input[type="button"]für mein Experiment verwendet habe. Es ist nicht aktualisiert das Attribut auf einem input[type="text"]- jsbin.com/ahire4/2 Sprechen Sie über die gewundene !! Nicht nur das Element, sondern auch die Art ...
TJ Crowder
664

Ich denke, Tim hat es ganz gut gesagt , aber lasst uns zurücktreten:

Ein DOM-Element ist ein Objekt, eine Sache im Speicher. Wie die meisten Objekte in OOP verfügt es über Eigenschaften . Es enthält auch separat eine Karte der für das Element definierten Attribute (normalerweise aus dem Markup, das der Browser gelesen hat, um das Element zu erstellen). Einige Eigenschaften des Elements erhalten ihre Anfangswerte von Attributen mit demselben oder ähnlichen Namen ( valueerhält seinen Anfangswert vom Attribut "value"; hreferhält seinen Anfangswert vom Attribut "href", aber es ist nicht genau der gleiche Wert; classNamevom Attribut "Klasse"). Andere Eigenschaften erhalten ihre Anfangswerte auf andere Weise: Beispielsweise parentNodeerhält die Eigenschaft ihren Wert basierend auf dem übergeordneten Element.style Eigenschaft, ob es ein "style" -Attribut hat oder nicht.

Betrachten wir diesen Anker auf einer Seite unter http://example.com/testing.html:

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

Einige unentgeltliche ASCII-Kunstwerke (und viele Dinge weglassen):

+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| HTMLAnchorElement |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| href: "http://example.com/foo.html" |
| Name: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| Attribute: |
| href: "foo.html" |
| Name: "fooAnchor" |
| id: "fooAnchor" |
| Klasse: "test one" |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +

Beachten Sie, dass die Eigenschaften und Attribute unterschiedlich sind.

Obwohl sie unterschiedlich sind, schreiben einige Eigenschaften auf das Attribut zurück, von dem sie abgeleitet wurden, wenn Sie sie festlegen, da sich all dies entwickelt hat, anstatt von Grund auf neu entworfen zu werden. Aber nicht alle tun dies, und wie Sie von hrefoben sehen können, ist das Mapping nicht immer ein direktes "Weitergeben des Werts", manchmal ist eine Interpretation erforderlich.

Wenn ich davon spreche, dass Eigenschaften Eigenschaften eines Objekts sind, spreche ich nicht abstrakt. Hier ist ein Nicht-jQuery-Code:

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

(Diese Werte entsprechen den meisten Browsern; es gibt einige Abweichungen.)

Das linkObjekt ist eine echte Sache, und Sie können sehen, dass es einen echten Unterschied zwischen dem Zugriff auf eine Eigenschaft und dem Zugriff auf ein Attribut gibt .

Wie Tim sagte, die überwiegende Mehrheit will der Zeit, wir mit Eigenschaften zu arbeiten. Dies liegt zum Teil daran, dass ihre Werte (sogar ihre Namen) in allen Browsern konsistenter sind. Wir möchten meistens nur mit Attributen arbeiten, wenn keine zugehörige Eigenschaft vorhanden ist (benutzerdefinierte Attribute) oder wenn wir wissen, dass für dieses bestimmte Attribut das Attribut und die Eigenschaft nicht 1: 1 sind (wie bei hrefund "href" oben). .

Die Standardeigenschaften sind in den verschiedenen DOM-Spezifikationen aufgeführt:

Diese Spezifikationen haben ausgezeichnete Indizes und ich empfehle, Links zu ihnen griffbereit zu halten. Ich benutze sie die ganze Zeit.

Zu den benutzerdefinierten Attributen gehören beispielsweise alle data-xyzAttribute, die Sie möglicherweise auf Elemente setzen, um Metadaten für Ihren Code bereitzustellen (jetzt, da dies ab HTML5 gültig ist, solange Sie sich an das data-Präfix halten). (Neuere Versionen von jQuery ermöglichen Ihnen den Zugriff auf data-xyzElemente über die dataFunktion, aber diese Funktion ist nicht nur ein Accessor für data-xyzAttribute [sie macht mehr und weniger als das]. Wenn Sie ihre Funktionen nicht tatsächlich benötigen, würde ich die attrFunktion zur Interaktion verwenden mit data-xyzAttribut.)

attrFrüher hatte die Funktion eine verworrene Logik, um das zu bekommen, was sie wollten, anstatt das Attribut buchstäblich zu bekommen. Es verschmolz die Konzepte. Der Umzug nach propund attrsollte sie entmischen. Kurz in v1.6.0 jQuery zu weit gegangen in dieser Hinsicht, aber die Funktionalität wurde schnell wieder hinzugefügt , um attrzu handhaben, die gemeinsame Situationen , in denen Menschen nutzen , attrwenn technisch sollen sie nutzen prop.

TJ Crowder
quelle
Beeindruckend. Dieses neue 1.6.1-Update macht diese Frage wirklich ein bisschen ungültig. (aber nicht viel), aber dieser Link beantwortet sie im Grunde jetzt
Naftali aka Neal
Es hat es für mich nicht aufgehoben, ich habe nur einen Fehler mit jquery1.7 behoben, bei dem ich .attr ('class', 'bla') gesetzt habe, und es hat nicht funktioniert, wo .prop ('className', 'bla'). ) arbeitete
PandaWood
@PandaWood: .attr('class', 'bla')funktioniert wie erwartet für mich in 1.7.0 , 1.7.1 und 1.7.2 unter Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 und Safari 5.
TJ Crowder
Danke, in meinem Fall muss etwas Bestimmtes sein. Lassen Sie mich dies überprüfen und mit einem Testfall zurückkommen. Aber das Ändern des Codes, wie wir ihn gerade haben, in "prop / className" anstelle von "attr" behebt einen massiven Fehler für uns, der auftrat, als wir von jquery1.4 auf 1.7 umstellten - in allen Browsern
PandaWood
3
@TJCrowder re: .data- Es liest den Standardwert des Attributs, falls vorhanden, aber wenn Sie darauf schreiben, ändert es eine versteckte Eigenschaft des Elements und aktualisiert das Attribut nicht.
Alnitak
250

Diese Änderung hat für jQuery lange auf sich warten lassen. Seit Jahren begnügen sie sich mit einer Funktion namens attr(), die hauptsächlich DOM-Eigenschaften abruft, nicht mit dem Ergebnis, das Sie vom Namen erwarten würden. Die Trennung von attr()und prop()sollte dazu beitragen, die Verwirrung zwischen HTML-Attributen und DOM-Eigenschaften zu verringern. $.fn.prop()greift auf die angegebene DOM-Eigenschaft zu, während $.fn.attr()das angegebene HTML-Attribut erfasst wird.

Um zu verstehen, wie sie funktionieren, finden Sie hier eine ausführliche Erläuterung des Unterschieds zwischen HTML-Attributen und DOM-Eigenschaften:

HTML-Attribute

Syntax:

<body onload="foo()">

Zweck: Ermöglicht dem Markup, Daten für Ereignisse, Rendering und andere Zwecke zuzuordnen.

Visualisierung: HTML-Attribute Das Klassenattribut wird hier im Body angezeigt. Es ist über den folgenden Code zugänglich:

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

Attribute werden in Zeichenfolgenform zurückgegeben und können von Browser zu Browser inkonsistent sein. In einigen Situationen können sie jedoch von entscheidender Bedeutung sein. Wie oben beispielhaft dargestellt, erwartet der IE 8 Quirks Mode (und darunter) den Namen einer DOM-Eigenschaft in get / set / removeAttribute anstelle des Attributnamens. Dies ist einer von vielen Gründen, warum es wichtig ist, den Unterschied zu kennen.

DOM-Eigenschaften

Syntax:

document.body.onload = foo;

Zweck: Ermöglicht den Zugriff auf Eigenschaften, die zu Elementknoten gehören. Diese Eigenschaften ähneln Attributen, sind jedoch nur über JavaScript zugänglich. Dies ist ein wichtiger Unterschied, der zur Verdeutlichung der Rolle von DOM-Eigenschaften beiträgt. Beachten Sie, dass sich die Attribute vollständig von den Eigenschaften unterscheiden , da diese Zuweisung des Ereignishandlers unbrauchbar ist und das Ereignis nicht empfängt (body hat kein Onload-Ereignis, nur ein Onload-Attribut).

Visualisierung: DOM-Eigenschaften

Hier finden Sie eine Liste der Eigenschaften unter der Registerkarte "DOM" in Firebug. Dies sind DOM-Eigenschaften. Sie werden sofort einige von ihnen bemerken, da Sie sie zuvor verwendet haben, ohne es zu wissen. Ihre Werte erhalten Sie über JavaScript.

Dokumentation

Beispiel

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

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

In früheren Versionen von jQuery wird eine leere Zeichenfolge zurückgegeben. In 1.6 wird der richtige Wert zurückgegeben foo.

Ohne einen Blick auf den neuen Code für eine der beiden Funktionen geworfen zu haben, kann ich mit Zuversicht sagen, dass die Verwirrung mehr mit dem Unterschied zwischen HTML-Attributen und DOM-Eigenschaften zu tun hat als mit dem Code selbst. Hoffentlich hat dies einige Dinge für Sie geklärt.

-Matt

K.Dᴀᴠɪs
quelle
7
$.prop()Ruft DOM-Eigenschaften ab und $.attr()ruft HTML-Attribute ab. Ich versuche, die Lücke psychologisch zu schließen, damit Sie den Unterschied zwischen den beiden verstehen können.
10
Junge, ich bin jetzt auch verwirrt. Gibt $('#test').prop('value')also nichts zurück? Auch nicht .attr('checked')für ein Kontrollkästchen? Aber früher? Jetzt müsstest du es ändern prop('checked')? Ich verstehe die Notwendigkeit dieser Unterscheidung nicht - warum ist es wichtig, zwischen HTML-Attributen und DOM-Eigenschaften zu unterscheiden? Was ist der übliche Anwendungsfall, der diese Änderung "lange auf sich warten lässt" ? Was ist falsch daran, die Unterscheidung zwischen den beiden zu abstrahieren, da sich ihre Anwendungsfälle anscheinend größtenteils überschneiden?
BlueRaja - Danny Pflughoeft
5
@BlueRaja: Weil es einen gravierenden Unterschied zwischen den beiden Konzepten gibt, der, wenn Sie ihn wie früher unter jQuery unter den Teppich streichen, zu unerwarteten Fehlern führt. valueDies ist einer der offensichtlichsten Fälle, da die valueEigenschaft den aktuellen Wert eines Felds angibt, das valueAttribut jedoch den ursprünglichen Wert value="..."angibt, der im Attribut deklariert wurde , bei dem es sich tatsächlich um die defaultValueEigenschaft handelt. (Obwohl dieser spezielle Fall erneut durch Fehler in IE <9 verwirrt wird.)
Bobince
4
@ BlueRaja: Die Antwort darauf ist noch komplizierter. :-) Durch Festlegen attr('value', ...)in jQuery <1.6 wird die Eigenschaft festgelegt, sodass sich der aktuelle Wert ändert und der Standardwert nicht. In 1.6 wird das Attribut festgelegt, sodass sich theoretisch der Standardwert ändert und der aktuelle Wert nicht. Es gibt jedoch (mehr) Browser-Inkonsistenzen hinsichtlich der genauen Einstellung des valueAttributs. Im IE wird auch der aktuelle Wert festgelegt. In einigen Browsern wird der aktuelle Wert nur festgelegt, wenn der aktuelle Wert noch nicht festgelegt wurde. [weint]
Bobince
1
Genau wie @Quentin sagte: "Attribute werden durch HTML definiert. Eigenschaften werden durch DOM definiert." Die einfachste Version, die ich gelesen habe.
Alan Dong
241

Eine Eigenschaft befindet sich im DOM. Ein Attribut befindet sich im HTML-Code, der im DOM analysiert wird.

Weitere Details

Wenn Sie ein Attribut ändern, wird die Änderung im DOM angezeigt (manchmal mit einem anderen Namen).

Beispiel: Durch Ändern des classAttributs eines Tags wird die classNameEigenschaft dieses Tags im DOM geändert . Wenn Sie kein Attribut für ein Tag haben, haben Sie immer noch die entsprechende DOM-Eigenschaft mit einem leeren oder einem Standardwert.

Beispiel: Während Ihr Tag kein classAttribut hat, ist die DOM-Eigenschaft classNamemit einem leeren Zeichenfolgenwert vorhanden.

bearbeiten

Wenn Sie das eine ändern, wird das andere von einem Controller geändert und umgekehrt. Dieser Controller befindet sich nicht in jQuery, sondern im nativen Code des Browsers.

Yunzen
quelle
Bedeutet dies, dass es besser ist, das Attribut zu aktualisieren, da Sie dann sicherstellen, dass sowohl das Attribut als auch die Eigenschaft aktualisiert werden und aufeinander abgestimmt sind?
Luke
1
@ Luke the DOM ist die innere technische Darstellung, das Modell. Die HTML-Attribute sind eine äußere Darstellung, eine Ansicht. Wenn Sie das eine ändern, wird das andere von einem Controller geändert und umgekehrt.
Yunzen
@HerrSerker Also werden beide über einen Controller synchronisiert? Ich gehe davon aus, dass dies nur innerhalb der attr- und prop-Methoden von jQuery liegt. Hier ist eine Modifikation Ihrer Geige, in der ich dies genauer untersuche - jsfiddle.net/v8wRy - und bis jetzt scheinen sie gleichwertig zu sein.
Luke
3
"Wenn Sie den einen ändern, wird der andere von einem Controller geändert und umgekehrt. Dieser Controller befindet sich nicht in jQuery, sondern im nativen Code des Browsers." Dies gilt nicht für die meisten Attribute / Eigenschaften. Für die Mehrheit ist es nur eine Einwegübersetzung, bei der ein Attribut den Anfangswert der entsprechenden Eigenschaft bestimmt. Die beiden wichtigsten Antworten erläutern dies ausführlich.
18.
@ Vincent. Ich sehe nicht, wo die beiden obersten Antworten etwas sagen, das meiner Antwort widerspricht. Natürlich sind die meisten Attribute die Anfangswerte der entsprechenden DOM-Eigenschaften. Sie bedingen sich aber gegenseitig. Versuchen Sie etwas wie jQuery('p').prop('className', 'foo');in der Chrome-Konsole und Sie werden sehen, wie jeder Absatz das classAttribut thg erhält 'foo'. Natürlich nicht im Quellcode, der vom Server kommt. Das ist eine Konstante.
Yunzen
140

Nur die Unterscheidung zwischen HTML-Attributen und DOM-Objekten sorgt für Verwirrung. Für diejenigen, die gerne auf die DOM-Elemente einwirken, sind native Eigenschaften wie this.src this.value this.checkedusw. .propein sehr herzliches Willkommen in der Familie. Für andere ist es nur eine zusätzliche Verwirrungsebene. Lassen Sie uns das klären.

Der einfachste Weg, um den Unterschied zwischen .attrund zu erkennen, .propist das folgende Beispiel:

<input blah="hello">
  1. $('input').attr('blah'): kehrt 'hello'wie erwartet zurück. Keine Überraschungen hier.
  2. $('input').prop('blah'): gibt zurück undefined- weil es versucht wird [HTMLInputElement].blah- und es gibt keine solche Eigenschaft für dieses DOM-Objekt. Es existiert nur im Bereich als Attribut dieses Elements, dh[HTMLInputElement].getAttribute('blah')

Jetzt ändern wir ein paar Dinge wie folgt:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): kehrt 'apple'eh zurück? Warum nicht "Birne", da dies zuletzt auf dieses Element gesetzt wurde. Da die Eigenschaft für das Eingabeattribut und nicht für das DOM-Eingabeelement selbst geändert wurde, funktionieren sie im Grunde fast unabhängig voneinander.
  2. $('input').prop('blah'): kehrt zurück 'pear'

Das, womit Sie wirklich vorsichtig sein müssen, ist, die Verwendung dieser für dieselbe Eigenschaft in Ihrer Anwendung aus dem oben genannten Grund nicht zu mischen .

Sehen Sie sich eine Geige an, die den Unterschied demonstriert: http://jsfiddle.net/garreh/uLQXc/


.attrvs .prop:

Runde 1: Stil

<input style="font:arial;"/>
  • .attr('style') - gibt Inline-Stile für das übereinstimmende Element zurück, d. h "font:arial;"
  • .prop('style') - gibt ein Stildeklarationsobjekt zurück, dh CSSStyleDeclaration

Runde 2: Wert

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

$('input').prop('value', 'i changed the value');
  • .attr('value')- gibt 'hello'* zurück
  • .prop('value') -- kehrt zurück 'i changed the value'

* Hinweis: jQuery verfügt aus diesem Grund über eine .val()Methode, die intern gleichwertig ist.prop('value')

Gary Green
quelle
@Neal, weil es einen besseren Hinweis auf die Struktur der Abfragefunktionen gibt. "$ ('input'). prop ('blah'): Gibt undefiniert zurück - da versucht wird, [HTMLInputElement] .blah auszuführen - und keine solche Eigenschaft für dieses DOM-Objekt vorhanden ist. Sie ist nur im Bereich als Attribut vorhanden dieses Elements dh [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan
2
Scheint anders zu sein als das Dokument api.jquery.com/prop : "Die Methode .prop () sollte verwendet werden, um deaktiviert und aktiviert zu setzen, anstelle der Methode .attr (). Die Methode .val () sollte zum Abrufen von und verwendet werden Einstellungswert."
Schwan
53

TL; DR

Verwenden Sie prop()über attr()in der Mehrzahl der Fälle.

Eine Eigenschaft ist der aktuelle Status des Eingabeelements. Ein Attribut ist der Standardwert.

Eine Eigenschaft kann verschiedene Arten von Dingen enthalten. Ein Attribut kann nur Zeichenfolgen enthalten

Agjmills
quelle
1
Wenn möglich, kommen Sie mit ein paar einfachen Beispielen von dem, was Sie sagen und zeigen Sie auch, wann Sie es verwenden sollen prop() and when to go for attr(). Warten auf Antwort :)
Mou
36

Schmutzige Kontrolle

Dieses Konzept bietet ein Beispiel, bei dem der Unterschied erkennbar ist: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Versuch es:

  • drück den Knopf. Beide Kontrollkästchen wurden aktiviert.
  • Deaktivieren Sie beide Kontrollkästchen.
  • Klicken Sie erneut auf die Schaltfläche. Nur das propKontrollkästchen wurde aktiviert. KNALL!

$('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>

Bei einigen Attributen wie disabledon buttonwird beim Hinzufügen oder Entfernen des Inhaltsattributs disabled="disabled"die Eigenschaft (in HTML5 als IDL-Attribut bezeichnet) immer umgeschaltet, da http://www.w3.org/TR/html5/forms.html#attr-fe-disabled Folgendes sagt:

Das deaktivierte IDL-Attribut muss das deaktivierte Inhaltsattribut widerspiegeln.

Sie könnten also damit durchkommen, obwohl es hässlich ist, da es HTML ohne Notwendigkeit ändert.

Bei anderen Attributen wie checked="checked"on input type="checkbox"werden die Dinge unterbrochen, da sie beim Klicken schmutzig werden und das Hinzufügen oder Entfernen des checked="checked"Inhaltsattributs die Überprüfung nicht mehr umschaltet .

Aus diesem Grund sollten Sie meistens verwenden .prop, da dies die effektive Eigenschaft direkt beeinflusst, anstatt sich auf komplexe Nebenwirkungen beim Ändern des HTML-Codes zu verlassen.

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
quelle
Versuchen Sie der Vollständigkeit halber auch diese Variationen: 1) Bevor Sie auf die Schaltfläche klicken, aktivieren und deaktivieren Sie das erste Kontrollkästchen. 2) (Für dieses müssen Sie das Snippet ändern.) Geben Sie der ersten Eingabe ein checkedAttribut:checked="checked"
ᴠɪɴᴄᴇɴᴛ
33

Alles ist im Dokument :

Der Unterschied zwischen Attributen und Eigenschaften kann in bestimmten Situationen wichtig sein. Vor jQuery 1.6 berücksichtigte die Methode .attr () manchmal Eigenschaftswerte, wenn einige Attribute abgerufen wurden, was zu inkonsistentem Verhalten führen kann. Ab jQuery 1.6 bietet die .prop () -Methode eine Möglichkeit, Eigenschaftswerte explizit abzurufen, während .attr () Attribute abruft.

Also benutze Requisite!

Arnaud F.
quelle
2
Das heißt also, wenn ich zu 1.6 wechsle, werden viele Dinge kaputt gehen?
Naftali aka Neal
Nein, es ist nur ein inkonsistentes Verhalten. Wenn es vorher funktioniert, funktioniert es immer mit jQuery 1.6. Es ist nur so, dass die Requisite sicherer ist.)
Arnaud F.
6
Ich scheine mich zu erinnern. $.attr()Ich habe die meiste Zeit damit gearbeitet, nicht "manchmal". Die dadurch verursachte Verwirrung ist bis heute spürbar. Leider habe ich große Probleme, einen endgültigen Lesevorgang für HTML-Attribute im Vergleich zu DOM-Eigenschaften zu finden. Daher könnte ich hier gleich eine Antwort schreiben.
3
@ Arnaud-f Nicht wahr. Der gesamte Code vor 1.6, der zum Aktivieren der Kontrollkästchen attr ('checked') verwendet, wird jetzt beschädigt.
CaptSaltyJack
3
@Matt McDonald: Was für "... Probleme beim Finden eines endgültigen Lesens von HTML-Attributen im Vergleich zu DOM-Eigenschaften ..." meinen Sie? Eigenschaften (reflektiert und anderweitig) werden in der DOM2-HTML-Spezifikation beschrieben . Möglicherweise müssen Sie sich auch auf die DOM2- und DOM3- Spezifikationen beziehen .
TJ Crowder
28

Attribute befinden sich in Ihrem HTML- Textdokument / Ihrer HTML- Textdatei (== Stellen Sie sich vor, dies ist das Ergebnis Ihres analysierten HTML-Markups), während sich
Eigenschaften im HTML- DOM-Baum befinden (== im Grunde eine tatsächliche Eigenschaft eines Objekts im JS-Sinne).

Wichtig ist, dass viele von ihnen synchronisiert werden (wenn Sie die classEigenschaft aktualisieren , classwird auch das Attribut in HTML aktualisiert; andernfalls). Aber einige Attribute können zu einem unerwarteten Eigenschaften synchronisiert werden - zB Attribut checked entspricht Eigenschaft defaultChecked , so dass

  • manuell eine Checkbox ändern .prop('checked')Wert, aber wird sich nicht ändern .attr('checked')und .prop('defaultChecked')Werte
  • Die Einstellung $('#input').prop('defaultChecked', true)ändert sich ebenfalls .attr('checked'), dies ist jedoch für ein Element nicht sichtbar.

Als Faustregel gilt : Die .prop()Methode sollte für boolesche Attribute / Eigenschaften und für Eigenschaften verwendet werden, die in HTML nicht vorhanden sind (z. B. window.location). Alle anderen Attribute (die Sie im HTML-Code sehen können) können und sollten weiterhin mit der .attr() Methode bearbeitet werden. ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

Und hier ist eine Tabelle, die zeigt, wo .prop()bevorzugt wird (obwohl .attr()noch verwendet werden kann).

Tabelle mit bevorzugter Verwendung


Warum sollten Sie manchmal .prop () anstelle von .attr () verwenden, wenn letzteres offiziell empfohlen wird?

  1. .prop()kann jeden Typ zurückgeben - string, integer, boolean; while gibt .attr()immer einen String zurück.
  2. .prop()soll etwa 2,5 mal schneller sein als .attr().
Seen sind
quelle
etwas hat sich geändert, wie diese: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')oder $('#myTextBox').prop('type', 'button'). Und so weiter ...
@ Mr.Wolf, sorry, ich verstehe immer noch nicht was du meinst. Was hat sich verändert'? Die Syntax war schon immer so.
Seen sind
Ich denke, die Tabelle in Ihrer Antwort ist unnötig. Weil .prop()funktioniert gut mit allen Eigenschaften. Sie möchten nicht alle Eigenschaften in der .prop()Spalte markieren , oder?
@ Mr.Wolf, ich denke, es ist notwendig, weil es, wie bereits erwähnt, "zeigt, wo .prop()bevorzugt wird (obwohl .attr()es noch verwendet werden kann)"
Lakesare
Ich benutze normalerweise .attr()zum Definieren eines Ereignisses, was .prop()nicht kann. So : $('.myDiv').attr('onclick', 'alert("Hello world!")'). Wenn Sie ändern .attr()zu .prop(), wird es nicht funktionieren. Insgesamt denke ich, dass es keinen Grund gibt .attr(), den Wert festzulegen oder abzurufen id/class/href/checked/src...... Beachten Sie, dass ich nicht sage, dass Sie falsch liegen.
20

.attr()::

  • Ruft den Wert eines Attributs für das erste Element in der Gruppe der übereinstimmenden Elemente ab.
  • Gibt Ihnen den Wert des Elements an, wie er beim Laden der Seite im HTML-Code definiert wurde

.prop()::

  • Ruft den Wert einer Eigenschaft für das erste Element in der Gruppe der übereinstimmenden Elemente ab.
  • Gibt die aktualisierten Werte von Elementen an, die über Javascript / jquery geändert werden
Kgn-Web
quelle
13

Normalerweise möchten Sie Eigenschaften verwenden. Verwenden Sie Attribute nur für:

  1. Abrufen eines benutzerdefinierten HTML-Attributs (da es nicht mit einer DOM-Eigenschaft synchronisiert ist).
  2. Abrufen eines HTML-Attributs, das nicht mit einer DOM-Eigenschaft synchronisiert wird, z. B. Abrufen des "ursprünglichen Werts" eines Standard-HTML-Attributs, z <input value="abc">.
naor
quelle
7

attributes -> HTML

properties -> DOM

NkS
quelle
8
Ich weiß, was Sie sagen möchten, aber HTML ist eine Auszeichnungssprache und das DOM eine Darstellung, die aus dem HTML erstellt wurde. Ein DOMElement hat sowohl Attribute als auch Eigenschaften .
t.niese
@ t.niese, attirbutesauch eines der Eigentum vonDOM
NkS
Die kurze Antwort ist einfach.
Nabi KAZ
6

Vor jQuery 1.6 berücksichtigte die attr()Methode beim Abrufen von Attributen manchmal Eigenschaftswerte. Dies führte zu einem eher inkonsistenten Verhalten.

Die Einführung der prop()Methode bietet eine Möglichkeit, Eigenschaftswerte explizit abzurufen und .attr()Attribute abzurufen.

Die Dokumente:

jQuery.attr() Ruft den Wert eines Attributs für das erste Element in der Gruppe der übereinstimmenden Elemente ab.

jQuery.prop() Ruft den Wert einer Eigenschaft für das erste Element in der Gruppe der übereinstimmenden Elemente ab.

Gothburz
quelle
3

Erinnern Sie sich vorsichtig an die Verwendung prop(), Beispiel:

if ($("#checkbox1").prop('checked')) {
    isDelete = 1;
} else {
    isDelete = 0;
}

Die obige Funktion wird verwendet, um zu überprüfen, ob das Kontrollkästchen1 aktiviert ist oder nicht, falls aktiviert: return 1; wenn nicht: return 0. Funktion prop () wird hier als GET-Funktion verwendet.

if ($("#checkbox1").prop('checked', true)) {
    isDelete = 1;
} else {
    isDelete = 0;
}

Die obige Funktion wird verwendet, um das zu aktivierende Kontrollkästchen1 zu setzen und IMMER 1 zurückzugeben. Jetzt wird die Funktion prop () als SET-Funktion verwendet.

Mach dir keine Sorgen.

P / S: Wenn ich die Eigenschaft Image src überprüfe . Wenn der src leer ist, gibt prop die aktuelle URL der Seite zurück (falsch) und attr gibt eine leere Zeichenfolge zurück (rechts).

user2657778
quelle
In diesem Beispiel liegen Sie falsch : <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Es sollte funktionieren und den Bildspeicherort zurückgeben.
2

Eines .attr()kann das .prop()nicht: CSS-Selektoren beeinflussen

Hier ist ein Problem, das ich in den anderen Antworten nicht gesehen habe.

CSS-Auswahl [name=value]

  • wird antworten .attr('name', 'value')
  • aber nicht immer zu .prop('name', 'value')

.prop() betrifft nur wenige Attributselektoren

.attr() betrifft alle Attributselektoren

Bob Stein
quelle
0

1) Eine Eigenschaft befindet sich im DOM; Ein Attribut befindet sich im HTML-Code, der im DOM analysiert wird.

2) $ (elem) .attr ("geprüft") (1.6.1+) "geprüft" (Zeichenfolge) Ändert sich mit dem Status des Kontrollkästchens

3) $ (elem) .attr ("markiert") (vor 1.6) true (Boolean) Mit dem Status des Kontrollkästchens geändert

  • Meistens möchten wir eher für DOM-Objekte als für benutzerdefinierte Attribute wie verwenden data-img, data-xyz.

  • Auch einige Unterschiede beim Zugriff auf checkboxWert und href mit attr()und prop()als Sache ändern sich mit der DOM-Ausgabe mit prop()als vollständiger Verknüpfung von originund BooleanWert für Kontrollkästchen (pre-1.6)

  • Wir können nur mit propanderen als den angegebenen auf DOM-Elemente zugreifenundefined

Parth Trivedi
quelle
0

In prop () vs attr () gibt es noch einige weitere Überlegungen:

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked und defaultSelected..etc sollten mit der Methode .prop () abgerufen und festgelegt werden. Diese haben keine entsprechenden Attribute und sind nur Eigenschaften.

  • Kontrollkästchen für Eingabetyp

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • Die prop-Methode gibt einen booleschen Wert für "geprüft", "ausgewählt", "deaktiviert", "readOnly..etc" zurück, während attr eine definierte Zeichenfolge zurückgibt. Sie können also .prop ('checked') direkt in if-Bedingung verwenden.

  • .attr () ruft intern .prop () auf, sodass die .attr () -Methode etwas langsamer ist als der direkte Zugriff über .prop ().

Rishu Ranjan
quelle
-2

Die Antwort von Gary Hole ist sehr relevant, um das Problem zu lösen, wenn der Code so geschrieben ist

obj.prop("style","border:1px red solid;")

Da die Prop-Funktion das CSSStyleDeclarationObjekt zurückgibt, funktioniert der obige Code in einigen Browsern nicht richtig ( IE8 with Chrome Frame Pluginin meinem Fall mit getestet ).

So ändern Sie es in folgenden Code

obj.prop("style").cssText = "border:1px red solid;"

Problem gelöst.

zawhtut
quelle