개인프로젝트를 진행중 고민에 빠졌다. React-Slick 슬라이더 내, 각각의 요소에 클릭 이벤트를 따로 걸어두고 싶었다.
이게 왜 문제냐면... 슬라이더를 넘길 때 클릭 이벤트도 동시에 발생하는데, 넘길 때는 클릭 이벤트가 발생하면 안되게 만들어야했다.
구글링 끝에 방법을 알아냈다!! 링크
const clickOrDragDetection = () => {
const items = document.querySelectorAll('.slick-slider .item');
let moved //moved는 클릭 후, 움직일 때 true, 클릭만 할 때 false
let downListener = () => {
moved = false
}
let moveListener = () => {
moved = true
}
let upListener = () => { //moved 여부로 판단
if (moved) {
console.log('moved')
} else {
console.log('not moved')
}
}
// 이벤트 등록
for(const item of items) {
item.addEventListener('mousedown', downListener);
item.addEventListener('mousemove', moveListener)
item.addEventListener('mouseup', upListener);
}
// 이벤트 해제
return () => {
for(const item of items)
item.removeEventListener('mousedown', downListener)
.removeEventListener('mousemove', moveListener)
.removeEventListener('mouseup', upListener);
}
}
const Interest = () => {
const [moved, setMoved] = useState(false);
const downListener = () => {
setMoved(false);
}
const moveListener = () => {
setMoved(true);
}
const upListener = (code, idx) => {
// console.log(idx);
if (moved) {
console.log('moved')
} else {
console.log('not moved');
clickCategory(code, idx);
}
}
const setCategoryObj = interests.map((item, idx) => (
<div
ref={element => divRef.current[idx] = element}
key={idx}
>
<div
className={item.check ? 'item on' : 'item'}
onMouseUp={() => upListener(parseInt(item.categoryCode), idx)}
onMouseMove={moveListener}
onMouseDown={downListener}>
<div className="title-img">
<div className='click-part'>
<FontAwesomeIcon icon={faCheck} />
</div>
<img src={`/upload/images/${item.imageName}`} alt={item.name}/>
</div>
<span className="cat-title">{item.name}</span>
</div>
</div>
));
return(
<div className="interest-part">
<Slider {...settings}>
{setCategoryObj}
</Slider>
</div>
)
}
위 소스의 대부분은 무시해도 되고 onMouse~~() 부분이랑 state로 선언한 moved와 관련 함수만 체크하면 된다.
해결 완료! (라고 생각했다.)
문제는 해당 요소에 move 이벤트 시 true, down 이벤트 시 false 인데 down 이벤트 발생과 동시에 미세한 마우스 이동만 있어도 바로 true로 바뀐다는 거다.... 문제 해결 방법으로 setTimeout() 사용하였다.
let moveCount = 0;
const moveListener = () => {
if(moveCount === 0) {
moveSet();
moveCount++;
}
}
const moveSet = () => {
setTimeout(() => {
setMoved(true);
}, 100);
}
const upListener = (code, idx) => {
// console.log(idx);
if (moved) {
console.log('moved')
} else {
console.log('not moved');
clickCategory(code, idx);
}
}
끝!