반응형
버튼을 클릭하면 서버 요청이 한 번만 들어와야 하는데 2번 이상 들어오는 케이스가 생겼다.
버튼 중복 클릭을 방지하기 위해 클라이언트 단에서 처리가 필요했다.
총 2가지 방법을 사용해보았고, 둘 다 문제 없이 잘 실행된다.
실제로 적용해 배포한 건 두번째 방법이다.
우선 버튼은 아래와 같다.
<button id="serverCallButton" onclick="serverCallClick()">서버 호출 버튼</button>
1. 클릭 시 버튼 비활성화(diabled) 처리
버튼 중복 클릭 방지를 구글링했을 때 가장 많이 나오는 방법이다.
클릭 시 버튼 요소 자체를 비활성화시키는 것이다.
서버 호출 후 응답을 받은 이후에 다시 버튼을 활성화시켜주었다.
function serverCallClick() {
// 버튼 요소
const serverCallButton = $("#serverCallButton");
// 버튼이 비활성화되어 있는 경우(이미 클릭된 경우)
if (serverCallButton.prop("disabled")) {
console.log("서버 통신 중");
return;
}
// 버튼을 비활성화하여 중복 클릭 방지
serverCallButton.attr("disabled", true);
/**
* ...
* 서버 통신 관련 코드
* ...
*/
console.log("서버 통신 성공");
// 서버 통신 성공 후 버튼 활성화
serverCallButton.attr("disabled", false);
}
2. 디바운스(Debounce)
디바운스는 DOM 이벤트를 기반으로 실행하는 Javascript의 성능 상 이유로 인해 이벤트(event)를 제어(제한)하는 방법 중 하나다.
이벤트를 그룹화해서 특정 시간이 지난 후에 하나의 이벤트만 발생하도록 하는 기술이다. 즉, 연이어 호출되는 함수들 중 마지막 함수나 가장 처음 함수만 호출하도록 하는 것이다.
아래 코드를 통해서 나는 버튼 중복 클릭을 방지하기 위해 가장 처음 클릭만 서버를 호출하도록 하고 이후의 나머지 클릭들은 무시하도록 했다.
// 버튼 중복 클릭 방지(디바운싱)
function debounce(func, timeout = 300) {
let timer;
return (...args) => {
if (!timer) { // 이전에 설정된 타이머가 없는 경우에만 함수 호출 = 가장 처음에만 함수 호출
func.apply(this, args);
}
clearTimeout(timer);
timer = setTimeout(() => { // 일정 시간이 지난 후 timer 변수를 undefined로 설정해 다음 호출에 대비
timer = undefined;
}, timeout);
};
}
function serverCall() {
/**
* ...
* 서버 통신 관련 코드
* ...
*/
console.log("서버 통신 성공");
}
// 서버 호출 버튼 클릭
const serverCallClick = debounce(() => serverCall());
두 가지 방법 중 하나만 선택해서 적용하면 된다.
반응형