কীভাবে মাউস "ক্লিক" এবং "টেনে আনুন" পার্থক্য করবেন


165

আমি ব্যবহার jQuery.clickরাফায়েল গ্রাফে মাউস ক্লিক ঘটনা হ্যান্ডেল করতে এদিকে, আমি মাউস হ্যান্ডেল প্রয়োজন dragঘটনা, মাউস ড্র্যাগ নিয়ে গঠিত mousedown, mouseupএবং mousemoveরাফায়েল হবে।

আলাদা করা কঠিন clickএবং dragকারণ clickএছাড়াও ধারণ mousedown& mouseup, আমি কিভাবে জাভাস্ক্রিপ্ট তারপর মাউস আলাদা করতে পারেন "এ ক্লিক করুন" & মাউস "ড্র্যাগ"?

উত্তর:


192

আমি মনে করি পার্থক্যটি হ'ল একটি ড্রাগের mousemoveমধ্যে 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)

38
টেনে আনতে ট্রিগার করতে কেবল মাউসমোভের ন্যূনতম ডেল্টা এক্স বা ওয়াই মনে রাখবেন। এক টিক মাউসমেভের পরিবর্তে ক্লিক করার চেষ্টা করে ড্র্যাগ অপারেশন পেতে হতাশ হবেন
এরিক রাইডগ্রেন

12
আমি মনে করি না এটি শেষতম ক্রোমে আর কাজ করে: 32.0.1700.72 আপনি মাউসটি সরান কিনা তা মাউসমোভ আগুন
mrjrdnthms

17
এই গৃহীত উত্তর কোড এ XY মাউস স্থানাঙ্ক মধ্যে একটি সর্বনিম্ন ব-দ্বীপ শর্ত অন্তর্ভুক্ত করা উচিত mousedownএবং mouseupপরিবর্তে শোনার mousemoveঘটনা একটি পতাকা সেট করতে। তাছাড়া, এটা ইস্যু @mrjrdnthms উল্লেখ ঠিক হবে
Billybobbonnet

2
আমি ক্রোম 56 56.০.২৯২.8.৮ bit (64৪-বিট) চালিয়ে যাচ্ছি এবং আমি @ মির্জার্ড্যান্টহেমস বর্ণনা করছে এমন সমস্যাগুলি আমি अनुभव করছি না।
jkupczak

1
@ আমেরেলিকা এটি সম্ভবত কোনও বাগ নয় তবে প্রত্যাশিত আচরণ নয়, তবে আপনি যদি মাউসেন্টার এবং মাউসলেভের ঘটনাগুলি যদি আপনার ব্যবহারের ক্ষেত্রে আকর্ষণীয় হন তবে দেখতে পারেন
রিভনফল

37

আপনি যদি ইতিমধ্যে 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);
  });
});

এমনকি আপনি ক্লিক করার সময় মাউসটিকে একটি সামান্য বিট সরান, এটি বলবে drag। অন্যান্য মন্তব্যগুলির মতো একটি অতিরিক্ত সুযোগও এখানে বলার প্রয়োজন হতে পারে।
চিমনো

