Frage .prop () vs .attr ()


Damit 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 das Gleiche?

Und wenn ich machen muss zur Verwendung wechseln prop(), all die Alten attr() Anrufe werden unterbrochen, wenn ich zu 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 getAttribute als eine Schnur und die attr als eine Schnur, aber die prop Als ein CSSStyleDeclaration, Warum? Und wie wirkt sich das auf meine Programmierung in der Zukunft aus?


2053
2018-05-03 19:33


Ursprung


Antworten:


Update 1. November 2012

Meine ursprüngliche Antwort gilt speziell für jQuery 1.6. Mein Rat bleibt derselbe, aber jQuery 1.6.1 hat die Dinge ein wenig verändert: angesichts des vorhergesagten Haufen zerbrochener Websites, des jQuery-Teams rückgängig gemacht attr() zu etwas, das seinem alten Verhalten für boolesche Attribute nahe (aber nicht genau dasselbe) ist. John Resig auch darüber gebloggt. Ich kann die Schwierigkeiten sehen, in denen sie waren, aber immer noch nicht mit der Empfehlung zu bevorzugen attr().

Ursprüngliche Antwort

Wenn Sie nur jQuery und nicht das DOM direkt verwendet haben, könnte dies eine verwirrende Änderung sein, obwohl es konzeptionell definitiv eine Verbesserung darstellt. Nicht so gut für die bazzillions von Websites, die jQuery verwenden, die jedoch als Ergebnis dieser Änderung ausfallen werden.

Ich fasse die wichtigsten Punkte zusammen:

  • Normalerweise willst du prop() eher, als attr().
  • In den meisten Fällen prop() macht was attr() pflegte zu tun. Ersetzen von Anrufen für attr() mit prop() in Ihrem Code wird in der Regel funktionieren.
  • Eigenschaften sind in der Regel einfacher zu handhaben als Attribute. Ein Attributwert darf nur eine Zeichenfolge sein, während eine Eigenschaft von einem beliebigen Typ sein kann. Zum Beispiel, die checked Eigenschaft ist ein Boolescher, der style Eigenschaft ist ein Objekt mit individuellen Eigenschaften für jeden Stil, der size Eigenschaft ist eine Zahl.
  • Wenn sowohl eine Eigenschaft als auch ein Attribut mit demselben Namen vorhanden sind, wird bei der Aktualisierung von einer die andere aktualisiert. Bei bestimmten Attributen von Eingaben, wie z value und checkedFür diese Attribute stellt die Eigenschaft immer den aktuellen Zustand dar, während das Attribut (außer in älteren Versionen von IE) dem Standardwert / checkness der Eingabe entspricht (in der defaultValue / defaultChecked Eigentum).
  • Diese Änderung entfernt einige der magischen jQuery-Ebenen, die vor Attributen und Eigenschaften stecken, was bedeutet, dass jQuery-Entwickler ein wenig ü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 folgende Spezifikationen: DOM4, HTML-DOM, DOM Level 2, DOM Level 3. Mozillas DOM-Dokumentation gilt für die meisten modernen Browser und ist einfacher zu lesen als die Spezifikationen, so dass Sie ihre finden können DOM Referenz hilfreich. Da ist ein Abschnitt über Elementeigenschaften.

Als ein Beispiel dafür, wie Eigenschaften einfacher zu handhaben sind als Attribute, sollten Sie ein Kontrollkästchen in Betracht ziehen, das anfänglich 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 auf Stack Overflow und Sie finden häufig folgende Vorschläge:

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

Das ist eigentlich die einfachste Sache auf der Welt, die mit der checked Boolesche Eigenschaft, die seit 1995 in jedem gängigen skriptfähigen Browser existiert und einwandfrei funktioniert:

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

Die Eigenschaft aktiviert oder deaktiviert auch das Kontrollkästchen trivial:

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

In jQuery 1.6 wird dies eindeutig

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

Die Idee der Verwendung der checked Attribut für das Scripting eines Kontrollkästchens ist nicht hilfreich und unnötig. Das Anwesen ist was Sie brauchen.

  • Es ist nicht offensichtlich, was der richtige Weg ist, das Kontrollkästchen zu aktivieren oder zu deaktivieren checked Attribut
  • Der Attributwert gibt den Standardwert und nicht den aktuellen sichtbaren Status wieder (außer in einigen älteren Versionen von IE, wodurch die Dinge noch schwieriger werden). Das Attribut sagt nichts darüber aus, ob das Kontrollkästchen auf der Seite aktiviert ist. Sehen http://jsfiddle.net/VktA6/49/.

1734
2018-05-03 23:06



Ich denke Tim sagte es ganz gut, aber lass uns zurücktreten:

