.prop () vs .attr ()


2297

Тож 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?

ОНОВЛЕННЯ

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>

(див. також цю загадку: http://jsfiddle.net/maniator/JpUF2/ )

Консоль записує getAttributeяк рядок, так і attrяк рядок, але propяк a CSSStyleDeclaration, чому? І як це впливає на моє кодування в майбутньому?


17
Це буде представляти певний інтерес: books.google.ca/…

28
@Neal, це тому, що ця зміна перевершує jQuery. Різниця між атрибутами HTML та властивостями DOM є величезною.

7
Мене сумно бачити, що зміни jQuery повернули зміни. Вони прямують у неправильному напрямку.

4
@Neal. Так, і це просто ускладнює проблему далі, ніж розділяти два методи.

6
@BritishDeveloper відповідь складніша, ніж просто зазначити, що завжди використовуйте x або y, оскільки це залежить від того, що ви маєте намір отримати. Ви хочете атрибут, або ви хочете властивість? це дві дуже різні речі.
Кевін Б

Відповіді:


1874

Оновлення 1 листопада 2012 року

Моя оригінальна відповідь стосується спеціально jQuery 1.6. Моя порада залишається такою ж, але jQuery 1.6.1 дещо змінив речі: перед обличчям передбачуваної кулі зламаних веб-сайтів команда jQuery повернулася attr()до чогось близького (але не зовсім такому, як) його старої поведінки щодо булевих атрибутів . Джон Ресіг також блогував про це . Я бачу труднощі, з якими вони стикалися, але все ще не згоден з його рекомендацією віддати перевагу 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 . Документація DOM на Mozilla є дійсною для більшості сучасних браузерів і її легше читати, ніж специфікації, тому їхній довідник 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/ .

2
@TJCrowder, тоді які?
Naftali aka Neal

9
@Neal: Якщо ви хочете знати , що є властивості DOM елементів і яким чином атрибути можуть посіяти їх цінності, ці посилання на руку: DOM2 специфікації HTML , в DOM2 специфікації і DOM3 специфікації. Індекси в кожному випадку є чудовими і посилають вас на ретельний опис об'єкта нерухомості, звідки походить його вартість тощо.
TJ Crowder

4
@Neal: Перегляньте, чим вона відрізняється: джерело та характер інформації. valueНаприклад, подивіться на приклад Тіма . Функція, яка називається, attrяка отримує властивість, value а не атрибут "value", не має великого сенсу (і вони можуть бути різними). Якщо рухатися вперед, attrробити атрибути та propробити властивості буде зрозуміліше, хоча перехід для деяких буде болючим. Не сприймайте це неправильно, немає нічого, як відступити назад та прочитати характеристики, щоб зрозуміти, що таке властивості.
TJ Crowder

54
@Neal: Елемент DOM - це об'єкт. Властивості - це властивості цього об'єкта, як і будь-який інший об'єкт програмування. Деякі з цих реквізитів отримують свої початкові значення з атрибутів у розмітці, які також зберігаються на об'єкті DOM в окремій карті атрибутів. У більшості випадків запис на опору змінює лише опору, хоча, на жаль, є деякі реквізити, які записують будь-які зміни до базового attr ( valueнаприклад), але спробуємо в основному це ігнорувати. 99% часу ви хочете працювати з реквізитом. Якщо вам потрібно працювати з фактичним атрибутом, ви, ймовірно, це знаєте.
TJ Crowder

4
@Tim: "Зміна valueвластивості вводу не змінює його valueатрибут у сучасних браузерах" Я не думав, що це сталося, саме тому я почав використовувати його як приклад, але коли я почав кодувати приклад, занурився якщо він не оновлювався на Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Виявляється, це тому, що я використовував input[type="button"]для свого експерименту. Він не оновлює атрибут на input[type="text"]- jsbin.com/ahire4/2 Поговори про згорнуте !! Не просто елемент, а його тип ...
TJ Crowder

664

Я думаю, що Тім сказав це досить добре , але давайте відступимо:

Елемент DOM - це об'єкт, річ у пам'яті. Як і більшість об'єктів в OOP, він має властивості . Окремо він також має карту атрибутів, визначених на елементі (як правило, виходячи з розмітки, яку читав браузер для створення елемента). Деякі властивості елемента отримують свої початкові значення з атрибутів з однаковими або подібними іменами ( valueотримує початкове значення з атрибута "value"; hrefотримує своє початкове значення з атрибута "href", але це не зовсім те саме значення; classNameвід атрибут "class"). Інші властивості отримують свої початкові значення іншими способами: Наприклад, 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: "перевірити один" |
| атрибути: |
| href: "foo.html" |
| ім'я: "fooAnchor" |
| id: "fooAnchor" |
| клас: "тест один" |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− + +

Зауважте, що властивості та атрибути відрізняються.

Тепер, хоча вони є різними, оскільки все це розвивалося, а не проектувалося з нуля, ряд властивостей списується до атрибуту, який вони отримали, якщо ви їх встановили. Але це не все, і як видно hrefзверху, картографування не завжди є прямим «передати значення далі», іноді тут береться інтерпретація.

Коли я говорю про властивості, що є властивостями об'єкта, я не кажу абстрактно. Ось код, який не jQuery:

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мав на меті знищити їх. Коротко в v1.6.0 JQuery зайшов занадто далеко в цьому відношенні, але функціональність швидко додає назад в attrобробляти загальні ситуації , коли люди використовують , attrколи технічно вони повинні використовувати prop.


Ого. що нове оновлення 1.6.1 дійсно зводить нанівець це питання .. (але не дуже), але це посилання в основному відповідає на нього зараз
Naftali aka Neal

Це не зводило нанівець це для мене, я просто виправив помилку за допомогою jquery1.7, де я встановлював .attr ('class', 'bla'), і він не працював, де .prop ('className', 'bla' ) працював
PandaWood

@PandaWood: .attr('class', 'bla')працює як очікується для мене в 1.7.0 , 1.7.1 та 1.7.2 на Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 та Safari 5.
TJ Crowder

Дякую, у моєму випадку має бути щось конкретне, дозвольте мені перевірити це та повернусь із тестовим кейсом. Але змінивши код, як ми його маємо зараз, просто "prop / className", замість "attr" виправляє для нас масову помилку, яка потрапила, коли ми перейшли з jquery1.4 до 1.7 - у всіх браузерах
PandaWood

3
@TJCrowder re: .data- він прочитає значення за замовчуванням атрибута, якщо він присутній, але якщо ви запишете його, він змінить приховане властивість елемента, а не оновить атрибут.
Альнітак

250

Ця зміна вже давно приходить до jQuery. Протягом багатьох років вони задовольнялися функцією, названою в attr()основному, отриманими властивостями DOM, а не результатом, якого б ви очікували від цього імені. Сегрегація attr()та prop()повинна допомогти полегшити деяку плутанину між атрибутами HTML та властивостями DOM. $.fn.prop()захоплює вказане властивість DOM, а $.fn.attr()захоплює вказаний атрибут HTML.

Щоб повністю зрозуміти, як вони працюють, ось розширене пояснення різниці між атрибутами HTML та властивостями DOM.

Атрибути HTML

Синтаксис:

<body onload="foo()">

Мета: Дозволяє розмітці мати пов'язані з нею дані для подій, візуалізації та інших цілей.

Візуалізація: Атрибути HTML атрибут класу показаний тут на тілі. Доступ до нього здійснюється за допомогою наступного коду:

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

Атрибути повертаються в рядковій формі і можуть бути невідповідними від браузера до браузера. Однак вони можуть бути життєво важливими в деяких ситуаціях. Як показано вище, режим IE 8 Quirks (і нижче) очікує назви DOM властивості в get / set / removeAttribute замість імені атрибута. Це одна з багатьох причин, чому важливо знати різницю.

Властивості DOM

Синтаксис:

document.body.onload = foo;

Призначення: надає доступ до властивостей, що належать до вузлів елементів. Ці властивості схожі на атрибути, але доступні лише через JavaScript. Це важлива відмінність, яка допомагає уточнити роль властивостей DOM. Зверніть увагу, що атрибути абсолютно відрізняються від властивостей , оскільки це призначення обробника подій марно і не отримає подію (тіло не має події завантаження, а лише атрибут onload).

Візуалізація: Властивості DOM

Тут ви помітите список властивостей на вкладці "DOM" у Firebug. Це властивості DOM. Ви відразу помітите досить багато з них, так як ви раніше ними користувалися, не знаючи про це. Їх значення - це те, що ви отримуватимете через JavaScript.

Документація

Приклад

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

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

У попередніх версіях jQuery це повертає порожню рядок. В 1.6, вона повертає правильне значення, foo.

Не дивлячись на новий код для будь-якої функції, я можу впевнено сказати, що плутанина більше пов'язана з різницею між атрибутами HTML та властивостями DOM, ніж із самим кодом. Сподіваємось, це очистило деякі речі для вас.

-Матт


7
$.prop()отримує властивості DOM, $.attr()отримує атрибути HTML. Я намагаюся подолати розрив психологічно, щоб ви могли зрозуміти різницю між ними.

10
Хлопчик, я і зараз розгублений. Так $('#test').prop('value')нічого не повертає? Ні .attr('checked')для прапорця? Але це раніше? Тепер вам доведеться змінити це prop('checked')? Я не розумію необхідності цього розрізнення - чому важливо розрізняти атрибути HTML та властивості DOM? Що є загальним випадком використання, який зробив цю зміну "надовго" ? Що не так з обмеженням розрізнення між ними, оскільки, здається, випадки їх використання здебільшого збігаються?
BlueRaja - Danny Pflughoeft

5
@BlueRaja: тому що між цими двома поняттями є серйозна основна різниця, яка, якщо ви чистите її під килимом, як раніше jQuery, призводить до несподіваних збоїв. valueє одним із найбільш очевидних випадків, оскільки valueвластивість дасть вам поточне значення поля, але valueатрибут дасть вам початкове значення, яке було оголошено в value="..."атрибуті, яке є власне defaultValueвластивістю. (Хоча цей конкретний випадок знову плутається з помилками в IE <9.)
bobince

4
@BlueRaja: Відповідь на це ще складніша. :-) Встановлення attr('value', ...)в jQuery <1.6 встановлює властивість, тому поточне значення змінюється, а значення за замовчуванням не відповідає. У 1.6 він встановлює атрибут, тому теоретично значення за замовчуванням змінюється, а поточне значення - ні. Однак існують (більше) невідповідності веб-переглядача щодо того, що саме valueробить цей атрибут. У IE він також встановлює поточне значення; у деяких браузерах воно встановлює лише поточне значення, якщо поточне значення раніше не було встановлено. [крики]
bobince

