.prop () срещу .attr ()

Така jQuery 1.6 има нова функция prop() .

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

или в този случай правят същото?

И ако трябва да премина към използването на prop() , всички стари attr() прекъснат, ако премина на 1.6?

UPDATE

 <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> 

(виж също този скрипт: http://jsfiddle.net/maniator/JpUF2/ )

Конзолата регистрира getAttribute като низ, а attr - като низ, но prop като CSSStyleDeclaration , защо? И как това ще се отрази на кодирането ми в бъдеще?

2141
03 мая '11 в 22:33 2011-05-03 22:33 Нийл заложи на 03 май '11 в 10:33 часа на 2011-05-03 22:33
@ 18 отговора

Актуализиране на 1 ноември 2012 г.

Първоначалният ми отговор се отнася конкретно за jQuery 1.6. Съветът ми остава същият, но jQuery 1.6.1 леко промени ситуацията: в лицето на предсказаната купчина от разбити уеб сайтове, екипът на jQuery върна attr() на нещо близко (но не съвсем същото) към старото си поведение за логически атрибути , John. Resig също съобщи това в блог . Виждам трудностите, с които се сблъскват, но все още не съм съгласен с неговата препоръка да предпочитат attr() .

Оригинален отговор

Ако сте използвали само jQuery, а не DOM директно, това може да бъде объркваща промяна, въпреки че със сигурност се подобрява концептуално. Не е толкова добро за базилионите на сайтовете jQuery, които се провалят в резултат на тази промяна.

Ще обобщя основните въпроси:

  • Обикновено се нуждаете от prop() и не от attr() .
  • В повечето случаи prop() прави това, което attr() правил преди. Замяната на attr() повиквания с prop() в кода обикновено ще работи.
  • Свойствата обикновено са по-лесни за справяне с атрибутите. Стойността на атрибута може да бъде само низ, докато собствеността може да бъде от всякакъв тип. Например, checked свойство е логическо свойство, свойството на style е обект с индивидуални свойства за всеки стил, а size свойство е число.
  • Където има свойство и атрибут със същото име, обикновено актуализирането ще актуализира другото, но това не се отнася за някои атрибути на входните данни, като например value и checked : за тези атрибути, имотът винаги представлява текущото състояние, докато атрибутът (за С изключение на по-старите версии на IE, тя съответства на стойността / валидирането на входа по подразбиране (отразено в defaultValue / defaultChecked ).
  • Тази промяна премахва някакъв слой магически jQuery, заседнал пред атрибутите и свойствата, което означава, че разработчиците на jQuery ще трябва да научат малко за разликата между свойствата и атрибутите. Това е нещо добро.

Ако сте разработчик на jQuery и сте объркани относно свойствата и атрибутите в този бизнес, трябва да направите крачка назад и да научите малко за него, защото jQuery вече не се опитва да ви предпази толкова много от тези неща. За авторитетни, но няколко реални думи по този въпрос има спецификации: DOM4 , HTML DOM , DOM Level 2 , DOM Level 3 . Документацията на Mozilla DOM е валидна за повечето съвременни браузъри и е по-лесна за четене от спецификациите, така че можете да намерите тяхната DOM справочна информация . Има раздел за свойствата на елемента .

Като пример за това как свойствата са по-лесни за обработване от атрибутите, помислете за първоначално провереното квадратче. Ето две възможни части на валиден HTML:

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

И така, как да знаете дали квадратчето за отметка е зададено с помощта на jQuery? Погледнете препълването на стека и обикновено ще намерите следните изречения:

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

Всъщност, това е най-простото нещо в света, което е свързано с checked булева собственост, която съществува и работи безпроблемно във всеки основен браузър с възможност за преглед от 1995 г .:

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

Свойството също прави незначително проверката или изчистването на флаг:

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

В jQuery 1.6 това определено става

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

Идеята за използване на checked атрибут за скрипт е безполезна и ненужна. Имотът е това, от което имате нужда.

  • Не е ясно какъв е правилният начин да проверите или махнете отметката с атрибута за checked
  • Стойността на атрибута отразява стойността по подразбиране, а не текущото видимо състояние (с изключение на някои по-стари версии на IE, което прави нещата още по-сложни). Атрибутът не указва дали квадратчето за отметка е отметнато на страницата. Вижте http://jsfiddle.net/VktA6/49/ .
1790
04 мая '11 в 2:06 2011-05-04 02:06 отговорът е даден от Тим Даун на 04 май '11 в 2:06 2011-05-04 02:06

Мисля, че Тим го каза доста добре , но го остави обратно:

DOM елементът е обект, елемент в паметта. Както повечето обекти в ООП, той има свойства. Освен това, отделно, има и атрибутна карта, дефинирана на елемента (обикновено тя идва от маркирането, което браузърът чете, за да създаде елемента). Някои от свойствата на даден елемент извличат своите начални стойности от атрибути със същите или подобни имена ( value получава първоначалната си стойност от атрибута "стойност"; href получава своята първоначална стойност от атрибута "href", но това не е точно същата стойност; className от атрибута " клас “). Други свойства получават първоначалните си стойности по други начини: например, свойството parentNode получава своята стойност на базата на своя родителски елемент; елемент винаги има свойство style , независимо дали има style атрибут или не.

Помислете за това котва на страницата на http://example.com/testing.html :

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

Някои безплатни ASCII изкуства (и оставяйки много неща):

 + + –––––––––––––––––––––––––––––––––––––– |  HTMLAnchorElement | + + –––––––––––––––––––––––––––––––––––––– |  href: "http://example.com/foo.html" | |  име: "fooAnchor" | |  id: "fooAnchor" | |  className: "test one" | |  атрибути: | |  href: "foo.html" | |  име: "fooAnchor" | |  id: "fooAnchor" | |  клас: "тест един" | + + ––––––––––––––––––––––––––––––––––––––

Моля, обърнете внимание, че свойствата и атрибутите са различни.

Сега, въпреки че те са различни, тъй като всичко това се развива и не се развива от нулата, редица свойства се записват обратно към атрибута, от който са получени, ако ги зададете. Но не всеки го прави и, както можете да видите от горния href , картографирането не винаги е директно за „предаване на смисъла”, понякога се използва интерпретация.

Когато говоря за свойства, които са свойства на обект, не говоря абстрактно. Ето някои не-jQuery код:

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

(Тези стойности съответстват на повечето браузъри, има някои опции.)

Обектът на link е истинското нещо и можете да видите, че има истинска разлика между достъпа до него и достъпа до него.

Както каза Тим, по- голямата част от това време искаме да работим с имоти. Това отчасти се дължи на факта, че техните стойности (дори и техните имена) обикновено са по-последователни между браузърите. Ние основно искаме да работим само с атрибути, когато няма свойство, асоциирано с него (потребителски атрибути), или когато знаем, че за този конкретен атрибут атрибутът и свойството не са 1: 1 (както при href и "href" по-горе).

Стандартните свойства са посочени в различни спецификации на DOM:

Тези спецификации имат отлични показатели и препоръчвам да ги поддържате удобни за използване; Използвам ги през цялото време.

Персонализираните атрибути включват например всички атрибути data-xyz , които можете да поставите в елементи, за да предоставите метаданни на кода си (сега това е валидно с HTML5, ако следвате префикса за data- ), (Последните версии на jQuery ви дават достъп до data-xyz използвайки функцията data , но тази функция не е само за аксесоари за атрибути data-xyz [прави това и повече и по-малко от това], ако наистина не се нуждаете от неговите функции, бих използвал функцията attr да взаимодействам с атрибута на data-xyz .)

Функцията attr използва някаква объркваща логика около получаването на това, което те смятат, че искаш, вместо да получи буквално атрибута. Той комбинира концепцията. Придвижването към prop и attr предназначено за тяхната деконфигурация. Накратко в версията 1.6.0, jQuery отиде твърде далеч в това отношение, но функционалността бързо беше добавена към attr да се справят с обичайните ситуации, в които хората използват attr когато технически трябва да използват prop .

639
04 мая '11 в 17:27 2011-05-04 17:27 Отговорът е даден от TJ Crowder 04 май '11 в 17:27 ч. 2011-05-04 17:27

Тази промяна дойде преди много време за jQuery. Години наред те са доволни от функция, наречена attr() която основно извлича свойствата на DOM, а не резултата, който очаквате от името. Сегрегацията на attr() и prop() трябва да помогне за смекчаване на някои обърквания между HTML атрибутите и DOM свойствата. $.fn.prop() улавя посоченото свойство DOM и $.fn.attr() улавя посочения HTML атрибут.

За да разберем напълно как работят, тук има подробно обяснение на разликите между HTML атрибутите и DOM свойствата.

Атрибути на HTML

синтаксис:

<body onload="foo()">

Цел: позволява на маркирането да има данни, свързани с него за събития, рендиране и други цели.

визуализация: 2019

242
03 мая '11 в 23:05 2011-05-03 23:05 отговорът е даден от user1385191 03 май '11 в 23:05 2011-05-03 23:05

Имотът е в DOM; Атрибутът е в HTML, който се анализира в DOM.

Допълнителна информация

Ако промените даден атрибут, тази промяна ще бъде отразена в DOM (понякога с друго име).

Пример: промяната на атрибута class на маркер ще промени свойството className на този маркер в DOM. Ако нямате атрибут в маркера, все още имате съответната собственост на DOM с празна или стойност по подразбиране.

Пример. Въпреки че вашият маркер няма атрибут class свойството DOM className съществува с празна стойност за низа.

да се промени

Ако промените една, другата ще бъде променена от контролера и обратно. Този контролер не е в jQuery, а в родния код на браузъра.

237
27 сент. отговор, даден yunzen 27 септември 2011-09-27 19:55 '11 в 19:55 2011-09-27 19:55

Това е само разликата между HTML атрибутите и объркващите DOM обекти. За тези, които са доволни от свойствата на свойствата на DOM, като this.src this.value this.checked и т.н., .prop е много топло посрещане в семейството. За други това е просто допълнително объркване. Нека бъде ясно.

Най-лесният начин да видите разликата между .attr и .prop е следният пример:

 <input blah="hello"> 
  • $('input').attr('blah') : връща 'hello' , както се очаква. Няма изненади.
  • $('input').prop('blah') : връща undefined - защото се опитва да направи [HTMLInputElement].blah - и няма такова свойство на този DOM обект. Той съществува само в домейна като атрибут на този елемент, т.е. [HTMLInputElement].getAttribute('blah')

Сега променяме няколко неща като това:

 $('input').attr('blah', 'apple'); $('input').prop('blah', 'pear'); 
  • $('input').attr('blah') : връща 'apple' eh? Защо не "круша", защото тя е последната за този елемент. Тъй като собствеността е променена на входен атрибут, а не на DOM входен елемент - те основно работят почти независимо един от друг.
  • $('input').prop('blah') : връща 'pear'

Това, което наистина трябва да бъдете внимателни, е просто да не смесвате използването на това за същия имот по време на приложението поради горната причина.

Вижте цигулката, показваща разликата: http://jsfiddle.net/garreh/uLQXc/


.attr vs .prop :

Първи кръг: Стил

 <input style="font:arial;"/> 
  • .attr('style') - връща вградени стилове за съответстващия елемент, т.е. "font:arial;"
  • .prop('style') - връща обекта на декларация за стил, т.е. CSSStyleDeclaration

Кръг 2: значение

 <input value="hello" type="text"/> $('input').prop('value', 'i changed the value'); 
  • .attr('value') - връща 'hello' *
  • .prop('value') - връща 'i changed the value'

* Забележка: jQuery по тази причина има .val() метод, който е вътрешно еквивалентен на .prop('value')

134
19 мая '11 в 13:18 2011-05-19 13:18 отговорът е даден от Гари Грийн на 19 май'11 в 13:18 2011-05-19 13:18

TL; DR

Използвайте prop() над attr() в повечето случаи.

Свойството е текущото състояние на входния елемент. Атрибутът е стойността по подразбиране.

Свойството може да съдържа неща от различен тип. Атрибутът може да съдържа само низове.

49
16 июля '14 в 12:45 2014-07-16 12:45 отговорът е даден от agjmills 16 юли 14 в 12:45 2014-07-16 12:45

Мръсна проверка

Тази концепция служи като пример, когато разликата е видима: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Опитайте:

  • натиснете бутона. И двете отметки бяха проверени.
  • махнете отметката от двете кутии.
  • натиснете отново бутона. Проверява се само знамето. BANG!

 <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> 

За някои атрибути, като например disabled на button , добавянето или премахването на атрибута на съдържанието е disabled="disabled" винаги превключва свойство (наричано атрибут IDL в HTML5), защото http://www.w3.org/TR/html5/forms.html #attr -fe-disabled казва:

Активираният IDL атрибут трябва да отразява атрибута на неработещото съдържание.

така че можете да се измъкнете от него, въпреки че е грозно, тъй като ненужно променя HTML.

За други атрибути, като checked="checked" при input type="checkbox" , всичко се разрушава, тъй като веднага щом кликнете върху него, той се замърсява, а след това добавянето или изтриването на checked="checked" атрибути не се checked="checked" за отмяна на проверката .

Ето защо трябва да използвате предимно .prop , защото то пряко засяга ефективното свойство, вместо да разчита на сложните странични ефекти от модифицирането на HTML.

35
06 июля '14 в 14:43 2014-07-06 14:43 отговор, даден от Ciro Santilli 06 改造 中心 六四 事件 法轮功 Юли 06 '14 в 14:43 2014-07-06 14:43

Всички докове :

Разликата между атрибути и свойства може да бъде важна в определени ситуации. Преди jQuery 1.6, методът .attr () понякога взема предвид стойностите на свойствата при извличането на определени атрибути, които биха могли да причинят непоследователно поведение. Започвайки от jQuery 1.6, методът .prop () осигурява начин за изрично получаване на стойности на свойствата, докато .attr () връща атрибутите.

Така че използвайте опора!

32
03 мая '11 в 22:35 2011-05-03 22:35 отговорът е даден от Arnaud F. 03 май '11 в 10:35 2011-05-03 22:35

атрибутите са във вашия текстов документ / HTML файл (== представете си, че това е резултат от анализиране на маркирането на html маркиране), докато свойствата са в HTML дървото DOM (== основно действителното свойство на някой обект в JS смисъла).

Важно е да се отбележи, че много от тях са синхронизирани (ако обновявате свойството class атрибутът class в html също ще бъде актуализиран, но иначе). Но някои атрибути могат да бъдат синхронизирани с неочаквани свойства - например, checked атрибут съответства на свойството defaultChecked , така че

  • Ръчното поставяне на отметка в квадратчето ще промени стойността на .prop('checked') , но няма да промени стойностите на .attr('checked') и .prop('defaultChecked')
  • задаването на $('#input').prop('defaultChecked', true) също ще промени .attr('checked') , но това няма да се вижда на елемента.

Правилото за палеца : методът .prop() трябва да се използва за логически атрибути / свойства и за свойства, които не съществуват в html (например, window.location). Всички други атрибути (които можете да видите в html) могат и трябва да продължат да бъдат манипулирани с помощта на .attr() . ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

И тук е таблица, показваща къде се предпочита .prop() (въпреки че .attr() все още може да се използва).

2019

26
12 июня '15 в 8:56 2015-06-12 08:56 отговор е даден от lakesare 12 юни '15 в 8:56 2015-06-12 08:56

.attr() :

  • Получете стойност на атрибута за първия елемент в набора от съвпадащи елементи.
  • Дава ви стойността на елемента, както е дефиниран в html на зареждането на страницата.

.prop() :

  • Получете стойност на имота за първия елемент в набора от съвпадащи елементи.
  • Дава актуализирани стойности на елементи, които са модифицирани с помощта на javascript / jquery
18
08 дек. Отговорът е даден Kgn-web 08 dec. 2015-12-08 12:14 '15 в 12:14 2015-12-08 12:14

Обикновено искате да използвате свойства. Използвайте атрибути само за:

  • Получаване на персонализиран атрибут HTML (защото той не е синхронизиран с DOM собствеността).
  • Получаване на HTML атрибут, който не се синхронизира със свойството DOM, например. получавате "оригиналната стойност" на стандартния HTML атрибут, например <input value="abc">.
13
02 февр. отговорът е даден naor 02 Feb. 2014-02-02 23:36 '14 в 23:36 ч. 2014-02-02 23:36

attributes → HTML

properties → DOM

7
26 дек. Отговорът е даден NkS 26 декември. 2014-12-26 16:28 '14 в 16:28 2014-12-26 16:28

Преди jQuery 1.6, методът attr() понякога взема предвид стойностите на свойствата при извличане на атрибути, което води до противоречиво поведение.

Въвеждането на метода prop() осигурява начин за извличане на стойности на свойства, докато .attr() извлича атрибути.

документи:

jQuery.attr() Вземете стойността на атрибута за първия елемент в набора от съвпадащи елементи.

jQuery.prop() Вземете стойността на свойството за първия елемент в съвкупността от съвпадащи елементи.

6
25 окт. отговор, даден от Gothburz на 25 октомври. 2015-10-25 03:05 '15 в 3:05 2015-10-25 03:05

Внимателно ни напомнете за използването на prop() , например:

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

Горната функция се използва за проверка на квадратчето за отметка1 или не, ако е отметнато: return 1; if not: return 0. Функция prop() используется здесь как функция GET.

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