본문 바로가기
Portfolio/Publishing

스크롤 시 한 영역씩 이동

by chaen98 2021. 4. 8.
반응형

 

안녕하세요 :)

 

오늘은 포트폴리오에서 많이 사용하는 스크롤 시 영역이 이동되는 쿼리를 해볼까 합니다

이전 포스팅에서 JS플러그인을 소개하는 글에서 처음으로 소개했던 플러그인을 사용해도 무방하지만

코드로 작성할 수 있으면 더 좋지 않을까 해서 제가 학원에서 배운 것을 공유를 해드릴게요^^

 

포트폴리오에 사용된 JS

포트폴리오를 준비하면서 벤치마킹을 열심히 하면서 괜찮은 JS 플러그인들이 많아서 소개하려합니다. 1. fullPage.js 첫번째로 소개해줄 플러그인은 첫번째 포트폴리오 기획했던 내용중 https://chpofo

chpofo.tistory.com

먼저 완성작을 먼저 보고 코딩을 시작해 봅시다:)

 

스크롤 시 영역이동

영상에서와 같이 스크롤을 하면 한 영역씩 이동이 되는 그런 코드를 작성해봅시다

생각보다 어렵지 않으니까 천천히 따라 해 보아요

 


우선 HTML부터 작성을 해야겠지오?

<body>
      <div class="content"><h1>1</h1></div>
      <div class="content"><h1>2</h1></div>
      <div class="content"><h1>3</h1></div>
      <div class="content"><h1>4</h1></div>
      <div class="content"><h1>5</h1></div>
      <div class="content"><h1>6</h1></div>
      <div class="content"><h1>7</h1></div>
</body>

간단하죠??

지금은 그냥 영역을 나누기만 해서 간단하지만 나중에 포트폴리오를 작성할 때는

<div> 태그 안에다가 원하는 내용을 작성하시기만 하면 됩니다 :)

 

CSS로 영역을 확실하게 나누어봅시다

html{overflow: hidden;}

html, body{width: 100%; height: 100%;}

.content{
	width: 100%; height: 100%;
	background-color: blueviolet;
	
	position: relative;
}
.content > h1{
	position: absolute;
	top: 50%; left: 50%;
	transform: translate(-50%,-50%);

	font-size: 20em;
	font-weight: bold;
	text-shadow: 4px 4px 4px rgba(0, 0, 0, 0.6);

}
.content:nth-child(even){background-color: #333;}

 

소스코드 살펴보기

1 : 스크롤바를 없애기 위한 소스

3 :. content 요소의 높이를 전체 화면으로(뷰포트) 설정하기 위해 먼저 html 요소와 body 요소의 높이를 설정

6 : 단위의 기준은 부모인 html, body의 크기가 되므로 영역하나 가 전체 화면을 차지할 수 있다

9 : <h1> 요소가 .content 요소의 영역을 기준으로 배치가 되도록 포지션 값을 준다

12~14 : .content 요소의 영역을 기준으로 가운데 배치

21 : .content요소의 짝수의 배경을 바꿔서 영역을 보기 좋게 색상을 변경

 

 

여기까지도 충분히 이해할 수 있는 부분이라고 생각합니다

CSS에서 처음 듣는 단어나 이해를 못하겠다면 댓글로 달아주시면 제가 다시 한번 더 설명을 해드릴게요

 

 

이것을 구현하기 위한 마지막! 중요한 단계 JS를 작성을 해야겠지요??

jQuery는 소스를 나누어서 설명하고 마지막에 한 번에 다시 적어드릴게요

 

 

1. 기본 이벤트 제거

window.addEventListener("wheel", function(e){
	e.preventDefault();
},{passive : false});

 

 소스코드 살펴보기

우리가 사용할 이벤트는 wheel이벤트인데, 휠을 굴렸을 때 스크롤이 되지 않도록 하려면 wheel의 기본 이벤트인 scroll를 제거를 해줘야 한다.

근데 여기서 패시브모드를 해제를 해야 한다고 한다.

저도 이게 기억이 안 나서 다시 찾아보고 공부를 해봤는데 제가 이해한 선에서 설명을 해드릴게요 :)

 

📢 패시브 모드?해제?false??

passive는 addeventListener() 옵션중에 1개이다
passive옵션은 trueflase 값을 가지게 된다

flase인 경우 : preventDefault()를 이용해서 이벤트 자체를 막을 수 있기 때문에, 브라우저는 scroll를 계속할지 안할지를 매번 검사하게 된다. passive옵션의 기본값이다.
true인 경우 : 스크롤이벤트를 막지 않겠다! preventDefalt()를 사용할 수 없다.

