지식 정리 📝

iframe으로 인한 width 드래그 조절 문제 해결한 방법

엄성준 2025. 8. 22. 20:38
728x90

리스트 영역(. listContainer)의 width를 마우스 드래그로 조절하는 기능을 구현하던 중 예상치 못한 문제가 발생했습니다.

일반적으로는 mousedown → mousemove → mouseup 이벤트 흐름을 따라 자연스럽게 동작합니다.

하지만 DOM 안에 iframe이 존재하면 문제가 생겼습니다.

 

❗️ 문제 상황

width 드래그 조절 실패 영상

 

기본적인 resize 로직은 다음과 같이 작성했습니다:

startResizing(event) {
  this.isResizing = true;
  this.initialX = event.clientX;
  const listContainer = document.querySelector('.listContainer');
  this.initialWidth = listContainer.offsetWidth;

  document.addEventListener('mousemove', this.resize);
  document.addEventListener('mouseup', this.stopResizing);
},

 

마우스를 드래그하다가 커서가 iframe 위에 올라가면 부모 문서의 이벤트 흐름이 끊겨 더 이상 mousemove 이벤트를 감지하지 못하는 현상이 발생했습니다.

 

이유는 간단했습니다:
👉 iframe은 하나의 독립된 문서로 취급되기 때문에, iframe 위로 마우스가 올라가면 부모 DOM에서 이벤트를 받을 수 없기 때문입니다.


✅  해결 방법

이를 해결하기 위해 투명한 오버레이(overlay) 레이어를 추가하는 방식을 사용했습니다.
드래그가 시작되면 화면 전체에 투명한 div를 덮어씌워, 마우스가 iframe 위로 올라가더라도 이벤트가 끊기지 않도록 했습니다.

아래와 같이 코드를 수정하니 iframe이 있는 상황에서도 정상적으로 width 조절이 가능해졌습니다.

startResizing(event) {
  this.isResizing = true;
  this.initialX = event.clientX;
  const listContainer = document.querySelector('.listContainer');
  this.initialWidth = listContainer.offsetWidth;

  // 오버레이 추가
  this._overlay = document.createElement('div');
  Object.assign(this._overlay.style, {
    position: 'fixed',
    inset: '0',
    zIndex: '999999',
    cursor: 'ew-resize',
    background: 'transparent',
  });
  document.body.appendChild(this._overlay);

  document.addEventListener('mousemove', this.resize);
  document.addEventListener('mouseup', this.stopResizing);
},

resize(event) {
  if (this.isResizing) {
    const dx = event.clientX - this.initialX;
    const newWidth = this.initialWidth + dx;

    // 최소 / 최대 width 제약 조건
    if (newWidth >= 460 && newWidth <= window.innerWidth - 800) {
      document.querySelector('.listContainer').style.width = `${newWidth}px`;
    }
  }
},

stopResizing() {
  this.isResizing = false;
  document.removeEventListener('mousemove', this.resize);
  document.removeEventListener('mouseup', this.stopResizing);

  // 오버레이 제거
  if (this._overlay) {
    this._overlay.remove();
    this._overlay = null;
  }
}

 

width 드래그 조절 성공 영상


💡 느낀 점

처음에는 단순히 이벤트 연결 문제라고 생각했는데, iframe이 독립된 문서라는 점을 간과하고 있었습니다.

이번 문제를 해결하면서 iframe 위에서는 부모 문서의 이벤트가 끊긴다는 사실을 명확히 이해하게 되었고, 앞으로 유사한 상황이 발생했을 때 빠르게 원인을 파악하고 해결할 수 있을 것 같습니다.