Разработайте причину взаимосвязи между свойством элемента и его соответствующим атрибутом
Я озадачен причиной того, как работает связь между некоторым property
элемента DOM и его соответствующими attributes
.
Ниже приведен график из jquery in action 2015 Bear Bibeault
книги jquery in action 2015 Bear Bibeault
, показывающий взаимосвязь между property
и attribute
элемента DOM.
Чтобы дополнительно объяснить концепцию, у автора был следующий код и пояснения для кода.
Мой вопрос: почему некоторые property
и attribute
синхронизируются, почему некоторые из них не синхронизированы и почему некоторые attributes
не имеют соответствующего property
?
Я нашел отличный пост, объясняющий взаимосвязь между property
и attribute
, но он не касался того, почему он был разработан таким образом. Я надеюсь понять причины, лежащие в основе дизайна.
Связанный вопрос, если я хочу получить или установить значение в элементе DOM, должен ли я получить/установить property
или attribute
?
И как мы находим связь между конкретным property
и его соответствующим attribute
когда нам нужно? Есть ли документация, в которой подробно описываются отношения?
Ответы
Ответ 1
Вы найдете ответы, скрытые в HTML-спецификациях. Сначала я хочу, чтобы вы взглянули на атрибуты и свойства элемента input
(заголовок "Атрибуты контента" и "Интерфейс DOM") и раздел об отражении атрибутов (первый абзац).
Вы заметите, что все атрибуты имеют соответствующие свойства, а управление свойством изменяет атрибут, который он отражает. Стоит отметить, что:
(1) Атрибут может отражаться на свойстве с немного другим именем. Классическим примером является class
атрибут, который отражается от className
собственности и for
атрибута, который отражается от htmlFor
собственности.
(2) Аналогично, checked
атрибут отражается свойством defaultChecked
тогда как checked
свойство представляет внутреннее состояние флажка независимо от checked
атрибута. Это всегда вызывало путаницу среди программистов (и авторов книг). Разница объясняется в конце этого ответа.
(3) Приведенные атрибуты (например, атрибут "книга" в вашем примере) не будут создавать соответствующее свойство и наоборот. С этой целью спецификации HTML описывают механизм, называемый атрибутами dataset
свойством dataset
.
Связанный вопрос, если я хочу получить или установить значение в элементе DOM, должен ли я получить/установить property
или attribute
?
Зависит. Например, оба следующих результата дают идентичный результат и HTML:
document.getElementById("div-1").title = "Hello";
document.getElementById("div-1").setAttribute("title") = "Hello";
Однако для элементов формы вы должны манипулировать состоянием, а не атрибутом. Предположим, у вас есть эта разметка HTML:
<input type="checkbox" id="checkbox-1">
И вы выполните одно из следующих действий:
document.getElementById("checkbox-1").defaultChecked = true;
document.getElementById("checkbox-1").setAttribute("checked", "checked");
И вот результат:
<input type="checkbox" id="checkbox-1" checked="checked">
Но проверяется, действительно ли флажок установлен, зависит от загрязненности элемента управления (т.е. Если его состояние было изменено в какой-то момент). Для элементов формы вы обычно управляете свойствами, соответствующими внутреннему состоянию:
document.getElementById("checkbox-1").checked = true;
Ответ 2
DOM - это то, что в значительной степени выросло "естественно". Вы должны учитывать, что HTML (значение: атрибуты) на первом месте, и первоначально не было никаких скриптов. В конце концов, Netscape представил JavaScript с тем, что вы считаете крайне ограниченным API сегодня. Этот API был направлен на манипулирование формами, а не на произвольные HTML-элементы. И затем Netscape и Internet Explorer вышли с различными вариантами того, что они называли DHTML, тогда (Dynamic HTML). Вариант Netscape опирался на специальный <layer>
и никто его не помнит сегодня. Вариант Internet Explorer допускал более общий доступ к элементам HTML и, в частности, имел отображение свойств атрибутов 1:1.
Хотя Internet Explorer выиграл эту войну, ее вариант DHTML был разработан, когда люди думали об именах атрибутов HTML как фиксированной коллекции. С произвольными атрибутами у него было слишком много проблем. Например:
- Атрибут
class
не может быть сопоставлен с JavaScript изначально, потому что class
является зарезервированным ключевым словом. Хотя последующие изменения в стандарте JavaScript допускали использование зарезервированных ключевых слов в качестве имен свойств, Internet Explorer должен сопоставить атрибут class
с свойством className
. Установка атрибута className
для элемента или свойства el["class"]
на объекте JavaScript приводила к смешным несоответствиям. - Атрибуты HTML не чувствительны к регистру, а свойства JavaScript чувствительны к регистру. Таким образом, у Internet Explorer были всевозможные хаки, чтобы признать намерение. Что произошло, когда элемент был
<FOO SOMEATTIRIBUTE>
и вы пытались получить доступ к el.someAttribute
или el.SOMEATTRIBUTE
из JavaScript? Я больше не помню, но это было некрасиво. - Объекты JavaScript всегда имеют методы. Например, атрибут
toString
не может быть сопоставлен с свойством, поскольку он маскирует метод toString()
.
Ни один браузер, кроме Internet Explorer, никогда не реализовал это сопоставление атрибутов свойствам 1:1, и даже Internet Explorer отказался от него, как только это было возможно с точки зрения обратной совместимости (это заняло очень много времени). Вместо этого атрибуты и свойства теперь рассматриваются как отдельные пространства имен. Браузеры предоставят вам некоторые свойства в качестве ярлыков для доступа к атрибутам и манипуляций, но они действительно доступны только для вашего удобства. И есть некоторые обратные случаи совместимости, загрязняющие воды: атрибут value
и атрибут value
фактически не сопоставляются друг с другом, первый отражает текущее состояние элемента, тогда как последнее отражает его начальное состояние.
Изменить: просто для справки вы приводите следующее выражение:
Если атрибут существует как встроенное свойство, но он имеет значение Boolean, значение не синхронизируется.
Это неправильно, поведение не имеет ничего общего с булевыми против строк. Как упоминалось выше, свойство value
аналогично отсутствует синхронизация с checked
свойством. С другой стороны, логическое hidden
свойство будет соответствующим образом синхронизироваться с соответствующим атрибутом. Из того, что я могу сказать, вы найдете отсутствующую синхронизацию между свойством и атрибутом вокруг оригинальных API-интерфейсов обработки форм, которые были введены Netscape - это просто обратная совместимость.
Поэтому, возможно, вам не следует доверять людям, которые пишут книги по jQuery с вопросами DOM. В конце концов, они явно решили отказаться от непосредственного касания DOM и выбрали совершенно другое представление с собственным набором причуд.