ajax는 비동기 통신을 위한 방법인데 간혹 연속 클릭으로 인해 중복 처리가 되는 경우가 있다. 물론 프로그램단에서 db 조건과 비교하여 막는 방법이 있지만 request 한 페이지에 외부 api 통신이 있을 경우 딜레이가 발생되어 중복체크를 하가기 어렵다. 따라서 이번편에서는 클라이언트단에서 연속 click 이벤트를 막는 방법에 대해 예제소스를 통해 알아보자.

 

우선 아래와 같은 ajax 비동기 통신을 하는 프로그램을 만들어 준다. 

<!-- juqery 3.5.1 -->
<script src="//code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> 

<form id="form">
	<p><input type="text" name="email" value="" placeholder="이메일을 입력해주세요"></p>
	<p><textarea name="content" placeholder="문의 내용을 입력해주세요."></textarea></p>
	<p><input type="submit" value="문의하기"></p>
</form>
<script>

// form 데이터를 serializeObject 로 변환해주는 서포트 메드 (https://blog.redinfo.co.kr/post/view?pid=68 참고)
$.fn.serializeObject = function () {
    let result = {};
    let serializeArray;

    try{
        if( $(this)[0].nodeName == 'FORM'){ serializeArray = this.serializeArray();}
        else{ serializeArray = $(this)[0].children; }
    }catch(e){ return result; }

    $.each(serializeArray,function(i,e){
        try{
            let node = result[e.name];
            if ( (e.type == 'checkbox' || e.type == 'radio') && e.checked !== true ){ return true;}
            if (typeof node !== 'undefined' && node !== null) {
                if ($.isArray(node)) { node.push(e.value);} 
                else {result[e.name] = [node, e.value];}
            } 
            else {result[e.name] = e.value;}
        }catch(e){}
    });
    return result;
};	

// 서브밋 이벤트
var authSubmit = true; // ajax 통신 서브밋 연속클릭 제어변수 선언
$(document).on('click','#form input[type="submit"]',function(e){

	// ajax 통신 서브밋 연속클릭 제어변수 체크
	if( authSubmit !== true){ alert('잠시만 기다려주세요.'); return false; }

	var $form = $('#form');
	var data = $form.serializeObject();
	try{
		if( data.email == ''){ throw {msg: '이메일을 입력해주세요.',name:'email'};}
		if( data.content == ''){ throw {msg: '문의내용을 입력해주세요.',name:'content'};}
	}catch(e){
		alert(e.msg);
		$form.find('[name="'+e.name+'"]').focus();
		return false;
	}

	authSubmit = false;
	$.ajax({url:'request.php',data:data, dataType:'json', type:'post'})
	.done(function(e){
		alert(e.msg);
		$form[0].reset();
		return false;	
	})
	.always(function(e){
		authSubmit = true; // ajax 통신 서브밋 연속클릭 제어변수 초기화
	});
	return false;
});
</script>

 

그다음 비동기 통신으로 받을 페이지를 아래와 같이 `reqeust.php`로 작성해 준다. 참고로 예제이때문에 간단하게 딜레이를 발생시킬 sleep 함수를 추가하여 처리하였다.

<?php # request.php
// db 처리 
//		....... 생략 

// 결과 

sleep(3);

die(json_encode(array('msg'=>'문의가 등록되었습니다.')));

 

마지막으로 위의 소스를 실행하여 문의하기를 연속 클릭해보면 `잠시만 기다려주세요.` 라는 알럿창을 볼 수가 있는데 이는 `request.php` 에서 sleep 함수에 의해 3초간 딜레이가 발생되어 아직 응답을 받지 못하였기때문이다.  이를 제어하는 변수는 아래와 같다.  

var authSubmit = true; // ajax 통신 서브밋 연속클릭 제어변수 선언

 

참고로 예제소스를 보면 `serializeObject` 메서드가 있는데 해당 메서드는 form 의 데이터를 object 로 변환해주는 유용한 메서드로 공식 지원되는 메서드는 아니기때문에 위와 같이 커스텀하여 사용해야한다.  참고로 해당 메서드는 아래 포스팅에서 확인 가능하다. 

 
[JS&JQUERY] 커스텀 메소드 | serializeObject - R BLOG
스크립트를 이용하여 AJAX처리를 하다보면 Form 데이터들을 추출해야할때가 있다. 물론 각각 뽑아서 써도 되지만, 소스코드 몇타를 더 쳐야하는 불편함이 있는데 나같은 경우 타이핑하는걸 정말 귀찮아 하기 때문에 최소한으로 타이핑을 할 수 있는걸 찾아서 쓰곤한다. 아래는 serializeObject 메소드 예제이니 참고하여 사용하면 된다. $.fn.seria··· - R BLOG
blog.redinfo.co.kr/post/view?pid=68