@ChiMo আমি ব্যবহার করা হয়েছে করছি প্রথম থেকে মাউস অবস্থান সংরক্ষণ করছে না evtএবং দ্বিতীয় অবস্থানে সঙ্গে তুলনা evt, তাই, উদাহরণস্বরূপ: if (evt.type === 'mouseup' || Math.abs(evt1.pageX - evt2.pageX) < 5 || Math.abs(evt1.pageY - evt2.pageY) < 5) { ...
গুস্তাভো রডরিগস

1
আমি এই প্রশ্নের অন্যান্য সমস্ত উত্তর চেষ্টা করেছিলাম, এবং এটি কেবলমাত্র যা পরীক্ষার সময় কাজ করেছিল .on('mouseup mousemove touchend touchmove')এবং এর উপরে অবস্থান ভেরিয়েবলগুলি সেট করে না। দুর্দান্ত সমাধান!
TheThirdMan

কখনও কখনও যখন আমি কোনও উপাদানটিতে ক্লিক করি তখন মাউসআপের পরিবর্তে "evt.type" রিটার্ন "মাউসমেভ"। আমি কীভাবে এই সমস্যাটি সমাধান করতে পারি?
লিবু ম্যাথিউ

27

ক্লিনার ES2015

let drag = false;

document.addEventListener('mousedown', () => drag = false);
document.addEventListener('mousemove', () => drag = true);
document.addEventListener('mouseup', () => console.log(drag ? 'drag' : 'click'));

অন্যরা মন্তব্য হিসাবে কোনও ত্রুটি অনুভব করেনি।


6
এটি ক্ষুদ্র পদক্ষেপের সাথে ক্লিকগুলি ভুগছে।
আমির কেবি

1
@ আমিরকিবি আপনি মাউসমেভগুলির সংখ্যা গণনা করতে পারেন (বা এমনকি দুটি ক্লিকের মধ্যে দূরত্ব গণনা করতে
পারলেও

19

এটি ভাল কাজ করা উচিত। গৃহীত উত্তরের মতো (যদিও jQuery ব্যবহার করা হচ্ছে) তবে isDraggingনতুন মাউসের অবস্থান mousedownইভেন্টের থেকে পৃথক হলে পতাকাটি পুনরায় সেট করা হবে । গৃহীত উত্তরের মতো নয়, এটি ক্রোমের সাম্প্রতিক সংস্করণগুলিতে কাজ করে, যেখানে mousemoveমাউস সরানো হয়েছিল কিনা তা নির্বিশেষে বরখাস্ত করা হয়েছে।

var isDragging = false;
var startingPos = [];
$(".selector")
    .mousedown(function (evt) {
        isDragging = false;
        startingPos = [evt.pageX, evt.pageY];
    })
    .mousemove(function (evt) {
        if (!(evt.pageX === startingPos[0] && evt.pageY === startingPos[1])) {
            isDragging = true;
        }
    })
    .mouseup(function () {
        if (isDragging) {
            console.log("Drag");
        } else {
            console.log("Click");
        }
        isDragging = false;
        startingPos = [];
    });

আপনি mousemoveযদি সামান্য কিছুটা সহনশীলতা যোগ করতে চান তবে আপনি স্থানাঙ্ক চেকটিও সামঞ্জস্য করতে পারেন (অর্থাত্ ক্ষুদ্র চলাচলকে ক্লিক হিসাবে টেনে আনুন, ড্রাগ হিসাবে নয়)।


12

আপনি যদি 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 তার উত্তরে যা করেছে তার এটি সরাসরি ক্লোন, তবে আরএক্সজেএসে রূপান্তরিত।

এছাড়াও আকর্ষণীয় ব্যবহার samplesampleঅপারেটর উৎস থেকে সর্বশেষ মান নিতে (হবে mergeএর mousedownএবং mousemove) এবং নির্গত যখন ভেতরের পর্যবেক্ষণযোগ্য ( mouseup) নির্গত হয়।


22
আমি আমার সমস্ত কোড পর্যবেক্ষণযোগ্যদের সাথে লিখি যাতে আমার বস আমাকে প্রতিস্থাপনের জন্য অন্য কাউকে নিয়োগ করতে না পারে।
চুল্লী

11

যেমনটি মির্জডান্টহামস স্বীকৃত উত্তরের বিষয়ে তাঁর মন্তব্যে উল্লেখ করেছেন, এটি ক্রোমে আর কাজ করে না (এটি সর্বদা মাউসমেভকে আগুন দেয়), আমি গুস্তাভোর উত্তরটি (যেহেতু আমি jQuery ব্যবহার করছি) Chrome এর আচরণের সমাধানের জন্য রূপান্তর করেছি।

var currentPos = [];

$(document).on('mousedown', function (evt) {

   currentPos = [evt.pageX, evt.pageY]

  $(document).on('mousemove', function handler(evt) {

    currentPos=[evt.pageX, evt.pageY];
    $(document).off('mousemove', handler);

  });

  $(document).on('mouseup', function handler(evt) {

    if([evt.pageX, evt.pageY].equals(currentPos))
      console.log("Click")
    else
      console.log("Drag")

    $(document).off('mouseup', handler);

  });

});

Array.prototype.equalsফাংশন এই থেকে আসে উত্তর


1
এটি প্রায় আমার জন্য কাজ করেছে, কিন্তু আমি [evt.pageX, evt.pageY].equals()আদেশ থেকে একটি ত্রুটি পেয়েছি । আমি এটি দিয়ে প্রতিস্থাপন করেছি (evt.pageX === currentPos[0] && evt.pageY===currentPos[1]), এবং সব ভাল ছিল। :)
user2441511

equalsকোড চাহিদা আমার পোস্টের নীচে লিংক থেকে যুক্ত করার জন্য
ফ্রান্সিসকো অ্যাকুইনো

আহ, এটি ব্যাখ্যা করে। ধন্যবাদ।
ব্যবহারকারী 2441511

1
আমি যুক্তি বুঝতে পারছি না। কেন তুমি আপডেট করব currentPosউপর mousemove? এর অর্থ এই নয় যে আপনি কয়েকটি ড্রাগকে ক্লিক হিসাবে বিবেচনা করবেন?
নির্বান-মিসু

1
আপনি "mouseup"মাউসটি চলার সময় এটি আগুন দেয় না ।
চিমনো

9

এই সমস্ত সমাধানগুলি ক্ষুদ্রতর মাউস গতিবিধিতে বিরতি দেয় বা অতিরিক্ত জটিল হয়।

দুটি ইভেন্ট শ্রোতার সাহায্যে এখানে একটি সাধারণ অভিযোজিত সমাধান। ডেল্টা হল পিক্সেলের এমন দূরত্ব যা কোডটিকে ক্লিকের পরিবর্তে ড্রাগ হিসাবে টানা শ্রেণিবদ্ধ করার জন্য আপনাকে অবশ্যই আপ এবং ডাউন ইভেন্টগুলির মধ্যে অনুভূমিকভাবে বা উল্লম্বভাবে স্থানান্তরিত করতে হবে। এর কারণ এটি কখনও কখনও আপনি মাউস বা আপনার আঙুলটি উঠানোর আগে কয়েক পিক্সেল সরান।

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!
  }
});

