在另一个 DOM 元素上调度鼠标滚轮事件
Posted
技术标签:
【中文标题】在另一个 DOM 元素上调度鼠标滚轮事件【英文标题】:Dispatch mouse wheel event on another DOM element 【发布时间】:2013-03-09 10:35:58 【问题描述】:我有一个带有可滚动 div 的网页。 在可滚动 div 之上,我绝对定位了与可滚动 div 的一半重叠的 div。
当我将鼠标光标放在可滚动的 div 上时,我可以用鼠标滚轮滚动它。但是当我将光标移到重叠的 div 上时,鼠标滚轮会停止滚动该 div(这是正确的行为,因为绝对定位的 div 不在可滚动的 div 内)。
问题:如何将绝对定位的 div 接收到的滚动事件传递或分派给这个底层的可滚动 div,以使这个绝对定位的 div 对鼠标滚轮事件“透明”。
我可以让它在 Chrome 中运行,但不能在 IE 和 Firefox 中运行。 如何重写此代码以使其在 IE 和 Firefox 中运行?
if ($.browser.webkit)
$(".overlap-container").bind("mousewheel", function (e)
var origEvent = e.originalEvent;
var evt = document.createEvent("WheelEvent");
evt.initWebKitWheelEvent(
origEvent.wheelDeltaX,
origEvent.wheelDeltaY,
window,
0,
0,
0,
0,
origEvent.ctrlKey,
origEvent.altKey,
origEvent.shiftKey,
origEvent.metaKey);
$(".scroll-container").get(0).dispatchEvent(evt);
);
请参见此处的示例: http://jsfiddle.net/HAc4K/5
已编辑:此问题最初来自 jqGrid - 冻结的列不会对鼠标滚轮滚动做出反应。
在 Chrome 和 Firefox 中支持很棒的 CSS 属性:pointer-events:none
【问题讨论】:
【参考方案1】:看起来像是 jQuery 的一个已知问题:OriginalEvent not supported in IE
【讨论】:
这里jsfiddle.net/HAc4K/5是没有originalEvent的更新版本【参考方案2】:简短的回答:在使用 Internet Explorer 的情况下,您在 the demo 中使用了错误的 initWheelEvent
参数。该方法应该有the documentation 中描述的16 个参数。你目前只使用了11个参数相同的initWebKitWheelEvent
,但initWheelEvent
的所有参数的含义绝对是另一回事。你必须修复initWheelEvent
的参数。
【讨论】:
这里是更改版本jsfiddle.net/HAc4K/5,带有该文档中的参数,并且没有使用 originalEvent。我尝试了很多不同的参数集,但都没有成功。【参考方案3】:使用RetargetMouseScroll
(overlap container, scroll container)
。
【讨论】:
此库仅适用于window
目标,不适用于 htmlElement。但经过一些编辑后,它开始工作。这不是真正的重定向,而是接近它——至少这个库正确地计算了像素中的滚动移位量——所以滚动左右部分的外观没有区别。
顺便说一句,更改是:在第 34 行替换 targetWindow.scrollBy(0, scrollAmount); with if (targetWindow.scrollBy) targetWindow.scrollBy(0, scrollAmount); else if (targetWindow.scrollByLines) targetWindow.scrollByLines(scrollAmountLines);否则 targetWindow.scrollTop = targetWindow.scrollTop + scrollAmount;
谢谢,我会考虑将其添加到库中。【参考方案4】:
我意识到这不是您正在寻找的,但至少在 Chrome、IE7+ 和 Firefox 3.5+ 中,这可以满足您的要求 - 当覆盖它的 div 接收滚动事件时滚动底层 div:
http://jsfiddle.net/b9chris/yM3qs/
这样做只是因为重叠的 div 是它重叠的 div 的子级 - 没有 jquery 传递任何鼠标滚轮事件(尽管它正在监听滚动以确保重叠的 div 保持在需要的位置)。
然而,在 jqGrid 中实现这种解决方法可能需要在其中修改相当多的代码。
HTML:
<div id=under>
(content goes here)
<div id=over></div>
</div>
CSS:
#under
position: absolute;
left: 0; top: 0;
width: 220px; height: 200px;
overflow-y: scroll;
#over
position: absolute;
left: 1px; top: 100px;
width: 200px; height: 100px;
z-index: 2;
JS:
(function()
$('#under').on('scroll', function()
$('#over').css('top', $(this).scrollTop() + 100);
);
)();
【讨论】:
【参考方案5】:这是2019年重叠容器获取***事件的解决方案:
document.querySelector('.overlap').on('wheel', (e) =>
const overlap = e.target
overlap.style.pointerEvents = 'none'
setTimeout(() => overlap.style.pointerEvents = 'auto', 0)
)
这样 overlapped 元素会从名为 .overlap
的 overlapping 元素获取***事件。
【讨论】:
以上是关于在另一个 DOM 元素上调度鼠标滚轮事件的主要内容,如果未能解决你的问题,请参考以下文章