我使用jQuery。点击来处理Raphael图形上的鼠标点击事件,同时,我需要处理鼠标拖动事件,鼠标拖动在Raphael中由鼠标下拉,鼠标上拉和鼠标移动组成。

很难区分点击和拖动,因为点击也包含鼠标下拉和鼠标上拉,我怎么能区分鼠标“点击”和鼠标“拖动”然后在Javascript?


当前回答

你可以这样做:

var div = document.getElementById("div"); div.addEventListener("mousedown", function() { window.addEventListener("mousemove", drag); window.addEventListener("mouseup", lift); var didDrag = false; function drag() { //when the person drags their mouse while holding the mouse button down didDrag = true; div.innerHTML = "drag" } function lift() { //when the person lifts mouse if (!didDrag) { //if the person didn't drag div.innerHTML = "click"; } else div.innerHTML = "drag"; //delete event listeners so that it doesn't keep saying drag window.removeEventListener("mousemove", drag) window.removeEventListener("mouseup", this) } }) body { outline: none; box-sizing: border-box; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; overflow: hidden; } #div { /* calculating -5px for each side of border in case border-box doesn't work */ width: calc(100vw - 10px); height: calc(100vh - 10px); border: 5px solid orange; background-color: yellow; font-weight: 700; display: grid; place-items: center; user-select: none; cursor: pointer; padding: 0; margin: 0; } <html> <body> <div id="div">Click me or drag me.</div> </body> </html>

其他回答

来自@Przemek的回答,

函数listenClickOnly(元素,回调,阈值=10){ 让拖动= 0; 元素。addEventListener('mousedown', () => drag = 0); 元素。addEventListener('mousemove', () => drag++); 元素。addEventListener('mouseup', e => { 如果(拖动<阈值)回调(e); }); } listenClickOnly ( 文档, () => console.log('click'), 10 );

如果你想使用Rxjs:

var element = document; Rx.Observable .merge( Rx.Observable.fromEvent(element, 'mousedown').mapTo(0), Rx.Observable.fromEvent(element, 'mousemove').mapTo(1) ) .sample(Rx.Observable.fromEvent(element, 'mouseup')) .subscribe(flag => { console.clear(); console.log(flag ? "drag" : "click"); }); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://unpkg.com/@reactivex/rxjs@5.4.1/dist/global/Rx.js"></script>

这是@wong2在他的回答中所做的直接克隆,但转换为RxJs。

样本的使用也很有趣。示例操作符将从源(mousedown和mousemove的合并)中获取最新的值,并在内部观察对象(mouseup)发出时发出它。

很简单,

el = document.getElementById("your_id"); var isDown = false; 埃尔。addEventListener('mousedown', function () { isDown = true; }); 埃尔。addEventListener('mouseup', function () { isDown = false; }); 埃尔。addEventListener('鼠标移动',函数(){ if (isDown) { //你的代码在这里 } });

清洁ES2015

Let drag = false; 文档。addEventListener('mousedown', () => drag = false); 文档。addEventListener('mousemove', () => drag = true); 文档。addEventListener('mouseup', () => console.log(拖动?'拖动':'点击'));

正如其他人评论的那样,没有遇到任何bug。

所有这些解决方案要么在微小的鼠标移动上失效,要么过于复杂。

下面是一个使用两个事件侦听器的简单适应性解决方案。Delta是您必须在上下事件之间水平或垂直移动的距离(以像素为单位),以便代码将其归类为拖拽而不是单击。这是因为有时你会在抬起鼠标或手指之前移动几个像素点。

const delta = 6;
let startX;
let startY;

element.addEventListener('mousedown', function (event) {
  startX = event.pageX;
  startY = event.pageY;
});

element.addEventListener('mouseup', function (event) {
  const diffX = Math.abs(event.pageX - startX);
  const diffY = Math.abs(event.pageY - startY);

  if (diffX < delta && diffY < delta) {
    // Click!
  }
});