当前位置: 首页 > 面试题库 >

为什么JS函数名称与元素ID冲突?

袁晟
2023-03-14
问题内容

我有两个几乎相同的简单JS小提琴,它们在选择更改时调用一个函数。在这两种情况下,函数名称都与select
ID相同,但是由于某种原因,第一个小提琴可以正常工作,而第二个小提琴却因JavaScript错误而失败 is not a function :在FF9(Linux),Chromium16(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>

在FF9(Linux),Chromium16(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>

首先 ,我不明白为什么第一个可以正常工作,而第二个却不能工作。

第二 -关于冲突的JS函数名称和元素ID是否有JS规范或限制?


问题答案:

这是一个源于JavaScript 1.0到1.3的遗留范围链问题,当时编程语言和我们现在称为DOMAPI(当时称为“动态HTML”)之间没有区别。

如果您的表单控件(此处为:select元素)是表单的一部分(form元素的后代),那么Form表示该form元素的对象在控件的事件处理程序属性值(第二个-接下来是表单控件对象本身,其次是该代码的变量对象)。

JavaScript™由BrendanEich(当时为Netscape)设计,是一种编程语言,对于初学者来说易于使用,并且可以很好地与HTML文档配合使用(作为SunJava的补充;因此,名称经常被混淆)。因为在那些早期语言和(网景)DOM API是一个,这个(过)简化施加到DOMAPI,以及:甲Form对象具有控件的名称包含在形式,它表示作为其属性的名称即参考相应的表单控件对象。IOW,你可以写

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()功能是的属性的ECMAScript其去年来的时候,全局对象之后的Form对象(实施对象HTMLFormElement在W3C DOM接口),作用域链。

但是,此处引用的表单控制对象border是不可调用的(不实现ECMAScript-internal[[Call]]方法或实现该方法,以便在调用时引发异常)。因此,如果您尝试使用调用对象border(this.value)TypeError则会引发异常,您应该在脚本控制台中看到该异常(例如Chromium16.0.912.77[DeveloperBuild118311Linux]的开发人员工具中的“ TypeError:border不是函数”) 。

作为1990年代Netscape的竞争对手,Microsoft必须复制MSHTML DOM的该功能,以便为Netscape编写的代码也可以在Internet
Explorer(3.0)和JScript(1.0)中运行。微软的竞争对手出于完全相同的原因将其复制到其DOM实现中。它成为
准标准 (现在称为“ DOM Level 0 ”)的一部分。

然后是DOM Level 2HTML规范,这是对当前DOM实现的通用功能进行标准化和扩展的持续努力。自2003年1月9日起成为W3C建议书,其ECMAScript语言绑定指定HTMLCollections的项可以使用方括号属性访问器语法…
通过其名称 ID 进行访问,等同于调用实现该接口的对象的方法[``]``namedItem()``HTMLCollection

form表单中用于表单控件的元素对象和元素对象分别HTMLCollection是W3CDOMHTMLDocument::forms和中的项HTMLFormElement::elements。但是为了向后兼容浏览器,

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

必须 等同

document.myForm.myControl

因此,最迟在W3C DOM 2级HTML接口的实现中,此功能也开始应用于 ID为id属性值)的 元素
(例如,在Chromium中可以看到)。

结果,在16年前JavaScript™中引入的便利功能仍然像今天的客户端DOM脚本中的错误一样使您咬伤。

如果避免使用相同的名称或ID为表单控件和表格,你作为用户定义的函数标识符使用,并且已经用于内置形式属性(比如actionsubmitreset),那么这成为一个问题的更小。同样,对函数及其参数之一使用相同的标识符(而不是混淆代码)也是一个坏主意,这会使函数对象无法从函数内部进行访问(函数上下文的变量对象在其作用域链中排在首位)
)。



 类似资料:
  • 问题内容: 处理一个项目,差不多完成了,只是整理了HTML,我发现您实际上没有被允许使用的ID只是一个数字, 属性“ id”具有无效值“ 567”。属性ID为ID类型。如上所述,它应该以字母开头并且不能有空格 我可以遍历我的代码并添加一个字母,然后在jQuery中使用该值时将其删除,但这会很混乱,我不需要。 是否有理由不应该将数字用作ID? 问题答案: 这就是规范所说的。 根据HTML 4规范:

  • 问题内容: 我在此站点上看到了一些东西: 用JavaScript和PHP处理HTML表单元素数组 http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=343 它说过将数组放在name属性中,以及如何获取输入集合的值。例如 但据我所知,HTML input元素已通过数组就绪。例如,在客户端()或服务器端(在PHP或ASP.NET中)

  • 问题内容: 我在课堂上有这个功能: 我尝试使用此函数来调用该函数: 问题是编译器希望它看起来像这样: 为什么第一个会导致错误? 问题答案: Swift 2.0更新 :现在,默认情况下,函数的功能与方法相同,并且对于两种方法而言: 第一个参数没有外部名称;和 其他参数的外部名称与内部名称相同。 除此之外,下面的规则仍然适用,只是速记语法已消失。 这是一个更一般的答案:函数在类之外定义为真函数时以及在

  • 问题内容: 注意:在Windows Server 2012 R2 Standard上运行MariaDB 10.2.27。 我想生成用于MariaDB的随机整数,因此我一直在尝试使用MariaDB RAND()函数。我的期望和理解都偏离了基础(绝对有可能!),或者MariaDB RAND()函数不是非常随机的。 使用BIGINT(20)专栏中,我想生成随机整数最大长度为16位,所以我用这个SQL:

  • 问题内容: 这种“强调”似乎经常发生,我想知道这是否是Python语言中的要求,还是仅仅是一个约定问题? 另外,有人可以说出并解释哪些函数倾向于带有下划线,以及为什么(例如)? 问题答案: 从Python PEP 8-Python代码样式指南: [描述性:命名样式](https://www.python.org/dev/peps/pep-0008/#descriptive-naming- styl

  • 问题内容: 我使用上面的python代码来练习一些基本的Selenium操作。我找不到任何元素,无论是名称还是ID。不管我尝试什么,我总是会遇到相同的错误,这表明我要查找的元素不存在。(想法是按一下其中一个按钮…) 这是网站html代码的一部分: 这是所说的网站(链接断开) 任何帮助将不胜感激。 顺便说一句,这是我尝试运行的第一个使用Selenium的程序,是否有可能需要更改某些设置或需要安装其他