요소가 화면 밖에 있는지 확인하는 방법


81

DIV 요소가 화면에서 떨어지지 않는지 jQuery로 확인해야합니다. 요소는 CSS 속성에 따라 표시되고 표시되지만 다음과 같은 방법으로 의도적으로 화면 외부에 배치 될 수 있습니다.

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

:visible요소의 높이와 너비가 0이 아니므로 jQuery 선택기를 사용할 수 없습니다 .

나는 멋진 일을하지 않습니다. 이 절대 위치 배치는 내 Ajax 프레임 워크가 일부 위젯의 숨기기 / 표시를 구현하는 방식 입니다.


나뿐만 아니라이 '중복'질문에 대한 답변을했다 : stackoverflow.com/questions/5353934/...
Tokimon

답변:


135

"오프 스크린"의 정의에 따라 다릅니다. 뷰포트 내에 있습니까, 아니면 페이지의 정의 된 경계 내에 있습니까?

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-screen-tall DIV의 맨 아래에있는 요소는 항상 "offscreen"이됩니다.
Coderer

@scurker 나는 이것을 작동시킬 수 없었다. 다음은 문제에 대한 내 SO 질문 (jsFiddle 포함)입니다. stackoverflow.com/questions/26004098/…
crashwap

el이 몸 앞에 부모 (절대 또는 상대적)를 배치하면 이것이 아닐 것이라고 생각하는 것이 잘못입니까?
fekiri malek

@fekirimalek 당신은 그 설명하기 위해 예를 올바른 업데이트되었습니다있다
scurker

7
현재 (2017 년 1 월) Element.getBoundingClientRect ()에는 x 및 y 대신 top, right, bottom 및 left 속성이 있기 때문에 Chrome에서는 작동하지 않습니다.
Asu

18

여기 에는 브라우저의 스크롤 위치를 고려하여 요소가 브라우저의 보이는 뷰포트 내에 있는지 여부를 테스트 할 수 있는 jQuery 플러그인 이 있습니다.

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

부분 가시성을 확인할 수도 있습니다.

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

한 가지 단점은 믹스에 수평 위치를 추가하는 것이 충분히 쉬울지라도 수직 위치 / 스크롤링에서만 작동한다는 것입니다.


이것은 매우 가벼운 플러그인입니다. 스크롤 업시 고정 된 navbar를 얻고 추가 ​​한 후 몇 분 이내에 반응 형으로 작업 할 수있었습니다. 좋은 제안입니다.
Nappstir

이 플러그인은 매우 가볍고 구현하기가 매우 쉽습니다. 하위 메뉴와 관련된 문제를 해결했습니다.
Theo Orphanos 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가 될 수 있습니다.
Ryan Shillington

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 : Cannot read property 'getBoundingClientRect'of undefined 거기 ur 함수를 사용하려고 할 때 얻을 수 있습니다.
Ludvig W

안녕하세요 Lurr ... $ ( "# divId"). isOnScreen (true); 'divId'가 화면에서 벗어 났고 'false'를 반환했습니다. 그래서, 나는 그것의 작동 느낌
Anirban


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의 위치를 $(div).position()확인하고 left 및 top margin 속성이 0 미만인지 확인할 수 있습니다.

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

2
div가 뷰에서 네거티브가 아닌 경우 어떻게됩니까?
dude
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.