Câu hỏi làm cách nào để phân biệt sự kiện nhấp chuột và sự kiện nhấp đúp?


Tôi có một nút duy nhất trong li với id "my_id". tôi đính kèm two jquery sự kiện với phần tử này

1.  $("#my_id").click(function() { 
            alert('single click');
    });

2.   $("#my_id").dblclick(function() {
              alert('double click');
    });

Nhưng mỗi lần nó mang lại cho tôi single click


76
2018-03-31 08:24


gốc


Các nhấp chuột duy nhất sẽ luôn luôn phải cháy, nó không thể biết nếu một nhấp đúp sẽ xảy ra trừ khi nó thực sự xảy ra trong thời gian nhấp đúp được chỉ định. - Pieter Germishuys
Điều này là có thể, hãy kiểm tra câu trả lời của tôi. Bạn phải đợi vài ms sau lần nhấp đầu tiên và kiểm tra xem có nhấp chuột mới cho đến thời gian đã chỉ định hay không. Bằng cách đó, bạn có thể biết nếu điều này chỉ đơn giản hoặc nhấp đúp chuột. - Adrien Schuler


Các câu trả lời:


Bạn cần sử dụng thời gian chờ để kiểm tra xem có nhấp chuột nào khác sau lần nhấp đầu tiên không.

Đây là thủ thuật:

// Author:  Jacek Becela
// Source:  http://gist.github.com/399624
// License: MIT

jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
  return this.each(function(){
    var clicks = 0, self = this;
    jQuery(this).click(function(event){
      clicks++;
      if (clicks == 1) {
        setTimeout(function(){
          if(clicks == 1) {
            single_click_callback.call(self, event);
          } else {
            double_click_callback.call(self, event);
          }
          clicks = 0;
        }, timeout || 300);
      }
    });
  });
}

Sử dụng:

$("button").single_double_click(function () {
  alert("Try double-clicking me!")
}, function () {
  alert("Double click detected, I'm hiding")
  $(this).hide()
})
<button>Click Me!</button>

CHỈNH SỬA:

Như đã nêu bên dưới, thích sử dụng nguồn gốc dblclick biến cố: http://www.quirksmode.org/dom/events/click.html

Hoặc một được cung cấp bởi jQuery: http://api.jquery.com/dblclick/


45
2018-03-31 08:30



Điều này có vẻ hoạt động tốt nói chung nhưng không phải thời gian trễ được cho phép giữa các lần nhấp (theo đó hai nhấp chuột được hiểu là nhấp đúp) khác nhau theo cấu hình hệ thống? Có thể an toàn hơn để dựa vào dblclick biến cố - Jon z
Tôi nghĩ bạn nói đúng, dblclick chắc chắn là con đường để đi ngày hôm nay. jQuery cũng xử lý sự kiện này: api.jquery.com/dblclick - Adrien Schuler
@AdrienSchuler - Từ tài liệu bạn liên kết: Nó là không thể chấp nhận để ràng buộc xử lý cho cả các sự kiện nhấp chuột và dblclick cho cùng một phần tử. Câu hỏi là về việc có cả hai. - Álvaro González
Nice gist, cảm ơn. - huesforalice


Hành vi của dblclick sự kiện được giải thích tại Chế độ quirks.

Thứ tự của các sự kiện cho một dblclick Là:

  1. Di chuột xuống
  2. mouseup
  3. nhấp chuột
  4. Di chuột xuống
  5. mouseup
  6. nhấp chuột
  7. dblclick

Một ngoại lệ cho quy tắc này là (tất nhiên) Internet Explorer với thứ tự tùy chỉnh của chúng:

  1. Di chuột xuống
  2. mouseup
  3. nhấp chuột
  4. mouseup
  5. dblclick

Như bạn có thể thấy, việc nghe cả hai sự kiện cùng nhau trên cùng một phần tử sẽ dẫn đến các cuộc gọi thêm vào click xử lý.


68
2018-04-01 09:30



không chắc dblclick thậm chí còn đáng tin cậy ... nếu tôi nhấp một lần ... đợi một hoặc hai giây, sau đó nhấp lại, tôi nhận được dblclick sự kiện vào lần nhấp thứ hai! - Michael


Một hàm đơn giản. Không yêu cầu khung công tác hay khung công tác khác. Chuyển các hàm của bạn thành các tham số

