2013-11-22 15 views
10

Dưới đây là JSFiddle về hành vi mà tôi thấy, liên quan đến nhấp chuột giữa và sự kiện click trong Chrome và FF.Tại sao nhấp chuột giữa không kích hoạt 'nhấp' trong một số trường hợp?

nghe tiếng 'click' kinda sorta làm việc

Cách tiếp cận 1: Bind một handler click trực tiếp đến một a phần tử và một trung nhấp chuột sẽ kích hoạt các handler trong Chrome nhưng không phải trong FF.

$('div a').on('click', function(ev) { 
    // middle click triggers this handler 
}); 

Cách tiếp cận 2: Bind một giao click xử lý để một div mà chứa một hoặc nhiều a. Nhấp chuột giữa sẽ không phải kích hoạt trình xử lý này trong Chrome hoặc FF.

$('div').on('click', 'a', function(ev) { 
    // middle click doesn't trigger this handler 
}); 

Cách tiếp cận này là rất có giá trị nếu div bắt đầu ra trống rỗng và a yếu tố này được điền vào sau đó bằng một cuộc gọi AJAX, hoặc là kết quả của một số đầu vào người dùng.

'mouseup' làm việc

Sử dụng mouseup thay vì click nguyên nhân cả hai cách tiếp cận 1 và 2 để làm việc trong cả hai trình duyệt.

// Approach 1 w/ mouseup 
$('div a').on('mouseup', function(ev) { 
    // middle click **does** trigger this handler in Chrome and FF 
}); 

// Approach 2 w/ mouseup 
$('div').on('mouseup', 'a', function(ev) { 
    // middle click **does** trigger this handler in Chrome and FF 
}); 

Đây là JSFiddle với mouseup.

Điều này thật thú vị và có thể hữu ích trong một số trường hợp, bởi vì mouseup gần như là click. Nhưng mouseupkhông phải làclick và tôi sau hành vi của click. Tôi không muốn tạo mô phỏng mousedown; setTimeout; mouseup hacky của click.

Tôi khá chắc chắn câu trả lời là "không", nhưng có cách nào giữa các trình duyệt gây ra nhấp chuột giữa để kích hoạt trình xử lý click không? Nếu không, lý do tại sao là gì?

Trả lời

6

Sự kiện nhấp thường được kích hoạt cho chuột trái tuy nhiên, tùy thuộc vào trình duyệt, sự kiện nhấp chuột có thể xảy ra hoặc có thể không xảy ra cho nút bên phải và/hoặc giữa.

Trong Internet Explorer và Firefox, sự kiện nhấp không được kích hoạt cho các nút bên phải hoặc giữa.

Do đó, chúng tôi không thể sử dụng sự kiện nhấp chuột một cách đáng tin cậy cho trình xử lý sự kiện ở nút giữa hoặc nút phải. Thay vào đó, để phân biệt giữa các nút chuột, chúng tôi phải sử dụng các sự kiện chuột và chuột giống như hầu hết các trình duyệt đều thực hiện các sự kiện chuột và đám cháy cho bất kỳ nút chuột nào.

trong Firefox và Chrome event.which phải chứa số cho biết nút chuột đã được nhấn (1 còn lại, 2 là giữa, 3 là đúng).

Trong Internet Explorer, mặt khác, event.button cho biết nút chuột nào được nhấp (1 còn lại, 4 là giữa, 2 là đúng);

event.button cũng sẽ hoạt động trong Firefox và các trình duyệt khác, nhưng các con số có thể hơi khác (0 còn lại, 1 là giữa, 2 là đúng).

Vì vậy, để đưa rằng cùng nhau chúng ta thường làm một cái gì đó như thế này:

document.onmousedown = function(e) { 
    var evt = e==null ? event : e; 

    if (evt.which) { // if e.which, use 2 for middle button 
     if (evt.which === 2) { 
      // middle button clicked 
     } 
    } else if (evt.button) { // and if e.button, use 4 
     if (evt.button === 4) { 
      // middle button clicked 
     } 
    } 
} 

Như jQuery bình thường hóa event.which, bạn chỉ cần có để sử dụng trong xử lý sự kiện jQuery, và như vậy được thực hiện:

$('div a').on('mousedown', function(e) { 
    if (e.which === 2) { 
     // middle button clicked   
    } 
}); 

Nói cách khác, bạn không thể sử dụng sự kiện onclick, do đó, để mô phỏng nó, bạn có thể sử dụng cả hai chuột và chuột.

Bạn có thể thêm bộ hẹn giờ để giới hạn thời gian cho phép giữa sự kiện di chuột và chuột hoặc thậm chí ném vào trình xử lý di chuột để hạn chế chuyển động giữa sự kiện chuột và chuột và khiến trình xử lý sự kiện không kích hoạt nếu con trỏ chuột di chuyển hơn mười điểm ảnh, vv các possibilites gần như là vô tận, vì vậy mà không thực sự là một vấn đề.

$('#test').on({ 
    mousedown: function(e) { 
     if (e.which === 2) { 
      $(this).data('down', true); 
     } 
    }, 
    mouseup: function(e) { 
     if (e.which === 2 && $(this).data('down')) { 
      alert('middle button clicked'); 
      $(this).data('down', false); 
     } 
    } 
}); 
+2

Tôi đánh giá cao câu trả lời của bạn, tuy nhiên tôi đã nêu trong câu hỏi "Tôi không muốn tạo ra một hacky' mousedown; setTimeout; mouseup' mô phỏng 'click'." Việc phát minh lại nhấp chuột có vẻ như là một ý tưởng tồi, nhưng tôi sẽ cân nhắc lại ưu và khuyết điểm. – mwcz

+1

Và tôi đã nói trong câu trả lời của tôi rằng đó là cách đáng tin cậy duy nhất để nắm bắt một cú nhấp chuột vào nút giữa, không có lựa chọn thay thế. – adeneo

+0

Có cần sử dụng so sánh === thay vì == không? Tại sao? Cảm ơn. –

4

Câu trả lời ngắn gọn: Không.

Câu hỏi đặt ra là, bạn muốn nắm bắt các nhấp chuột giữa cho điều gì? Một nhấp chuột giữa không có nghĩa là tương tác với trang hiện tại mà là để mở một liên kết trong một tab mới.

Chrome hiện cũng đang làm việc trên droping hành vi này: https://code.google.com/p/chromium/issues/detail?id=255

Và hiện nay là một cuộc thảo luận chung về mailing list w3c về chủ đề này: http://lists.w3.org/Archives/Public/www-dom/2013JulSep/0203.html


Tuy nhiên, bây giờ, bạn có thể bắt middleclicks trong Firefox ở cấp tài liệu:

$(document).on('click', function(e){ 
    console.log(e); 
}); 
+0

Tuyệt vời, cảm ơn thông tin cơ bản. Trường hợp sử dụng đang thu thập dữ liệu phân tích cho các nhấp chuột giữa (giống như ctrl + nhấp chuột). Ctrl + click sẽ kích hoạt các trình xử lý onclick. – mwcz

+0

Vấn đề Chromium 255, [comment 160] (https://bugs.chromium.org/p/chromium/issues/detail?id=255#c160) nói về sự kiện mới ['auxclick'] (https: // developer.mozilla.org/en-US/docs/Web/Events/auxclick) và [yêu cầu này trong trang web caniuse] (https://github.com/Fyrd/caniuse/issues/2923) bao gồm các liên kết hữu ích hơn nữa. –

Các vấn đề liên quan