jStack - jQuery Event Stack Management


/ Published in: JavaScript
Save to your folder(s)

Allows the user to bind an event into a certain position in the call stack for events.


Copy this code and paste it in your HTML
  1. /*!
  2.  * jStack - jQuery Event Stack Management
  3.  * by Eric Garside (http://eric.garside.name)
  4.  *
  5.  * Dual licensed under:
  6.  * MIT: http://www.opensource.org/licenses/mit-license.php
  7.  * GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
  8.  */
  9. (function($){
  10.  
  11. $.extend($.fn, {
  12. // Determine the objects position in the cache, if any
  13. cachePosition: function(){
  14. return $.data(this[0]);
  15. },
  16.  
  17. // Allow the user to splice an event into a specific position in the event cache
  18. bindIntoStack: function(pos, type, func){
  19. return this.each(function(){
  20. var namespaces = type.split("."), // Explode out namespaces, if any
  21. evType = namespaces.shift(), // Grab the actual type
  22. el = $(this), // Use the jQuery reference to the first element instead of the domElement
  23. position = el.cachePosition(); // Get the location of the element in the cache.
  24.  
  25. if (!position) return; // If we have a position, we can access the cache, which holds the jQuery event stack.
  26.  
  27. var cache = $.cache[ position ]; // Grab a reference to the cache so we can do some sanity checks
  28.  
  29. el.bind(type, func); // Now we need to bind the new function to the call stack through jQuery
  30.  
  31. if (!cache || // If we don't have the a pre-existing event cache, bind the function as a new entry and exit
  32. !cache.events ||
  33. !cache.events[ evType ]) return;
  34.  
  35. var events = cache.events[ evType ],// Grab a copy of the events cache for the given type
  36. fromExpando = [], // [stackPosition => uuidIDInjQueryCache, ...]
  37. toReplace = null, // A copy of the function we'll be replacing, if any
  38. i = 0;
  39.  
  40. $.each(events, function(k){
  41. fromExpando.push(k);
  42. if (i == pos) toReplace = this; // If the positions are equal, this is the function we want to replace
  43. ++i;
  44. })
  45.  
  46. if (!toReplace) return; // If the position in the stack has not yet been reached, there's no slicing to be done
  47.  
  48. var newPos = fromExpando.pop(); // The position we'll be placing in
  49.  
  50. // Perform the actual position swap in the cache
  51. $.cache[ position ].events[ evType ][ fromExpando[pos] ] = $.cache[ position ].events[ evType ][ newPos ];
  52. $.cache[ position ].events[ evType ][ newPos ] = toReplace;
  53. })
  54.  
  55. return this;
  56. }
  57. });
  58.  
  59. })(jQuery);
  60.  
  61. // Code to test with
  62. $(function(){
  63.  
  64. var test = $('#test')
  65. .bind('clickr.one', function(){ console.log('evt1') })
  66. .bind('clickr.two', function(){ console.log('evt2') })
  67. .bind('clickr.three', function(){ console.log('evt3') })
  68. .bind('clickr.four', function(){ console.log('evt4') })
  69. .bindIntoStack(0, 'clickr.override', function(e){
  70. console.log('I am now first, and I prevent all other events.');
  71. e.stopImmediatePropagation();
  72. return false;
  73. })
  74. .click(function(){ $(this).trigger('clickr') })
  75. $('#unbind').click(function(){ test.unbind('clickr.override') })
  76. })
  77.  
  78. /**
  79.  * Test HTML:
  80. <body>
  81. <button id="test">Test Events</button>
  82. <button id="unbind">Unbind Override Trigger</button>
  83. </body>
  84.  */

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.