Ну ... Я нашел некоторые проблемы в каждом предлагаемом решении здесь.
- Вы должны быть в состоянии выбрать, если вы хотите весь элемент быть на экране или только любой его части
- Предлагаемые решения терпит неудачу, если элемент выше/шире окна и своего рода обложки окно браузера.
Вот мое решение, которое включает jQuery
.fn
функцию экземпляра и expression
. Я создал больше переменных внутри своей функции, чем мог, но для сложной логической задачи я хотел бы разделить ее на более мелкие, четко обозначенные фрагменты.
Я использую getBoundingClientRect
метод, который возвращает позицию элемента относительно окна просмотра поэтому мне не нужно заботиться о положении прокрутки
Useage:
$(".some-element").filter(":onscreen").doSomething();
$(".some-element").filter(":entireonscreen").doSomething();
$(".some-element").isOnScreen(); // true/false
$(".some-element").isOnScreen(true); // true/false (partially on screen)
$(".some-element").is(":onscreen"); // true/false (partially on screen)
$(".some-element").is(":entireonscreen"); // true/false
Источник:
$.fn.isOnScreen = function(partial){
//let's be sure we're checking only one element (in case function is called on set)
var t = $(this).first();
//we're using getBoundingClientRect to get position of element relative to viewport
//so we dont need to care about scroll position
var box = t[0].getBoundingClientRect();
//let's save window size
var win = {
h : $(window).height(),
w : $(window).width()
};
//now we check against edges of element
//firstly we check one axis
//for example we check if left edge of element is between left and right edge of scree (still might be above/below)
var topEdgeInRange = box.top >= 0 && box.top <= win.h;
var bottomEdgeInRange = box.bottom >= 0 && box.bottom <= win.h;
var leftEdgeInRange = box.left >= 0 && box.left <= win.w;
var rightEdgeInRange = box.right >= 0 && box.right <= win.w;
//here we check if element is bigger then window and 'covers' the screen in given axis
var coverScreenHorizontally = box.left <= 0 && box.right >= win.w;
var coverScreenVertically = box.top <= 0 && box.bottom >= win.h;
//now we check 2nd axis
var topEdgeInScreen = topEdgeInRange && (leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally);
var bottomEdgeInScreen = bottomEdgeInRange && (leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally);
var leftEdgeInScreen = leftEdgeInRange && (topEdgeInRange || bottomEdgeInRange || coverScreenVertically);
var rightEdgeInScreen = rightEdgeInRange && (topEdgeInRange || bottomEdgeInRange || coverScreenVertically);
//now knowing presence of each edge on screen, we check if element is partially or entirely present on screen
var isPartiallyOnScreen = topEdgeInScreen || bottomEdgeInScreen || leftEdgeInScreen || rightEdgeInScreen;
var isEntirelyOnScreen = topEdgeInScreen && bottomEdgeInScreen && leftEdgeInScreen && rightEdgeInScreen;
return partial ? isPartiallyOnScreen : isEntirelyOnScreen;
};
$.expr.filters.onscreen = function(elem) {
return $(elem).isOnScreen(true);
};
$.expr.filters.entireonscreen = function(elem) {
return $(elem).isOnScreen(true);
};
Я дал ответ на этот вопрос, а также на этом «дубликата» вопрос: http://stackoverflow.com/ вопросы/5353934/check-if-element-is-visible-on-screen/5354536 # 5354536 – Tokimon