你所指的改变并非谷歌单方面的举动,而是谷歌计划的一部分。名为 Web Animations 1.0 的 W3C 标准草案 http://dev.w3.org/fxtf/web-animations/。您遇到麻烦的具体修改是DOM 的扩展Element界面 http://dev.w3.org/fxtf/web-animations/#extensions-to-the-element-interface其中添加了三个新方法,包括animate()
:
由于 DOM Elements 可能是动画的目标,因此 Element 接口 [DOM4] 扩展如下:Element implements Animatable;
这允许以下类型的使用。elem.animate({ color: 'red' }, 2000);
这里的 DOM 代表“文档对象模型”,即另一个标准,与 HTML 分开 http://www.w3.org/TR/dom/它定义了 JavaScript 和其他语言应如何公开 HTML、XML 或类似文档并与之交互。该标准多年来已进行了多次扩展,因此添加此新方法Element
这些物体绝不是史无前例的,也不可能引起争议。
您的具体问题是之一命名空间冲突。 JavaScript 的作用域规则在任何情况下都相对复杂,当您在 HTML 属性中嵌入事件处理程序时,会出现一些特殊的逻辑,如这篇关于“事件属性”的 MDN 文章 https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Event_attributes.
结果是,当你写onclick="animate();"
, animate
被查找为多个作用域或命名空间中的属性,包括:
- 作为被单击元素的属性,该元素已绑定到
this
;如果发现,animate()
将表现得与this.animate()
- 作为全球财产
window
对象,在任何情况下始终是最后检查的范围;因此,如果没有找到其他东西,animate()
将相当于window.animate()
你的问题是你依赖于从全局命名空间调用的东西,但是对 DOM 的更改意味着它现在定义在this
以及(具体来说,它是在所有后代的原型中Element
)。由于新函数优先于现有函数,因此会发生意外的行为变化。
因此,对代码最简单的修复是更具体地限定您的事件,如下所示onclick="window.animate();"
。您不仅应该对您知道现在存在冲突的方法和变量执行此操作,还应该对所有这些方法和变量执行此操作,以便将来它们不会受到 DOM 的其他更改的影响。 (这是该方法的演示 http://jsfiddle.net/bKB8E/4/.)
但是,如果您想让代码更加健壮,则应该进行更广泛的更改,以使其符合最新的编码实践:
- 而不是使用“事件属性”,例如
onclick
,以编程方式添加事件侦听器。现代 API 是addEventListener https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener,尽管很多人更喜欢像这样的图书馆jQuery http://jquery.com/这使得使用不同的浏览器变得更容易,并简化了常见任务(在这种情况下,您可以使用the .on() method http://api.jquery.com/on/).
- 不要将函数放入全局作用域,而是将它们设置为某个对象的属性,以便您可以跟踪自己的名称空间。更好的是,如果将它们与 HTML 分开(使用类似
addEventListener
或者 jQuery 的.on
),你可以让它们private变量,甚至无法从全局范围访问,通过使用IIFE https://en.wikipedia.org/wiki/IIFE(一个封闭函数,其存在只是为了创建一个新的变量范围)。