1
Так само, як сказав @Quentin, "Атрибути визначаються HTML. Властивості визначаються DOM". Найпростіша версія, яку я прочитав.
Алан Донг

240

Власність знаходиться в DOM; атрибут знаходиться в HTML, який розбирається в DOM.

Подальша деталізація

Якщо ви зміните атрибут, зміна відобразиться в DOM (іноді з іншим іменем).

Приклад: Зміна classатрибута тегу змінить classNameвластивість цього тегу в DOM. Якщо у вас немає атрибута тегу, у вас все ще є відповідне властивість DOM з порожнім або значенням за замовчуванням.

Приклад: Хоча ваш тег не має classатрибута, властивість DOM classNameіснує зі значенням порожнього рядка.

редагувати

Якщо ви зміните одну, іншу змінить контролер, і навпаки. Цей контролер знаходиться не в jQuery, а в рідному коді браузера.


Так це означає, що краще оновити атрибут, оскільки тоді ви гарантуєте, що атрибут та властивість оновлюються та вирівнюються?
Лука

1
@Luke DOM - це внутрішнє технічне представлення, модель. Атрибути HTML - це зовнішнє представлення, вид. Якщо ви зміните одну, іншу змінить контролер, і навпаки.
юнзен

@HerrSerker Отже, обидва вони синхронізуються через контролер? Я припускаю, що це лише в методах attr і prop jQuery? Ось модифікація вашої загадки, де я вивчаю це більше - jsfiddle.net/v8wRy - і поки вони здаються рівнозначними.
Лука

