2016-09-08 9 views
0

을 드래그 앤 드롭을 사용할 때의 난이 간단한 RxJS를 통해 드래그 N 드롭에 대한 코드가 있다고 가정합시다 요소에 클릭을 방지하는 방법 :RxJS : N

const { fromEvent } = Rx.Observable; 
const target = document.querySelector('.box'); 

const mouseup = fromEvent(target, 'mouseup'); 
const mousemove = fromEvent(document, 'mousemove'); 
const mousedown = fromEvent(target, 'mousedown'); 

document.getElementById("click") 
.addEventListener("click",() => { 
    alert('clicked'); 
}) 

const mousedrag = mousedown.selectMany((md) => { 
    const startX = md.clientX + window.scrollX, 
     startY = md.clientY + window.scrollY, 
     startLeft = parseInt(md.target.style.left, 10) || 0, 
     startTop = parseInt(md.target.style.top, 10) || 0; 
    md.preventDefault(); 
    return mousemove.map((mm) => { 
    mm.preventDefault(); 
    return { 
     left: startLeft + mm.clientX - startX, 
     top: startTop + mm.clientY - startY 
    }; 
    }).takeUntil(mouseup); 
}); 

const subscription = mousedrag.subscribe((pos) => { 
    target.style.top = pos.top + 'px'; 
    target.style.left = pos.left + 'px'; 
}); 

그리고 간단한 HTML을

<div class="box"> 
    <a id="click">Click test</a> 
</div> 

DEMO

이제 상자를 클릭하고 끌어 오면 드래그됩니다. 그러나 "Click test"를 클릭하여 드래그하면 OK로 드래그되지만 드래그를 중지하면 경고가 표시됩니다. 이것을 피하는 방법?

preventDefault 우리가 아이를 클릭 한 이후로 작동하지 않습니다. 우리가 전파를 막을 것이기 때문에 stopPropagation 또한, 작동하지 않을 것입니다,하지만

답변

1

mousedownclick 두 개의 다른 이벤트입니다 경고 클릭 핸들러는 상자의 하위에있다. AFAIK 당신은 다른 하나에서 하나를 막을 수 없습니다. 하지만 예를 들어 rx 코드에 특정 클래스 이름을 설정하고 클릭 핸들러에서이 클래스를 테스트 할 수 있습니다. mouseup 이벤트에서 클래스를 다시 제거 할 수 있습니다. click 이벤트 핸들러가 발생하기 전에이 이벤트가 호출 되었기 때문에 이벤트 루프에 다시 넣으려고 setTimeout을 사용했습니다. 이 작업을 수행하는 방법에 대해 더 잘 알고 있다면 알려주십시오.

fiddle (RxJS 5로 작성)을 참조하십시오.

전체 코드 :

const { fromEvent } = Rx.Observable; 
const target = document.querySelector('.box'); 

const mouseup = fromEvent(target, 'mouseup'); 
const mousemove = fromEvent(document, 'mousemove'); 
const mousedown = fromEvent(target, 'mousedown'); 

document.getElementById("click") 
    .addEventListener("click", function(event) { 
    if (!event.target.classList.contains('rx-drag')) { 
     alert('clicked'); 
    } 
    }); 

const mousedrag = mousedown.mergeMap((md) => { 
    const startX = md.clientX + window.scrollX, 
     startY = md.clientY + window.scrollY, 
     startLeft = parseInt(md.target.style.left, 10) || 0, 
     startTop = parseInt(md.target.style.top, 10) || 0; 

    md.target.classList.add('rx-drag'); 
    md.preventDefault(); 
    return mousemove.map((mm) => { 
    mm.preventDefault(); 
    return { 
     left: startLeft + mm.clientX - startX, 
     top: startTop + mm.clientY - startY 
    }; 
    }).takeUntil(mouseup.do(() => { 
    setTimeout(() => { 
     md.target.classList.remove('rx-drag'); 
    }); 
    })); 
}); 

const subscription = mousedrag.subscribe((pos) => { 
    target.style.top = pos.top + 'px'; 
    target.style.left = pos.left + 'px'; 
}); 
+0

작동하지만 기본적으로는 (i가 다른 구성 요소에 4-5 태그가 있다면 무엇을) 해킹/내 아이디어와 이벤트를 클릭 문서화하는 후크를 추가했다가 useCapture를 누른 다음 마우스 이동 이벤트가 발생하면 preventDefault() 및 stopPropogation을 사용하거나 취소하십시오. 하지만 그걸 제대로 작동시키지 못했습니다. – gerasalus