.prop() vs .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

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 как CSSStyleDeclaration, почему? И как это повлияет на мою кодировку в будущем?

2004
задан Neal 03 мая '11 в 22:33
источник поделиться

17 ответов

Обновление 1 ноября 2012

Мой оригинальный ответ относится к jQuery 1.6. Мой совет остается тем же, но jQuery 1.6.1 немного изменил ситуацию: перед предсказанной кучей сломанных веб-сайтов команда jQuery вернула attr() к чему-то близкому (но не совсем так же), как и его прежнее поведение для логических атрибутов. Джон Ресиг также рассказал об этом. Я вижу трудности, с которыми они столкнулись, но все же не согласен с рекомендацией предпочесть attr().

Оригинальный ответ

Если вы только когда-либо использовали jQuery, а не DOM напрямую, это может быть запутанным изменением, хотя это, безусловно, концептуально улучшается. Не так хорошо для bazillions сайтов, использующих jQuery, которые сломаются в результате этого изменения.

Я кратко изложу основные проблемы:

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

Если вы разработчик jQuery и путаетесь в этом бизнесе по свойствам и атрибутам, вам нужно сделать шаг назад и немного узнать об этом, поскольку jQuery больше не пытается так сильно защитить вас от этого материала, Для авторитетного, но несколько сущего слова по этому вопросу есть спецификации: DOM4, HTML DOM, Уровень DOM 2, Уровень DOM 3. Документация DOM для Mozilla действительна для большинства современных браузеров и ее легче читать, чем спецификации, поэтому вы можете найти их раздел о свойствах элемента.

В качестве примера того, как свойства проще обрабатывать, чем атрибуты, рассмотрите флажок, который был первоначально проверен. Вот две возможные части допустимого HTML:

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

Итак, как вы узнаете, установлен ли флажок с помощью jQuery? Посмотрите на Stack Overflow, и вы обычно найдете следующие предложения:

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

На самом деле это самая простая вещь в мире, которая связана с checked Boolean свойством, которое существовало и работало безупречно в каждом главном браузере с возможностью просмотра с 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/.
1707
ответ дан Tim Down 04 мая '11 в 2:06
источник поделиться

Я думаю, Тим сказал это довольно хорошо, но пусть отступит:

Элемент DOM - это объект, предмет в памяти. Как и большинство объектов в ООП, у него есть свойства. Он также, отдельно, имеет карту атрибутов, определенных на элементе (обычно это происходит из разметки, которую браузер читает для создания элемента). Некоторые из свойств элемента получают свои начальные значения из атрибутов с одинаковыми или похожими именами (value получает свое начальное значение из атрибута "значение"; href получает свое начальное значение из атрибута "href", но это не совсем то же значение; className из атрибута "class" ). Другие свойства получают свои начальные значения другими способами: например, свойство parentNode получает свое значение, основанное на его родительском элементе; элемент всегда имеет свойство 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" |
| name:       "fooAnchor"                   |
| id:         "fooAnchor"                   |
| className:  "test one"                    |
| attributes:                               |
|    href:  "foo.html"                      |
|    name:  "fooAnchor"                     |
|    id:    "fooAnchor"                     |
|    class: "test one"                      |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

Обратите внимание, что свойства и атрибуты различны.

Теперь, хотя они различны, поскольку все это развивается, а не разрабатывается с нуля, ряд свойств записывается обратно в атрибут, из которого они получены, если вы их установили. Но не все это делают, и, как вы можете видеть из 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.

611
ответ дан T.J. Crowder 04 мая '11 в 17:27
источник поделиться

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

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

Атрибуты HTML

Синтаксис:

<body onload="foo()">

Цель: Позволяет разметке иметь связанные с ней данные для событий, рендеринга и других целей.

Визуализация: HTML Attributes Атрибут класса показан здесь на теле. Он доступен через следующий код:

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

Атрибуты возвращаются в виде строки и могут быть непоследовательными от браузера к браузеру. Однако они могут быть жизненно важными в некоторых ситуациях. Как показано выше, IE Quirks Mode (и ниже) ожидает имя свойства DOM в get/set/removeAttribute вместо имени атрибута. Это одна из многих причин, почему важно знать разницу.

Свойства DOM

Синтаксис:

document.body.onload = foo;

Цель: Предоставляет доступ к свойствам, которые принадлежат узлам элемента. Эти свойства похожи на атрибуты, но доступны только через JavaScript. Это важное различие, которое помогает выяснить роль свойств DOM. Обратите внимание, что атрибуты полностью отличаются от свойств, так как это назначение обработчика событий бесполезно и не получит событие (у тела нет события onload, только атрибута onload).

Визуализация: DOM Properties

Здесь вы увидите список свойств на вкладке "DOM" в Firebug. Это свойства DOM. Вы сразу заметите немало из них, поскольку вы будете использовать их раньше, не зная об этом. Их значения - это то, что вы будете получать через JavaScript.

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

Пример

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

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

В более ранних версиях jQuery это возвращает пустую строку. В 1.6 возвращается правильное значение, foo.

Не взглянув на новый код для любой функции, я могу с уверенностью сказать, что путаница больше связана с различием между атрибутами HTML и свойствами DOM, чем с самим кодом. Надеюсь, это прояснило вам кое-что.

Матф

230
ответ дан user1385191 03 мая '11 в 23:05
источник поделиться

Свойство находится в DOM; атрибут находится в HTML, который анализируется в DOM.

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

Если вы измените атрибут, это изменение будет отражено в DOM (иногда с другим именем).

Пример: изменение атрибута class тега изменит свойство className этого тега в DOM. Если у вас нет атрибута в теге, у вас все еще есть соответствующее свойство DOM с пустым или значением по умолчанию.

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

изменить

Если вы измените одно, другое будет изменено контроллером и наоборот. Этот контроллер не находится в jQuery, но в собственном коде браузера.

227
ответ дан HerrSerker 27 сент. '11 в 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:

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

<input style="font:arial;"/>
  • .attr('style') - возвращает встроенные стили для согласованного элемента i.e. "font:arial;"
  • .prop('style') - возвращает объект объявления стиля i.e. 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')

127
ответ дан Gary Green 19 мая '11 в 13:18
источник поделиться

TL; DR

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

Свойство - это текущее состояние элемента ввода. Атрибут - это значение по умолчанию.

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

43
ответ дан agjmills 16 июля '14 в 12:45
источник поделиться

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

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

Итак, используйте prop!

31
ответ дан Arnaud F. 03 мая '11 в 22:35
источник поделиться

грязная проверка - пример, где разница наблюдаемая.

Чтобы увидеть это, запустите следующий фрагмент и:

  • нажмите кнопку. Оба флажка были проверены.
  • снимите оба флажка.
  • снова нажмите кнопку. Установлен флажок prop. BANG!

