.prop () против .attr ()

2301

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

Нафтали ака Нил
источник
17
Это будет представлять определенный интерес: books.google.ca/…
28
@ Нил, это потому, что это изменение выходит за рамки jQuery. Разница между атрибутами HTML и свойствами DOM огромна.
7
Мне грустно видеть, что jQuery отменил изменения. Они движутся в неправильном направлении.
4
@Neal. Да, и это только усложняет проблему, а не разделяет два метода.
6
@BritishDeveloper ответ сложнее, чем просто указывать всегда использовать x или y, потому что это зависит от того, что вы намереваетесь получить. Вы хотите атрибут или недвижимость? это две очень разные вещи.
Кевин Б.

Ответы:

1876

Обновление 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 . Документация 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/ .
Тим Даун
источник
2
@TJCrowder, тогда какие?
Нафтали ака Нил
9
@Neal: Если вы хотите знать , что есть свойства DOM элементов и каким образом атрибуты могут посеять их ценности, эти ссылки на руку: DOM2 спецификации HTML , в DOM2 спецификации и DOM3 спецификации. Индексы в каждом случае превосходны и связывают вас прямо с подробным описанием объекта недвижимости, откуда берется его стоимость и т. Д.
TJ Crowder
4
@Neal: Re, что отличает это: источник и характер информации. Посмотрите на valueпример Тима , например. Вызываемая функция, attrкоторая извлекает свойство, value а не атрибут «значение», не имеет особого смысла (и они могут отличаться). Движение вперед, attrвыполнение атрибутов и propсоздание свойств будет более понятным, хотя для некоторых переход будет болезненным. Не поймите это неправильно, нет ничего лучше, чем вернуться назад и прочитать спецификации, чтобы понять, что это за свойства.
TJ Crowder
54
@Neal: элемент DOM - это объект. Свойства - это свойства этого объекта, как и любого другого объекта программирования. Некоторые из этих реквизитов получают свои начальные значения из атрибутов разметки, которые также хранятся в объекте DOM в отдельной карте атрибутов. В большинстве случаев запись в реквизит только меняет реквизит, хотя, к сожалению, есть некоторые реквизиты, которые записывают любые изменения в базовый атрибут ( 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 - это объект, вещь в памяти. Как и большинство объектов в ООП, у него есть свойства . Он также отдельно имеет карту атрибутов, определенных для элемента (обычно исходящих из разметки, которую браузер считал для создания элемента). Некоторые из свойств элемента получают свои начальные значения из атрибутов с такими же или похожими именами ( valueполучает его начальное значение из атрибута «value»; hrefполучает его начальное значение из атрибута «href», но это не совсем то же самое значение; classNameиз атрибут "класс"). Другие свойства получают свои начальные значения другими способами: например, 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" |
| имя: "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.

TJ Crowder
источник
Ух ты. это новое обновление 1.6.1 действительно сводит на нет этот вопрос ... (но не очень), но эта ссылка в основном отвечает на него сейчас
Нафтали, он же Нил,
Это не аннулировало его для меня, я просто исправил ошибку, используя 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 Mode (и ниже) ожидается имя свойства DOM в get / set / removeAttribute вместо имени атрибута. Это одна из многих причин, почему важно знать разницу.

DOM Properties

Синтаксис:

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, чем с самим кодом. Надеюсь, это прояснило некоторые вещи для вас.

Матф

K.Dᴀᴠɪs
источник
7
$.prop()получает свойства DOM, $.attr()получает атрибуты HTML. Я пытаюсь преодолеть этот разрыв психологически, чтобы вы могли понять разницу между ними.
10
Мальчик, я тоже растерялся. Так что $('#test').prop('value')ничего не возвращает? И не .attr('checked')для флажка? Но раньше? Теперь вам придется изменить это на prop('checked')? Я не понимаю необходимости этого различия - почему важно различать атрибуты HTML и свойства DOM? Каков общий вариант использования, который сделал это изменение "долгое время вперед" ? Что плохого в том, чтобы абстрагировать различие между этими двумя понятиями, так как их варианты использования в основном пересекаются?
BlueRaja - Дэнни Пфлюгофт
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». Простейшая версия, которую я прочитал.
Алан Донг
241

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

Дальнейшие детали

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

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

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

редактировать

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

yunzen
источник
Значит ли это, что лучше обновить атрибут, потому что тогда вы гарантируете, что атрибут и свойство будут обновлены и выровнены?
Люк
1
@ Luke DOM - это внутреннее техническое представление, модель. Атрибуты HTML - это внешнее представление, представление. Если вы измените один, другой будет изменен контроллером, и наоборот.
Юньзень
@HerrSerker То есть они оба синхронизируются через контроллер? Я предполагаю, что это только в методах attr и prop jQuery? Вот модификация вашей скрипки, где я исследую это подробнее - jsfiddle.net/v8wRy - и пока они кажутся эквивалентными.
Люк
3
«Если вы измените один, другой будет изменен контроллером, и наоборот. Этот контроллер не в jQuery, а в собственном коде браузера». Это не верно для большинства атрибутов / свойств. Для большинства это только односторонний перевод, где атрибут определяет начальное значение соответствующего свойства. Два верхних ответа объясняют это подробно.
ᴠɪɴᴄᴇɴᴛ
@Vincent. Я не вижу, где два верхних ответа говорят что-то, противоречащее моему ответу. Конечно, большинство атрибутов являются начальными значениями соответствующих свойств DOM. Но они взаимозависимы. Попробуйте что-то вроде jQuery('p').prop('className', 'foo');консоли Chrome, и вы увидите, как каждый абзац получает classатрибут thg 'foo'. Конечно, нет в исходном коде, который приходит с сервера. Это константа.
yunzen
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'): возвращает 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/


.attrпротив .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') "
Угур Гюмюшан
2
Отличается от doc, api.jquery.com/prop : «Метод .prop () должен использоваться, чтобы установить отключенный и проверенный вместо метода .attr (). Метод .val () должен использоваться для получения и значение настройки. "
лебедь
53

TL; DR

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

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

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

agjmills
источник
1
если возможно, предоставьте несколько простых примеров того, что вы говорите, а также покажите, когда использовать prop() and when to go for attr(). жду ответа :)
Mou
36

