如何使用JavaScript在Firefox中触发鼠标滚轮事件?

20

我正在使用WebDriver进行自动化测试,但是它目前无法模拟鼠标滚轮事件。作为解决方法,我正在尝试使用JavaScript来触发这些事件。我目前在一个普通的HTML页面上进行所有的滚轮实验,而不是在WebDriver框架内。

我特别想要在一个可滚动的div元素上触发鼠标滚轮事件。

到目前为止,我已经成功地在Chrome和IE9中完成了这个过程,但是在Firefox(5.x)中似乎无法工作。

我正在使用以下跨浏览器代码来检测鼠标滚轮事件是否被触发,我从网络上抓取了这段代码。当我在创建的可滚动div(id ='view')中滚动鼠标滚轮时,这段代码可以在所有浏览器中检测到事件的触发。

<script type="text/javascript">
  function wheel(event) {
    var delta = 0;
    if (!event) {
      event = view.event;
    }
    if (event.wheelDelta) {
      delta = event.wheelDelta / 120;
    }
    else if (event.detail) {
      delta = -event.detail / 3;
    }
    
    alert(delta);
  }
  
  var view = document.getElementById('view');
  
  if (view.addEventListener) {
    view.addEventListener('DOMMouseScroll', wheel, false);
  }
  
  view.onmousewheel = wheel;
</script>

调用下面的函数时,能够在Chrome和IE9中触发鼠标滚轮事件,并以预期的行为在上述处理程序中被捕获。

function ChromeWheel () {
  var evt = document.createEvent("MouseEvents");
  evt.initEvent('mousewheel', true, true);
  evt.wheelDelta = 120;
  view.dispatchEvent(evt);
}
当然,这不适用于Firefox。我发现现有的文档过于稀少和混乱,无法知道FF如何处理这个问题。有人能展示一下在Firefox中触发鼠标滚轮事件的最基本方法吗?使其具有滚轮增量(放置在Firefox期望的位置),以便我的处理程序可以获取它。

我一直想知道为什么人们想要直接触发本地事件。如果这是你的页面和你的代码,你想看到鼠标滚动的效果,为什么不直接调用函数,当你的代码接收到鼠标滚动事件时执行。你应该能够将其从你的代码中分离出来,并直接调用它,而不需要通过事件系统,这样它就没有浏览器依赖性,并且可以在任何地方正常工作。 - jfriend00
3
因为这并不仅仅是我的代码,而且我甚至对作为应用程序一部分触发事件也不感兴趣。我正在尝试将应用程序作为QA过程的一部分进行测试,对我们来说很重要的是不要开始在各个地方修改代码以实现这一点。 - Justin Aquadro
知道您尝试做什么会有所帮助。难道没有专业的工具用于Web页面的QA测试,可以模拟各种用户事件,包括各种鼠标事件,并且这些工具在系统级别注入事件,因此它们可以与所有浏览器一起工作吗? - jfriend00
我在第一段中说,我正在使用WebDriver(Selenium的一部分)来实现这个目的。它模拟了一些东西,但目前不包括鼠标滚轮。 - Justin Aquadro
抱歉,我第一次错过了。 - jfriend00
这里发布的代码在IE8上是否有效? - David
1个回答

15

好的,

  1. 在代码的Mozilla部分,如果你正在监听DOMMouseScroll事件,那么你也应该派发一个DOMMouseScroll事件,对吗?(mousewheel似乎是由WebKit复制的Microsoft发明,但不是Gecko)。
  2. 你应该调用适当的init...()方法来设置(只读)事件属性,对于鼠标事件来说,这个方法是initMouseEvent()。(规范

这里有一个修复后的测试用例,在Firefox中可以正常工作:http://jsfiddle.net/6nnMV/

可能对你没有用,但对其他想模拟事件的人可能会有兴趣,这里是Mozilla中(特权)单元测试如何模拟“真实”事件的方法:http://hg.mozilla.org/mozilla-central/annotate/a666b4f809f0/testing/mochitest/tests/SimpleTest/EventUtils.js#l248


根据规范,initWheelEvent() 似乎是更好的选择(或者说这通常还没有实现?)。然而,演示显然有效,参考资料也非常有价值。谢谢。 - Justin Aquadro
@jaquadro:是的,在Mozilla中还没有:http://mxr.mozilla.org/mozilla-central/search?string=initWheelEvent - Nickolay
我在想,有没有人知道最近的FF版本是否已经解决了滚轮问题,使其像其他浏览器一样工作,而不需要自己的DOMMouseScroll事件等?像FF10+这样的版本,还是像FF3.X / FF5.x一样工作? - David
但这实际上并不会滚动页面。如果我将其更改为window.dispatchEvent,页面也不会滚动。有没有办法做到这一点? - Jason B
1
你可以在单独的问题中进行测试或询问。我猜不会有影响,因为触发合成事件通常除了触发事件侦听器之外没有任何效果。 - Nickolay
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接