要素が画面外にあるかどうかを確認する方法


81

DIV要素が画面から外れていないかどうかをjQueryで確認する必要があります。要素はCSS属性に従って表示および表示されますが、次の方法で意図的に画面外に配置することができます。

position: absolute; 
left: -1000px; 
top: -1000px;

jQueryを使用できませんでした :visible要素の高さと幅がゼロ以外であるセレクターを。

私は特別なことは何もしていません。この絶対位置の配置は、私のAjaxフレームワークがいくつかのウィジェットの非表示/表示を実装する方法です。


:私は、この「重複」問題についても同様にこれに答えを与えたstackoverflow.com/questions/5353934/...
Tokimon

回答:


136

「オフスクリーン」の定義が何であるかによって異なります。それはビューポート内ですか、それともページの定義された境界内ですか?

Element.getBoundingClientRect()を使用すると、要素がビューポートの境界内(つまり、オンスクリーンまたはオフスクリーン)にあるかどうかを簡単に検出できます。

jQuery.expr.filters.offscreen = function(el) {
  var rect = el.getBoundingClientRect();
  return (
           (rect.x + rect.width) < 0 
             || (rect.y + rect.height) < 0
             || (rect.x > window.innerWidth || rect.y > window.innerHeight)
         );
};

次に、それをいくつかの方法で使用できます。

// returns all elements that are offscreen
$(':offscreen');

// boolean returned if element is offscreen
$('div').is(':offscreen');

2
私はこれが好きでしたが、要素がスクロール可能なコンテナ内にあると壊れます。ウィンドウの高さが要素のoffsetTopよりも小さいため、高さ2画面のDIVの下部にある要素は常に「オフスクリーン」になります。
コーダー2013

@scurkerこれを機能させることができませんでした。ここでの問題について(jsFiddleで)私のSOの質問は:stackoverflow.com/questions/26004098/...
crashwapは

elが親(絶対または相対)を体の前に配置した場合、これはそうではないと考えるのはここで間違っていますか?
fekiri malek 2016

@fekirimalekあなたは正しいです、私はそれを説明するために例を更新しました
scurker 2016

7
Element.getBoundingClientRect()にはxとyの代わりにtop、right、bottom、leftのプロパティがあるため、現在(2017年1月)これは少なくともChromeでは機能しないことに注意してください。
asu 2017年

18

ここにjQueryプラグインがあり、ブラウザーのスクロール位置を考慮して、要素がブラウザーの表示ビューポート内にあるかどうかをユーザーがテストできます。

$('#element').visible();

部分的な可視性を確認することもできます。

$('#element').visible( true);

1つの欠点は、垂直方向のポジショニング/スクロールでのみ機能することですが、水平方向のポジショニングをミックスに追加するのは簡単なはずです。


これは非常に軽量なプラグインです。追加してから数分以内に、上にスクロールして応答性の高いナビゲーションバーを修正することができました。素晴らしい提案。
nappstir 2017

このプラグインは非常に軽量で、実装が非常に簡単です。サブメニューで発生した問題を解決しました。
テオオルファノス2017

9

ビューポートの外にあるかどうかをチェックするプラグインは必要ありません。

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
var d = $(document).scrollTop();

$.each($("div"),function(){
    p = $(this).position();
    //vertical
    if (p.top > h + d || p.top > h - d){
        console.log($(this))
    }
    //horizontal
    if (p.left < 0 - $(this).width() || p.left > w){
        console.log($(this))
    }
});

1
$(this).offset代わりにを使用した場合、これは機能します$this.position。現在は、親からの距離を計算しているだけです。これは、完全にラップするdivである可能性があります。
ライアン

7

ええと...私はここで提案されたすべての解決策にいくつかの問題を見つけました。

  • 要素全体を画面に表示するか、要素の一部だけを表示するかを選択できるはずです。
  • 提案されたソリューションは、要素がウィンドウよりも広い/高ければ失敗とちょっとカバーブラウザウィンドウを。

