为什么调用Window.scroll()会给出一个受信任的事件?

时间:2016-04-15 21:08:53

标签: javascript javascript-events

我的Chrome扩展程序需要产生类似人类的鼠标和键盘行为(具体而言,生成isTrusted值为true的事件。除了滚动chrome.debugger API之外,我可以做我需要的一切。

但似乎Window.scroll()方法就此目的而言足以支持Chrome 52和Firefox 48.0a1。通过将事件侦听器附加到页面可以观察到这一点,如下所示:

document.addEventListener("scroll", function (event) { 
    console.log("event trusted? " + event.isTrusted);
});

然后在开发人员控制台中运行类似window.scroll(0, 10);的内容。这会将event trusted? true记录到开发者控制台。

我的问题是:为什么会这样?在这种情况下,isTrusted属性不应该是false,因为滚动事件是由脚本明确生成的吗?

2 个答案:

答案 0 :(得分:6)

这是按照DOM Living Standard

的规范
  

注意: isTrusted便于用户代理event dispatched(与使用dispatchEvent()相对)。唯一的遗留异常是click(),这会导致用户代理将event属性初始化为isTrustedDOM Level 3 Events Specification分派。{/ em>

此外,在3.4. Trusted events

  

user agent

     

user agent生成的事件,无论是作为用户交互的结果,还是作为DOM更改的直接结果,都受createEvent()信任,具有权限不通过initEvent()方法提供给脚本生成的事件,使用dispatchEvent()方法修改,或通过isTrusted方法调度。受信任的isTrusted属性事件的值为true,而不受信任的事件的CSSOM View Module Editor's Draft属性值为false

因此,isTrusted仅反映事件是否已使用createEventinitEventdispatchEvent人工调度或创建。现在,查看Window.scroll的{​​{1}}定义:

  

调用 scroll() 方法后,必须执行以下步骤:

     

[...]

     
      
  1. 如果使用两个参数调用,请遵循以下子步骤:
  2.         

    [...]

         

    12. Perform a scroll视口到位置文档的根元素作为关联元素(如果有),否则为null,并且滚动行为是选项behavior词典成员的值。

该方法中没有任何地方是使用createEventinitEventdispatchEvent创建的人工事件,因此isTrusted的值为true。请注意,使用Window.scroll仍会触发事件处理程序,因为它与事件循环集成,并且在滚动视口或元素时会发出scroll事件。但是,,使用createEventinitEventdispatchEvent

使用isTrusted事件不是检测脚本是否生成事件的可靠方法。它仅检测是否已使用createEventinitEventdispatchEvent创建并分派了一个事件。

答案 1 :(得分:0)

似乎*.scroll或更改scrollTop属性并未正确构造事件。正如您在示例中所看到的,如果我自己创建事件,则isTrustedfalse。我认为这是引擎中的一个错误

"use strict";
var event = new Event('scroll');

//target.addEventListener(type, listener[, options]);
//target.addEventListener(type, listener[, useCapture]);
//target.addEventListener(type, listener[, useCapture, wantsUntrusted  ]); // Gecko/Mozilla only
window.addEventListener('scroll', function(e) {
  console.log(e.isTrusted);
}, false);

console.log('JS engine event:');
window.scroll(10, 10);

setTimeout(function() {
  console.log('Selfmade event:');
  window.dispatchEvent(event);
}, 1000);

setTimeout(function() {
  console.log('Another event triggered by changing the scrollTop property:');
  window.scrollTop = '20px';
}, 2000);
#container {
  width: 100px;
  height: 10000px;
  overflow: scroll;
}
<div id="container">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
  sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
  Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</div>