click
이벤트와 dblclick
이벤트를 사용하고, 클릭을 setTimeout
으로 일정 시간 동안 지연시켜 더블클릭인지 단일 클릭인지 확인하는 방법을 사용한다.
JavaScript로 작성한 후 React 버전으로 수정 작성하였다.
모듈 파일 (handlers.js)
setupDblClickHandler
함수는 더블 클릭 시 클릭 타이머를 정리하는 역할만 수행한다.
// handlers.js
const clickTimeouts = new WeakMap();
export function setupClickHandler(element, handleClick) {
element.addEventListener("click", function(event) {
clearTimeout(clickTimeouts.get(element)); // 기존 타이머 클리어
const timeout = setTimeout(function() {
handleClick(event);
}, 500); // 500ms 후에 클릭 이벤트로 처리
clickTimeouts.set(element, timeout); // 새로운 타이머 저장
});
}
export function setupDblClickHandler(element) {
element.addEventListener("dblclick", function() {
clearTimeout(clickTimeouts.get(element)); // 기존 타이머 클리어
});
}
메인 파일 (main.js)
// main.js
import { setupClickHandler, setupDblClickHandler } from './handlers.js';
document.addEventListener("DOMContentLoaded", function() {
// 예제 핸들러 함수
function exampleClickHandler(event) {
alert(`Single Click Detected on element: ${event.target.id}`);
}
// 요소를 동적으로 선택
var button1 = document.getElementById("myButton1");
var button2 = document.getElementById("myButton2");
// 동적 핸들러를 각 요소에 설정
setupClickHandler(button1, exampleClickHandler);
setupClickHandler(button2, exampleClickHandler);
setupDblClickHandler(button1);
setupDblClickHandler(button2);
});
HTML 파일
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Element and Handler</title>
</head>
<body>
<button id="myButton1">Click or Double Click Me</button>
<button id="myButton2">Another Button</button>
<script type="module" src="main.js"></script>
</body>
</html>
코드 설명
setupClickHandler
: 클릭 이벤트가 발생하면 타이머를 설정하여 단일 클릭 이벤트를 처리한다.- 이전 타이머를 정리하고 새로운 타이머를 설정하여 500ms 후에
handleClick
함수를 호출한다.
- 이전 타이머를 정리하고 새로운 타이머를 설정하여 500ms 후에
setupDblClickHandler
: 더블 클릭 이벤트가 발생하면 타이머를 정리한다.- 클릭 타이머를 정리하여 단일 클릭 이벤트가 호출되지 않도록 한다.
exampleClickHandler
: 단일 클릭 이벤트 핸들러로, 클릭된 요소의 ID를alert
창에 표시한다.- HTML 파일:
main.js
를type="module"
로 포함하여 모듈 시스템을 사용한다.
주의 사항
- 이 구조에서는 더블 클릭 시 추가 로직을 처리하지 않는다. 만약 더블 클릭에 다른 동작을 추가하고 싶다면,
setupDblClickHandler
함수를 다시 확장해야 한다. - 최신 브라우저 환경에서 작동하도록 설계되었기 때문에 구형 브라우저에서는 ES6 모듈과
WeakMap
지원을 확인해야 한다.
React에서 사용 가능하도록 수정한 버전 1
React에서 setupClickHandler
와 setupDblClickHandler
기능을 제공하는 방법으로, 커스텀 훅을 사용하여 단일 클릭과 더블 클릭을 구분하는 로직을 구현할 수 있다. 커스텀 훅은 재사용 가능한 로직을 추상화하고 컴포넌트에서 쉽게 사용할 수 있도록 도와준다.
아래는 useClickHandler
라는 커스텀 훅을 작성하고 이를 React 컴포넌트에서 사용하는 예시이다.
1. useClickHandler
커스텀 훅 작성
hooks/useClickHandler.js
단일 클릭과 더블 클릭을 처리할 수 있는 useClickHandler
훅을 작성한다. 이 훅은 clickHandler
를 인자로 받아서 클릭 이벤트와 더블 클릭 이벤트를 처리한다.
// hooks/useClickHandler.js
import { useRef, useEffect } from 'react';
export function useClickHandler(clickHandler) {
const clickTimeoutRef = useRef(null);
useEffect(() => {
// 타이머를 클리어하는 함수
const clearClickTimeout = () => {
if (clickTimeoutRef.current) {
clearTimeout(clickTimeoutRef.current);
clickTimeoutRef.current = null;
}
};
const handleClick = (event) => {
clearClickTimeout();
clickTimeoutRef.current = setTimeout(() => {
clickHandler(event);
}, 300); // 300ms 후에 클릭 이벤트로 처리
};
const handleDblClick = () => {
clearClickTimeout(); // 더블 클릭 시 타이머 클리어
};
return { handleClick, handleDblClick };
}, [clickHandler]);
return { handleClick, handleDblClick };
}
2. React 컴포넌트에서 훅 사용
useClickHandler
훅을 사용하여 클릭 이벤트와 더블 클릭 이벤트를 처리하는 예제 컴포넌트를 작성한다.
components/ClickHandlerComponent.js
// components/ClickHandlerComponent.js
import React from 'react';
import { useClickHandler } from '../hooks/useClickHandler';
export function ClickHandlerComponent() {
const { handleClick, handleDblClick } = useClickHandler((event) => {
alert(`Single Click Detected on element: ${event.target.id}`);
});
return (
<div>
<button
id="myButton1"
onClick={handleClick}
onDoubleClick={handleDblClick}
>
Click or Double Click Me
</button>
<button
id="myButton2"
onClick={handleClick}
onDoubleClick={handleDblClick}
>
Another Button
</button>
</div>
);
}
3. 앱 컴포넌트
React 앱에서 ClickHandlerComponent
를 사용.
App.js
// App.js
import React from 'react';
import { ClickHandlerComponent } from './components/ClickHandlerComponent';
function App() {
return (
<div className="App">
<h1>React Click and Double Click Handler</h1>
<ClickHandlerComponent />
</div>
);
}
export default App;
4. 프로젝트 구조
/project-root
├── /src
│ ├── /components
│ │ └── ClickHandlerComponent.js
│ ├── /hooks
│ │ └── useClickHandler.js
│ └── App.js
├── index.html
└── index.js
코드 설명
useClickHandler
훅:clickTimeoutRef
를 사용하여 클릭 타이머를 관리한다.handleClick
과handleDblClick
함수는 각각 클릭과 더블 클릭 이벤트를 처리한다.clearClickTimeout
함수는 타이머를 클리어하여 단일 클릭과 더블 클릭을 구분한다.useEffect
는clickHandler
가 변경될 때마다 새로 등록된 핸들러를 업데이트 한다.
ClickHandlerComponent
컴포넌트:useClickHandler
훅을 사용하여 클릭 및 더블 클릭 핸들러를 생성한다.- 각 버튼에
handleClick
과handleDblClick
을 이벤트 핸들러로 설정한다.
App
컴포넌트:ClickHandlerComponent
를 사용하여 버튼 클릭 이벤트를 처리합니다.
추가 사항
- 의존성 관리:
useClickHandler
훅은clickHandler
가 변경될 때마다 타이머를 관리하도록 의존성을 설정한다. - 타이머 관리: 타이머는
useRef
로 관리되어 컴포넌트가 리렌더링되더라도 상태가 유지된다.
React에서 사용 가능하도록 수정한 버전 2
React에서 이벤트 핸들러를 설정하고 단일 클릭과 더블 클릭을 구분하기 위해, Hook을 사용하여 상태를 관리할 수 있다. 아래 예시에서는 useEffect
와 useRef
를 사용하여 DOM 이벤트를 설정하고, useState
를 사용하여 클릭 타이머 상태를 관리한다.
1. Custom Hook (useClickHandler.js)
먼저, 클릭과 더블 클릭 핸들러를 설정하는 Custom Hook을 정의한다.
// useClickHandler.js
import { useEffect, useRef } from 'react';
const useClickHandler = (elementRef, handleClick) => {
const clickTimeoutRef = useRef(null);
useEffect(() => {
const element = elementRef.current;
const handleSingleClick = (event) => {
clearTimeout(clickTimeoutRef.current);
clickTimeoutRef.current = setTimeout(() => {
handleClick(event);
}, 300); // 300ms 후에 클릭 이벤트로 처리
};
const handleDoubleClick = (event) => {
clearTimeout(clickTimeoutRef.current); // 더블 클릭 시 타이머 클리어
};
if (element) {
element.addEventListener('click', handleSingleClick);
element.addEventListener('dblclick', handleDoubleClick);
}
// Cleanup 이벤트 리스너
return () => {
if (element) {
element.removeEventListener('click', handleSingleClick);
element.removeEventListener('dblclick', handleDoubleClick);
}
};
}, [elementRef, handleClick]);
};
export default useClickHandler;
2. 컴포넌트 파일 (MyComponent.js)
Custom Hook을 사용하여 단일 클릭 이벤트 핸들러를 설정하는 컴포넌트를 작성한다.
// MyComponent.js
import React, { useRef } from 'react';
import useClickHandler from './useClickHandler';
const MyComponent = () => {
const buttonRef1 = useRef(null);
const buttonRef2 = useRef(null);
const handleClick = (event) => {
alert(`Single Click Detected on element: ${event.target.id}`);
};
useClickHandler(buttonRef1, handleClick);
useClickHandler(buttonRef2, handleClick);
return (
<div>
<button id="myButton1" ref={buttonRef1}>Click or Double Click Me</button>
<button id="myButton2" ref={buttonRef2}>Another Button</button>
</div>
);
};
export default MyComponent;
코드 설명
- Custom Hook (useClickHandler.js):
useClickHandler
는elementRef
와handleClick
을 인자로 받는다.clickTimeoutRef
는useRef
를 사용하여 클릭 타이머를 저장한다.useEffect
를 사용하여 컴포넌트가 마운트될 때 이벤트 리스너를 설정하고 언마운트될 때 정리한다.- 단일 클릭 이벤트를 처리하는
handleSingleClick
과 더블 클릭 시 타이머를 정리하는handleDoubleClick
을 정의한다.
- 컴포넌트 파일 (MyComponent.js):
buttonRef1
과buttonRef2
는 각각 두 버튼의 참조를 저장한다.handleClick
은 단일 클릭 이벤트 핸들러로, 클릭된 요소의id
를alert
로 표시한다.useClickHandler
를 사용하여 각 버튼에 대해 클릭 핸들러를 설정한다.- 버튼 요소에
ref
속성을 설정하여 DOM 요소를 참조할 수 있게 한다.
React 애플리케이션 구조
/src
/components
MyComponent.js
/hooks
useClickHandler.js
index.js
React 애플리케이션 설정
index.js
애플리케이션의 진입점으로, MyComponent
를 렌더링.
import React from 'react';
import ReactDOM from 'react-dom';
import MyComponent from './components/MyComponent';
ReactDOM.render(
<React.StrictMode>
<MyComponent />
</React.StrictMode>,
document.getElementById('root')
);