Ein DOM-Element ist ein Objekt, eine Sache im Speicher. Wie die meisten Objekte in OOP hat es Eigenschaften. Es hat auch separat eine Karte der Attribute, die auf dem Element definiert sind (normalerweise von dem Markup, das der Browser zum Erstellen des Elements gelesen hat). Einige der Elemente Eigenschaften erhalten ihre Initiale Werte von Attribute mit den gleichen oder ähnlichen Namen (value erhält seinen Anfangswert vom Attribut "value"; href erhält seinen Anfangswert aus dem "href" -Attribut, aber es ist nicht genau derselbe Wert; className aus dem Attribut "Klasse"). Andere Eigenschaften erhalten ihre ursprünglichen Werte auf andere Weise: Zum Beispiel die parentNode Die Eigenschaft erhält ihren Wert basierend auf dem übergeordneten Element. Ein Element hat immer ein style Eigenschaft, ob sie ein Attribut "style" hat oder nicht.

Betrachten wir diesen Anker in einer Seite an http://example.com/testing.html:

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

Einige unentgeltliche ASCII-Kunst (und eine Menge Zeug weglassen):

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

Beachten Sie, dass die Eigenschaften und Attribute unterschiedlich sind.

Nun, obwohl sie verschieden sind, weil sich all dies entwickelt und nicht von Grund auf neu entworfen wurde, schreiben einige Eigenschaften auf das Attribut zurück, von dem sie abgeleitet wurden, wenn Sie sie setzen. Aber nicht alle, und wie du sehen kannst hrefoben ist das Mapping nicht immer eine gerade "Pass auf den Wert", manchmal gibt es Interpretation beteiligt.

Wenn ich über Eigenschaften als Eigenschaften eines Objekts spreche, 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 sind wie bei den meisten Browsern; es gibt einige Variationen.)

Das link Objekt ist eine reale Sache, und Sie können sehen, es gibt einen echten Unterschied zwischen dem Zugriff auf ein Eigentum darauf und Zugriff auf ein Attribut.

Wie Tim sagte, die große Mehrheit der Zeit wollen wir mit Immobilien arbeiten. Teilweise liegt das daran, dass ihre Werte (sogar ihre Namen) tendenziell konsistenter über Browser hinweg sind. Wir wollen meist nur mit Attributen arbeiten, wenn keine Eigenschaft damit verbunden ist (benutzerdefinierte Attribute), oder wenn wir wissen, dass für dieses spezielle Attribut das Attribut und die Eigenschaft nicht 1: 1 sind (wie bei href und "href" oben).

Die Standardeigenschaften sind in den verschiedenen DOM-Spezifikationen angelegt:

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

Zu den benutzerdefinierten Attributen gehören beispielsweise alle data-xyz Attribute, die Sie auf Elemente setzen können, um Metadaten für Ihren Code bereitzustellen (jetzt, da dies für HTML5 gilt, solange Sie sich an die data- Präfix). (Aktuelle Versionen von jQuery geben Ihnen Zugriff auf data-xyz Elemente über die data Funktion, aber diese Funktion ist nicht nur ein Accessor für data-xyz Attribute [es tut mehr und weniger als das]; es sei denn, du benötigst tatsächlich seine Funktionen, würde ich das verwenden attr Funktion um mit zu interagieren data-xyz Attribut.)

Das attr Funktion verwendet, um etwas gewundene Logik herum zu bekommen, was sie dachten, dass Sie wollten, anstatt buchstäblich das Attribut zu erhalten. Es hat die Konzepte zusammengeführt. Umziehen nach prop und attr war dazu bestimmt, sie zu entmischen. Kurz zu v1.6.0 ging jQuery in dieser Hinsicht zu weit, aber funktional wurde schnell wieder hinzugefügt zu attr mit den üblichen Situationen umgehen, in denen Menschen arbeiten attr wenn sie technisch verwendet werden sollten prop.


621
2018-05-04 14:27



Diese Änderung wurde für jQuery erst lange bevorsteht. Seit Jahren sind sie zufrieden mit einer Funktion namens attr() das meist DOM-Eigenschaften abgerufen, nicht das Ergebnis, das Sie von dem 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() ergreift die angegebene DOM-Eigenschaft, während $.fn.attr() ergreift das angegebene HTML-Attribut.

Um zu verstehen, wie sie funktionieren, finden Sie hier eine ausführliche Erklärung zum Unterschied zwischen HTML-Attributen und DOM-Eigenschaften .:

HTML-Attribute

Syntax:

<body onload="foo()">

Zweck: Ermöglicht Markup, Daten für Ereignisse, Rendering und andere Zwecke zugeordnet zu haben.

