将鼠标滚轮事件从一个div传递到另一个div

10

我想知道如何将鼠标滚轮/滚动事件(用户尝试滚动)从

传递到,并想知道是否可能以及如何实现。

以下是我遇到的情况示例:

+------------+     +------------+|
|   header   |     |   header   ||
+------------+     +------------+|
|           ||     |            ||
|           ||     |            ||
| container ||     | container  ||
|           ||     |            ||
|           ||     |            ||
+------------+     +------------+|
 situation 1        situation 2

情境


情境2是“传统”设置,在此设置中,可以滚动整个页面。当您的光标悬停在标题上(即使它可能是固定的),滚动尝试将被传递到body/html。由于容器溢出了body/html,因此如果用户旋转鼠标滚轮,则容器将移动/滚动。由于标题是固定的,因此它将保持在相同的位置。

情境1是我的测试设置。容器的内容溢出容器会导致容器显示滚动条。现在,当用户的光标悬停在标题上并且用户旋转鼠标滚轮时,我希望容器也能滚动。

更新1

情境1 的jsfiddle。

情境2 的jsfiddle。

更新2

我创建了另一个fiddle,展示了我的进展,其中可能包含解决方案,但我无法让它起作用。这可能会启发其他人找到实际的解决方案 :) 我收到错误:(index):69 Uncaught InvalidStateError: Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched.(目前仅在chrome中滚动事件)

更新3

最接近我期望的解决方案,它基于“其他解决方案2”。感谢Maksym Stepanenko的研究,似乎尚不可能。如果有人找到方法,我将保留问题未答复 :)


其他解决方案


这些问题讨论了这个问题,但没有提供我期望的工作方式的解决方案:


1
你能否将你的HTML代码添加到问题中?这对于回答非常重要,因为我们需要看到结构如何配合以确定事件冒泡。 - Rory McCrossan
好的,当然可以!请给我一些时间 :) - Dex
你能否创建一个JavaScript/jQuery函数来滚动容器,然后在容器和标题的滚动事件中调用它? - Sgt AJ
如果我理解正确,那么解决方案看起来像是“其他解决方案2”,其中scrollTop被设置。然而,这并不像浏览器自己滚动那样“流畅”。您可以在此fiddle中查看差异(提供了该答案:http://jsfiddle.net/Toukakoukan/5bwWe/20/),此示例在Firefox中不起作用,但可以修复。 - Dex
为什么毫无理由地给我点踩?我的意思是,只要给我提供一些改进问题的指针就可以了... - Dex
3
有些人在Stack Overflow上只是为了点踩,然后去回答另一个问题也会做同样的事情。他们看到语法错误就会点踩。人真奇怪。 - Alexandre
3个回答

5

我也需要这个功能。

如果你正在监听"wheel"事件,你可以获取有关滚动的"delta"信息。然后,你只需将该差值应用于目标div即可。

document.addEventListener('DOMContentLoaded', function() {
  const target = document.querySelector('#container');

  // listen on the whole document; you could restrict this to an element though
  document.addEventListener('wheel', function(event) {
    target.scrollTop += event.deltaY;
  });
});

我还没有在移动设备上测试过,但我怀疑它在那里不起作用。


谢谢您的回答。设置scrollTop方法可以工作,但它不是一个真正的滚动事件传输。我想要事件被传递的原因是浏览器对滚动事件的响应方式。当没有使用scrollTop时,它会平稳地滚动。如果使用scrollTop,则滚动变成了“震动”到新位置。请查看此jsfiddle中滚动的差异:https://jsfiddle.net/9hydg8sx/8/ - Dex

3
经过多小时的研究,我找到了以下内容:
  1. 你实际上无法调用浏览器对事件(例如滚动)的默认反应,因为它发生在事件分派之前。

    类似的解释可以在这里找到。

  2. dispatchEvent的作用是触发JavaScript中实现的处理程序的事件。例如:Fiddle

  3. 你唯一跨浏览器的方法是使用scrollTop,带或不带不同的缓动效果(如jquery动画)。因为即使对于Firefox和其他浏览器,分派滚动事件的方式也有所不同。

希望这能够有所帮助。

更新1

我在这篇文章中找到,可以在Firefox中模拟滚动事件,但我无法让其正常工作。

谢谢你的研究!我也尝试了另一篇帖子,但无论在Chrome还是FireFox中,window.QueryInterface都未定义,所以我也不知道他是如何让它工作的。 - Dex

0
如果您正在尝试在iframe中捕获鼠标滚轮事件并将其发送到父级,这是我让它正常工作的方法。
在iframe加载的页面中,我放置了一个ID为"everything"的DIV,该DIV包围了整个BODY页面。
然后,在iframe中加载的页面底部插入此SCRIPT。
 document.getElementById("everything").addEventListener("mousewheel", function (e) {
    parent.scrollme(e.deltaY);
});

然后在父级中,我必须在顶部附近插入这个脚本

function scrollme( i ){
 window.scrollTo(window.scrollX, window.scrollY + i);

}

这将在 iframe 中捕获滚轮事件并将其传递给父级。


谢谢您的回答。这个使用了与@zjm的回答相同的原理,尽管滚动事件的来源不同。 - Dex

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