Cóż ... znalazłem kilka problemów w każdym proponowanym tutaj rozwiązaniu.
- Powinieneś móc wybrać, czy chcesz, aby cały element był na ekranie, czy tylko jakakolwiek jego część
- Proponowane rozwiązania zawodzą, jeśli element jest wyższy / szerszy niż okno i trochę zakrywa okno przeglądarki.
Oto moje rozwiązanie, które obejmuje jQuery
.fn
funkcję instancji iexpression
. Utworzyłem więcej zmiennych w mojej funkcji, niż mogłem, ale w przypadku złożonego problemu logicznego lubię podzielić ją na mniejsze, wyraźnie nazwane części.
Używam getBoundingClientRect
metody, która zwraca pozycję elementu względem widoku, więc nie muszę przejmować się pozycją przewijania
Zastosowanie :
$(".some-element").filter(":onscreen").doSomething();
$(".some-element").filter(":entireonscreen").doSomething();
$(".some-element").isOnScreen();
$(".some-element").isOnScreen(true);
$(".some-element").is(":onscreen");
$(".some-element").is(":entireonscreen");
Źródło :
$.fn.isOnScreen = function(partial){
var t = $(this).first();
var box = t[0].getBoundingClientRect();
var win = {
h : $(window).height(),
w : $(window).width()
};
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;
var coverScreenHorizontally = box.left <= 0 && box.right >= win.w;
var coverScreenVertically = box.top <= 0 && box.bottom >= win.h;
var topEdgeInScreen = topEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );
var bottomEdgeInScreen = bottomEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );
var leftEdgeInScreen = leftEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );
var rightEdgeInScreen = rightEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );
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);
};