3
"Якщо ви зміните один, інший буде змінено контролером, і навпаки. Цей контролер знаходиться не в jQuery, а в рідному коді браузера." Це не стосується більшості атрибутів / властивостей. Для більшості це лише односторонній переклад, де атрибут визначає початкове значення відповідного властивості. Два найкращих відповіді пояснюють це докладно.
ᴠɪɴᴄᴇɴᴛ

@Vincent. Я не бачу, де два найкращих відповіді говорять про щось, що суперечить моїй відповіді. Звичайно, більшість атрибутів є початковими значеннями відповідних властивостей DOM. Але вони взаємозалежні. Спробуйте щось на зразок jQuery('p').prop('className', 'foo');консолі Chrome, і ви побачите, як кожен абзац отримує classатрибут thg 'foo'. Звичайно, не у вихідному коді, який надходить із сервера. Це константа.
юнзен

140

Саме розмежування між атрибутами HTML і об'єктами DOM викликає плутанину. Для тих, хто комфортно діє на елементи DOM, рідні властивості, такі this.src this.value this.checkedтощо, .prop- це дуже теплий прийом для родини. Для інших це лише додатковий шар плутанини. Розберемо це.

Найпростіший спосіб побачити різницю між собою .attrта .propнаступний приклад:

<input blah="hello">
  1. $('input').attr('blah'): повертається 'hello'як очікувалося. Тут немає сюрпризів.
  2. $('input').prop('blah'): return undefined- тому що це намагається зробити [HTMLInputElement].blah- і такої властивості на цьому об'єкті DOM не існує. Він існує лише в області застосування як атрибут цього елемента, тобто[HTMLInputElement].getAttribute('blah')

