提问者:小点点

Google Chrome(build 84)中断Javascript事件(未捕获的TypeError:Timeline.ToggleWatcher不是函数)


我们有一个页面似乎被最新的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中已经成为一个保留字了吗?


共3个答案

匿名用户

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>