.prop() vs .attr() в jQuery: пошаговый разбор с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему эта тема так важна?

Если вы когда-нибудь писали на jQuery код, который должен был получить или установить значение атрибута у HTML-элемента, вы наверняка сталкивались с двумя методами: .prop() и .attr(). На первый взгляд они делают одно и то же. Но на практике разница между ними — это источник сотен багов и тысяч вопросов на Stack Overflow.

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

Эта статья — не сухая документация. Это ваш личный гид по одной из самых запутанных тем в jQuery.

Коротко: атрибуты vs свойства

Прежде чем нырять в код, давайте разберемся с теорией. В DOM (Document Object Model) есть два понятия:

  • Атрибут (attribute) — то, что написано в HTML-коде. Например, <input type="checkbox" checked="checked">. Атрибуты всегда строки.
  • Свойство (property) — то, что хранится в объекте DOM-элемента после того, как браузер прочитал HTML. Свойства могут быть любого типа данных: строка, булево, число, объект.

Метод .attr() работает с атрибутами. Метод .prop() — со свойствами. Звучит просто? Да, но есть нюансы.

Главная ловушка: булевы атрибуты

Самый популярный пример, который ломает голову новичкам — это чекбоксы, радио-кнопки и другие элементы с булевыми атрибутами (checked, disabled, selected, readonly).

Представьте, что у вас есть такой HTML:

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

Вы хотите проверить, отмечен ли чекбокс. Логично написать так:

console.log( $('#myCheckbox').attr('checked') ); // "checked" (строка!)
console.log( $('#myCheckbox').prop('checked') ); // true (булево!)

Вот она, разница! .attr() возвращает строку "checked", если атрибут есть в HTML, и undefined, если его нет. А .prop() возвращает true или false, в зависимости от текущего состояния элемента в DOM.

Теперь самое интересное: что будет, если пользователь снимет галочку?

// После того, как пользователь снял галочку:
console.log( $('#myCheckbox').attr('checked') ); // "checked"! (HTML не изменился)
console.log( $('#myCheckbox').prop('checked') ); // false (состояние изменилось)

Вот почему использовать .attr() для проверки состояния чекбокса — это ошибка. Атрибут checked в HTML остаётся неизменным, а свойство checked в DOM меняется динамически. .prop() всегда даёт актуальный ответ.

Правило большого пальца

Есть простое правило, которое поможет вам не ошибаться:

  • Используйте .prop(), когда вам нужно получить или изменить динамическое состояние элемента (например, checked, disabled, selected, value у input).
  • Используйте .attr(), когда вам нужно прочитать или изменить статический атрибут из HTML (например, href, src, data-*, id, class).

Запомните: .prop() — для свойств, которые меняются в процессе работы. .attr() — для атрибутов, которые заданы в разметке.

Пошаговый пример: работа с disabled

Давайте разберем ещё один классический случай — кнопку с атрибутом disabled.

<button id="myButton" disabled>Нажми меня</button>

Попробуем проверить, активна ли кнопка:

console.log( $('#myButton').attr('disabled') ); // "disabled" (строка)
console.log( $('#myButton').prop('disabled') ); // true (булево)

Теперь представьте, что мы хотим сделать кнопку активной. Как это сделать правильно?

// Неправильно (не сработает):
$('#myButton').attr('disabled', false); // Удалит атрибут, но не всегда корректно

// Правильно:
$('#myButton').prop('disabled', false); // Меняет свойство, кнопка становится активной

Почему .attr('disabled', false) может не сработать? Потому что браузер видит атрибут disabled — и всё, кнопка disabled. Даже если вы установите атрибут в false, сам факт наличия атрибута делает элемент неактивным. А .prop() меняет свойство, и браузер реагирует корректно.

Когда .attr() всё ещё нужен?

Не думайте, что .prop() — это универсальная замена. Есть задачи, где без .attr() не обойтись.

  • Чтение кастомных атрибутов data-*. Хотя для этого лучше использовать метод .data(), но если вам нужно получить именно строковое значение атрибута (не преобразованное jQuery), .attr() — ваш выбор.
  • Атрибуты, которые не имеют соответствующего свойства. Например, colspan у таблицы или rowspan.
  • Работа с SVG-элементами. В некоторых версиях jQuery .prop() может работать некорректно с SVG, и .attr() является более безопасным вариантом.

Вот пример с data- атрибутом:

<div id="myDiv" data-user-id="12345">Привет, пользователь!</div>
console.log( $('#myDiv').attr('data-user-id') ); // "12345" (строка)
console.log( $('#myDiv').data('userId') );       // 12345 (число, если возможно)

Как видите, .data() пытается преобразовать тип, а .attr() возвращает чистую строку. Выбор зависит от задачи.

Ещё один важный пример: value у input

С атрибутом value тоже есть пу

Блоги

Рекомендаций по книгам