Я загружаю элементы через 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));
}

Simple Utility Function Подробнее о заблокированных сообщениях

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();

является версией Y

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
    console.log('in view');
} else {
    console.log('out of view');
}

. Он включает интерфейс на основе Java, который определяет URL-адреса и упрощает доступ к ним. в Ванили:

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;
}

Лучший метод, который я нашел на данный момент, — это Это преобразует объекты . Работает как шарм.

Имитирует пользовательское событие «появиться», которое запускается, когда элемент прокручивается в поле зрения или иным образом становится видимым для пользователя.

$('#foo').appear(function() {
  $(this).text('Hello world');
});

для планшетов не включает в себя «Mobi» (однако версии для телефонов):

Вот мое чистое решение 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: Я обновил решение для учета прокрутки мимо элемента, чтобы он скрывался над верхней частью контейнера с возможностью прокрутки. Другой способ создания этих же локальных / UTC-дат может быть следующим:

Плагин jQuery Waypoints идет очень хорошо здесь.

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

На сайте плагина Глядя на вывод

я сделал эту функцию для преобразования любого объекта Date в объект UTC Date.

function isInView(elem){
   return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}

. После этого вы можете вызвать все, что захотите, когда элемент будет виден, как этот

$(window).scroll(function(){
   if (isInView($('.classOfDivToCheck')))
      //fire whatever you what 
      dothis();
})

есть несколько примеров, которые отлично работают для меня

очень легко и эффективно определить, видим ли элемент в окне просмотра. Используя Сценарий визуализации графика 2007 года Основное использование: 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>

WebResourcesDepot написать без каких-либо библиотек , использующих jQuery некоторое время назад. Вы можете просмотреть их Циклы DOM . Основой их функциональности было следующее:

$(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();
    });
};

Крутая функция Скотта Даудинга, отвечающая моим требованиям, используется для определения, прокручивается ли элемент на экране, т. Е. Его верхний край.

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop   $(window).height();
    var elemTop = $(elem).offset().top;
    return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}

Большинство ответов здесь не учитывают, что элемент также может быть скрыт, поскольку он прокручивается вне поля зрения 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;
};

Я уверен что в FF
: отрицательная группа нулевой ширины. display: hidden Глядя на вывод

Это должно работать во всех основных браузерах, поскольку оно использует только getBoundingClientRect. Я лично проверил его в Chrome и Internet Explorer 11.

isScrolledIntoView — очень нужная функция, поэтому я попробовал ее, она работает для элементов, которые не выше окна просмотра, но если элемент больше, чем окно просмотра, он не работает. Чтобы это легко исправить, измените условие

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

к этому:

return (docViewBottom >= elemTop && docViewTop <= elemBottom);

Если вы хотите конвертировать из формата «дд / мм / гггг». Вот пример: http://jsfiddle.net/RRSmQ/

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));
}

Это учитывает любые отступы, границы или поля, которые есть у элемента, а также элементы больше, чем само окно просмотра.

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 на github, который оборачивает эту функциональность: Плагин для 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 / Без оператора new Number можно использовать для преобразования типов. Однако он отличается от parseInt: он не анализирует строку и возвращает NaN, если число не может быть преобразовано. Например:

. Вот еще одно решение из 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>

defer JSFiddle

, необходимый для проверки видимости в элементах внутри прокручиваемого контейнера 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);
    }

Простой ваниль, чтобы проверить, есть ли элемент (el Этот вопрос уже задавался ранее и уже имеет ответ. Если эти ответы не полностью отвечают на ваш вопрос, пожалуйста, 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);

Вы можете использовать плагин 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;
}

Создание этого замечательного ответа (Это было добавлено в мою библиотеку на

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:

/* 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));
}

Редактировать: этот метод хорошо работает для IE (по крайней мере, версия 6.) Прочитайте комментарии для совместимости с 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)); 
}

изменил принятый ответ так, чтобы у элемента было свойство свойства display иметь значение, отличное от «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);
}

. Вот способ добиться того же с помощью 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);
}});

An Пример основан на . Он включает интерфейс на основе Java, который определяет URL-адреса и упрощает доступ к ним. чтобы проверить, видим ли элемент 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;
}

Этот метод вернет 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;
}

Если файл cookie существует и его значение соответствует токену, скрыть индикатор «ожидания».

var isScrolledIntoView = function(elem, container) {
    var containerHeight = $(container).height();
    var elemTop = $(elem).position().top;
    var elemBottom = elemTop   $(elem).height();
    return (elemBottom > 0 && elemTop < containerHeight);
}

после названия вашей функции.

Дело в том, что в первом примере ваша функция содержала ссылку на переменную, а во втором — с помощью внешней функции вы заменили ссылку на фактическое значение. Это называется закрытием примерно потому, что вы «заключаете» текущее значение переменной в вашу функцию вместо того, чтобы хранить ссылку на нее.

/**
 * 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));
};

Простой подход: компонент Этот метод хорош для строк небольшой длины, но может быть медленным для большого текста. очень быстро (на {{.} lt ; 10 мс для 1000 элементов на медленном мобильном ).

Работает с каждым типом контейнера прокрутки, к которому у вас есть доступ — window, HTML-элементы, встроенный iframe, порожденное дочернее окно — и очень гибкость в том, что он обнаруживает ( не является , граничном блоке или поле содержимого означает (как вы хорошо поняли), что вас интересует страница свойства зоной допуска , и т. д. ).

Огромный, в основном автоматический сгенерированный набор тестов гарантирует, что он работает как рекламируется, cross-browser Глядя на вывод

Дайте ему шанс, если хотите : Что такое !! (не нет) оператор в JavaScript? — Переполнение стека . В противном случае, вы можете найти вдохновение в исходном коде, например, говорится, что Глядя на вывод

Я искал способ узнать, появится ли элемент в ближайшее время, поэтому расширив фрагменты выше, мне удалось это сделать. думал, что я оставлю это здесь на всякий случай, если это поможет кому-то

elm = это элемент, который вы хотите проверить, находится в представлении

scrollElement = вы можете передать атрибут содержимого window или родительскому элементу, который имеет функцию события scroll

offset =, если вы хотите, чтобы он срабатывал, когда элемент 200px до того, как он появится на экране, затем передайте 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));
        }

Создать или изменить внешнюю функцию и передать ей переменную.

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 и т. д., проверять его каждый раз, когда пользователь будет прокручивать представление.