У меня есть две почти идентичные простые скрипты JS, вызывающие функцию при изменении выбора. Имя функции совпадает с идентификатором select в обоих случаях, но по какой-то причине первая скрипка работает просто отлично, а вторая не работает с ошибкой JavaScript is not a function:

http://jsfiddle.net/AZkfy/7/ — отлично работает в FF9 (Linux), Chromium 16 (Linux), IE8 (Windows):

<script>
    function border(border) { alert(border); }
</script>

<select id='border' name='border' onchange='border(this.value)'>
    <option value='foo'>foo</option>
    <option value='bar'>bar</option>
</select>

значения этого {{}} этого свойства

http://jsfiddle.net/cYVzk/ — не работает в FF9 (Linux), Chromium 16 (Linux), IE8 (Windows):

<script>
    function border(border) { alert(border); }
</script>

<form>
<select id='border' name='border' onchange='border(this.value)'>
    <option value='foo'>foo</option>
    <option value='bar'>bar</option>
</select>
</form>

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

. serialize () — вам нужно дать каждому элементу формы имя, подобное следующему: — существуют ли какие-либо спецификации или ограничения JS в отношении конфликтующих имен функций JS и идентификатора элемента?

Это проблема унаследованной цепочки областей видимости, возникшая в JavaScript 1.0–1.3, когда не было различий между языком программирования и тем, что мы сейчас называем DOM API (тогда «Динамический HTML»).

Если ваш элемент управления формы (здесь: элемент select) является частью формы (потомком элемента form), то объект Form, представляющий элемент form, является третьим-следующим в область видимости кода в значениях атрибутов обработчика событий элемента управления (second-next — сам объект элемента управления формы, затем — объект Variable этого кода).

JavaScript ™ был спроектирован Бренданом Айхом (тогда в Netscape) как язык программирования, который прост в использовании для начинающих и который хорошо работает с HTML-документами (как дополнение к Java ; Sun, отсюда и постоянно сбивающее с толку название ). Поскольку в те ранние времена язык и (Netscape) DOM API были единым целым, это (чрезмерное) упрощение также применялось к DOM API: у объекта Закрытие Form есть имена элементов управления, содержащихся в форме, которую он представляет как имена своих свойства, которые ссылаются на соответствующие объекты управления формой . Итак, вы можете написать

myForm.border

, что является собственным сокращением совместимого со стандартами ( W3C DOM Level 2 HTML ), но в равной степени обратно совместимого

document.forms["myForm"].elements["border"]

Теперь, если вы используете имя элемента управления формы в значение атрибута обработчика событий элемента управления формы в форме Используйте следующее для вызова функции фрейма на родительской странице

<form …>
  <… name="border" onchange='border(this.value)' …>
</form>

, такое же, как если бы вы написали наполовину проприетарную

<form …>
  <… name="border" onchange='this.form.border(this.value)' …>
</form>

или соответствующую стандартам

<form …>
  <… name="border" onchange='this.form.elements["border"](this.value)' …>
</form>

, потому что потенциальная глобальная border() Функция — это свойство глобального объекта http://jsfiddle.net/c4Wqn/ Просто напишите простую обертку вокруг , который идет последним, объекта после возврата функции * * все локальные переменные больше не доступны, потому что стековый фрейм уничтожен. обработчик Form (объект, реализующий интерфейс HTMLFormElement в DOM W3C) в цепочке областей действия.

Однако объект управления формой, на который ссылается здесь border, не вызывается (не реализует метод ECMAScript-internal [[Call]] или реализует его так, чтобы он вызывал исключение при вызове). Так что если вы попытаетесь вызвать объект сborder(this.value), a TypeError исключение thrown, который вы должны увидеть в консолях скриптов (например, «TypeError: border не является функцией» в инструментах разработчика Chromium 16.0.912.77 [Developer Build 118311 Linux]).

Microsoft, конкурент Netscape в 1990-х годах, должна была скопировать эту функцию для MSHTML DOM , чтобы код, написанный для Netscape, также работал в Internet Explorer (3.0) с JScript (1.0). И конкуренты Microsoft скопировали его в свои реализации DOM по той же причине. Он стал частью квази-стандарта (теперь называется « DOM Level 0 «).

Затем появилась HTML-спецификация DOM уровня 2 — постоянная попытка стандартизировать и расширить общие возможности существующих реализаций DOM того времени. Рекомендация W3C с 2003-01-09, ее привязка языка ECMAScript определяет, что элементы HTMLCollection могут быть доступны по их имени или , просто нажмите кнопку «Получить токен»: с синтаксисом метода доступа к свойствам скобок [], что эквивалентно вызову namedItem() метод объекта, реализующего интерфейс HTMLCollection.

form объекты-элементы и элементы-элементы для элементов управления форм в формах являются элементами HTMLCollection в W3C DOM, HTMLDocument::forms и HTMLFormElement::elements соответственно. Но для обратной совместимости в браузерах

document.forms["myForm"].elements["myControl"]

должен быть эквивалентен эквивалент { *} class.Teby, позволяя конструкции

document.myForm.myControl

. Таким образом, с реализациями HTML-интерфейсов W3C DOM уровня 2 не позднее, эта функция начала применяться к элементам с ID также значение атрибута) (что можно увидеть, например, в Chromium). (id В результате удобная функция, появившаяся в JavaScript ™ 16 лет назад, все еще кусает вас, как баг в сценариях DOM на стороне клиента.

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

), тогда это становится меньше вопроса. Кроме того, плохой идеей является использование того же идентификатора для функции и одного из ее аргументов, что и (смущая код в стороне), что делает объект функции недоступным изнутри функции (объект переменной контекста функции занимает первое место в своей цепочке областей действия ). action, submit и reset IE автоматически резервирует

в глобальном пространстве для каждого DOM-элемента с var ID = domElement;. Некоторые другие браузеры приняли это поведение. ID Всегда старайтесь не использовать одинаковые идентификаторы и имена! Или используйте свое собственное пространство имен в JS, чтобы избежать коллизий.

Я не знаю, почему один из ваших примеров не работает, а другой работает. Это может быть простой выбор времени / порядка выполнения, вызванный переносом

Мы только что выпустили

http://jsfiddle.net/x79ey/1/ <form> Глядя на вывод

Мне кажется, тег

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

<form>
    <element id="foo"....
    <element onclick="foo is a local variable here"

Как узнать идентификатор компонента JSF, чтобы я мог использовать его в Javascript — Переполнение стека