$('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 on button, добавление или удаление атрибута content disabled="disabled" всегда переключает свойство (называемое атрибутом IDL в HTML5), потому что http://www.w3.org/TR/html5/forms.html#attr-fe-disabled говорит:

Отключенный атрибут IDL должен отражать атрибут отключенного контента.

чтобы вы могли уйти от него, хотя он уродлив, так как он изменяет HTML без необходимости.

Для других атрибутов, таких как checked="checked" на input type="checkbox", все ломается, потому что как только вы нажимаете на него, он становится грязным, а затем добавление или удаление атрибута checked="checked" content больше не отменяет проверочную проверку.

Вот почему вы должны использовать в основном .prop, поскольку он напрямую влияет на эффективное свойство, вместо того чтобы полагаться на сложные побочные эффекты.

31
ответ дан Ciro Santilli 包子露宪 六四事件 法轮功 06 июля '14 в 14:43
источник поделиться

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

table with preferred usage


Почему вы иногда хотите использовать .prop() вместо .attr(), где официально официально заявлено последнее?

  • .prop() может возвращать любой тип - string, integer, boolean; а .attr() всегда возвращает строку.
  • .prop() называется примерно в 2,5 раза быстрее, чем .attr().
25
ответ дан lakesare 12 июня '15 в 8:56
источник поделиться

.attr():

  • Получить значение атрибута для первого элемента в наборе согласованных элементов.
  • Дает вам значение элемента, как оно определено в html на загрузке страницы

.prop():

  • Получить значение свойства для первого элемента в наборе согласованных элементов.
  • Дает обновленные значения элементов, которые изменяются с помощью javascript/jquery
14
ответ дан Kgn-web 08 дек. '15 в 12:14
источник поделиться

Обычно вы хотите использовать свойства. Использовать атрибуты только для:

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

attributes → HTML

properties → DOM

6
ответ дан NkS 26 дек. '14 в 16:28
источник поделиться

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

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

Документы:

jQuery.attr() Получите значение атрибута для первого элемента в наборе согласованных элементов.

jQuery.prop() Получить значение свойства для первого элемента в наборе согласованных элементов.

6
ответ дан Peter.R3x 25 окт. '15 в 3:05
источник поделиться

Осторожно напоминайте об использовании prop(), например:

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

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

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

Вышеуказанная функция используется для установки checkbox1 для проверки и возврата ALWAY 1. Теперь функция prop() используется как функция SET.

Не испортите.

P/S: Когда я проверяю свойство src. Если src пуст, prop возвращает текущий URL-адрес страницы (неверно) и attr возвращает пустую строку (справа). p >

2
ответ дан user2657778 17 окт. '15 в 19:12
источник поделиться

jQuery 1.6 вводит функцию .prop() и разделяет атрибуты и свойства DOM, он поднял много вопросов о различии между функциями .attr и .prop.

см. ниже пример

<input id="demo" type="text" value="Kansagara" />

Теперь я изменил текст "Kansagara" на "Hitesh" в текстовом поле.

$("#demo").attr("value");   // returns Kansagara
$("#demo").prop("value");   // returns Hitesh

Теперь у вас есть идея, что это значит. Изменяется только свойство элементов, поскольку оно находится в DOM и динамическом. Но атрибут элементов находится в тексте HTML и не может быть изменен. В широком смысле свойство всегда представляет текущее состояние, в то время как атрибут (за исключением старых версий IE) представляет начальное состояние или предназначен для атрибутов html, поскольку они строго определены. атрибут ничего не сообщает о текущем состоянии.

для флажка (jquery 1.6 +)

<input id="check1" checked="checked" type="checkbox" />

.attr('checked') //returns  checked
.prop('checked') //returns  true
.is(':checked') //returns true

метод prop возвращает значение Boolean для отмеченного, выбранного, отключенного, readOnly..etc, в то время как attr возвращает определенную строку. Таким образом, вы можете напрямую использовать .prop('checked) в условии if.

.attr() вызывает .prop() внутри, поэтому метод .attr() будет немного медленнее, чем доступ к ним непосредственно через .prop().

Для jQuery 1.6+, prop будет использоваться в основном потому, что он прост и шире, чем attr. В большинстве старых проектов attr используется для получения текущей информации о состоянии элемента. Но теперь опора взяла эту работу, и атр будет заменен на prop.

Надежда, это помогает.

0
ответ дан Hitesh Kansagara 08 апр. '18 в 18:31
источник поделиться

1) Свойство находится в DOM; атрибут находится в HTML, который анализируется в DOM.

2) $(elem).attr( "checked" ) (1.6.1+) "checked" (String) Будет изменение с состоянием флажка

3) $(elem).attr( "checked" ) (pre-1.6) true (Boolean) Изменено с состоянием флажка

  • В основном мы хотим использовать для объекта DOM вместо пользовательского атрибута например data-img, data-xyz.

  • Также некоторые различия при доступе к значению checkbox и href с attr() и prop() по мере изменения вещи с выходом DOM с prop() в качестве полной ссылки из origin и Boolean значение для флажка (pre-1.6)

  • Мы можем получить доступ только к элементам DOM с помощью prop other, а затем undefined

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>prop demo</title>
  <style>
    p {
      margin: 20px 0 0;
    }
    b {
      color: blue;
    }
  </style>

</head>

<body>

  <input id="check1" type="checkbox" checked="checked">
  <label for="check1">Check me</label>
  <p></p>

  <script>
    $("input").change(function() {
      var $input = $(this);
      $("p").html(
        ".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
        ".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
        ".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
    }).change();
  </script>

</body>

</html>
0
ответ дан Parth Trivedi 18 дек. '15 в 12:28
источник поделиться

Ответ Gary Hole очень важен для решения проблемы, если код написан таким образом

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

Так как функция prop возвращает объект CSSStyleDeclaration, код выше не работает должным образом в каком-либо браузере (в моем случае тестируется с IE8 with Chrome Frame Plugin).

Таким образом, изменяя его на следующий код

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

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

-2
ответ дан zawhtut 15 окт. '15 в 11:38
источник поделиться

Другие вопросы по меткам