<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
    <script>
        function doubleclick(el, onsingle, ondouble) {
            if (el.getAttribute("data-dblclick") == null) {
                el.setAttribute("data-dblclick", 1);
                setTimeout(function () {
                    if (el.getAttribute("data-dblclick") == 1) {
                        onsingle();
                    }
                    el.removeAttribute("data-dblclick");
                }, 300);
            } else {
                el.removeAttribute("data-dblclick");
                ondouble();
            }
        }
    </script>

17
2018-04-16 09:16



Tôi nghĩ rằng đây sẽ là câu trả lời tốt nhất. Tuy nhiên, tôi phải giảm thời gian chờ xuống 200 để nó hoạt động trên Windows IE8, nhưng giá trị này có thể là hệ điều hành và người dùng phụ thuộc. Và cũng đã lưu tham chiếu bộ hẹn giờ để có thể hủy thực hiện nhấp chuột nếu nhấp đúp được đăng ký. - xpereta
Cảm ơn bạn cho đoạn mã này, nó hoạt động tốt trên chrome và firefox (mặc dù chrome không cần hack này để làm việc với dbl và duy nhất). - victor
sử dụng el.dataset.dblclick sẽ là một cách tốt hơn để làm điều này ngay bây giờ. - WORMSS


Tôi e rằng hành vi này phụ thuộc vào trình duyệt:

Nó là vô tình để ràng buộc xử lý để   cả sự kiện nhấp chuột và dblclick cho   cùng một yếu tố. Trình tự của   sự kiện được kích hoạt khác nhau từ trình duyệt   với trình duyệt, với một số nhận được hai   nhấp vào các sự kiện trước dblclick và   những người khác chỉ có một. Nhấn đúp chuột   độ nhạy (thời gian tối đa giữa   nhấp chuột được phát hiện dưới dạng gấp đôi   nhấp chuột) có thể khác nhau tùy theo hệ điều hành   và trình duyệt, và thường   người dùng có thể định cấu hình.

http://api.jquery.com/dblclick/

Chạy mã của bạn trong Firefox, cảnh báo () trong click() xử lý ngăn bạn nhấp vào lần thứ hai. Nếu bạn loại bỏ cảnh báo như vậy, bạn sẽ nhận được cả hai sự kiện.


12
2018-03-31 08:30





Vâng để kích đúp vào (bấm hai lần), trước tiên bạn phải bấm một lần. Các click() xử lý kích hoạt trên lần nhấp đầu tiên của bạn và kể từ khi cảnh báo bật lên, bạn không có cơ hội thực hiện nhấp chuột thứ hai để kích hoạt dblclick() xử lý.

Thay đổi trình xử lý của bạn để làm điều gì đó khác với alert() và bạn sẽ thấy hành vi. (có lẽ thay đổi màu nền của phần tử):

$("#my_id").click(function() { 
    $(this).css('backgroundColor', 'red')
});

$("#my_id").dblclick(function() {
    $(this).css('backgroundColor', 'green')
});

8
2018-03-31 08:29



Điểm tốt - cảnh báo tạm dừng thực hiện. - Jon z


Không có câu trả lời nào thỏa mãn nhu cầu của tôi vì vậy tôi đã tạo ra một giải pháp lấy cảm hứng từ ý chính được đăng bởi @AdrienSchuler. Chỉ sử dụng giải pháp này khi bạn muốn liên kết một nhấp chuột VÀ nhấp đúp vào một phần tử. Nếu không, tôi khuyên bạn nên sử dụng click và dblclick người nghe.

Đây là những khác biệt:

  • Vanillajs, Không phụ thuộc
  • Đừng chờ đợi trên setTimeout để xử lý nhấp chuột hoặc trình xử lý Doubleclick
  • Khi nhấp đúp lần đầu tiên nó sẽ kích hoạt trình xử lý nhấp chuột, thì trình xử lý Doubleclick

Javascript:

function makeDoubleClick(doubleClickCallback, singleClickCallback) {
    var clicks = 0, timeout;
    return function() {
        clicks++;
        if (clicks == 1) {
            singleClickCallback && singleClickCallback.apply(this, arguments);
            timeout = setTimeout(function() { clicks = 0; }, 400);
        } else {
            timeout && clearTimeout(timeout);
            doubleClickCallback && doubleClickCallback.apply(this, arguments);
            clicks = 0;
        }
    };
}

Sử dụng:

var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));

Dưới đây là cách sử dụng trong jsfiddle, nút jQuery là hành vi của câu trả lời được chấp nhận.

jsfiddle


5
2017-10-10 09:59



