簡體   English   中英

RxJS:如何在使用拖動n拖放時防止單擊元素

[英]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也不起作用,因為我們將停止向上傳播,但是警報單擊處理程序位於該框的子項上

mousedownclick是兩個不同的事件。 抱歉,您不能在另一個內部停下腳步。 但是您可以例如在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM