Firefox:以编程方式触发自动滚动

时间:2018-12-08 17:55:52

标签: javascript firefox dom-events autoscroll

我想听一个中键按下(mousedown事件),然后有条件地执行一个操作(与具体操作无关)或恢复为默认设置,即使用以下命令进入“自动滚动模式”显示自动滚动图标,直到用户释放中间按钮。

我的代码侦听mousedown事件,并检查按下的按钮是否为中间按钮。然后确定是否采取默认操作,如果不采取默认操作,则通过调用event.preventDefault阻止默认操作。问题在于实际的鼠标按下与执行操作之间存在延迟,因此当用户按下并按住该按钮时,不会立即执行该操作。取而代之的是,在短时间内观察到鼠标的移动,并基于该移动,或者在释放按钮之后执行自定义操作,或者立即执行mousedown的默认操作。在采取默认操作的情况下,我希望Firefox的行为就像用户按下中间按钮一样。开始自动滚动。这不会发生,因为browser chrome对合成事件(以编程方式产生的事件)没有反应。

如何以编程方式触发Firefox中的自动滚动?有没有办法使用userChrome.css来更改行为(例如,使自动滚动监听合成事件)?

var elem = document.getElementById('watchedElement')
var active = false

elem.onmousedown = function(event) {
  if (event.button !== MIDDLE_BUTTON || active) { return }
  event.preventDefault()

  startParams = getStartParams()
  active = true
}

elem.onmousemove = function(event) {
  if (!active) { return }

  if (shouldTakeDefaultAction()) {
    elem.dispatchEvent(new MouseEvent('mousedown',
                           {'button': MIDDLE_BUTTON, 'which': MIDDLE_BUTTON}))
    active = false
  }
}

elem.onmouseup = function(event) {
  if (event.button !== MIDDLE_BUTTON || !active) { return }
  event.preventDefault()

  takeCustomAction()
  active = false
}

编辑:更多信息

我为YouTube创建了一个Greasemonkey插件,该插件可以执行以下操作:

  • 当我单击中间按钮(不拖动)时,切换全屏模式
  • 按下中间按钮向左/向右拖动时,它将在视频中向后/向前搜索
  • 当我上下拖动时,我想滚动

因此必须阻止默认操作,并且将鼠标拖动到一定距离时,我们可以决定是搜索还是滚动。一旦通过拖动“移动”了一定数量的像素,就计算并评估了轨迹的角度。如果拖动是垂直的,则我要激活滚动,否则请等待按钮被释放然后搜索。仅在释放按钮后才搜索视频,例如。拖动时没有“实时预览”。

1 个答案:

答案 0 :(得分:3)

据我所知,无法从JavaScript内触发Firefox的自动滚动模式。但是,显然可以在其处于活动状态时进行中断,例如通过致电window.scrollTo()

此外,如果页面实际上并未水平滚动,则在自动滚动模式处于活动状态时水平拖动鼠标光标也无效。大多数网页都没有。

基于这些观察结果,这是一个替代解决方案(略图):

  1. 让中间点击传播并触发其默认操作,从而启用自动滚动模式。

  2. 像往常一样执行水平拖动检测。

  3. 如果检测到水平拖动,请调用window.scrollTo(window.scrollX, window.scrollY),这将关闭Firefox的自动滚动模式,然后继续进行视频搜索。

我用此方法看到的主要缺点是:a)当您检测到拖动方向时,自动滚动指示器将短暂可见;以及b)如果用户稍微向对角方向拖动鼠标,它们仍然可能最终滚动页面上下几个像素。 (这可能取决于用户的谨慎程度和协调程度。自动滚动功能本身似乎具有一个小的内置“死区”,因此您需要将鼠标光标向上或向下移动至少十二个像素左右。在页面实际开始垂直滚动之前。)

前者似乎是不可避免的,但界面上有些古怪;您的用户可能甚至没有真正注意到它。为了缓解后一个问题,您可能想要在步骤1中保存window.scrollXwindow.scrollY的值,并在步骤3中使用保存的值,从而将页面恢复到之前的滚动位置拖动的开始。在页面稍微滚动然后跳回时,这仍然可能导致令人讨厌的“混蛋”,但是,与使页面永久向下移动相比,它可能不那么令人讨厌。