[JS] 클릭과 드래그 이벤트 구분하기(React)

P__.mp4·2022년 9월 11일

JAVASCRIPT

목록 보기
2/4

개인프로젝트를 진행중 고민에 빠졌다. React-Slick 슬라이더 내, 각각의 요소에 클릭 이벤트를 따로 걸어두고 싶었다.

이게 왜 문제냐면... 슬라이더를 넘길 때 클릭 이벤트도 동시에 발생하는데, 넘길 때는 클릭 이벤트가 발생하면 안되게 만들어야했다.

구글링 끝에 방법을 알아냈다!! 링크

JavaScript에서 해결법

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);
	}
}

React에서 사용

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);
  }
}

끝!

profile
개발은 자신감

0개의 댓글