web-dev-qa-db-ja.com

スクロール後に要素が表示されるかどうかを確認する方法

私はAJAXを介して要素を読み込んでいます。それらの中には、ページを下にスクロールした場合にのみ表示されるものがあります。
ある要素が現在ページの可視部分にあるかどうかを知る方法はありますか?

1056
yoavf

これでうまくいくはずです。

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

この答え 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;
}
346
bravedick

私がこれまでに見つけた最良の方法は jQueryプラグイン です。魅力のように働きます。

カスタムの「出現」イベントを模倣します。これは、要素がビューにスクロールインしたとき、またはユーザーに表示されるようになったときに発生します。

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

このプラグインを使用すると、非表示または表示領域外のコンテンツに対する不要な要求を防ぐことができます。

118
Joe Lencioni

これがスクロール可能なコンテナの中に隠れていても機能する私の純粋な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:画面の上から見えなくなったときに処理するように更新しました。

76
Ally

jQuery Waypointsプラグインはここでとても素敵になります。

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

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

41
Fedir RYKHTIK

どうですか?

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

その後、要素がこのように表示されたら、必要なものは何でもトリガーできます。

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

それは私のためにうまく働きます

20
webicy

( "new") IntersectionObserver APIの使用

ビューポートに要素が表示されているかどうかを判断するのは非常に簡単で効率的です。 observerを使用することで、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ではサポートされていません)

15
vsync

WebResourcesDepot wrote スクロール中にロードするスクリプト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();
    });
};
14
Sampson

私の要件に合わせたScott Dowdingのクールな機能を調整しました - これは要素がちょうどスクリーン、すなわちその上端にスクロールしたかどうかを見つけるために使われます。

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

ここでのほとんどの答えは、要素がページ全体だけでなく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でそれをテストしました。

8
Domysee

isScrolledIntoView は非常に必要な関数なので、試してみましたが、ビューポートよりも大きくない要素に対しては機能しますが、要素がビューポートよりも大きい場合は機能しません。これを直すには簡単に状況を変える

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

これに:

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

ここにデモを見なさい: http://jsfiddle.net/RRSmQ/ /

7
Robert

新しい "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 );

私はJamesと呼ばれる一口によってここのコメント( http://remysharp.com/2009/01/26/element-in-view-event-plugin/ )でこれを見つけました

6
ness-EE

これは、要素に含まれるパディング、ボーダー、マージン、およびビューポート自体よりも大きい要素を考慮します。

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
6
Brent Barbata
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));
}
6
Pascal Gagneur

スクロール可能な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);
    }
5
Pigmalión

これは 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 でそれを参照してください。

5
Adrian P.

要素(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);
5
Denis Matafonov

あなたがスクロールするときに要素が現在のビューポートにあるかどうかチェックするために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;
}
4
Vasuki Dileep

この素晴らしい答え を基にして、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
3
rpearce

表示される品質にするために、要素の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);
}
3
evanmcd

あなたが他の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)); 
}
3
Samiya Akhtar

この答え に基づく例は、要素が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;
}
3
Brendan Nee

私は自分のアプリケーションにそのようなメソッドを持っていますが、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との互換性のためにコメントを読んでください。

3
Romain Linsolas

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

コンポーネント 多数の要素を処理するように設計されたタスクを作成しました 非常に高速 (1000個の要素に対して<10msのチューニング低速のモバイルで)。

アクセスできるすべてのタイプのスクロールコンテナー(ウィンドウ、HTML要素、埋め込みiframe、生成された子ウィンドウ)で機能し、検出するものに非常に柔軟です( 完全または部分的な可視性境界ボックスまたはコンテンツボックス 、カスタム トレランスゾーンetc )。

ほとんどが自動生成される巨大なテストスイートは、アドバタイズされたとおりに動作することを保証します cross-browser

必要であれば、試してみてください: jQuery.isInView 。そうでなければ、ソースコードにインスピレーションを見つけるかもしれません。 ここ

2
hashchange

このメソッドは、要素のいずれかの部分がページに表示されている場合に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;
}
2
Rafael Garcia

スクロール可能div(container)の簡単な修正

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より大きい場合、これは機能しません。

2

この質問に対する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;
}

この関数は、ウィンドウ内での要素の先頭位置を返すか、または.getBoundingClientRect()メソッドで要素以外のものを渡した場合は0を返します。この方法は長い間使われてきたので、あなたのブラウザがそれをサポートしていないことを心配する必要はないはずです。

今、私たちの要素の一番上の位置は:

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をロードする必要がない!

2
WebWanderer

私は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イベント関数などの中に簡単に追加して、ユーザーがビューをスクロールするたびにそれをチェックすることができます。

2
pie6k

私はその要素が間もなく表示されるかどうかを確認する方法を探していたので、スニペットを上記のように拡張することでそれを実現できました。念のために、ここに置いておいてください。

Elm =はビューにある要素です。

scrollElement = window またはスクロールを持つ親要素を渡すことができます

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));
        }
2
Sonny Lloyd

私はこの短い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));
};
2
Lorenz Lo Sauer

この回答 :のより効率的なバージョン

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

これを自分のスクリプトと組み合わせて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;");
        }
    }
1
tree

要素がスクロール可能なコンテナ内に表示されるかどうかを検出する簡単なプラグインを作成しました

    $.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');のように呼ぶ

それが役立つことを願っています。

0
user3491125

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;
0
Alireza

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

これを行うための私にとって一貫して動作する唯一のプラグインは、次のとおりです。 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;
}
0
Click Upvote