如何在 Javascript 中实现“onVisible”事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3806290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement an 'onVisible' event in Javascript?
提问by RobertG
Is there any technique or set of techniques that can be used to implement what, in effect, would be an onVisible 'event' in JavaScript?
是否有任何技术或一组技术可用于在 JavaScript 中实现实际上是 onVisible 的“事件”?
I would like my JavaScript to detect when an element in a web page, such as a paragraph of text, or an image, becomes visible in a browser window as a user scrolls down a page. I would also like a corresponding 'event', onNotVisible, to fire when an element that was once visible in the browser window can no longer be seen.
当用户向下滚动页面时,我希望我的 JavaScript 检测网页中的元素(例如一段文本或图像)何时在浏览器窗口中可见。我还希望在无法再看到曾经在浏览器窗口中可见的元素时触发相应的“事件”onNotVisible。
If it cannot be easily implemented in JavaScript, are there any browser specific events that can provide the same functionality?
如果它不能在 JavaScript 中轻松实现,是否有任何浏览器特定事件可以提供相同的功能?
回答by Bj?rn
I had to try this myself, and this is what I came up with:
我不得不自己尝试这个,这就是我想出的:
<!DOCTYPE html>
<html>
<head>
<script>
var EventListener = function(element, callback) {
this._el = element;
this._cb = callback;
this._at = false;
this._hasBeenVisible = false;
this._hasBeenInvisible = true;
var _me = this;
window.onscroll = function() {
for (q in EventListener.queue.onvisible) {
EventListener.queue.onvisible[q].call();
}
for (q in EventListener.queue.oninvisible) {
EventListener.queue.oninvisible[q].call();
}
};
return {
onvisible: function() {
EventListener.queue.onvisible.push(function() {
if (!_me._at && _me._hasBeenInvisible && (window.pageYOffset + window.innerHeight) > _me._el.offsetTop && window.pageYOffset < (_me._el.offsetTop + _me._el.scrollHeight)) {
_me._cb.call();
_me._at = true;
_me._hasBeenVisible = true;
}
});
EventListener.queue.oninvisible.push(function() {
if (_me._hasBeenVisible && ((window.pageYOffset + window.innerHeight) < _me._el.offsetTop || window.pageYOffset > (_me._el.offsetTop + _me._el.scrollHeight))) {
_me._hasBeenInvisible = true;
_me._hasBeenVisible = false;
_me._at = false;
}
});
},
oninvisible: function() {
EventListener.queue.oninvisible.push(function() {
if (!_me._at && _me._hasBeenVisible && ((window.pageYOffset + window.innerHeight) < _me._el.offsetTop || window.pageYOffset > (_me._el.offsetTop + _me._el.scrollHeight))) {
_me._cb.call();
_me._at = true;
_me._hasBeenInvisible = true;
}
});
EventListener.queue.onvisible.push(function() {
if (_me._hasBeenInvisible && (window.pageYOffset + window.innerHeight) > _me._el.offsetTop && window.pageYOffset < (_me._el.offsetTop + _me._el.scrollHeight)) {
_me._hasBeenVisible = true;
_me._hasBeenInvisible = false;
_me._at = false;
}
});
}
};
}
EventListener.queue = {
onvisible: [],
oninvisible: []
};
function addListener(element, event, fn) {
if (typeof element == 'string')
element = document.getElementById(element);
var listener = new EventListener(element, fn);
if (listener['on' + event.toLowerCase()])
return listener['on' + event.toLowerCase()].call();
}
window.onload = function() {
addListener('event-element', 'visible', function() {
alert("Element One Visible!");
});
addListener('event-element', 'invisible', function() {
alert("Element One Invisible!");
});
addListener('event2-element', 'visible', function() {
alert("Element Two Visible!");
});
addListener('event2-element', 'invisible', function() {
alert("Element Two Invisible");
});
}
</script>
</head>
<body>
<h1>Hey!</h1>
<div style="height: 1500px;">
Please scroll down some pixels.
</div>
<p id="event-element">
This element should cast an event 'onvisible' and 'oninvisible'.
</p>
<div style="height: 1000px;">
</div>
<p id="event2-element">
Another one!
</p>
</body>
</html>
Tested in:
测试于:
- FireFox 3.6 (works)
- Chrome 6.0.472 (works)
- Opera 10.62 (works)
- Safari 4 (Works in a very buggy and irritating way, don't use popups if you try it here!)
- 火狐 3.6(作品)
- Chrome 6.0.472(有效)
- 歌剧 10.62(作品)
- Safari 4(以一种非常有缺陷和刺激性的方式工作,如果您在这里尝试,请不要使用弹出窗口!)
(The code is also available on PasteBin)
The above code is not optimized in any way, I just started writing and ended when it worked. Preferrably you would probably want to use only one queue, refactor some code and make it more generic. Provided as is.
上面的代码没有做任何优化,我刚开始写,运行时就结束了。最好您可能只想使用一个队列,重构一些代码并使其更通用。按原样提供。
回答by DanMan
You'd have to set up an event listener for the document's or window's onscroll event. Then you'd measure the currently visible area by adding the clientHeight to scrollTop, and then you check if your element of choice is within that area. Something like this
您必须为文档或窗口的 onscroll 事件设置一个事件侦听器。然后,您将通过将 clientHeight 添加到 scrollTop 来测量当前可见区域,然后检查您选择的元素是否在该区域内。像这样的东西
myElem=document.getElementById('some_id');
scrollOffset=document.getElementsByTagName('html')[0].scrollTop;
visibleHeight=document.getElementsByTagName('html')[0].clientHeight;
if(myElem.offsetTop>=scrollOffset && myElem.offsetTop<=scrollOffset+visibleHeight){
// element is in visible area
}
If that's the case you set some flag somewhere in your code.
如果是这种情况,您可以在代码中的某处设置一些标志。
You're likely to run into browser incompatibilities there though. So better use some library.
不过,您可能会遇到浏览器不兼容的问题。所以最好使用一些图书馆。
回答by David Hull
One of the answersin the questionlinked above by @edbond gives a pointer to the jQuery appear plugin. This plugin allows you to attach appearand disappearcallbacks to an element that are called as the element scrolls into and out of view, which sounds like exactly what you are looking for.
其中的答案的问题,上述由@edbond链接给出了一个指向jQuery的出现插件。这个插件允许你附加appear和disappear回调一个元素,当元素滚动进出视图时被调用,这听起来正是你正在寻找的。