Visualisierung: HTML AttributesDas Klassenattribut wird hier im Body angezeigt. Es ist zugänglich durch den folgenden Code:

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. Sie können jedoch in einigen Situationen lebenswichtig 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 den Attributen, sind jedoch nur über JavaScript zugänglich. Dies ist ein wichtiger Unterschied, der zur Klärung der Rolle von DOM-Eigenschaften beiträgt. Bitte beachten Sie, dass Attribute sich völlig von Eigenschaften unterscheiden, da diese Event-Handler-Zuweisung nutzlos ist und das Ereignis nicht empfangen wird (Body hat kein Onload-Ereignis, nur ein Onload-Attribut).

Visualisierung: DOM Properties

Hier finden Sie eine Liste der Eigenschaften unter der Registerkarte "DOM" in Firebug. Dies sind DOM-Eigenschaften. Sie werden sofort eine ganze Reihe von ihnen bemerken, da Sie sie schon vorher benutzt haben, ohne es zu wissen. Ihre Werte erhalten Sie durch 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 gibt es den richtigen Wert zurück, foo.

Ohne auf den neuen Code für eine der Funktionen zu schauen, kann ich mit Sicherheit sagen, dass die Verwirrung mehr mit dem Unterschied zwischen HTML-Attributen und DOM-Eigenschaften als mit dem Code selbst zu tun hat. Hoffentlich hat dies einige Dinge für dich aufgeräumt.

-Matt


234
2018-05-03 20:05



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 widergespiegelt (manchmal mit einem anderen Namen).

Beispiel: Ändern der class Attribut eines Tags ändert die className Eigenschaft dieses Tags im DOM. 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 keine hat class Attribut, die DOM-Eigenschaft className existiert mit einem leeren String-Wert.

bearbeiten

Wenn Sie den einen ändern, wird der andere von einem Controller geändert und umgekehrt. Dieser Controller befindet sich nicht in jQuery, sondern im systemeigenen Code des Browsers.


232
2017-09-27 16:55



Es ist nur die Unterscheidung zwischen HTML-Attributen und DOM-Objekten, die Verwirrung stiften. Für diejenigen, die sich wohl fühlen, wirken auf die DOM-Elemente native Eigenschaften wie z this.src  this.value  this.checked etc, .prop ist ein sehr herzliches Willkommen in der Familie. Für andere ist es nur eine zusätzliche Ebene der Verwirrung. Lasst uns das klären.

Der einfachste Weg, um den Unterschied zu sehen .attr und .prop ist das folgende Beispiel:

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

Jetzt ändern wir ein paar Dinge wie folgt:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): kehrt zurück 'apple' wie? Warum nicht "Birne", wie das zuletzt für dieses Element festgelegt wurde. Weil die Eigenschaft am Input-Attribut geändert wurde, nicht am DOM-Input-Element selbst - sie funktionieren quasi unabhängig voneinander.
  2. $('input').prop('blah'): kehrt zurück 'pear'

Die Sache, mit der du wirklich vorsichtig sein musst, ist einfach Mischen Sie nicht die Verwendung dieser für die gleiche Eigenschaft in Ihrer Anwendung aus dem oben genannten Grund.

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


.attr vs .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, d.h. CSSStyleDeclaration

Runde 2: Wert

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

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

* Hinweis: jQuery hat aus diesem Grund eine .val() Methode, die intern entspricht .prop('value')


131
2018-05-19 10:18



TL; DR

Benutzen prop() Über attr() in den meisten Fällen.

EIN Eigentum ist der aktuelle Status des Eingabeelements. Ein Attribut ist der Standardwert.

Eine Eigenschaft kann Dinge verschiedener Typen enthalten. Ein Attribut kann nur Zeichenfolgen enthalten


48
2017-07-16 09:45



Schmutzige Überprüfungen

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

Versuch es:

  • drück den Knopf. Beide Checkboxen wurden überprüft.
  • Deaktivieren Sie beide Kontrollkästchen.
  • Klicken Sie erneut auf die Schaltfläche. Nur der prop Checkbox wurde überprüft. 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>

Für einige Attribute wie disabled auf button, Hinzufügen oder Entfernen des Inhaltsattributs disabled="disabled" schaltet die Eigenschaft immer um (in HTML5 als IDL-Attribut bezeichnet) http://www.w3.org/TR/html5/forms.html#attr-fe-disabled sagt:

Das deaktivierte IDL-Attribut muss das deaktivierte Inhaltsattribut enthalten.

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

Für andere Attribute wie checked="checked" auf input type="checkbox"Dinge brechen ab, denn wenn du einmal darauf klickst, wird es schmutzig und dann kannst du das hinzufügen oder entfernen checked="checked" Inhaltsattribut schaltet die Überprüfung nicht mehr um.

Deshalb sollten Sie meistens verwenden .prop, da es die effektive Eigenschaft direkt beeinflusst, anstatt sich auf komplexe Nebenwirkungen zu verlassen.


34
2017-07-06 11:43