【问题标题】:Transfer a mousewheel/scroll event from one div to another将鼠标滚轮/滚动事件从一个 div 转移到另一个
【发布时间】:2016-06-28 14:54:50
【问题描述】:

我想知道是否可以以及如何将鼠标滚轮/滚动事件(用户尝试滚动)从header 传输到@987654329 @。

我有以下示例情况:

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

情况


情况 2 是可以滚动整个页面的“传统”设置。当您的光标悬停在标题上时(即使它可能已修复),滚动尝试将传递到 body/html。由于容器溢出 body/html,如果用户旋转他/她的鼠标滚轮,容器将移动/滚动。因为 header 是固定的,所以它会保持在相同的位置。

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

更新 1

situation 1 的 jsfiddle

situation 2 的 jsfiddle

更新 2

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

更新 3

This 最接近我基于“其他解决方案 2”的预期解决方案。感谢 Maksym Stepanenko 的研究,这似乎还不可能。我暂时不回答这个问题,以防有人找到方法:)


其他解决方案


这些问题讨论了这个问题,但没有像我期望的那样为这个设置提供解决方案:

【问题讨论】:

  • 您能否将您的 HTML 添加到问题中。这对答案至关重要,因为我们需要了解结构如何组合在一起以确定事件冒泡。
  • 是的,当然!给我几分钟:)
  • 你不能只创建一个滚动容器的javascript/jQuery函数,它由容器的滚动事件和标题的滚动事件调用吗?
  • 是的,那么解决方案看起来像(如果我理解正确的话)设置了 scrollTop 的“其他解决方案 2”。然而,这并不像浏览器倾向于自行滚动那样“流畅”。你可以看到这个小提琴的区别(提供了那个遮阳篷:jsfiddle.net/Toukakoukan/5bwWe/20),这个例子在 Firefox 中也不起作用,但可以修复
  • 有些人在 SO 上只是为了投反对票,然后他们继续提出另一个问题来做同样的事情。他们看到语法错误并投反对票。人很奇怪。

标签: javascript jquery html css


【解决方案1】:

我最终也需要这个功能。

如果您正在收听“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.net/9hydg8sx/8
【解决方案2】:

经过数小时的研究,这是我能找到的。

  1. 您实际上不能调用浏览器对事件的默认反应(例如滚动),因为它发生在事件被调度之前。 here 解释了类似的事情。

  2. dispatchEvent 所做的 - 实际上是触发在 javascript 中实现的处理程序的事件。例如Fiddle

  3. 您唯一的跨浏览器方式是 scrollTop 有或没有不同的缓动(如 jquery animate)。因为即使调度滚动事件对于 FF 和其他浏览器的工作方式也不同。

希望对你有帮助。

更新 1

我发现this post 指出您实际上可以在 Firefox 中模拟滚动事件,但我无法使其工作。

【讨论】:

  • 感谢您的研究!我也尝试了另一篇文章,但 window.QueryInterface 在 chrome 和 FireFox 中都未定义,所以我也不知道他是如何工作的..
【解决方案3】:

如果您尝试在 iframe 中捕获鼠标滚轮事件并将其发送给父级,这就是我让它工作的方式。

在 iframe 中加载的页面中,我放置了一个 id="everything" 的 DIV,它包含了页面的整个 BODY

然后,在 iframe 中加载的页面底部插入此 SCRIPT。

 document.getElementById("everything").addEventListener("mousewheel", function (e) {
    parent.scrollme(e.deltaY);
});

然后在父级中,我必须在顶部附近插入此 SCRIPT

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

}

这会将 Wheelscroll 捕获在 iframe 中,并将事件推送到父级。

【讨论】:

  • 感谢您的遮阳篷。这个使用原理和@zjm 的 awnser 一样,只是滚动事件的来源不同。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 2016-11-05
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
相关资源
最近更新 更多