簡體   English   中英

如何檢查元素是否在屏幕外

[英]How to check if an element is off-screen

如果 DIV 元素沒有脫離屏幕,我需要檢查 jQuery。 這些元素是可見的並根據 CSS 屬性顯示,但它們可以通過以下方式有意放置在屏幕外:

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

我不能使用 jQuery :visible選擇器,因為元素的高度和寬度不為零。

我沒有做任何花哨的事情。 這種絕對位置放置是我的Ajax框架實現某些小部件的隱藏/顯示的方式。

取決於您對“屏幕外”的定義是什么。 那是在視口內,還是在頁面的定義邊界內?

使用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');

這里有一個jQuery 插件,它允許用戶測試元素是否落在瀏覽器的可見視口內,同時考慮瀏覽器的滾動位置。

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

您還可以檢查部分可見性:

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

一個缺點是它僅適用於垂直定位/滾動,盡管將水平定位添加到組合中應該很容易。

無需插件來檢查是否在視口之外。

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

嗯...我在這里提出的每個解決方案中都發現了一些問題。

  • 您應該能夠選擇是否希望整個元素出現在屏幕上或只是其中的任何部分
  • 如果元素高於/寬於窗口並且有點覆蓋瀏覽器窗口,則建議的解決方案將失敗。

這是我的解決方案,其中包括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);
};

我創建了一個小插件來執行此操作 ,它具有一些靈活的選項(在您調整瀏覽器窗口大小時也可以使用)。

我知道這有點晚了,但這個插件應該可以工作。 http://remysharp.com/2009/01/26/element-in-view-event-plugin/

$('p.inview').bind('inview', function (event, visible) {
if (visible) {
  $(this).text('You can see me!');
} else {
  $(this).text('Hidden again');
}
  • 獲取到給定元素頂部的距離
  • 添加相同給定元素的高度。 這將告訴您從屏幕頂部到給定元素末尾的總數。
  • 然后你所要做的就是從文檔總高度中減去它

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

盡管最初的發帖人要求使用 JQuery 解決方案,但他們還在問題上添加了一個 JavaScript 標記,這也允許添加這個更現代的解決方案:

TLDR:使用IntersectionObserver API

以下是我在原生 JavaScript 和 React 中制作的兩個沙箱,用於在工作示例中展示這一點:

  1. Vanilla JavaScript 示例沙箱
  2. React 示例沙箱(使用 react-intersection-observer NPM 模塊)

更長一點的答案:這個問題被問到已經有 10 多年了,當時使用這些 JQuery 解決方案是有意義的,但是今天我們不再需要 JQuery 來滿足這種需求了:

Intersection Observer API 提供了一種方法來觀察目標元素與祖先元素或頂級文檔視口的交集的變化。

它很容易使用,首先創建一個觀察者並在它被觸發時傳遞你想要做的事情(一個回調函數),並且還可以選擇傳遞一個選項對象,例如,在這個問題的情況下,我們需要threshold 選項,值為 1 以確保元素完全在視口內,如果不是,那么我們將知道它是“屏幕外”:

const doable = () => {
  //do something
}
const observer = new IntersectionObserver(doable, { threshold: 1 });

現在調用它的observe()方法並將你想要觀察的元素傳遞給它:

observer.observe(observee)

您可以使用$(div).position()檢查 div 的位置,並檢查左邊距和上邊距屬性是否小於 0 :

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM