Last active
May 8, 2018 08:42
-
-
Save barneycarroll/6592823 to your computer and use it in GitHub Desktop.
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…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Middle click has reverted. Investigate.