Тепер ми змінюємо кілька речей на кшталт цього:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): повертає, 'apple'а? Чому б не "груша", як це було встановлено останнім на цьому елементі. Оскільки властивість було змінено на вхідному атрибуті, а не на самому вхідному елементі DOM - вони в основному майже працюють незалежно один від одного.
  2. $('input').prop('blah'): повертає 'pear'

Те, що вам дійсно потрібно бути обережним, - це лише не змішувати використання цих даних для однієї і тієї ж власності у вашій заявці з вищезазначеної причини.

Дивіться скрипку, яка демонструє різницю: http://jsfiddle.net/garreh/uLQXc/


.attrvs .prop:

1 раунд: стиль

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


@Neal, тим не менш, він краще посилається на структуру функцій jquery. "$ ('input'). prop ('blah'): повертається невизначено - тому що він намагається зробити [HTMLInputElement] .blah - і такого властивості для цього об'єкта DOM не існує. Він існує лише в області застосування як атрибут цього елемента, тобто [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan

2
Здається, відрізняється від doc, api.jquery.com/prop : "Метод .prop () слід використовувати для встановлення вимкнених і перевірених замість методу .attr (). Метод .val () слід використовувати для отримання та значення налаштування. "
лебідь

53

TL; DR

Використання prop()більш attr()в більшості випадків.

Властивість представляє поточний стан вхідного елемента. Атрибут є значенням за замовчуванням.

Властивість може містити речі різного типу. Атрибут може містити лише рядки


1
якщо можливо, прийти з кількома простими зразками того, що говорить ур, а також показати, коли його використовувати prop() and when to go for attr(). чекаю на відповідь :)
Mou

36

Брудна перевіреність

Ця концепція дає приклад, коли різницю можна помітити: http://www.w3.org/TR/html5/forms.html#concept-input-cont-dirty

Спробуй:

  • натисніть кнопку. Обидва прапорці встановлені.
  • зніміть прапорці обох прапорців.
  • натисніть кнопку ще раз. propПеревірено лише прапорець. БАНГ!

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

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

