본문 바로가기

IT

[JS] 스크롤 내리다 대상이 캐치 이벤트(또는 클래스) 생성 / 제거

 

에피소드

모바일 웹 프로젝트 중 상품 목록을 보여주는 리스트가 있다. 처음 기획에는 상품 이미지만 보여주거나 동영상의 프리뷰 이미지만 보여줬는데 추가사항으로 비디오를 넣어주고 해당 비디오가 화면에 보일 시 자동으로 실행이 되야하는게 요청이 있었다. 

문제

스크롤이 특정 영상에 도달하면 자동재생 / 벗어나면 자동정지

해결

스크롤 위치 값을 계산하여 모든 특정 영상($videos)을 기준으로 현재 스크롤 위치에 따라 클래스 또는 이벤트를 실행 / 제거

참고사항

비디오/오디오는 브라우저에서 자동실행(이벤트실행)을 하기 위해서는 음소거(muted) 상태여야한다.
아래 참고자료와 구글 개발자포럼을 봐도 장황하게 설명 되어 있다. 하지만 브라우저 정책이기 때문에 그냥 video 태그에 muted를 추가하면 해결된다.

참고 : https://stackoverflow.com/questions/49930680/how-to-handle-uncaught-in-promise-domexception-play-failed-because-the-use

//스크롤 중 대상($videos)이 화면 중간에 위치하면 클래스 추가 또는 이벤트(재생/일시정지) 실행
$(window).on('scroll',scrollFn); 

        // Scroll Event
        $.fn.scrollGet = function(){ 
          var offset = $(window).scrollTop() + $(window).height() / 2, 
              $videos = $('.video_obj'); 

         if ($videos.length == 0) { 
         	$(window).off('scroll', $.fn.scrollAni); 
         } 

         $videos.each(function(i) { 
         	var $video = $(this), 
           	video = $video.find('video'), 
         	item_top = $video.offset().top, 
         	item_h = $video.height(); 
           	// console.log($video.offset().top) 
           	if (($video.offset().top) < offset && (item_top + item_h) > offset) { 
              if(!$video.hasClass('video_on')){ 
              video.get(0).play(); 
              $video.addClass('video_on'); 
              } 
           	} else { 
              if($video.hasClass('video_on')){ 
                  video.get(0).pause(); 
                  $video.removeClass('video_on'); 
              } 
           } 
         }); 
        }; 
        
// Scroll Event Function 
function scrollFn(){ 
	$.fn.scrollGet(); 
}