我们有一个页面似乎被最新的chrome更新(到84)破坏了。 有一个带有onclick事件的复选框,该事件不再激发。 出现错误:未捕获的TypeError:Timeline.ToggleWatcher不是函数
附件是调用这个JavaScript函数的HTML
<ul class="dropdown-menu dropdown-menu-right condensed-dropdown">
<li>
<a class="pos-rel" data-watcher-toggle-type="submitter" data-notify="submitter" data-selected="true" onclick="timeline.toggleWatcher('submitter')">
<span class="dropdown-toggle-icon">
<i class="fa fw fa-check-square"></i>
</span>
<span class="history-filter-label">Submitter</span> </a>
</li>
<li>
<a class="pos-rel" data-watcher-toggle-type="analyst" data-notify="analyst" data-selected="false" onclick="timeline.toggleWatcher('analyst')">
<span class="dropdown-toggle-icon">
<i class="fa fw fa-square-o"></i>
</span>
<span class="history-filter-label">Assigned Analyst</span></a>
</li>
<li>
<a class="pos-rel" data-watcher-toggle-type="watcher" data-notify="watcher" data-selected="true" onclick="timeline.toggleWatcher('watcher')">
<span class="dropdown-toggle-icon">
<i class="fa fw fa-check-square"></i>
</span>
<span class="history-filter-label">Watchers</span></a>
</li>
</ul>
timeline在JavaScript中已经成为一个保留字了吗?
Timeline
不是“保留字”,它是Document
的属性:
https://developer.mozilla.org/en-us/docs/web/api/document/timeline
您应该以编程方式添加事件处理程序,而不是在标记中使用内联属性并依赖全局变量,全局变量将被添加到document
中的任何新属性所遮蔽。
例如,这样可以很好地工作:
null
<html>
<head><title>Bug Test</title></head>
<body>
<button id="btn">Works</button>
<script>
var timeline = {
dosomething: function(param){
alert('doing something: '+param);
}
}
document.querySelector('#btn').addEventListener('click', event => {
timeline.dosomething("works");
});
</script>
</body>
</html>
它不是一个保留词。 另外,如果您使用window.timeline.doSomething
,它也可以工作。
您看到此问题的原因是document
现在有一个新属性timeline
。
现在您可能想知道为什么这很重要,您不是在编写document.timeline
,而只是在编写timeline
,对吗? 好吧,原因是历史的:为了使编写内联事件处理程序更简单,更短,在它们的范围内有些东西是今天有点意想不到的。
详细信息可以在HTML规范中阅读(检查“范围”下的说明)。 此外,这个堆栈溢出答案进一步探讨了这个主题。
您可以将其想象为在多个嵌套的with
块内调用代码:
带有(文档)
内部的元素上:with(formElement)
with(element)
(为其编写处理程序的元素本身)正如您所看到的,问题在于在此上下文中,document.timeline
在您的作用域中可以作为timeline
访问,从而覆盖具有相同名称的全局变量。
贴完之后,又做了一些测试。。。 看起来时间线现在实际上是一个保留词。 请参阅下面的示例HTML:
<html>
<head><title>Bug Test</title></head>
<body>
<button onclick="mgtest.dosomething('hello there')">Works</button>
<button onclick="timeline.dosomething('hello there')">Does Not Work</button>
</body>
<script>
var mgtest = {
dosomething: function(param){
alert('doing something: '+param);
}
}
var timeline = {
dosomething: function(param){
alert('doing something: '+param);
}
}
</script>
</html>