【问题标题】:Scroll event isn't propagated to parent滚动事件不会传播到父级
【发布时间】:2018-11-26 14:23:54
【问题描述】:

我有一个带有overflow-y: scroll; 的grid-div,这个grid-div 有一段时间是10000pixels 长。在 grid-div 的特定项目的 mouserhover 上,我正在触发 mouserhover 事件,并且用户在元素上显示工具提示。现在用户在 body 元素下添加这个弹出窗口。并且用户在窗口上编写了滚动事件,如果触发了滚动事件,则隐藏工具提示。但是当用户仍然在我的 grid-div 上时,滚动事件仅在 grid-div 上触发,并且事件不会传播到任何父元素(html、body、window),因此用户无法隐藏该元素。

那么为什么滚动事件不像点击事件那样传播呢?传播事件的可能解决方案是什么?

这是我面临的问题的示例fiddle,这里我没有添加工具提示,而只是重现该滚动问题的示例代码。在这里,我期望对于每个“Scrolled On div”都应该在日志中写入“Scrolled On Window”。

$(window).on("scroll", function() {
  // While scrolling on div why this event is not fired?
  $('#eventData').append('<div>Scrolled On Window</div>');
});

$('#grid-div').on("scroll", function() {
  $('#eventData').append('<div>Scrolled On div</div>');
});
#grid-div {
  height: 200px;
  overflow-y: scroll;
  border: 1px solid gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div id="grid-div">
  <br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A
</div>
<div id="eventData">
</div>

【问题讨论】:

  • 您需要显示您遇到问题的代码。根据您的代表次数,您应该知道这一点。当triggered by elements 时滚动事件也不会冒泡
  • @SuperCoolHandsomeGelBoy:添加小提琴...
  • @PatrickEvans:是的,我正在制作小提琴……但错误地提前发布了问题;)
  • @Pete:更新小提琴
  • 你可能需要debounce or throtle滚动。

标签: javascript jquery


【解决方案1】:

当它是触发事件的元素时,滚动事件不会冒泡

https://developer.mozilla.org/en-US/docs/Web/Events/scroll

气泡:不在元素上,而是在触发时气泡到默认视图 在文件上

如果您还想执行窗口滚动事件,您需要自己触发它

$(window).trigger("scroll");

$(window).on("scroll", function(e,e2) {
  // While scrolling on div why this event is not fired?
  //get original event if triggered programmatically
  e = e2 || e;
  $('#eventData').append('<div>Scrolled On Window</div>');
});

$('#grid-div').on("scroll", function(e) {
  $('#eventData').append('<div>Scrolled On div</div>');
  //all parameters after the first will be passed to the event callback
  //so here passing it the original event.
  $(window).trigger("scroll",e);
});
#grid-div {
  height: 100px;
  overflow-y: scroll;
  border: 1px solid gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div id="grid-div">
  <br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A<br/>A
</div>
<div id="eventData">
</div>

【讨论】:

  • hmmm,有什么方法可以让我忽略 $(window).trigger("scroll",e);???
  • 如果您的目标是隐藏工具提示,为什么不在 grid-div 滚动事件中隐藏它?
  • grid div 是独立组件,tooltip 是独立组件,所以我不希望grid 组件中有tooltip 的具体代码
  • @ParagBhayani,如果它们彼此独立,那么两者都不应该尝试相互交互或解决涉及对方的问题。那将是最终开发人员的问题。
  • 嗯,这就是为什么我想知道为什么不传播滚动,因为它应该是通用的方法......
【解决方案2】:

有已知的方法,如其他人建议的手动触发事件

$(window).trigger("scroll");

还有另一种通用的方法,就是在捕获阶段监听滚动事件(旧的 IE 浏览器不支持这个)。

document.addEventListener("scroll", function() {
  console.log("document Scrolled during capture phase")
}, true);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2017-06-08
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    相关资源
    最近更新 更多