背景
我正在编写一个组件,可以在点击时打开子菜单。我无法知道此组件在页面上的放置位置或嵌套在可能设置overflow
属性的区域中的距离。
鉴于溢出可能会剪切子菜单,而是将子菜单本身附加到body
,使其具有绝对位置,并通过代码将其链接到原始组件。这可以解决溢出问题。
问题:
但是,如果用户滚动子菜单仍然存在,而不是使用其链接的组件移动,所以我需要能够收听页面上发生的任何和所有滚动事件所以我可以适当地重新定位子菜单。
如果有一种简单的方式来收听所有滚动事件,或者如果有另一种更好的方式来执行此组件,我将非常感谢任何输入。
我已经和JSFiddle一起玩了sandbox但是我没有取得任何成功,也没有在这个网站或其他任何地方找到答案;虽然也许我使用了错误的搜索词,但我无法想象我是第一个有这个问题的人。
修改
为了解决投票问题,我没有在没有提供代码的情况下请求帮助调试问题,也不会问一些未来不会帮助任何人的事情。我问我怎么会去听某种类型的所有事件而不管可能发生在哪里,我觉得这种事件在全球都适用,尽管这可能是主观的。
修改
$(window).on('scroll', function(){ /**/ });
不是一个选项,因为它只监听窗口滚动,而不是任何嵌套的滚动。
$('#ex1 #ex2').on('scroll', function(){ /**/ });
不是一个选项,因为它要求实施代码的人知道页面上可能滚动的任何当前或可能的未来区域。
答案 0 :(得分:37)
您应该能够使用第三个参数true
附加文档级侦听器,以捕获所有元素上的滚动事件。这是看起来像:
document.addEventListener('scroll', function(e){ }, true);
最后的true
是重要的部分,它告诉浏览器在调度时捕获事件,即使该事件通常不会冒泡,如更改,焦点和滚动。
以下是一个示例:http://jsbin.com/sayejefobe/1/edit?html,js,console,output
答案 1 :(得分:2)
您需要查看滚动是发生在窗口级别还是元素级别。通常在你的情况下'*'就足够了。
$('*').scroll(function() {
alert('scroll');
});
以下是更新后的链接:http://jsfiddle.net/wAadt/1
答案 2 :(得分:2)
如何列出所有元素和窗口?
$('*').add(window).scroll(function() {
console.log('scroll');
});
答案 3 :(得分:2)
执行此操作的最佳方法是找出哪些元素可滚动,然后将侦听器附加到它们。您可以在任何页面更改上运行此功能,以确保您始终获得所有滚动条。
这比在每个元素上使用侦听器(正如其他解决方案所做的)在性能方面的好处是:每次页面更新时,侦听器都会更新。有很多,这很快就会影响性能和内存使用。
更新的小提琴:http://jsfiddle.net/ArtOfCode/wAadt/8/
代码:
$("*").each(function() {
if($(this).css("overflow") == "auto" || $(this).css("overflow") == "scroll") {
$(this).scroll(function() {
console.log("scroll");
});
}
});
(感谢@pebbl的帮助)
然后你可以将它包装在一个函数中并在更改时运行它:
function addListeners() {
$("*").each(function() {
if($(this).css("overflow") == "auto" || $(this).css("overflow") == "scroll") {
$(this).css('border', '1px solid red').scroll(function() {
console.log("scroll");
});
}
});
}
$("body").on("change",function()
addListeners();
}
不可否认,它有点令人费解,但它解决了尽可能少的事件监听器的问题。