Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active May 8, 2018 08:42
Embed
What would you like to do?
Internet Explorer's click event's `which` property won't indicate which mouse button was clicked. To get around this, create distinct `leftclick`, `rightclick` and `middleclick` events which reliably prevent default behaviour. Also creates the `anyclick` event for convenience, which is essentially equivalent to `click` with `event.which` polyfil…
void function whichClickClosure( $ ){
var events = {
1 : 'leftclick',
2 : 'middleclick',
3 : 'rightclick'
},
// List of interruption events for symbolic linking between custom and native events
interrupts = [
'preventDefault',
'stopPropagation',
'stopImmediatePropagation'
],
// A dummy empty event, used in custom interruption
emptyEvent = $.Event();
function makeInterrupts( customEvent, ensuingEvent ){
var output = {};
$.each( interrupts, function makeCustomInterrupt( index, method ){
output[ method ] = function customInterrupt(){
emptyEvent[ method ].call( this );
$( customEvent.target ).one( ensuingEvent, function defferedInterrupt( ensuingEvent ){
ensuingEvent[ method ]();
} );
};
} );
return output;
}
// We need to capture all mousedowns
$( document ).on( 'mousedown', function mousedownFilter( mousedown ){
// Determine which event we're listening for
var eventType = events[ mousedown.which ];
// Discard anything we can't map
if( !eventType ){
return;
}
$( document ).one( 'mouseup', function mouseupFilter( mouseup ){
// The custom click event we'll fire
var eventObject = {},
// The ensuing native event the event symbolizes
ensuingEvent = '';
// Only capture events on the same element
if( mousedown.target !== mouseup.target ){
return;
}
// Middleclicks only trigger on links
if( eventType === 'middleclick' && $( mouseup.target ).is( 'a' ) ){
return;
}
if( eventType === 'middleclick' || eventType === 'leftclick' ){
ensuingEvent = 'click';
}
// Rightclicks also fire off contextmenu
if( eventType === 'rightclick' ){
ensuingEvent = 'contextmenu';
}
// Extend the eventObject
$.extend(
// Including all the deeper stuff
true,
// ...
eventObject,
// Take all the properties of mouseup...
mouseup,
// With our type and timestamp...
$.Event( eventType )
);
// Add custom interrupts
$.extend(
true,
eventObject,
makeInterrupts( eventObject, ensuingEvent )
);
$( mouseup.target )
// Fire this event on the target
.trigger( eventObject )
// Also fire an 'anyclick' event (with all the same internals) for convenience
.trigger( $.extend( eventObject, { type : 'anyclick' } ) );
} );
} );
}( jQuery );
@barneycarroll
Copy link
Author

Middle click has reverted. Investigate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment