[javascript] 개인정보 취급방침 스크롤시 동작 처리

페리·2021년 4월 30일
post-thumbnail

맡고있는 프로젝트에서 [개인정보 취급방침 동의 페이지]를 만들게 되었다.

요즘 개인정보 취급방침을 안 읽는 사람이 많기 때문에(나 포함) 스크롤 시에 다음과 같이 동의 항목이 다음과 같이 열리도록 설정하는 것이 목적이다.

또한 동의함을 체크해야 가입 버튼이 활성화된다.


(아마도 기능 뿐 아니라 css도 함께 변경되도록 설정해놓았기 때문에 코드 분석에 어려움이 있을 수도 있다는 점 참고)

먼저 html 코드는 다음과 같다.

<div class="container d-flex flex-column" style="padding-top:1rem;">
	<h5 style="color:black;">> 개인정보 취급방침 동의</h5>
	<span style="font-size:1rem; color:blue;">* 아래 약관을 읽은 후 이용가능합니다.</span>
	<div class="flex-center" style="padding-top:1rem;">
		<textarea id="privacy_scroll" style="resize:none; width:100%; height:20rem; padding:0.5rem;" readonly>
	-개인정보 취급방침 동의내용 작성하시면 됩니다.-
		</textarea>			
    	</div>
    <form style="width:100%; text-align:center; margin:1rem 0;">
    	<p style="display:inline-block; margin-bottom:0;"><b>위 개인정보 수집에 대한 동의를 거부할 권리가 있으며, </b></p><p style="display:inline-block;"><b>&nbsp;동의 거부시에는 회원가입이 제한 됩니다.</b></p>
        <div><b>개인정보 취급방침에 동의하십니까?</b> 
              <div class="radio-wrapper">
                    <label id="privacy-text1" style="margin-left:0.5rem; color:#e3e3e3;">
                    <input type="radio" id="agree" name="privacy" value="agree" style="border:1px solid #e3e3e3; background-color:white;" disabled/> 동의함 
                    </label>
                    <label id="privacy-text2" style="margin-left:0.5rem; color:#e3e3e3;">
                        <input type="radio" id="disagree" name="privacy" value="disagree" style="border:1px solid #e3e3e3; background-color:#e3e3e3;" checked="checked" disabled/> 동의안함 
                    </label>
               </div>
	</div>			
        <input type="button" id="privacy_submit" onclick="alert('약관 동의 후 이용 가능합니다.');" value="가입하기" style="border:1px solid #e3e3e3; color:#e3e3e3;"/>
     </form>
</div>

css 파일은 따로 만들지 않고, inline으로 작성하였다.

여기서 중요한 것은

textarea의 id : privacy_scroll
radio input(동의)의 id : agree
radio input(미동의)의 id : disagree
radio input의 name : privacy
submit button의 id : privacy_submit

라고 했을 때에

두 가지 경우가 있다.

(1) 스크롤을 모두 내렸을 때 체크가 가능하도록.
(2) 스크롤을 내리기만 해도 체크가 가능하도록.

개발자마다 원하는 방식을 선택하여 적용하면 된다.

js를 파악하기 전에 알아두어야 할 요소는 다음과 같다.

textarea의 전체 scroll할 수 있는 범위내에서의 scroll 위치를 나타내는 scrollTop,
스크롤되어 나타나는 부분까지의 높이를 나타내는 scrollHeight.


(1) 스크롤을 모두 내렸을 때 체크가 가능하도록 만드는 경우의 js

사실 구글링에 나와있는 자료 대부분은 scroll 시에 메뉴바 숨기기, 헤더 숨기기 등 scroll을 했는지 안했는지에 중점을 두고 코드가 작성되어 있었다.

scroll을 끝까지 했는지를 판단하려면,
scroll의 크기 + scrollTop > scrollHeight 로 조건을 만드는게 가장 이상적이지 않을까 싶은데, scroll의 크기를 구하는 것은 알지 못하여서 고민해보았다.

그래서 고민한 결과, 350정도의 여유를 주고,
scrollTop + 350 > scrollHeight의 조건을 주었더니 정상적으로 동작하게 되었다.

사실 정확하게 스크롤이 끝에 닿을 때를 측정하지는 못한다.
하지만, 거의 내려간 것을 확인 후에 변화하기 때문에 어느정도 비슷하게 구현한 셈이다.

$("#privacy_scroll").scroll(function(){
    var scrollTop = $(this).scrollTop();
    var scrollHeight = $(this).prop('scrollHeight');
  
    if (scrollTop + 350 >= scrollHeight) {
    	$("#agree").removeAttr("disabled");
        $("#disagree").removeAttr("disabled");
        $("#privacy-text1").css("color","black");
        $("#privacy-text2").css("color","black");
        $("#privacy_submit").attr("disabled");
        $("#agree").css("border", "1px solid black");
        $("#disagree").css("border", "1px solid black");
        
        // privacy라는 name을 가진 radio input의 check css 변경
        $('input[name="privacy"]').each(function() {
        	var checked = $(this).prop('checked');
        	if(checked) {
        		$(this).css("background-color", "black");
        	} else {
			$(this).css("background-color", "white");
        	}
        });
    }
});

(2) 스크롤을 내리기만 해도 체크가 가능하도록 만드는 경우의 js

이 경우는 너무 쉽다. scrollTop의 초기 위치가 0이기 때문에 0을 넘기만 하면 scroll이 움직인 것이기 때문이다.

$("#privacy_scroll").scroll(function(){
    var scrollTop = $(this).scrollTop();
  
    if (scrollTop > 0) {
    	$("#agree").removeAttr("disabled");
        $("#disagree").removeAttr("disabled");
        $("#privacy-text1").css("color","black");
        $("#privacy-text2").css("color","black");
        $("#privacy_submit").attr("disabled");
        $("#agree").css("border", "1px solid black");
        $("#disagree").css("border", "1px solid black");
        
        // privacy라는 name을 가진 radio input의 check css 변경
        $('input[name="privacy"]').each(function() {
        	var checked = $(this).prop('checked');
        	if(checked) {
        		$(this).css("background-color", "black");
        	} else {
			$(this).css("background-color", "white");
        	}
        });
    }
});

위와 같이 코드를 짜게되면 두 경우 모두 사용가능해진다.

0개의 댓글