Element.animate()在HTML4中 [英] Element.animate() in HTML4

查看:367
本文介绍了Element.animate()在HTML4中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Chrome的人似乎已经有一个自己使用Element.animate(),有效地打破所有现有的HTML页面,使用沿着 onclick =animate();



HTML 4 / Transitional规范下的浏览器是否合法?这是W3C正式有权限的东西吗?



有什么小时网站所有者可以做什么来防止这种进一步的违规行为?



编辑:
测试用例:

 <!DOCTYPE HTML PUBLIC -  // W3C // DTD HTML 4.01过渡/ / 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 =buttononclick =animate(); value =push me!>
< / body>
< / html>

结果未捕获TypeError:无法在元素上执行animate :需要1个参数,但只有0个存在。在Chrome上,但适用于FireFox。

解决方案

您所指的更改不是Google的单方面举措,而是 W3C标准草案Web Animations 1.0 。您遇到问题的具体修改是 DOM的扩展名元素界面,它添加了三种新方法,包括 animate()


$由于DOM元素可能是动画的目标,因此元素接口[DOM4]的扩展如下:元素实现Animatable;



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


DOM这里代表文档对象模型,它是另一个标准,与HTML分开,它定义了JavaScript和其他语言应该暴露和与HTML,XML或类似文档交互。这个标准多年来已经有了很多的扩展,所以添加这个新方法到 Element 对象并不是前所未有的,或者可能是有争议的。






您的具体问题是命名空间冲突之一。 JavaScript的范围规则在任何情况下都相对复杂,当您将事件处理程序嵌入到HTML属性中时,有一些特殊的逻辑,如关于事件属性的MDN文章



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




  • 作为点击元素的属性,已绑定到;如果找到, animate()将与 this.animate()

  • 作为全局窗口对象的属性,它始终是在任何情况下检查的最后一个范围;因此,如果没有找到其他东西, animate()将相当于 window.animate()



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



因此,您的代码最简单的修复是为了更有效地限制您的事件,因为的onclick = window.animate();。你应该这样做不仅仅是你知道现在有冲突的方法和变量,而是在所有这些方法和变量上,以便将来不会受DOM的其他变化的影响。 (这是该方法的演示)。






但是,如果要使代码更加强大,您需要进行更广泛的更改,使其符合更新的编码习惯:




  • 而不是使用诸如 onclick 的事件属性,而是以编程方式添加事件监听器。现代API是 addEventListener ,虽然许多人喜欢像 jQuery 这样的图书馆,这样可以更轻松地使用不同的浏览器,简化常见任务(在这种情况下) ,您将使用 .on()方法)。

  • 而不是将函数放入全局范围,使其成为某些对象的属性,以便您可以跟踪自己的命名空间。更好的是,如果你把它们与HTML分开(使用类似 addEventListener 或jQuery的 .on ),你可以通过使用 IIFE (一个封闭的),使他们变量,甚至不能从全局范围访问仅存在于创建新变量范围的函数)。


It seems the people at Chrome have appropriated Element.animate() for themselves, effectively breaking all existing HTML pages using something along the lines of onclick="animate();".

Is this legal for a browser under the HTML 4/Transitional spec? Is this something that W3C would formally have authority over?

Is there anything small-time website owners can do to prevent any further transgressions of this sort?

EDIT: Test Case:

<!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>

Results in Uncaught TypeError: Failed to execute 'animate' on 'Element': 1 argument required, but only 0 present. on Chrome, but works in FireFox.

解决方案

The change you are referring to is not a unilateral move by Google, but part of a draft W3C standard called Web Animations 1.0. The specific modification you are running into trouble with is the extension to the DOM Element interface which adds three new methods, including animate():

Since DOM Elements may be the target of an animation, the Element interface [DOM4] is extended as follows: Element implements Animatable;

This allows the following kind of usage. elem.animate({ color: 'red' }, 2000);

DOM here stands for "Document Object Model", which is another standard, separate from HTML which defines how JavaScript and other languages should expose and interact with an HTML, XML, or similar document. This standard has had many expansions over the years, so the addition of this new method to Element objects is by no means unprecedented or likely to be controversial.


Your specific problem is one of namespace collision. JavaScript's scoping rules are relatively complex in any situation, and when you embed an event handler in an HTML attribute, there is some special logic, as explained in this MDN article about "event attributes".

The upshot is that when you write onclick="animate();", animate is looked up as a property in multiple scopes, or namespaces, including:

  • as a property of the clicked element, which has been bound to this; if found, animate() will behave the same as this.animate()
  • as a property of the global window object, which is always the last scope checked in any situation; thus if nothing else is found, animate() will be equivalent to window.animate()

Your problem is that you are relying on something being called from the global namespace, but the changes to the DOM mean that it is now defined on this as well (specifically, it is in the prototype of all descendants of Element). Since the new function takes precedence over your existing one, an unexpected behaviour change occurs.

The simplest fix to your code is therefore to qualify your event more specifically, as onclick="window.animate();". You should do this not just for methods and variables you know have conflicts now, but on all of them, so that they won't be affected by other changes to the DOM in future. (Here is a demo of that approach.)


However, if you want to make your code more robust, there are more extensive changes you should make to bring it in line with more up to date coding practices:

  • Rather than using "event attributes" such as onclick, add event listeners programmatically. The modern API for this is addEventListener, although many people prefer a library like jQuery which makes it easier to work with different browsers, and simplifies common tasks (in this case, you'd use the .on() method).
  • Rather than putting functions into a global scope, make them properties of some object, so that you can keep track of your own namespaces. Even better, if you keep them separate from the HTML (using something like addEventListener or jQuery's .on), you can make them private variables, not even accessible from global scope, by using an IIFE (an enclosing function which exists only to create a new variable scope).

这篇关于Element.animate()在HTML4中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