Грязная проверка

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

Попробуйте это:

  • нажмите на кнопку. Оба флажка были проверены.
  • снимите оба флажка.
  • нажмите кнопку еще раз. Только 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>

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

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

так что вам может это сойти с рук, хотя это уродливо, поскольку он без необходимости модифицирует HTML.

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

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

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
Для полноты также попробуйте следующие варианты: 1) Перед нажатием кнопки установите флажок, а затем снимите первый флажок. 2) (Для этого вам потребуется изменить фрагмент). Присвойте первому входному checkedатрибуту атрибут:checked="checked"
ᴠɪɴᴄᴇɴᴛ
33

Все в док :

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

Так что используйте опору!

Арно Ф.
источник
2
Так что это значит, когда я переключаюсь на 1.6, многие вещи сломаются?
Нафтали ака Нил
Нет, это просто противоречивое поведение, если оно работает раньше, оно всегда будет работать с jQuery 1.6, просто опора безопаснее;)
Арно Ф.
6
Кажется, я помню. $.attr()восстанавливая свойства большую часть времени я работал с ним, а не «иногда». Путаница, вызванная этим, все еще резонансна сегодня. К сожалению, у меня много проблем с поиском окончательного прочтения атрибутов HTML и свойств DOM, поэтому я мог бы написать здесь ответ немного.
3
@ Арно-ф Не правда. Весь код, предшествующий 1.6, который использует attr ('флажок') для проверки флажков, теперь будет сломан.
CaptSaltyJack
3
@Matt McDonald: Что ты имеешь в виду под «... проблемой при поиске окончательного прочтения атрибутов HTML и свойств DOM ...»? Свойства (отраженные и иные) описаны в спецификации HTML DOM2 ; Вам также может понадобиться обратиться к спецификациям DOM2 и DOM3 .
TJ Crowder
28

атрибуты находятся в вашем текстовом документе / файле HTML (== представьте, что это результат анализа вашей разметки html), тогда как
свойства находятся в дереве DOM HTML (== в основном это фактическое свойство некоторого объекта в смысле 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()может вернуть любой тип - string, integer, boolean; while .attr()всегда возвращает строку.
  2. .prop()Говорят, что примерно в 2,5 раза быстрее, чем .attr().
lakesare
источник
что - то изменилось, как эти: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')или $('#myTextBox').prop('type', 'button'). И так далее ...
@ Мистер Волк, извини, я не понимаю, что ты имеешь в виду. что изменилось'? синтаксис всегда был таким.
Озеро
Я думаю, что таблица в вашем ответе не нужна. Потому что .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.
Kgn-веб
источник
13

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

  1. Получение пользовательского атрибута HTML (поскольку он не синхронизируется со свойством DOM).
  2. Получение атрибута HTML, который не синхронизируется со свойством DOM, например, получение «исходного значения» стандартного атрибута HTML, например <input value="abc">.
Наор
источник
7

attributes -> HTML

properties -> ДОМ

НКС
источник
8
Я знаю, что вы хотите сказать, но HTML - это язык разметки, а DOM - представление, созданное из HTML. DOMElement имеет как атрибуты, так и свойства .
t.niese
@ t.niese, attirbutesтакже одна из собственностиDOM
NkS
Краткий ответ прост.
Наби КАЗ
6

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

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

Документы:

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

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

Gothburz
источник
3

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

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

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

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

Вышеприведенная функция используется для установки флажка 1 для проверки и ВСЕГДА возврата 1. Теперь функция prop () используется в качестве функции SET.

Не путайся

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

user2657778
источник
Вы не правы в этом примере <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) $ (elem) .attr ("флажок") (1.6.1+) "флажок" (строка) будет меняться в зависимости от состояния флажка

3) $ (elem) .attr ("флажок") (до версии 1.6) true (булево) Изменено с состоянием флажка

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

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

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

Парт Триведи
источник
0

Есть еще несколько соображений в prop () против attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked и defaultSelected..etc должны быть получены и установлены с помощью метода .prop (). Они не имеют соответствующих атрибутов и являются только свойствами.

  • Для типа ввода флажок

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • Метод prop возвращает логическое значение для check, selected, disabled, readOnly..etc, а attr возвращает определенную строку. Таким образом, вы можете напрямую использовать .prop ('флажок') в условии if.

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

Ришу Ранджан
источник
-2

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

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

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

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

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

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

zawhtut
источник