এখন পর্যন্ত সেরা উত্তর!
জর্জিও টেম্পেস্তা

হাই @ এন্ড্রেয়ার্ড, আমি কি এটির deltaজন্য ব্যবহৃত হয় তা জানতে পারি? এটি মোবাইল ডিভাইসে ট্যাপ দিয়ে কিছু করার আছে?
হাজিক

1
@ হাজিক আমি মনে করি যে শীর্ষ সমাধানের মন্তব্যে লোকেরা উল্লিখিত হিসাবে delta"একটি টিক চিহ্নের কারণে পরিবর্তে একটি ড্রাগ টান দেওয়ার চেষ্টা করতে হতাশ হবে"
মাইকেল বাইখোভসেভ

1
আমি একটি ব্যাখ্যা দিয়ে উত্তর আপডেট করেছি। মূলত যদি আপনার আঙুলটি 6 পিক্সেলের কম হয় তবে এটি ক্লিক হিসাবে গণ্য হবে। যদি এটি 6 বা ততোধিক পিক্সেল সরিয়ে নিয়ে যায় তবে এটি একটি টানা হিসাবে গণ্য হবে।
andrerd

5

ড্রাগটি সনাক্ত করতে 5 পিক্সেল x / y থিশোল্ড সহ jQuery ব্যবহার করা:

var dragging = false;
$("body").on("mousedown", function(e) {
  var x = e.screenX;
  var y = e.screenY;
  dragging = false;
  $("body").on("mousemove", function(e) {
    if (Math.abs(x - e.screenX) > 5 || Math.abs(y - e.screenY) > 5) {
      dragging = true;
    }
  });
});
$("body").on("mouseup", function(e) {
  $("body").off("mousemove");
  console.log(dragging ? "drag" : "click");
});

2

যদি কেবল ড্র্যাগ কেস ফিল্টার করতে হয় তবে এটি এর মতো করুন:

var moved = false;
$(selector)
  .mousedown(function() {moved = false;})
  .mousemove(function() {moved = true;})
  .mouseup(function(event) {
    if (!moved) {
        // clicked without moving mouse
    }
  });

1

ডেল্টেক্স এবং ডেল্টাওয়াইয়ের সাথে খাঁটি জেএস

এই ডেল্টাক্স এবং ডেল্টাওয়াই এক টিক মাউসমেভের কারণে ক্লিক করার পরিবর্তে একটি টানুন অপারেশন পাওয়ার চেষ্টা করার সময় হতাশার অভিজ্ঞতা এড়াতে স্বীকৃত উত্তরে একটি মন্তব্যে প্রস্তাবিত ।

    deltaX = deltaY = 2;//px
    var element = document.getElementById('divID');
    element.addEventListener("mousedown", function(e){
        if (typeof InitPageX == 'undefined' && typeof InitPageY == 'undefined') {
            InitPageX = e.pageX;
            InitPageY = e.pageY;
        }

    }, false);
    element.addEventListener("mousemove", function(e){
        if (typeof InitPageX !== 'undefined' && typeof InitPageY !== 'undefined') {
            diffX = e.pageX - InitPageX;
            diffY = e.pageY - InitPageY;
            if (    (diffX > deltaX) || (diffX < -deltaX)
                    || 
                    (diffY > deltaY) || (diffY < -deltaY)   
                    ) {
                console.log("dragging");//dragging event or function goes here.
            }
            else {
                console.log("click");//click event or moving back in delta goes here.
            }
        }
    }, false);
    element.addEventListener("mouseup", function(){
        delete InitPageX;
        delete InitPageY;
    }, false);

   element.addEventListener("click", function(){
        console.log("click");
    }, false);

1