처음에는 passive모드의 기본값이 flase이니까 따로 써줄 필요가 없지 않나 생각을 했었는데 아닌가봐요ㅜㅜ
그래서 더 검색해보고 찾아본 결과

기본이벤트를 제거를 해도 여전히 스크롤이 여전히 되고 오류가 발생이된다고 한다.
→ 이유는 패시브모드에서 동작하는 이벤트 이기 때문에
→ 그래서 패시브 모드를 끈 상태에서 기본이벤트를 제거를해야되는거다

아니 근데 passive모드의 기본값이 flase라며... 내가 잘못 본건가.. 저좀 이거 이해좀 시켜주세요..ㅠㅠ

 

2. 참조하는 요소 미리 탐색 및 선언

var $html = $("html");

var page = 1;

var lastPage = $(".content").length;

$html.animate({scrollTop:0},10);

▼ 소스코드 살펴보기

3 : 뷰포트에 표시되는 페이지의 번호

5 : 마지막 페이지의 번호 

7 : 문서(페이지)가 로드되면 첫 페이지 시작

 

3. 휠을 굴리면 다음 페이지, 이전 페이지

$(window).on("wheel", function(e){

	if($html.is(":animated")) return;

	if(e.originalEvent.deltaY > 0){
		if(page== lastPage) return;

		page++;
	}else if(e.originalEvent.deltaY < 0){
		if(page == 1) return;

		page--;
	}
	var posTop = (page-1) * $(window).height();

	$html.animate({scrollTop : posTop});

});

▼ 소스코드 살펴보기

1 : 이벤트 핸들러로 마우스 휠을 굴리면 발생하는 이벤트

3 : 아래에서 호출된 .animate 메서드로 생성된 스크롤 효과가 쌓이지 않도록 스크롤이 진행되는 동안 발생하는 wheel이벤트는 무시한다.

5, 9 : e(jQuery가 반환) .originalEvent(자바스크립트에서의 원래 이벤트) .deltaY(마우스 휠을 어느 방향으로 얼만큼을 굴렸는지 → 양수이면 아래쪽으로 굴린 거, 음수이면 위쪽으로 굴린 거다)

6 : 마지막 페이지인 경우에는 이벤트 핸들러 종료(스크롤될 것이 없으니 마지막에서 멈춰!!)

8, 12 : 스크롤을 아래로 했으면 페이지 +1, 위로 올렸으면 -1씩 시키기 

10 : 첫 번째 페이지인 경우에도 이벤트 핸들러 종료(올라갈 곳이 없으니 첫 번째에서 멈춰!!)

14 : 이동할 페이지의 번호에 스크롤할 위치 계산

16 : 계산한 위치로 이동

 

 

 

처음 보신 분들은 복잡할 수도 있지만 한줄한줄 천천히 읽고 이해를 하면 쉽게 다들 구현할 수 있을 거예요~

잘되는지 실행도 해보고 console.log 찍어서 확인도 해보세요!!

오늘 작성한 글이 도움이 되는 분들이 많았으면 좋겠네요ㅎㅎ

많이 어려우시면 지난번에 소개해드린 플러그인을 사용해서 구현하면 되는 거고

방법은 여러 가지가 있으니까 저의 소스뿐만 아니라 다른 사람들의 소스로도 구현해보세요

본인한테 맞고 이해하기 쉬운 코드로 구현하는 게 좋은 코드이니까요 :)

 

 

 

궁금하신 점이나 이해하기 어려운 부분은

댓글로 달아주시면 제가 친절하고 아는 선에서 알려드릴게요^^

 

 

 

 

 

 

댓글과 하트는 저에게 많은 힘이 됩니다 :)

반응형

댓글13

  • ㅇㅇㅇ 2021.06.30 10:19

    안녕하세요 원페이지 관련 소스 알아보다가 포스팅글을 보게되었습니다. 자세히 설명이 되어있어서 이해하기 좋았습니다. 근데 보다가 궁금해서요 저 코드는 반응형으로도 작동 되는건가요?? 모바일로는 다른 코드를 이용해야된다면 혹시 알려주실수 있는지 댓글 남깁니다 ~ ^^
    답글

    • chaen98 2021.06.30 10:27 신고

      안녕하세여 :)
      해당 소스는 width/height 값을 100%로 설정하여 뷰포트에 꽉 차게 잡혀있습니다.
      그래서 모바일을 원페이지로 퍼블리싱을 할때도 큰 차이가 없을거 같습니다.
      해보시고 문제있으시면 대댓글 달아주시면 확인해드리겠습니다.

  • ㅎㅎ 2021.07.07 12:15

    안녕하세요 잘 봤습니다 덕분에 많은 도움이 되었어요 감사합니다!!
    답글

  • ㅠㅠ 2021.08.10 03:41

    안녕하세요~!원페이지 소스로 포폴 만들다가 여쭤볼게 있어서요..
    다름이 아니라..스크롤은 부드럽게 잘되는데 제가 각 페이지별로 넣은 애니메이션이 페이지 열었을때 동시에 실행되어서요..ㅠㅠ저는 페이지가 넘어갈때 각 페이지에 들어간 애니메이션이 순차적으로 실행되었으면 하는데.. 왜 동시에 다 실행될까요?ㅠㅠ디자이너라..스크립트 소스도 다 엉킨거같고...ㅠㅠ알려주시면 감사할것같습니다 ㅠㅠ
    답글

    • chaen98 2021.08.10 09:28 신고

      애니메이션을 어느 위치에 왔을때 실행되도록 걸어놨는데 페이지이동되면서 위치가 한번에 딱 바뀌게 되니까 그거때문에 동시에 실행이 되는거 아닌까요??
      애니메이션 시간 조절을 해서 텀을 주면 페이지가 변경된 다음에 순차적으로 되지 않을까 싶은데 정확한 내용은 저도 소스를 봐야 이해가 될거 같아요
      제가 ㅠㅠ님의 댓글을 이해한걸로는 animation-delay로 시간 텀을 주시는게 맞을거 같아요
      한번 시간 텀 조절해보시고 안돼면 다시 해당 문제점을 가지고 대댓글 달아주시면 확인해보도록 하겠습니다

  • ㅠㅠ 2021.08.12 03:37

    제가 2페이지에 setInterval로 그래프 애니메이션을 넣었는데 그냥 1페이지에서부터 바로 실행이 되네요..2페이지 뜨면 실행시키고싶은데~코드 수정을 못하겠네여..또르르르륵..ㅠ0ㅠ
    답글

  • 123 2021.09.23 17:28

    페이지를 중간에 새로고침하면 그부분 에서 시작하는게 아니라 첫페이지로 가버리는건 의도된 건가요? 궁금해서 질문 남겨요.
    답글

    • chaen98 2021.09.27 17:47 신고

      새로고침을 하게 되면 페이지가 새로 시작되는거여서 자동으로 첫부분으로 돌아가게 되는거 같아여. 따로 코드를 손대서 의도한건 아닙니다.
      근데 그부분에서 새로고침이 되게 하는 코드가 있는걸로 알고 있는데 거기까지는 아직 제가 공부를 못했네요~~ 공부를 하게 된다면 포스팅으로 올려드리도록 하겠습니다^^

  • 초롱 2021.10.06 20:03

    안녕하세요~! 덕분에 원하던대로 잘 완성되었습니다
    그런데 모바일에선 스크롤이 되지않고 메인에 멈춰있는데 어떻게하면 스크롤이내려갈까요 ㅠ,,,
    답글

    • chaen98 2021.11.08 13:29 신고

      해당 부분 또한 저도 생각지도 못한 부분이여서 저도 다시한번 확인 후 재 업로드를 해드리도록 하겠습니다.

  • 얼큰한솜사탕 2021.11.07 15:41

    정보 감사합니다! 혹시 마지막 페이지 도달햇을시 다시 스크롤 정상작동 되게하려면 어떤걸 건드려야할까요 ? 이제 코딩 입문이라 감이 안잡히네요 ㅠㅠ
    답글

    • chaen98 2021.11.08 13:29 신고

      저도 잘은 모르겠지만, 기본 이벤트를 제거한 것을 취소하면 되지 않을까 싶네요~~
      저도 한번 시도를 해보고 다시 업로드를 해드리도록 하겠습니당.ㅎ

  • 얼큰한솜사탕 2021.11.09 17:48

    답변감사드립니다! 문장으로는 이해는 했지만 ..ㅋㅋㅋ 코딩이 제 머리로는 아직 불가능한가봐요 말뜻은 알겟는데 방법을 모르겟네유ㅠㅠㅠㅠ 업로드를 기다리며 고심을 해봐야겟네요 ㅋ
    답글