如何在Javascript中实现'onVisible'事件?
是否有任何技术或一组技术可用于实现什么,实际上,这将是JavaScript中的一个onVisible“事件”?
当用户向下滚动页面时,我希望使用JavaScript来检测网页中的元素(如文本段落或图像)在浏览器窗口中是否可见。 我还希望在浏览器窗口中一次可见的元素不能再被看到时触发相应的'event'onNotVisible。
如果在JavaScript中无法轻松实现,是否有任何可以提供相同功能的浏览器特定事件?
我不得不亲自尝试一下,这就是我想到的:
<!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>
经测试:
(该代码也可用于PasteBin)
上面的代码没有以任何方式进行优化,我刚刚开始编写并在其工作时结束。 最好你可能只想使用一个队列,重构一些代码并使其更通用。 按原样提供。
您必须为文档或窗口的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
}
如果是这样的话,你可以在你的代码中设置一些标志。
尽管如此,你可能会遇到浏览器不兼容问题。 所以最好使用一些库。
在上面通过@edbond链接的问题中的答案之一给出了一个指向jQuery插件的指针。 这个插件允许你将appear
和disappear
回调附加到元素,当元素滚动进出视图时调用该元素,这听起来像你正在寻找的东西。