Я загружаю элементы через AJAX. Некоторые из них видны только при прокрутке страницы.
Есть ли способ узнать, находится ли элемент в видимой части страницы?
Это должно сделать трюк:
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
Простая служебная функция Это позволит вам вызвать функцию утилиты, которая принимает элемент, который вы ищете, и если вы хотите, чтобы элемент полностью отображался или частично.
function Utils() {
}
Utils.prototype = {
constructor: Utils,
isElementInView: function (element, fullyInView) {
var pageTop = $(window).scrollTop();
var pageBottom = pageTop + $(window).height();
var elementTop = $(element).offset().top;
var elementBottom = elementTop + $(element).height();
if (fullyInView === true) {
return ((pageTop < elementTop) && (pageBottom > elementBottom));
} else {
return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
}
}
};
var Utils = new Utils();
Использование
var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);
if (isElementInView) {
console.log('in view');
} else {
console.log('out of view');
}
Этот ответ в Vanilla:
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
var elemTop = rect.top;
var elemBottom = rect.bottom;
// Only completely visible elements return true:
var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
// Partially visible elements return true:
//isVisible = elemTop < window.innerHeight && elemBottom >= 0;
return isVisible;
}
isVisible = elementTop < window.innerHeight && elementBottom >= 0
? В противном случае половина элемента на экране возвращает false.
Лучший метод, который я нашел до сих пор, - это jQuery появляется плагин. Работает как шарм.
Восхищает пользовательское событие "появляется", которое срабатывает, когда элемент прокручивается в окно просмотра или иным образом становится видимым для пользователя.
$('#foo').appear(function() { $(this).text('Hello world'); });
Этот плагин можно использовать для предотвращения ненужных запросов на контент, скрытый или за пределами видимой области.
Вот мое чистое решение JavaScript, которое работает, если оно также скрыто внутри прокручиваемого контейнера.
Демо здесь (попробуйте изменить размер окна тоже)
var visibleY = function(el){
var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height,
el = el.parentNode
// Check if bottom of the element is off the page
if (rect.bottom < 0) return false
// Check its within the document viewport
if (top > document.documentElement.clientHeight) return false
do {
rect = el.getBoundingClientRect()
if (top <= rect.bottom === false) return false
// Check if the element is out of view due to a container scrolling
if ((top + height) <= rect.top) return false
el = el.parentNode
} while (el != document.body)
return true
};
РЕДАКТИРОВАТЬ 2016-03-26: Я обновил решение для учета прокрутки мимо элемента, чтобы он скрывался над верхней частью контейнера с возможностью прокрутки. РЕДАКТИРОВАТЬ 2018-10-08: Обновлено для обработки при прокрутке вне экрана над экраном.
return top <= document.documentElement.clientHeight && top >= 0;
Плагин jQuery Waypoints здесь очень приятный.
$('.entry').waypoint(function() {
alert('You have scrolled to an entry.');
});
На сайте плагина есть несколько примеров.
$('#my-div').waypoint(function() { console.log('Hello there!'); }, { offset: '100%' });
Как насчет
function isInView(elem){
return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}
После этого вы можете запускать все, что хотите, как только элемент будет выглядеть следующим образом
$(window).scroll(function(){
if (isInView($('.classOfDivToCheck')))
//fire whatever you what
dothis();
})
Это работает для меня просто отлично
WebResourcesDepot написал a script для загрузки при прокрутке, который использовал jQuery некоторое время назад. Вы можете посмотреть их Live Demo Here. Говядина их функциональности была такой:
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
lastAddedLiveFunc();
}
});
function lastAddedLiveFunc() {
$('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
$.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
function(data){
if (data != "") {
$(".wrdLatest:last").after(data);
}
$('div#lastPostsLoader').empty();
});
};
Tweeked Scott Dowding классная функция для моего требования - это используется для поиска, если элемент просто прокручивается в экран, то есть верхний край.
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
очень просто и эффективно определить, видится ли элемент в окне просмотра. Используя наблюдателя, он устраняет необходимость прикреплять событие scroll
и вручную проверять обратный вызов события.
// this is the target which is observed
var target = document.querySelector('div');
// configure the intersection observer instance
var intersectionObserverOptions = {
root: null,
rootMargin: '150px',
threshold: 1.0
}
var observer = new IntersectionObserver(onIntersection, intersectionObserverOptions);
// provice the observer with a target
observer.observe(target);
function onIntersection(entries){
entries.forEach(entry => {
console.clear();
console.log(entry.intersectionRatio)
target.classList.toggle('visible', entry.intersectionRatio > 0);
// Are we in viewport?
if (entry.intersectionRatio > 0) {
// Stop watching
// observer.unobserve(entry.target);
}
});
}
.box{ width:100px; height:100px; background:red; margin:1000px; }
.box.visible{ background:green; }
Scroll both Vertically & Horizontally...
<div class='box'></div>
isScrolledIntoView - очень нуждающаяся функция, поэтому я попробовал ее, она работает для элементов, которые не являются более сложными, чем область просмотра, но если элемент больше, чем область просмотра, он не работает. Чтобы исправить это, легко измените условие
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
:
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
Смотрите демонстрацию здесь: http://jsfiddle.net/RRSmQ/
Большинство ответов здесь не учитывают, что элемент также можно скрывать, потому что он прокручивается вне поля div, а не только всей страницы.
Чтобы покрыть эту возможность, вам в основном нужно проверить, находится ли элемент внутри границ каждого из его родителей.
Это решение делает именно это:
function(element, percentX, percentY){
var tolerance = 0.01; //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
if(percentX == null){
percentX = 100;
}
if(percentY == null){
percentY = 100;
}
var elementRect = element.getBoundingClientRect();
var parentRects = [];
while(element.parentElement != null){
parentRects.push(element.parentElement.getBoundingClientRect());
element = element.parentElement;
}
var visibleInAllParents = parentRects.every(function(parentRect){
var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
var visiblePercentageX = visiblePixelX / elementRect.width * 100;
var visiblePercentageY = visiblePixelY / elementRect.height * 100;
return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
});
return visibleInAllParents;
};
Он также позволяет указать, какой процент он должен быть видимым в каждом направлении.
Он не охватывает возможность того, что он может быть скрыт из-за других факторов, таких как display: hidden
.
Это должно работать во всех основных браузерах, поскольку используется только getBoundingClientRect
. Я лично протестировал его в Chrome и Internet Explorer 11.
Здесь рассматриваются любые дополнения, границы или поля, которые имеют элемент, а также элементы, которые больше, чем сам вид просмотра.
function inViewport($ele) {
var lBound = $(window).scrollTop(),
uBound = lBound + $(window).height(),
top = $ele.offset().top,
bottom = top + $ele.outerHeight(true);
return (top > lBound && top < uBound)
|| (bottom > lBound && bottom < uBound)
|| (lBound >= top && lBound <= bottom)
|| (uBound >= top && uBound <= bottom);
}
Чтобы вызвать его, используйте что-то вроде этого:
var $myElement = $('#my-element'),
canUserSeeIt = inViewport($myElement);
console.log(canUserSeeIt); // true, if element is visible; false otherwise
Существует плагин для jQuery, называемый inview, который добавляет новое событие "inview".
Вот какой код для плагина jQuery, который не использует события:
$.extend($.expr[':'],{
inView: function(a) {
var st = (document.documentElement.scrollTop || document.body.scrollTop),
ot = $(a).offset().top,
wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
return ot > st && ($(a).height() + ot) < (st + wh);
}
});
(function( $ ) {
$.fn.inView = function() {
var st = (document.documentElement.scrollTop || document.body.scrollTop),
ot = $(this).offset().top,
wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
return ot > st && ($(this).height() + ot) < (st + wh);
};
})( jQuery );
Я нашел это в комментарии здесь (http://remysharp.com/2009/01/26/element-in-view-event-plugin/) от парня по имени Джеймс
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop(),
docViewBottom = docViewTop + $(window).height(),
elemTop = $(elem).offset().top,
elemBottom = elemTop + $(elem).height();
//Is more than half of the element visible
return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}
Вот еще одно решение от http://web-profile.com.ua/
<script type="text/javascript">
$.fn.is_on_screen = function(){
var win = $(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
if( $('.target').length > 0 ) { // if target element exists in DOM
if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
$('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
} else {
$('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
}
}
$(window).scroll(function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
$('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
} else {
$('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
}
}
});
</script>
Смотрите это в JSFiddle
Обычная ваниль, чтобы проверить, является ли элемент (el
) видимым в прокручиваемом div (holder
)
function isElementVisible (el, holder) {
holder = holder || document.body
const { top, bottom, height } = el.getBoundingClientRect()
const holderRect = holder.getBoundingClientRect()
return top <= holderRect.top
? holderRect.top - top <= height
: bottom - holderRect.bottom <= height
},
Использование jQuery:
var el = $('tr:last').get(0);
var holder = $('table').get(0);
isVisible = isScrolledIntoView(el, holder);
Создание этого отличного ответа, вы можете немного упростить его с помощью ES2015 +:
function isScrolledIntoView(el) {
const { top, bottom } = el.getBoundingClientRect()
return top >= 0 && bottom <= window.innerHeight
}
Если вы не заботитесь о том, что верхний экран выходит из окна, и просто заботитесь о том, чтобы снизу было просмотрено, это можно упростить до
function isSeen(el) {
return el.getBoundingClientRect().bottom <= window.innerHeight
}
или даже однострочный
const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight
Вы можете использовать плагин jquery "onScreen", чтобы проверить, находится ли элемент в текущем окне просмотра при прокрутке. Плагин устанавливает для параметра ": onScreen" селектора значение true, когда селектор появляется на экране. Это ссылка для плагина, который вы можете включить в свой проект. " http://benpickles.github.io/onScreen/jquery.onscreen.min.js"
Вы можете попробовать приведенный ниже пример, который работает для меня.
$(document).scroll(function() {
if($("#div2").is(':onScreen')) {
console.log("Element appeared on Screen");
//do all your stuffs here when element is visible.
}
else {
console.log("Element not on Screen");
//do all your stuffs here when element is not visible.
}
});
Код HTML:
<div id="div1" style="width: 400px; height: 1000px; padding-top: 20px; position: relative; top: 45px"></div> <br>
<hr /> <br>
<div id="div2" style="width: 400px; height: 200px"></div>
CSS
#div1 {
background-color: red;
}
#div2 {
background-color: green;
}
Вот способ добиться того же, используя Mootools, в горизонтальном, вертикальном или обоих.
Element.implement({
inVerticalView: function (full) {
if (typeOf(full) === "null") {
full = true;
}
if (this.getStyle('display') === 'none') {
return false;
}
// Window Size and Scroll
var windowScroll = window.getScroll();
var windowSize = window.getSize();
// Element Size and Scroll
var elementPosition = this.getPosition();
var elementSize = this.getSize();
// Calculation Variables
var docViewTop = windowScroll.y;
var docViewBottom = docViewTop + windowSize.y;
var elemTop = elementPosition.y;
var elemBottom = elemTop + elementSize.y;
if (full) {
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
&& (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
} else {
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
},
inHorizontalView: function(full) {
if (typeOf(full) === "null") {
full = true;
}
if (this.getStyle('display') === 'none') {
return false;
}
// Window Size and Scroll
var windowScroll = window.getScroll();
var windowSize = window.getSize();
// Element Size and Scroll
var elementPosition = this.getPosition();
var elementSize = this.getSize();
// Calculation Variables
var docViewLeft = windowScroll.x;
var docViewRight = docViewLeft + windowSize.x;
var elemLeft = elementPosition.x;
var elemRight = elemLeft + elementSize.x;
if (full) {
return ((elemRight >= docViewLeft) && (elemLeft <= docViewRight)
&& (elemRight <= docViewRight) && (elemLeft >= docViewLeft) );
} else {
return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft));
}
},
inView: function(full) {
return this.inHorizontalView(full) && this.inVerticalView(full);
}});
Изменен принятый ответ, чтобы элемент должен был отображать свойство, отличное от "none" до качества, как видимое.
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
var elemDisplayNotNone = $(elem).css("display") !== "none";
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
}
Мне нужно было проверить видимость элементов внутри прокручиваемого контейнера DIV
//p = DIV container scrollable
//e = element
function visible_in_container(p, e) {
var z = p.getBoundingClientRect();
var r = e.getBoundingClientRect();
// Check style visiblilty and off-limits
return e.style.opacity > 0 && e.style.display !== 'none' &&
e.style.visibility !== 'hidden' &&
!(r.top > z.bottom || r.bottom < z.top ||
r.left > z.right || r.right < z.left);
}
e.style.opacity > 0
на (!e.style.opacity || e.style.opacity > 0)
потому что по умолчанию это пустая строка для меня в FF.
Если вы хотите настроить его для прокрутки в другом div,
function isScrolledIntoView (elem, divID)
{
var docViewTop = $('#' + divID).scrollTop();
var docViewBottom = docViewTop + $('#' + divID).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
У меня такой метод в моем приложении, но он не использует jQuery:
/* Get the TOP position of a given element. */
function getPositionTop(element){
var offset = 0;
while(element) {
offset += element["offsetTop"];
element = element.offsetParent;
}
return offset;
}
/* Is a given element is visible or not? */
function isElementVisible(eltId) {
var elt = document.getElementById(eltId);
if (!elt) {
// Element not found.
return false;
}
// Get the top and bottom position of the given element.
var posTop = getPositionTop(elt);
var posBottom = posTop + elt.offsetHeight;
// Get the top and bottom position of the *visible* part of the window.
var visibleTop = document.body.scrollTop;
var visibleBottom = visibleTop + document.documentElement.offsetHeight;
return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}
Изменить: этот метод хорошо работает для I.E. (по крайней мере, версия 6). Прочитайте комментарии для совместимости с FF.
Я искал способ увидеть, скоро ли элемент появится в списке, поэтому, расширив фрагменты выше, я смог это сделать. думал, что оставил бы это здесь на всякий случай, если это поможет кому-то
elm = элемент, который вы хотите проверить, находится в представлении
scrollElement = вы можете передать окно или родительский элемент со списком
offset = если вы хотите, чтобы он срабатывал, когда элемент находился на расстоянии 200 пикселей до его отображения на экране, а затем передайте 200
function isScrolledIntoView(elem, scrollElement, offset)
{
var $elem = $(elem);
var $window = $(scrollElement);
var docViewTop = $window.scrollTop();
var docViewBottom = docViewTop + $window.height();
var elemTop = $elem.offset().top;
var elemBottom = elemTop + $elem.height();
return (((elemBottom+offset) >= docViewBottom) && ((elemTop-offset) <= docViewTop)) || (((elemBottom-offset) <= docViewBottom) && ((elemTop+offset) >= docViewTop));
}
Пример, основанный на этом ответе, чтобы проверить, является ли элемент видимым на 75% (т.е. менее 25% от него отключено от экрана).
function isScrolledIntoView(el) {
// check for 75% visible
var percentVisible = 0.75;
var elemTop = el.getBoundingClientRect().top;
var elemBottom = el.getBoundingClientRect().bottom;
var elemHeight = el.getBoundingClientRect().height;
var overhang = elemHeight * (1 - percentVisible);
var isVisible = (elemTop >= -overhang) && (elemBottom <= window.innerHeight + overhang);
return isVisible;
}
Я предпочитаю использовать jQuery expr
jQuery.extend(jQuery.expr[':'], {
inview: function (elem) {
var t = $(elem);
var offset = t.offset();
var win = $(window);
var winST = win.scrollTop();
var elHeight = t.outerHeight(true);
if ( offset.top > winST - elHeight && offset.top < winST + elHeight + win.height()) {
return true;
}
return false;
}
});
чтобы вы могли использовать его таким образом
$(".my-elem:inview"); //returns only element that is in view
$(".my-elem").is(":inview"); //check if element is in view
$(".my-elem:inview").length; //check how many elements are in view
Вы можете легко добавить такой код внутри функции события scroll
и т.д., чтобы проверять его каждый раз, когда пользователь будет прокручивать представление.
expr
для проверки видимости прокрутки элемента имеет огромный недостаток, поскольку он может работать только для элементов, которые не находятся внутри самих контейнеров прокрутки, поскольку вы используете объект window
в качестве жестко заданной области видимости.
Я адаптировал это короткое расширение функции jQuery, которое вы можете свободно использовать (лицензия MIT).
/**
* returns true if an element is visible, with decent performance
* @param [scope] scope of the render-window instance; default: window
* @returns {boolean}
*/
jQuery.fn.isOnScreen = function(scope){
var element = this;
if(!element){
return;
}
var target = $(element);
if(target.is(':visible') == false){
return false;
}
scope = $(scope || window);
var top = scope.scrollTop();
var bot = top + scope.height();
var elTop = target.offset().top;
var elBot = elTop + target.height();
return ((elBot <= bot) && (elTop >= top));
};
Простая модификация для прокручиваемого div (контейнера)
var isScrolledIntoView = function(elem, container) {
var containerHeight = $(container).height();
var elemTop = $(elem).position().top;
var elemBottom = elemTop + $(elem).height();
return (elemBottom > 0 && elemTop < containerHeight);
}
ПРИМЕЧАНИЕ: это не работает, если элемент больше, чем прокручиваемый div.
Этот метод вернет true, если какая-либо часть элемента будет видна на странице. Он работал лучше в моем случае и может помочь кому-то другому.
function isOnScreen(element) {
var elementOffsetTop = element.offset().top;
var elementHeight = element.height();
var screenScrollTop = $(window).scrollTop();
var screenHeight = $(window).height();
var scrollIsAboveElement = elementOffsetTop + elementHeight - screenScrollTop >= 0;
var elementIsVisibleOnScreen = screenScrollTop + screenHeight - elementOffsetTop >= 0;
return scrollIsAboveElement && elementIsVisibleOnScreen;
}
Более эффективная версия этого ответа:
/**
* Is element within visible region of a scrollable container
* @param {HTMLElement} el - element to test
* @returns {boolean} true if within visible region, otherwise false
*/
function isScrolledIntoView(el) {
var rect = el.getBoundingClientRect();
return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
}
На этот вопрос более 30 ответов, и ни один из них не использует удивительно простое, чистое JS-решение, которое я использовал. Нет необходимости загружать jQuery, чтобы решить эту проблему, как и многие другие.
Чтобы определить, находится ли элемент в окне просмотра, мы должны сначала определить положение элементов внутри тела. Нам не нужно делать это рекурсивно, как я когда-то думал. Вместо этого мы можем использовать element.getBoundingClientRect()
.
pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
Это значение представляет собой разность Y между вершиной объекта и вершиной тела.
Затем мы должны указать, находится ли элемент в пределах представления. Большинство реализаций спрашивают, находится ли полный элемент в пределах окна просмотра, поэтому это то, что мы рассмотрим.
Прежде всего, верхнее положение окна: window.scrollY
.
Мы можем получить нижнюю позицию окна, добавив высоту окна в верхнее положение:
var window_bottom_position = window.scrollY + window.innerHeight;
Позволяет создать простую функцию для получения верхней позиции элемента:
function getElementWindowTop(elem){
return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}
Эта функция вернет верхнюю позицию элемента в окне или вернет 0
, если вы передадите ей что-то отличное от элемента с методом .getBoundingClientRect()
. Этот метод существует уже давно, поэтому вам не нужно беспокоиться о том, что ваш браузер не поддерживает его.
Теперь наше верхнее положение элемента:
var element_top_position = getElementWindowTop(element);
И или нижняя позиция элемента:
var element_bottom_position = element_top_position + element.clientHeight;
Теперь мы можем определить, находится ли элемент в окне просмотра, проверяя, находится ли нижнее положение элемента ниже верхнего положения окна просмотра и проверяется, превышает ли верхнее положение элемента верхнее положение окна просмотра:
if(element_bottom_position >= window.scrollY
&& element_top_position <= window_bottom_position){
//element is in view
else
//element is not in view
Оттуда вы можете выполнить логику, чтобы добавить или удалить класс in-view
в своем элементе, который впоследствии можно обработать с помощью эффектов перехода в вашем CSS.
Я абсолютно удивлен тем, что я не нашел это решение нигде, но я считаю, что это самое чистое и эффективное решение, и он не требует загрузки jQuery!
Я написал компонент для задачи, предназначенный для обработки большого количества элементов чрезвычайно быстро (до мелодии < 10ms для 1000 элементов на медленном мобильном устройстве).
Он работает с каждым типом контейнера прокрутки, к которому у вас есть доступ, - к окну, элементам HTML, встроенному iframe, порожденному дочернему окну - и очень гибко в том, что он обнаруживает (полная или частичная видимость, рамка или поле содержимого, пользовательский зона толерантности, и т.д.).
Огромный, в основном автогенерированный набор тестов гарантирует, что он работает как рекламируемый, кросс-браузер.
Сделайте это, если хотите: jQuery.isInView. В противном случае вы можете найти вдохновение в исходном коде, например. здесь.
Я просто хотел поделиться тем, что я объединил это с моим script, чтобы переместить div так, чтобы он всегда оставался в поле зрения:
$("#accordion").on('click', '.subLink', function(){
var url = $(this).attr('src');
updateFrame(url);
scrollIntoView();
});
$(window).scroll(function(){
changePos();
});
function scrollIntoView()
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $("#divPos").offset().top;
var elemBottom = elemTop + $("#divPos").height();
if (elemTop < docViewTop){
$("#divPos").offset({top:docViewTop});
}
}
function changePos(){
var scrTop = $(window).scrollTop();
var frmHeight = $("#divPos").height()
if ((scrTop < 200) || (frmHeight > 800)){
$("#divPos").attr("style","position:absolute;");
}else{
$("#divPos").attr("style","position:fixed;top:5px;");
}
}
Мы можем сделать что-то подобное в современных браузерах, используя ES6:
const isFullySeen = el => el &&
typeof el.getBoundingClientRect === 'function' &&
el.getBoundingClientRect()['bottom'] + window.scrollY <=
window.innerHeight + window.scrollY &&
el.getBoundingClientRect()['top'] + window.scrollY <=
window.innerHeight + window.scrollY;
Сделал простой просмотр плагинов, если элемент виден внутри прокручиваемого контейнера
$.fn.isVisible = function(){
var win;
if(!arguments[0])
{
console.error('Specify a target;');
return false;
}
else
{
win = $(arguments[0]);
}
var viewport = {};
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
viewport.bottom = win.height() + win.offset().top;
return (!( bounds.top > viewport.bottom) && (win.offset().top < bounds.bottom));
};
Назовите его так: $('elem_to_check').isVisible('scrollable_container');
Надеюсь, что это поможет.
Проверяет, присутствует ли элемент на экране вообще, а не принятый подход ответа, который проверяет, находится ли div целиком на экране (что не будет работать, если div больше экрана). В чистом Javascript:
/**
* Checks if element is on the screen (Y axis only), returning true
* even if the element is only partially on screen.
*
* @param element
* @returns {boolean}
*/
function isOnScreenY(element) {
var screen_top_position = window.scrollY;
var screen_bottom_position = screen_top_position + window.innerHeight;
var element_top_position = element.offsetTop;
var element_bottom_position = element_top_position + element.offsetHeight;
return (inRange(element_top_position, screen_top_position, screen_bottom_position)
|| inRange(element_bottom_position, screen_top_position, screen_bottom_position));
}
/**
* Checks if x is in range (in-between) the
* value of a and b (in that order). Also returns true
* if equal to either value.
*
* @param x
* @param a
* @param b
* @returns {boolean}
*/
function inRange(x, a, b) {
return (x >= a && x <= b);
}
Единственный плагин, который работает для меня последовательно для этого, заключается в следующем: https://github.com/customd/jquery-visible
Я портировал этот плагин на GWT недавно, так как я не хотел добавлять jquery в качестве зависимости только для использования плагина. Здесь мой (простой) порт (просто включая функциональность, которая мне нужна для моего использования):
public static boolean isVisible(Element e)
{
//vp = viewPort, b = bottom, l = left, t = top, r = right
int vpWidth = Window.getClientWidth();
int vpHeight = Window.getClientHeight();
boolean tViz = ( e.getAbsoluteTop() >= 0 && e.getAbsoluteTop()< vpHeight);
boolean bViz = (e.getAbsoluteBottom() > 0 && e.getAbsoluteBottom() <= vpHeight);
boolean lViz = (e.getAbsoluteLeft() >= 0 && e.getAbsoluteLeft() < vpWidth);
boolean rViz = (e.getAbsoluteRight() > 0 && e.getAbsoluteRight() <= vpWidth);
boolean vVisible = tViz && bViz;
boolean hVisible = lViz && rViz;
return hVisible && vVisible;
}
После непродолжительной работы и использования нескольких кодов, которые не сработали. Это то, что сработало для меня по вертикальной видимости прокрутки с помощью JQuery. Замените '#footerplace' на элемент, который вы хотите отслеживать по вертикали.
jQuery.expr.filters.offscreen = function(el) {
var rect = el.getBoundingClientRect();
console.log(rect)
console.log('window height', $(window).height());
return (
(rect.top <= $(window).height()) && (rect.bottom <= $(window).height())
);
};
$(document).scroll(function(){
if ($('#footerplace').is(':offscreen')){
console.log('this is true');
$('#footerplace').is(':offscreen');
} else {
console.log('this is false');
$('#footerplace').is(':offscreen');
}
Только для Javascript:)
function isInViewport(element) {
var rect = element.getBoundingClientRect();
var html = document.documentElement;
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || html.clientHeight) &&
rect.right <= (window.innerWidth || html.clientWidth)
);
}
getBoundingClientRect
?