কোনও ওএসএম মানচিত্রে পাবলিক ক্রিয়াকলাপের জন্য (ক্লিকের উপর চিহ্নিতকারী চিহ্নিত করুন) প্রশ্নটি ছিল: 1) মাউসের নিচে সময়কাল কীভাবে নির্ধারণ করবেন-> আপ (আপনি প্রতিটি ক্লিকের জন্য একটি নতুন মার্কার তৈরি করতে পারবেন না) এবং ২) কী করেছেন ডাউন-> আপ চলাকালীন মাউস সরানো (যেমন ব্যবহারকারী মানচিত্রটি টানছে)।

const map = document.getElementById('map');

map.addEventListener("mousedown", position); 
map.addEventListener("mouseup", calculate);

let posX, posY, endX, endY, t1, t2, action;

function position(e) {

  posX = e.clientX;
  posY = e.clientY;
  t1 = Date.now();

}

function calculate(e) {

  endX = e.clientX;
  endY = e.clientY;
  t2 = (Date.now()-t1)/1000;
  action = 'inactive';

  if( t2 > 0.5 && t2 < 1.5) { // Fixing duration of mouse down->up

      if( Math.abs( posX-endX ) < 5 && Math.abs( posY-endY ) < 5 ) { // 5px error on mouse pos while clicking
         action = 'active';
         // --------> Do something
      }
  }
  console.log('Down = '+posX + ', ' + posY+'\nUp = '+endX + ', ' + endY+ '\nAction = '+ action);    

}

0

ক্লাস ভিত্তিক ভ্যানিলা জেএসের জন্য দূরত্বের প্রান্তটি ব্যবহার করে আরও একটি সমাধান

private initDetectDrag(element) {
    let clickOrigin = { x: 0, y: 0 };
    const dragDistanceThreshhold = 20;

    element.addEventListener('mousedown', (event) => {
        this.isDragged = false
        clickOrigin = { x: event.clientX, y: event.clientY };
    });
    element.addEventListener('mousemove', (event) => {
        if (Math.sqrt(Math.pow(clickOrigin.y - event.clientY, 2) + Math.pow(clickOrigin.x - event.clientX, 2)) > dragDistanceThreshhold) {
            this.isDragged = true
        }
    });
}

এবং ক্লাসে যুক্ত করুন (SOMESLIDER_ELEMENT এছাড়াও বিশ্বব্যাপী হতে নথি হতে পারে):

private isDragged: boolean;
constructor() {
    this.initDetectDrag(SOMESLIDER_ELEMENT);
    this.doSomeSlideStuff(SOMESLIDER_ELEMENT);
    element.addEventListener('click', (event) => {
        if (!this.sliderIsDragged) {
            console.log('was clicked');
        } else {
            console.log('was dragged, ignore click or handle this');
        }
    }, false);
}

0

আপনি যদি কোনও নির্দিষ্ট উপাদানটির ক্লিক বা টেনে আনার আচরণটি পরীক্ষা করতে চান তবে আপনি শরীরের কথা না শুনে এটি করতে পারেন।

$(document).ready(function(){
  let click;
  
  $('.owl-carousel').owlCarousel({
    items: 1
  });
  
  // prevent clicks when sliding
  $('.btn')
    .on('mousemove', function(){
      click = false;
    })
    .on('mousedown', function(){
      click = true;
    });
    
  // change mouseup listener to '.content' to listen to a wider area. (mouse drag release could happen out of the '.btn' which we have not listent to). Note that the click will trigger if '.btn' mousedown event is triggered above
  $('.btn').on('mouseup', function(){
    if(click){
      $('.result').text('clicked');
    } else {
      $('.result').text('dragged');
    }
  });
});
.content{
  position: relative;
  width: 500px;
  height: 400px;
  background: #f2f2f2;
}
.slider, .result{
  position: relative;
  width: 400px;
}
.slider{
  height: 200px;
  margin: 0 auto;
  top: 30px;
}
.btn{
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 100px;
  background: #c66;
}
.result{
  height: 30px;
  top: 10px;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css" />
<div class="content">
  <div class="slider">
    <div class="owl-carousel owl-theme">
      <div class="item">
        <a href="#" class="btn" draggable="true">click me without moving the mouse</a>
      </div>
      <div class="item">
        <a href="#" class="btn" draggable="true">click me without moving the mouse</a>
      </div>
    </div>
    <div class="result"></div>
  </div>
  
</div>


0

@ প্রজেমেকের উত্তর থেকে,

function listenClickOnly(element, callback, threshold=10) {
  let drag = 0;
  element.addEventListener('mousedown', () => drag = 0);
  element.addEventListener('mousemove', () => drag++);
  element.addEventListener('mouseup', e => {
    if (drag<threshold) callback(e);
  });
}

listenClickOnly(
  document,
  () => console.log('click'),
  10
);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.