HTML4中的Element.animate()

时间:2014-07-21 17:26:07

标签: javascript html google-chrome dom chromium

Chrome浏览器的用户似乎有appropriated Element.animate(),有效地使用onclick="animate();"的内容破坏了所有现有的HTML页面。

对于HTML 4 / Transitional规范下的浏览器,这是合法的吗?这是W3C正式拥有权力的东西吗?

是否有任何小型网站所有者可以做些什么来阻止此类进一步的违规行为?

编辑: 测试案例:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>test</title>
    <script type="text/javascript">
        function animate() {
            alert('this should work');
        }
    </script>
</head>
<body>
    <input type="button" onclick="animate();" value="push me!">
</body>
</html>

Chrome上Uncaught TypeError: Failed to execute 'animate' on 'Element': 1 argument required, but only 0 present.的结果,但在FireFox中有效。

1 个答案:

答案 0 :(得分:9)

您所指的更改不是Google的单方面行动,而是draft W3C standard called Web Animations 1.0的一部分。您遇到问题的具体修改是the extension to the DOM Element interface,它增加了三种新方法,包括animate()

  

由于DOM Elements可能是动画的目标,因此Element接口[DOM4]扩展如下:Element implements Animatable;

     

这允许以下类型的用法。 elem.animate({ color: 'red' }, 2000);

这里的DOM代表“文档对象模型”,它是another standard, separate from HTML,它定义了JavaScript和其他语言应该如何公开HTML,XML或类似文档并与之交互。多年来,这个标准经历了多次扩展,因此将这种新方法添加到Element个对象中绝不是前所未有的,也可能是有争议的。


您的具体问题是名称空间冲突之一。 JavaScript的范围规则在任何情况下都相对复杂,当您在HTML属性中嵌入事件处理程序时,会有一些特殊的逻辑,如this MDN article about "event attributes"中所述。

结果是,当您编写onclick="animate();"时,animate被查找为多个范围或命名空间中的属性,包括:

  • 作为已点击元素的属性,已绑定到this;如果找到,animate()的行为与this.animate()
  • 相同
  • 作为全局window对象的属性,它始终是在任何情况下检查的最后一个范围;因此,如果找不到其他内容,animate()将等同于window.animate()

您的问题是您依赖于从全局命名空间调用的内容,但对DOM的更改意味着它现在也在this上定义(具体来说,它在所有后代的原型中) Element)。由于新函数优先于现有函数,因此会发生意外的行为更改。

因此,对代码进行最简单的修复就是更具体地确定您的活动资格,onclick="window.animate();"。你应该这样做不只是你知道现在有冲突的方法和变量,而是所有这些方法和变量,这样它们将来不会受到对DOM的其他更改的影响。 (Here is a demo of that approach。)


但是,如果您希望使代码更加健壮,那么您应该进行更广泛的更改,以使其与更新的编码实践保持一致:

  • 不是使用onclick之类的“事件属性”,而是以编程方式添加事件侦听器。现代API是addEventListener,虽然很多人更喜欢像jQuery这样的库,这样可以更轻松地使用不同的浏览器,并简化常见任务(在这种情况下,您可以使用{{3} }})。
  • 不是将函数放入全局范围,而是将它们作为某个对象的属性,以便您可以跟踪自己的命名空间。更好的是,如果你将它们与HTML分开(使用诸如addEventListener或jQuery的.on之类的东西),你可以使它们成为私有变量,甚至不能从全局范围访问,通过使用the .on() method(一个仅用于创建新变量范围的封闭函数)。