[英]RxJS: How to prevent clicks on a element when using drag n drop
假設我有這個簡單的代碼,可以通過RxJS拖放:
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>
現在,如果單擊並拖動該框,則它會拖動確定。 但是,如果單擊“單擊測試”並將其拖動,則它會拖動為ok,但是在您停止拖動之后,將顯示警報。 如何避免這種情況?
preventDefault
不起作用,因為我們單擊了child。 stopPropagation
也不起作用,因為我們將停止向上傳播,但是警報單擊處理程序位於該框的子項上
mousedown
和click
是兩個不同的事件。 抱歉,您不能在另一個內部停下腳步。 但是您可以例如在rx代碼中設置特定的類名稱,然后在點擊處理程序中針對該類進行測試。 在mouseup
事件上,您可以再次刪除該類。 由於此事件是在click
事件處理程序發生之前被調用的,因此我使用setTimeout
將其放回事件循環中。 如果您對如何完成此操作有更好的了解,請告訴我。
參見小提琴 (用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';
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.