Сейчас большинство браузеров поддерживают getBoundingClientRect метод, который стал лучшей практикой. Использование старого ответа очень медленно , не точно и имеет несколько ошибок .
Правильное решение выбрано почти никогда не точное . Вы можете узнать больше о его ошибках.
Это решение было протестировано на IE7 +, iOS5 + Safari, Android2 +, Blackberry, Opera Mobile и IE Mobile 10 .
function isElementInViewport (el) {
//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
Как использовать:
Вы можете быть уверены, что приведенная выше функция возвращает правильный ответ в тот момент, когда она вызывается, но как насчет отслеживания видимости элемента как события?
Поместите следующий код внизу тега <body>
:
function onVisibilityChange(el, callback) {
var old_visible;
return function () {
var visible = isElementInViewport(el);
if (visible != old_visible) {
old_visible = visible;
if (typeof callback == 'function') {
callback();
}
}
}
}
var handler = onVisibilityChange(el, function() {
/* your code go here */
});
//jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);
/* //non-jQuery
if (window.addEventListener) {
addEventListener('DOMContentLoaded', handler, false);
addEventListener('load', handler, false);
addEventListener('scroll', handler, false);
addEventListener('resize', handler, false);
} else if (window.attachEvent) {
attachEvent('onDOMContentLoaded', handler); // IE9+ :(
attachEvent('onload', handler);
attachEvent('onscroll', handler);
attachEvent('onresize', handler);
}
*/
Если вы делаете какие-либо модификации DOM, они, конечно, могут изменить видимость вашего элемента.
Указания и общие подводные камни:
Может быть, вам нужно отслеживать масштабирование страницы / сжатие мобильного устройства? jQuery должен обрабатывать масштабирование / масштабирование кросс-браузер, иначе первый или второй ссылка должна вам помочь.
Если вы измените DOM , это может повлиять на видимость элемента. Вы должны взять это под контроль и позвонить handler()
вручную. К сожалению, у нас нет кросс-браузерного события onrepaint
. С другой стороны, это позволяет нам проводить оптимизацию и перепроверять только те модификации DOM, которые могут изменить видимость элемента.
Никогда и никогда используйте его внутри jQuery $ (document) .ready () только потому, что гарантия не применяется в данный момент. Ваш код может работать локально с вашим CSS на жестком диске, но после установки на удаленный сервер он потерпит неудачу.
После запуска DOMContentLoaded
применяются стили , но изображения еще не загружены . Итак, мы должны добавить window.onload
слушатель событий.
Мы пока не можем поймать событие увеличения / увеличения.
В крайнем случае может быть следующий код:
/* TODO: this looks like a very bad code */
setInterval(handler, 600);
Вы можете использовать потрясающую функцию pageVisibiliy HTML5 API, если вам важно, если вкладка с вашей веб-страницей активна и видима.
TODO: этот метод не обрабатывает две ситуации: