我使用jQuery。点击来处理Raphael图形上的鼠标点击事件,同时,我需要处理鼠标拖动事件,鼠标拖动在Raphael中由鼠标下拉,鼠标上拉和鼠标移动组成。
很难区分点击和拖动,因为点击也包含鼠标下拉和鼠标上拉,我怎么能区分鼠标“点击”和鼠标“拖动”然后在Javascript?
我使用jQuery。点击来处理Raphael图形上的鼠标点击事件,同时,我需要处理鼠标拖动事件,鼠标拖动在Raphael中由鼠标下拉,鼠标上拉和鼠标移动组成。
很难区分点击和拖动,因为点击也包含鼠标下拉和鼠标上拉,我怎么能区分鼠标“点击”和鼠标“拖动”然后在Javascript?
当前回答
如果你想使用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)发出时发出它。
其他回答
你可以这样做:
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>
我认为区别在于,在拖拽中,mousedown和mouseup之间有一个鼠标移动,但在点击中没有。
你可以这样做:
const element = document.createElement('div') element.innerHTML = 'test' document.body.appendChild(element) let moved let downListener = () => { moved = false } element.addEventListener('mousedown', downListener) let moveListener = () => { moved = true } element.addEventListener('mousemove', moveListener) let upListener = () => { if (moved) { console.log('moved') } else { console.log('not moved') } } element.addEventListener('mouseup', upListener) // release memory element.removeEventListener('mousedown', downListener) element.removeEventListener('mousemove', moveListener) element.removeEventListener('mouseup', upListener)
如果只是为了过滤掉拖动的情况,这样做:
var moved = false;
$(selector)
.mousedown(function() {moved = false;})
.mousemove(function() {moved = true;})
.mouseup(function(event) {
if (!moved) {
// clicked without moving mouse
}
});
基于这个答案,我在React组件中这样做:
export default React.memo(() => {
const containerRef = React.useRef(null);
React.useEffect(() => {
document.addEventListener('mousedown', handleMouseMove);
return () => document.removeEventListener('mousedown', handleMouseMove);
}, []);
const handleMouseMove = React.useCallback(() => {
const drag = (e) => {
console.log('mouse is moving');
};
const lift = (e) => {
console.log('mouse move ended');
window.removeEventListener('mousemove', drag);
window.removeEventListener('mouseup', this);
};
window.addEventListener('mousemove', drag);
window.addEventListener('mouseup', lift);
}, []);
return (
<div style={{ width: '100vw', height: '100vh' }} ref={containerRef} />
);
})
如果你已经在使用jQuery:
var $body = $('body');
$body.on('mousedown', function (evt) {
$body.on('mouseup mousemove', function handler(evt) {
if (evt.type === 'mouseup') {
// click
} else {
// drag
}
$body.off('mouseup mousemove', handler);
});
});