2013-11-22 94 views
10

以下是我看到的與Chrome和FF中的中點擊和click事件相關的JSFiddle行爲。爲什麼在幾種情況下中鍵不會觸發'點擊'?

「點擊」有點兒八九不離十工作

方法1:直接綁定click處理到a元素和中間點擊將引發Chrome的處理程序,但不是在FF。

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

方法2:綁定委派click處理程序,其包含一個或多個a一個div。中點擊將而不是在Chrome或FF中觸發此處理程序。

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

這種做法是極其寶貴的,如果格開始是空和a元件通過AJAX調用後填寫,或因爲一些用戶輸入的結果。

「鼠標鬆開」工作

使用mouseup代替click導致了兩個方法1和2在這兩個瀏覽器。

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

這裏的JSFiddlemouseup

這很有趣,在某些情況下可能會有用,因爲mouseup幾乎是click。但是mouseup不是click,而我之後的行爲是click。我不想創建click的模擬mousedown; setTimeout; mouseup

我敢肯定,答案是「不」,但是有沒有一個跨瀏覽器的方式來導致中鍵單擊觸發click處理程序?如果不是,原因是什麼?

回答

6

點擊事件通常是針對鼠標左鍵按鈕,但是,根據瀏覽器的不同,點擊事件可能會或可能不會發生在右側和/或中間按鈕上。

在Internet Explorer和Firefox中,不會爲右側或中間按鈕觸發點擊事件。

因此,我們無法可靠地在中間或右鍵上使用事件處理程序的click事件。

相反,爲了區分鼠標按鈕,我們必須使用mousedown和mouseup事件,因爲大多數瀏覽器都會爲任何鼠標按鈕觸發mousedown和mouseup事件。

在Firefox和Chrome中event.which應該包含一個數字,指示按下了什麼鼠標按鈕(1是左邊的,2是中間的,3是右邊的)。

另一方面,在Internet Explorer中,event.button表示點擊了什麼鼠標按鈕(1是左邊,4是中間,2是右邊);

event.button也應該可以在Firefox和其他瀏覽器中使用,但是數字可能略有不同(0是左邊的,1是中間的,2是正確的)。

所以,給我們共同平時做這樣的事情:

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 
     } 
    } 
} 

在jQuery正常化event.which,你應該只需要使用jQuery的事件處理程序,這樣做:

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

換句話說,你不能使用onclick事件,所以爲了模擬它,你可以同時使用mousedown和mouseup。

您可以添加一個計時器來限制mousedown和mouseup事件之間允許的時間,甚至可以引入mousemove處理程序來限制mousedown和mouseup事件之間的移動,並且如果鼠標指針不會觸發事件處理程序移動了超過十個像素等可能性幾乎是無止境的,所以這不應該是一個問題。

$('#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

我很感謝你的回答,但是我在「我不想創建hacky'mousedown; setTimeout; mouseup'模擬'click'」這個問題上做了陳述。重新點擊看起來似乎是一個壞主意,但我會再次權衡利弊。 – mwcz

+1

我在回答中指出,這是獲取中間按鈕點擊的唯一可靠方法,因此沒有其他選擇。 – adeneo

+0

是否需要使用===比較而不是==?爲什麼?謝謝。 –

4

簡答:沒有。

問題是,你想捕獲什麼中間點擊?中間點擊並不意味着與當前頁面交互,而是打開新標籤中的鏈接。

瀏覽器目前也正在對滴速此行爲:https://code.google.com/p/chromium/issues/detail?id=255

而且現在關於這一主題的W3C郵件列表上進行了一般性討論:http://lists.w3.org/Archives/Public/www-dom/2013JulSep/0203.html


然而現在,你能趕上在文檔級Firefox的middleclicks:

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

非常好,謝謝你的背景資料。用例捕獲中間點擊的分析數據(就像Ctrl +點擊)。 Ctrl +點擊會觸發onclick處理程序。 – mwcz

+0

Chromium問題255,[評論160](https://bugs.chromium.org/p/chromium/issues/detail?id=255#c160)討論了一個新事件['auxclick'](https:// developer.mozilla.org/en-US/docs/Web/Events/auxclick)以及[在caniuse網站上的此請求](https://github.com/Fyrd/caniuse/issues/2923)包含更有用的鏈接。 –

相關問題