javascript - scrollleft - jquery top




滾動後檢查元素是否可見 (20)

我通過AJAX加載元素。 其中一些只有在向下滾動頁面時才可見。
有什麼方法可以知道元素是否在頁面的可見部分?


Tweeked斯科特Dowding的酷功能為我的要求 - 這是用來發現元素是否剛剛滾動到屏幕上,即它的頂部邊緣。

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

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

WebResourcesDepot編寫了一個腳本,以便 在前 一段使用jQuery的 滾動過程加載 。 您可以在這裡查看他們的實時演示 。 其功能的牛肉是這樣的:

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

isScrolledIntoView是一個非常有用的函數,所以我嘗試了它,它適用於不比視口高的元素,但是如果元素比視口更大,則它不起作用。 要解決這個問題很容易改變條件

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

對此:

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

在此處查看演示: http://jsfiddle.net/RRSmQ/ : http://jsfiddle.net/RRSmQ/


使用新的IntersectionObserver API可以非常容易且高效地確定視口中可見的元素。 通過使用觀察者 ,它消除了附加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>

查看瀏覽器支持表 (IE / Safari不支持)


修改已接受的答案,以便元素必須將其顯示屬性設置為“無”以使其質量可見。

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

基於這個偉大的答案 ,您可以使用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

如果你想調整這個滾動另一個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)); 
}

怎麼樣

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

之後你可以觸發你想要的任何東西,一旦元素在視圖中就像這樣

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

這對我來說很好


您可以使用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;
}

我在我的應用程序中有這樣的方法,但它不使用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兼容性的註釋。


我更喜歡使用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事件函數等內輕鬆添加這樣的代碼,以便每次用戶將滾動視圖時檢查它。


我為這項任務編寫了一個組件 ,專門用於處理大量元素(對於慢速移動設備上的 1000個元素調整時間小於10ms)。

它適用於您可以訪問的每種類型的滾動容器 - 窗口,HTML元素,嵌入式iframe,衍生的子窗口 - 並且在檢測到的內容方面非常靈活( 全部或部分可見性邊框或內容框 ,自定義容差區域 etc )。

一個巨大的,主要是自動生成的測試套件確保它可以像廣告一樣, cross-browser

如果你喜歡,請給它一個: jQuery.isInView 。 否則,您可能會在源代碼中找到靈感,例如here


我需要檢查可滾動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);
    }

有一個名為inview的 jQuery插件 ,添加了一個新的“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/ ),名叫詹姆斯

這裡有一個相當不錯的例子(向下滾動到底部):

http://www.bbc.co.uk/sport/0/olympics/2012/

我不能100%確定該例子使用相同的代碼,但是...

編輯...我也寫了一個名為'exitview'的inview插件的擴展,它在元素離開頁面時觸發一個事件。 如果可能的話,任何對代碼感興趣的人都可以發帖。


簡單修改滾動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,則不起作用。


這是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查看它


這是一種使用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);
}});

這裡是我純粹的JavaScript解決方案,如果它隱藏在可滾動容器中,也可以工作。

在這裡演示 (嘗試調整窗口大小)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode;
  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);
  // Check its within the document viewport
  return top <= document.documentElement.clientHeight;
};

編輯2016年3月26日:我已經更新了解決方案,以考慮滾動瀏覽元素,因此它隱藏在可滾動容器頂部之上。


這裡的大多數答案都沒有考慮到元素也可以隱藏,因為它是從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中對其進行了測試。





scroll