Đoạn mã trên và phiên bản 'Vanilla' của fiddle của bạn không hoạt động ... đây là phiên bản Vanilla cố định: jsfiddle.net/jeum/cpbwx5vr/19 - jeum
@jeum Nó vẫn còn lừa cho tôi trong mọi trình duyệt. Điều gì "không hoạt động" và bạn mong đợi điều gì? Có vẻ như phiên bản của bạn không làm những gì tôi có ý định. - A1rPun
Nắm tay tôi đã sửa đổi phiên bản của tôi (loại bỏ đóng cửa đôi), hãy thử phiên bản mới: jsfiddle.net/jeum/cpbwx5vr/20 Vấn đề với fiddle của bạn (phiên bản Vanilla) là nhấp đúp sẽ kích hoạt trình xử lý đơn lẻ: nó truy xuất đơn + double cho tôi. - jeum
@jeum Điều đó đưa ra một lỗi. Vâng câu trả lời của tôi khác với các câu trả lời được chấp nhận và khác ở đây và tôi cũng xác định sự khác biệt này trong dòng này: Kích hoạt một nhấp chuột, sau đó là một DoubleClick (không chuyển thẳng đến Doubleclick) - A1rPun
Có lỗi một lần nữa, vì vậy phiên bản này trả lời câu hỏi chính: jsfiddle.net/jeum/cpbwx5vr/21. Bây giờ liên quan đến phiên bản của bạn (đó là sự thật mà tôi đã không hiểu), bạn có nhận thấy rằng 'jQuery' không đạt được những gì bạn muốn trong fiddle của bạn? - jeum


Một giải pháp Vanilla đơn giản khác dựa trên A1rPun câu trả lời (xem fiddle của mình cho giải pháp jQuery và cả hai đều nằm trong cái này).

Dường như KHÔNG kích hoạt trình xử lý một lần nhấp chuột khi người dùng nhấp đúp, trình xử lý một lần nhấp nhất thiết phải được kích hoạt sau một sự chậm trễ ...

var single = function(e){console.log('single')},
    double = function(e){console.log('double')};

var makeDoubleClick = function(e) {

  var clicks = 0,
      timeout;

  return function (e) {

    clicks++;

    if (clicks == 1) {
      timeout = setTimeout(function () {
        single(e);
        clicks = 0;
      }, 250);
    } else {
      clearTimeout(timeout);
      double(e);
      clicks = 0;
    }
  };
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);

4
2018-03-22 17:08



Điều này thực sự là lựa chọn tốt nhất nếu bạn không muốn nhấp chuột duy nhất bị sa thải :) - A1rPun


Đây là một sự thay thế mã của jeum cho một số sự kiện tùy ý:

 var multiClickHandler = function (handlers, delay) {
    var clicks = 0, timeout, delay = delay || 250;
    return function (e) {
      clicks++;
      clearTimeout(timeout);
      timeout = setTimeout(function () {
        if(handlers[clicks]) handlers[clicks](e);
        clicks = 0;
      }, delay);
    };
  }

  cy.on('click', 'node', multiClickHandler({
    1: function(e){console.log('single clicked ', e.cyTarget.id())},
    2: function(e){console.log('double clicked ', e.cyTarget.id())},
    3: function(e){console.log('triple clicked ', e.cyTarget.id())},
    4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
    // ...
  }, 300));

Cần thiết này cho một cytoscape.js ứng dụng.


3
2018-05-04 16:43



Tốt đẹp! chúng ta cũng có thể khai báo một biến mới bên trong hàm trả về và gán nó với this, là phần tử được nhấp và chuyển nó cho trình xử lý (cùng với e hoặc thay vì nó). - HeyJude


Sử dụng plugin jQuery Sparkle tuyệt vời. Plugin cung cấp cho bạn tùy chọn phát hiện nhấp chuột đầu tiên và cuối cùng. Bạn có thể sử dụng nó để phân biệt giữa nhấp chuột và dblclick bằng cách phát hiện xem nhấp chuột khác có được nhấp chuột đầu tiên hay không.

Kiểm tra nó tại http://balupton.com/sandbox/jquery-sparkle/demo/


2
2018-03-31 08:44





Tôi đã viết một plugin jQuery đơn giản cho phép bạn sử dụng một sự kiện 'singleclick' tùy chỉnh để phân biệt một nhấp chuột chỉ với một cú nhấp đúp:

https://github.com/omriyariv/jquery-singleclick

$('#someDiv').on('singleclick', function(e) {
    // The event will be fired with a small delay.
    console.log('This is certainly a single-click');
}

2
2017-09-27 13:50