これがjQuery .fnインスタンス関数とを含む私のソリューションですexpression。関数内に作成できるよりも多くの変数を作成しましたが、複雑な論理問題の場合は、それをより小さく、明確に名前が付けられた部分に分割するのが好きです。

getBoundingClientRectビューポートに対する要素の位置を返すメソッドを使用しているので、スクロール位置を気にする必要はありません。

使用法

$(".some-element").filter(":onscreen").doSomething();
$(".some-element").filter(":entireonscreen").doSomething();
$(".some-element").isOnScreen(); // true / false
$(".some-element").isOnScreen(true); // true / false (partially on screen)
$(".some-element").is(":onscreen"); // true / false (partially on screen)
$(".some-element").is(":entireonscreen"); // true / false 

出典

$.fn.isOnScreen = function(partial){

    //let's be sure we're checking only one element (in case function is called on set)
    var t = $(this).first();

    //we're using getBoundingClientRect to get position of element relative to viewport
    //so we dont need to care about scroll position
    var box = t[0].getBoundingClientRect();

    //let's save window size
    var win = {
        h : $(window).height(),
        w : $(window).width()
    };

    //now we check against edges of element

    //firstly we check one axis
    //for example we check if left edge of element is between left and right edge of scree (still might be above/below)
    var topEdgeInRange = box.top >= 0 && box.top <= win.h;
    var bottomEdgeInRange = box.bottom >= 0 && box.bottom <= win.h;

    var leftEdgeInRange = box.left >= 0 && box.left <= win.w;
    var rightEdgeInRange = box.right >= 0 && box.right <= win.w;


    //here we check if element is bigger then window and 'covers' the screen in given axis
    var coverScreenHorizontally = box.left <= 0 && box.right >= win.w;
    var coverScreenVertically = box.top <= 0 && box.bottom >= win.h;

    //now we check 2nd axis
    var topEdgeInScreen = topEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );
    var bottomEdgeInScreen = bottomEdgeInRange && ( leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally );

    var leftEdgeInScreen = leftEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );
    var rightEdgeInScreen = rightEdgeInRange && ( topEdgeInRange || bottomEdgeInRange || coverScreenVertically );

    //now knowing presence of each edge on screen, we check if element is partially or entirely present on screen
    var isPartiallyOnScreen = topEdgeInScreen || bottomEdgeInScreen || leftEdgeInScreen || rightEdgeInScreen;
    var isEntirelyOnScreen = topEdgeInScreen && bottomEdgeInScreen && leftEdgeInScreen && rightEdgeInScreen;

    return partial ? isPartiallyOnScreen : isEntirelyOnScreen;

};

$.expr.filters.onscreen = function(elem) {
  return $(elem).isOnScreen(true);
};

$.expr.filters.entireonscreen = function(elem) {
  return $(elem).isOnScreen(true);
};

1
make_footer_down.js:8 Uncaught TypeErrorが発生します:そこでur関数を使用しようとすると、undefinedのプロパティ 'getBoundingClientRect'を読み取れません。
ludvig W

こんにちはLurr ...私は$( "#divId")。isOnScreen(true);で試しました。ここで、「divId」は画面外にあり、「false」を返しました。だから、私はそれが機能していると感じています
Anirban 2017


1
  • 指定された要素の上部からの距離を取得します
  • 同じ指定された要素の高さを追加します。これにより、画面の上部から指定された要素の最後までの総数がわかります。
  • 次に、ドキュメントの高さの合計からそれを差し引くだけです。

    jQuery(function () {
        var documentHeight = jQuery(document).height();
        var element = jQuery('#you-element');
        var distanceFromBottom = documentHeight - (element.position().top + element.outerHeight(true));
        alert(distanceFromBottom)
    });
    

-1

を使用$(div).position()してdivの位置を確認し、左マージンと上マージンのプロパティが0未満であるかどうかを確認できます。

if($(div).position().left < 0 && $(div).position().top < 0){
    alert("off screen");
}

2
divが視野外で負でない場合はどうなりますか?
男2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.