All of the questions I've seen on how to detect a middle mouse click in JavaScript are related to jQuery, but I'm wondering how I can detect middle mouse button clicks with regular JavaScript. I tried using onClick(), but it only appears to work for the left mouse button.
Is there a JavaScript function that can detect both left and middle mouse button clicks or, if not, that can detect middle mouse button clicks?
The reason I ask is that I want to make a function call when links are clicked, irregardless of whether the left or middle mouse button was used.
onclick is not tied to a mouse, but more on the target element itself.
Here's how to detect whether an element is middle clicked:
document.body.onclick = function (e) {
if (e && (e.which == 2 || e.button == 4 )) {
console.log('middleclicked')
}
}
You have to use stuff that's already built into the DOM and Javascript engines and then put in cases where browsers differ (this is why jQuery is normally used).
document.getElementById("myBtn").onclick = function(event) {
event = event || window.event
// Now event is the event object in all browsers.
// Note: event.target - the reference to clicked element. IE uses event.srcElement
// In W3C there is a button property which works same in all browsers except IE:
// 0 - left button, 1 - middle button, 2 - right button
// For IE, left button = button & 1 (the 1st bit) is set to 1
// right button = button & 2 (the 2nd bit) is 1
// and middle button = button & 4 (the 3rd bit)
var left = event.button == 0 || 1 == event.button&1;
var middle = event.button == 1 || 1 == event.button&2;
var right = event.button == 2 || 1 == event.button&3;
// Put your code here
}
You'll have to detect the event 2
event = event || window.event; //make sure to pass the event into the function
if (event.which == 2) {
//do code..
}
The code below could help you. It can detect which mouse button the user clicked. e.which == 2 is for the middle button.
<script type="text/javascript">
function detect_button(e){
e = e || window.event;
if (e.which == null){
button = (e.button < 2) ? 'left' : ((e.button == 4) ? 'middle' : 'right');
}
else{
button = (e.which < 2) ? 'left' : ((e.which == 2) ? 'middle' : 'right');
}
alert(button);
}
</script>
The answers/solutions that are already here might work on others, but it doesn't work on me.
So my solution is: Instead of using the click event, I use the mousedown event
window.onmousedown = (event) => {
if (event.button == 1 || event.buttons == 4) {
console.log('middle mouse');
}
}
or
window.addEventListener('mousedown', (event) => {
if (event.button == 1 || event.buttons == 4) {
console.log('middle mouse');
}
});
Related
I want to check if the Tab key is pressed and held down and released so that I can perform some other actions with other key combinations.
var shifted = false;
var tabbed = false;
$(document).on('keyup keydown', function(e) {
shifted = e.shiftKey;
tabbed = e.keyCode === 9;
console.log(tabbed);
});
The above code is working fine for the Shift key, but it's not working for the Tab key. When the Tab key is pressed and held the tabbed variable should be true and when released it should be false.
To answer the question (rather than question if the question should be a question):
This MDN page describes how keyboard events work.
one keydown, with repeat = false
multiple keydown, with repeat = true
one keyup
So you can check for when the tab is started to be held down with keydown && !repeat and when it's stopped being held down with keyup
Note you must also cancel the event so that it doesn't do the correct/expected behaviour of tabbing to the next tabbed-indexed input (emphasis on what tab actually should be doing...)
It's also cleaner to keep the events separate, giving:
var tabdown = false;
$(document).on('keydown', function(e) {
if (e.keyCode === 9) {
tabdown = true;
return false;
}
if (tabdown && e.keyCode >= 49 && e.keyCode <= 51)
{
$("#in" + (e.keyCode-48)).focus();
return false;
}
});
$(document).on('keyup', function(e) {
if (e.keyCode === 9) tabdown = false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<em>hold tab and 1, 2 or 3 to change inputs</em><br/>
<input type='text' id='in1'>
<input type='text' id='in2'>
<input type='text' id='in3'>
But you'll note that an instruction is needed on the page as it's not a normal method - and also disables the normal method to easily/quickly switch between inputs in order.
This is not a recommended course of action.
But included here for completeness.
Use the following to identify is tabbed
tabbed = (e.keyCode === 9 && e.type === 'keydown')?true:false;
The web application I work on was designed and developed during the period where there existed only 2-button mice. Now that we have more than 3-button mice available in the market, all those extra buttons are causing havoc while using our application.
My intention is to allow the user to press only the left mouse button and disable all other buttons on his mice. Since, I do not have access to the user's system, I have to achieve this somehow through the browser itself (probably by using JavaScript).
How can I go about solving this problem? Any pointers would be really helpful.
W3C event model is kind enough to pass mouse information through the event object. That means you can actually read which mouse button was clicked. Example
document.body.addEventListener('click', function( event ) {
console.log('mouse button clicked: ', event.which);
}, false);
With that information its fairly trivial to only allow left-clicks, which are represented by the value 1.
document.body.addEventListener('click', function( event ) {
if( event.which === 1 ) {
// do something
} else {
event.stopPropagation();
event.preventDefault();
}
}, false);
It depends on the browser and document mode.
This is how we tweaked prototype.js buttonmaps to work on all browsers. Including IE10 in docmode < 9.
function _isButtonForDOMEvents(event, code) {
return event.which ? (event.which === code + 1) : (event.button === code);
}
//var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
function _isButtonForLegacyEvents(event, code) {
switch (code) { //Fix where IE10 in DocMode lt9 caused isLeftClick to fail
case 0: return event.button == 0 || event.button == 1;
case 1: return event.button == 4;
case 2: return event.button == 2;
default: return false;
}
}
function _isButtonForWebKit(event, code) {
switch (code) {
case 0: return event.which == 1 && !event.metaKey;
case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
case 2: return event.which == 3;
default: return false;
}
}
I think this is the closest you will get to disabling the buttons
document.addEventListener('click', function( e ){
if(e.which === 2 || e.which === 3) { // 2 = middle scroll button || 3 = right click
e.preventDefault();
e.stopPropagation();
return false;
}
});
Instead of click if it doesn't work you can try 'keydown' or 'keyup'
As you may know some browsers have this default functionality to scroll page down when spacebar is clicked. I usually like this feature, but due to nature of my website I need to get rid of it.
I've been using
window.onkeydown = function(e) {
return !(e.keyCode == 32);
};
which eats all spacebar functionality and gets the job done, however if user is typing in a comment or a search query and they press spacebar no space is added in a text as this functionality has been eaten up.
So is there a way to disable just the scrolling part and leave all other functionality as it is?
window.onkeydown = function(e) {
return !(e.keyCode == 32 && (e.target.type != 'text' && e.target.type != 'textarea'));
};
Maybe try this:
window.onkeydown = function(e) {
if(e.keyCode == 32 && e.target.nodeName.toUpperCase() === "BODY") e.preventDefault();
};
Probably need to equalise for IE:
window.onkeydown = function(e) {
var evt = e || window.event;
var elem = evt.target || evt.srcElement;
if(e.keyCode == 32 && elem.nodeName.toUpperCase() === "BODY") {
evt.preventDefault();
return false;
}
};
(untested)
But you would need to attach an event to/within each iframe, using iframeref.contentWindow.
After the page and iframes have loaded you could loop through the frames[] collection.
I have a text input, where I need to bind an event on doing a CTRL-V. I have set a global variable named ctrl which is set to 1 whenever a keydown is fired with a which value of 17. Similarly it is made 0 when a keyup is fired with which value of 17
Problem is, there are two CTRL keys. So if I do something like: first pressing the left CTRL key, and while pressing it down, press the right CTRL key also (so that both CTRL keys are pressed now), and then I release only one of them, the keyup is fired and the variable ctrl is set to 0, even though the other CTRL key is still being pressed.
How do I fire the events such that the variable is set to 0 only when both CTRL keys are up (I don't need to exactly differentiate between them).
Update : this is now possible in modern browsers
The easiest way to detect left and right control keys in Javascript
$(document).ready(function(){
$("html").keydown(function(e) {
if (e.ctrlKey) {
if (event.location == 1) console.log('left ctrl');
if (event.location == 2) console.log('right ctrl');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note: You have to click the inside white space when you run code snippet to activate keyboard keys. This is tested in Chrome and Safari.
There are two properties for this of keydown event.
You can differentiate left and right Ctrl by using
if ( e.location == 1 || e.keyLocation == 1 ) {
var keyPosition = 'left';
} else if ( e.location == 2 || e.keyLocation == 2 ) {
var keyPosition = 'right';
}
I don't think there is a way for that unless you write on lowlevel ... keyCode is the same for both (it is 17)
Just You can use e.ctrlKey as a way to determine if the control key was pressed.
However I read around and found one answer mentioning you could do that in IE but I did not try it from my side
you can use e.originalEvent.location instead of the global event.location
$(document).ready(function(){
$("html").keydown(function(e) {
if (e.ctrlKey) {
if (e.originalEvent.location === 1) console.log('left ctrl');
if (e.originalEvent.location === 2) console.log('right ctrl');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
below is your answer for three mouse keyup events. rest for mousewheel you should ask again:
/*
1 = Left Mousebutton
2 = Centre Mousebutton
3 = Right Mousebutton
*/
$(document).mousedown(function(e) {
if (e.which === 3) {
/* Right Mousebutton was clicked! */
alert("right key code 3");
}
else if(e.which === 2) {
alert("Centre key code 2");
}
else if(e.which === 1) {
alert("Left key code 1");
}
});
you can use this:
$('#inputboxinput').bind('keypress', function(e) {
if(e.keyCode==13){
// Enter pressed... do anything here...
}
});
the cross-browser way:
if (!event.which && ((event.charCode || event.charCode === 0) ? event.charCode: event.keyCode)) {
event.which = event.charCode || event.keyCode;
}
this is my code:
$('#handle').mousedown(function(e){
if( (!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 1) ) {
alert("Left Button");
}
})
this event is like to drag , but not drag ,
the left button Has been pressed, no released until mouseup,
so how to catch it using jquery ,
this is my demo : http://jsfiddle.net/ATZNW/1/
thanks
jQuery doesn't do this out of the box but you can fire your own events. Instead of alerting "left button", set some global variable dragging to true. Then:
$("#handle").mousemove(function (e) {
if (dragging) {
$(this).trigger("dragmove");
// Or just write the code you need here
}
});
Then you can handle that event elsewhere if you wish:
$("#handle").bind("dragmove", function (e) {
});