Відключений атрибут IDL повинен відображати відключений атрибут вмісту.

тож ви можете піти з ним, хоча це некрасиво, оскільки він без необхідності змінює HTML.

Для інших атрибутів , як checked="checked"на input type="checkbox", речі ламаються, тому що як тільки ви натиснете на неї, вона стає брудною, а потім додаючи або видаляючи checked="checked"атрибут вмісту НЕ тумблер checkedness більше .

Ось чому ви повинні використовувати в основному .prop, оскільки це впливає на ефективну властивість безпосередньо, а не покладатися на складні побічні ефекти зміни HTML.


Для повноти також спробуйте такі варіанти: 1) Перш ніж натиснути кнопку, встановіть прапорець, а потім зніміть прапорець біля першого пункту 2) (Для цього вам потрібно буде змінити фрагмент) Дайте першому вводу checkedатрибут:checked="checked"
ᴠɪɴᴄᴇɴᴛ

33

Все в документі :

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

Тому використовуйте опору!


2
Отже, це означає, що коли я перейду на 1.6, все багато зламається ??
Naftali aka Neal

Ні, це просто непослідовна поведінка, якщо вона працює раніше, вона завжди працюватиме з jQuery 1.6, це просто те, що підтримка безпечніша;)
Арно Ф.

6
Я наче пригадую. $.attr()отримання властивостей більшу частину часу я працював з ним, а не "іноді". Порозуміння, викликане ним, і досі резонує. На жаль, у мене виникають багато проблем з пошуком остаточного прочитання щодо атрибутів HTML проти властивостей DOM, тому я можу трохи написати тут відповідь.

3
@ Arnaud-f Неправда. Весь код, попередній до 1.6, який використовує attr ('прапорець') для встановлення прапорців, тепер буде порушений.
CaptSaltyJack

3
@Matt McDonald: Про яку саме "... проблему в пошуку остаточного зчитування атрибутів HTML проти властивостей DOM ..."? Властивості (відображені та інакше) описані в специфікації HTML DOM2 ; Ви також , можливо , буде потрібно звернутися до DOM2 і DOM3 специфікації.
TJ Crowder

28

атрибути знаходяться у вашому текстовому документі / файлі 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()не можна використовувати).

таблиця з бажаним використанням


Чому іноді ви хочете використовувати .prop () замість .attr (), де останні офіційно подаються?

  1. .prop()може повернути будь-який тип - рядок, цілий, булевий; при цьому .attr()завжди повертає рядок.
  2. .prop()як кажуть, приблизно в 2,5 рази швидше, ніж .attr().

що - щось змінилося, як ці: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')або $('#myTextBox').prop('type', 'button'). І так далі ...

@ Mr.Wolf, вибачте, я не розумію, що ви маєте на увазі. що "змінилося"? синтаксис завжди був таким.
озера

Я думаю, таблиця у вашій відповіді непотрібна. Тому що .prop()добре працює з усіма властивостями. Ви не хочете позначати всі властивості в .prop()стовпці, чи не так?

@ Mr.Wolf, я вважаю, що це потрібно, тому що, як уже було сказано, це "показує, куди .prop()краще (хоч .attr()ще можна використовувати)"
lakesare

Я зазвичай використовую .attr()для визначення події те, що .prop()не може. Як це: $('.myDiv').attr('onclick', 'alert("Hello world!")'). Якщо ви перейдете .attr()на .prop(), воно не працюватиме. В цілому, я думаю, немає підстав використовувати .attr()для встановлення або отримання значення id/class/href/checked/src...... Зауважте, що я не кажу, що ви помиляєтесь.

20

.attr():

  • Отримайте значення атрибута для першого елемента в наборі відповідних елементів.
  • Надає вам значення елемента, як було визначено в html при завантаженні сторінки

.prop():

  • Отримайте значення властивості першого елемента в наборі відповідних елементів.
  • Надає оновлені значення елементів, які змінюються через javascript / jquery

