jquery를 이용해서 객체가 화면안에 보이는지 여부를 판단하는 방법

애니메이션이 많은 페이지는 CPU를 많이 사용하게 되고, 사용자는 불편함을 느끼게 된다.
이 상황을 좀 개선시킬수 있는 방법이 있다면, 화면 밖에 있는 애니메이션을 제거하는 것이다. 그 애니메이션 객체가 화면 안으로 들어왔을때 애니메이션 시키고, 화면 바깥으로 나가면 애니메이션을 중지한다.

여기서는 화면 안으로 들어온 객체의 배경색을 빨갛게 변경시켜 보겠다.





1. 애니메이션 객체가 있다. 클래스는 vobj이다. 여기서는 <div>라고 하자.

  <div id="o2" class="vobj"></div>




2. css 속성을 준다.

  .vobj {
    background-color:blue;
  }
  .vobj.visible {
    background-color:red;
  }



3. jQuery 메서드를 확장한다.

  ( function( $ ) {
    $.fn.visible = function() {
      var $t=$(this), $w=$(window);
      var tt = $t.offset().top, th = $t.height(), tb=tt+th;
      var vt = $w.scrollTop(), vh = $w.height(), vb=vt+vh;
      if((tb<vt)||(vb<tt)) {
        console.log('invislble');
        return [false, false];
      }
      else if(((vt<=tt)&&(vb>=tb))||((vt>=tt)&&(vb<=tb))) {
        console.log('fully visible');
        return [true, true];
      }
      else {
        console.log('partly vislble');
        return [/*fully*/ false, /*partly*/ true];
      }
    }
  }) ( jQuery );




4. vobj들을 위한 변수와 함수를 준비한다.

  var vobjs;

  function vobjControl() {
    vobjs.each(function(i, e) {
    var je = $(e);
    var r = je.visible();
    r[1] ?
      je.addClass("visible") :
        r[0] ? 0 /* no op */ : je.removeClass("visible");
    });
  }




5. ready 상태가 되면 vobjControl()을 한번 실행한다. 이후의 실행을 위해서, 화면의 크기변화를 유발하는 이벤트 핸들러와 스크롤 이벤트 핸들러에 등록시킨다.

  $(document).ready( function(){
  
    vobjs = $(".vobj");

    vobjs.each( function( i, e ) {
      var je = $(e);
      if( je.visible()[1] ) {
        je.addClass("visible"); 
      } 
    });
    
    $(window).on('orientationchange resize scroll', function(){
      vobjControl();
    });

    ...

  });




6. animation을 화면에서 사라지게 하려고 display:none을 이용하면 layout jitter를 일으킨다. 그 결과로 화면 밖으로 나가서 보이지 않게된 객체가 실제로는 여전히 보이고 애니메이션을 실행중일 가능성이 50%이다.
Visibility:hidden을 이용하면 이 layout jitter를 피할 수 있다.