<!DOCTYPE html> <html> <head> <title>Determine Link Trigger Method With jQuery</title> </head> <body> <h1> Determine Link Trigger Method With jQuery </h1> <p> <a href="#" class="link">Click me please</a>!<br /> <a href="#" class="link">Click me please</a>!<br /> <a href="#" class="link">Click me please</a>!<br /> <a href="#" class="link">Click me please</a>!<br /> </p> <!-- Configure scripts. --> <script type="text/javascript" src="../jquery-1.7.1.js"></script> <script type="text/javascript"> // Set up a special Event Type which will help us to // determine what physical device was used to initiate the // click event on a given element: Mouse or Keywboard. Since // there doesn't appear to be anything inherent to the click // event that denotes device (cross-browser), we'll have to // use some surrounding events to setup the click event // handler data. The default device is considered the Mouse; // the alternate device is the keyboard. (function( $ ){ // When a key is depressed, we want to signal that this // might be a keyboard-initiated click event. As such, // we'll store a boolean to be used in the click event. function handleKeyDown( event ){ // Check to make sure that this key is one that is // capable of triggering a click event (ie. the enter // button, 13). if (event.which === 13){ $.data( this, "clickwithevent:keyboard", true ); } } // When a key is released, we know that the click event // will have already take place (if at all); as such, we // set the boolean flag to false since any subsequent // click event will be triggered by a mouse (or preceeded // by a keydown event). function handleKeyUp( event ){ $.data( this, "clickwithevent:keyboard", false ); } // When the click event is triggered, we need to // determine if the event was initiated by the keyboard // or the mouse. If the boolean flag is true, it means // that the click event was preceeded by the depression // of the Enter key, which indicates that the click event // was initiated by the keyboard. function handleClick( event ){ // Get the flag for keyboard-based click. var isKeyPress = $.data( this, "clickwithevent:keyboard" ); // Let's create a new event that extends the click // event. This way, when we trigger our "clickwith" // event, we get all of the contextual information // associated with the click; but, we don't // accidientally trigger click events. var clickEvent = createEvent( "clickwith", event ) // Tell jQuery to trigger the new event with a second // argument that indicates the initiator of the click // event. $.event.handle.apply( this, [clickEvent, (isKeyPress ? "keyboard" : "mouse")] ); } // I create a new jQuery event object using the given // event object as the collection of properties to copy. // This way, we can "extend" an existing Event object // without worrying about copying data we shouldn't. function createEvent( eventType, event ){ // For each event object, we will try to copy all of // the following properties that are available. var properties = [ "altKey", "bubbles", "button", "cancelable", "charCode", "clientX", "clientY", "ctrlKey", "currentTarget", "data", "detail", "eventPhase", "metaKey", "offsetX", "offsetY", "originalTarget", "pageX", "pageY", "prevValue", "relatedTarget", "screenX", "screenY", "shiftKey", "target", "view", "which" ]; // Create a new properties object that will be used // to create the new event. var eventProperties = {} // Copy over all properties from the old event. $.each( properties, function( index, property ){ // Make sure this property is available on // the original event. if (property in event){ // Copy it over to the new event property // collection. eventProperties[ property ] = event[ property ]; } } ); // Create and return the new event object with the // duplicated properties. return( new $.Event( eventType, eventProperties ) ); } // Configure the special event, "clickwith", so that // jQuery knows how to bind and unbind event handlers. $.event.special.clickwith = { // I configure each element that is bound to the // clickwith event. I am only called once per element. setup: function( data, namespaces ){ // Set up the key events that surround the click // events that setup the meta data. $( this ) .data( "clickwithevent:keyboard", false ) .on( "keydown.clickwithevent", handleKeyDown ) .on( "keyup.clickwithevent", handleKeyUp ) .on( "click.clickwithevent", handleClick ) ; }, // I remove the configuration from each element that // is bound to the clickwith event. I am only called // oncer per element.s teardown: function( namespaces ){ // Remove all traces of the special event. $( this ) .removeData( "clickwithevent:keyboard" ) .off( "keydown.clickwithevent" ) .off( "keyup.clickwithevent" ) .off( "click.clickwithevent" ) ; } }; })( jQuery ); // -------------------------------------------------- // // -------------------------------------------------- // // Make sure this event works on a direct event binding. $( "a.link" ).on( "clickwith", function( event, trigger ){ console.log( "LOCAL[ " + trigger + " ]", event ); } ); // Make sure this event works on a delegated event binding. $( document ).on( "clickwith", "a.link", function( event, trigger ){ console.log( "GLOBAL[ " + trigger + " ]", event ); } ); // Try manually triggering a click event (which should, in // turn, trigger a clickwith event, using the Mouse as the // default device trigger). $( "a.link:first" ) .trigger( "click" ) ; </script> </body> </html>