13

Зазвичай ви хочете використовувати властивості. Використовуйте атрибути лише для:

  1. Отримання спеціального атрибута HTML (оскільки він не синхронізований із властивістю DOM).
  2. Отримання атрибута HTML, який не синхронізується із властивістю DOM, наприклад, отримати "вихідне значення" стандартного атрибута HTML, наприклад <input value="abc">.

7

attributes -> HTML

properties -> DOM


8
Я знаю, що ви хочете сказати, але HTML - це мова розмітки, а DOM - представлення, створене з HTML. DOMElement має як атрибути, так і властивості .
t.niese

@ t.niese, attirbutesтакож одна з власністьDOM
NkS

Коротка відповідь проста.
Набі КАЗ

6

До jQuery 1.6 attr()метод іноді враховував значення властивостей під час отримання атрибутів, це спричиняло досить непослідовну поведінку.

Впровадження prop()методу забезпечує спосіб явного отримання значень властивостей, при цьому .attr()отримує атрибути.

Документи:

jQuery.attr() Отримайте значення атрибута для першого елемента в наборі відповідних елементів.

jQuery.prop() Отримайте значення властивості першого елемента в наборі відповідних елементів.


3

Акуратно нагадуйте про використання prop(), наприклад:

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

Функція, наведена вище, використовується для перевірки, чи встановлено прапорець1, чи ні, якщо встановлено: повернути 1; якщо ні: повернути 0. Функція prop (), що використовується тут як функція GET.

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

Функція, наведена вище, використовується для встановлення прапорця1, який потрібно перевіряти, і ЗАВЖДИ повертається 1. Тепер функція prop () використовується як функція SET.

Не плутайте.

P / S: Коли я перевіряю властивість Image src . Якщо src порожній, пропонуйте повернути поточну URL-адресу сторінки (неправильно), а attr повернути порожній рядок (праворуч).


Ви помиляєтеся в цьому прикладі: <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Він повинен працювати та повертати зображення.

2

Одна річ , яку .attr()можна зробити .prop()не може: вплинути на CSS селектори

Ось питання, якого я не бачив в інших відповідях.

CSS-селектор [name=value]

  • відповість на .attr('name', 'value')
  • але не завжди до .prop('name', 'value')

.prop() впливає лише на кілька селекторів атрибутів

.attr() впливає на всі селектори атрибутів


0

1) Власність знаходиться у DOM; атрибут знаходиться в HTML, який розбирається в DOM.

2) $ (елем.)

3) $ (elem) .attr ("встановлено") (до 1,6) вірно (булева) Змінено зі станом прапорця

  • В основному ми хочемо використовувати для об'єкта DOM, а не спеціальний атрибут на зразок data-img, data-xyz.

  • Крім того, деяка різниця при доступі до checkboxзначення, а href також attr()і prop()при зміні речі при виведенні DOM з prop()максимальним посиланням originта Booleanзначенням для прапорця (pre-1.6)

  • Ми можемо отримати доступ до елементів DOM лише з propіншими, ніж це даєundefined


0

Є ще кілька міркувань щодо prop () vs attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked та defaultSelected..etc слід отримати та встановити методом .prop (). Вони не мають відповідних атрибутів і є лише властивостями.

  • Для введення типу вставки

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • метод підтримки повертає булеве значення для перевіреного, вибраного, відключеного, readOnly..etc, а attr повертає заданий рядок. Таким чином, ви можете безпосередньо використовувати .prop ("зареєстрований"), якщо це стан.

  • .attr () викликає .prop () внутрішньо, тому метод .attr () буде дещо повільнішим, ніж доступ до них безпосередньо через .prop ().


-2

Відповідь Гері Хоула дуже актуальна для вирішення проблеми, якщо код написаний таким чином

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

Оскільки CSSStyleDeclarationоб'єкт повернення функції повернення , в наведеному браузері вище код не працює належним чином (тестується зIE8 with Chrome Frame Plugin в моєму випадку).

Таким чином змінюючи його на наступний код

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

вирішив проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.