Проблема заключается в цепочке областей действия функций, скомпилированных из значений атрибутов элемента HTML, объявленных в источнике HTML.Атрибуты формы on_eventName=functionBodyCode
демонстрируют это поведение.
По историческим причинам (DOM не существовало в его нынешнем виде, document.getElementByID
еще не было изобретено ...), такие функции компилируются с областью видимостицепь, содержащая объект, для которого предоставляется атрибут обработчика события, любой элемент form
, в котором находится элемент, и объект document
. Однако разные браузеры использовали разные подходы при эмуляции поведения Netscape.Некоторые браузеры включали любой родительский объект элемента, предоставляющего атрибут обработчика события, в то время как другие опускали некоторые подходящие объекты, такие как document
.
Технические подробности можно найти в «Javascript the Definition Guide» O'Reilly, раздел «19.1.6. Область действия обработчиков событий».
Основная рекомендация - избегать предоставления обработчиков событий в HTML - добавьте их в JavaScript, используя вместо этого addEventListener
.Если по какой-либо причине вызовы функций должны быть закодированы в значениях атрибутов HTML, не используйте имена функций, которые являются методами объектов DOM.
Обратите внимание, что цепочка пользовательских областей действия для обработчиков событий применяется только к функциям, созданным из атрибутов HTML. не применяется к функциям, созданным в JavaScript и добавленным к элементу с помощью addEventListener
или element.onEventName=aFunctionObject
.
В следующем фрагменте показано расположение имен свойств внешних элементов в цепочке областей действия обработчиков событий, определенных в HTML::
<form name="formName1" action="">
<p> Try to access the elements collection of the form:
<button type="button"
onclick="console.log( elements);">elements
</button>
</p>
</form>
<form name="formName2" action="" onsubmit="return false">
<p> Try to access form name as form.name:
<button type="button"
onclick="console.log( 'form.name: %s', form.name);">form.name
</button>
</p>
</form>
<form name="formName3" action="" onsubmit="return false">
<p>Access document.write as "write"
<button type="button"
onclick="console.log( 'write: %s', write);">write
</button>
</p>
</form>
В первой форме elements
является свойством окружающего элемента формы.
Во второй форме form
является свойством HTMLButtonElement.
В третьей форме write
является методом document
.