javascript - 要素が見えたら - jquery 要素が表示されたら




スクロール後に要素が表示されているかどうかを確認する (20)

私はAJAX経由で要素をロードしています。 それらの一部は、ページを下にスクロールすると表示されます。
要素がページの可視部分にあるかどうかわかる方法はありますか?


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

jQueryウェイポイントのプラグインはここでとてもうまく行きます。

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

プラグインサイトにはいくつかの例があります


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/


ここでのほとんどの答えは、ページ全体だけでなく、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で個人的にテストしました。


ここにhttp://web-profile.com.ua/別の解決策があり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見てください


この素晴らしい答えを踏まえて、ES2015 +を使用してさらに簡単に簡略化できます。

function isScrolledIntoView(el) {
  const { top, bottom } = el.getBoundingClientRect()
  return top >= 0 && bottom <= window.innerHeight
}

ウィンドウの上を出ないよう気にしないで、下を見ただけで気にしないと、これは次のように単純化できます。

function isSeen(el) {
  return el.getBoundingClientRect().bottom <= window.innerHeight
}

または1ライナー

const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight

これは、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);
}});

これはトリックを行う必要があります:

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

スクロール可能div( holder )に要素( el )が表示されているかどうかを確認するプレーンバニラ

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

スクロール可能な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より大きい場合、これは機能しません。


スクロール可能なコンテナ内に隠されている場合にも機能する、私の純粋な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
};

EDIT 2016-03-26:要素をスクロールしてスクロール可能なコンテナの上に隠されるように、ソリューションを更新しました。 EDIT 2018-10-08:画面の上をスクロールして表示されないときに処理するように更新されました。


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

新しい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ではサポートされていません)


私が今までに見つけた最良の方法は、 jQueryがプラグインとして表示されることです。 魅力のように動作します。

要素が表示にスクロールしたり、ユーザーに表示されたりしたときに発生するカスタムの「表示」イベントを模倣します。

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

このプラグインは、隠されているか、可視領域外にあるコンテンツに対する不要なリクエストを防止するために使用できます。


私は 非常に高速に多数の要素を処理するように設計されたタスク用のコンポーネントを作成しまし低速のモバイルで1000個の要素に対して10ミリ秒未満のチューンまで)。

ウィンドウ、HTML要素、組み込みiframe、生成された子ウィンドウなど、アクセス可能なあらゆる種類のスクロールコンテナで動作し、検出される内容に非常に柔軟性があります( 完全または部分的な可視性枠線ボックスまたはコンテンツボックス 、カスタム許容範囲ゾーン etc )。

主に自動生成された巨大なテストスイートは、宣伝されたcross-browserとして動作することを保証します。

もしあなたが好きなら、それを打ちなさい: jQuery.isInView 。 それ以外の場合は、ソースコードでインスピレーションを得るかもしれません。


私は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

あなたはeaslyこのようなコードをscrollイベント機能などの中に追加して、ユーザがビューをスクロールするたびにチェックすることができます。


私は、要素がすぐに見えるようになるかどうかを調べる方法を探していました。上にスニペットを拡張することによって、それを行うことができました。 誰かを助ける場合に備えて、私はこれをここに残すと思った

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






scroll