021.jquery.taphold.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // @author Rich Adams <rich@richadams.me>
  2. // Implements a tap and hold functionality. If you click/tap and release, it will trigger a normal
  3. // click event. But if you click/tap and hold for 1s (default), it will trigger a taphold event instead.
  4. ;(function($)
  5. {
  6. // Default options
  7. var defaults = {
  8. duration: 1000, // ms
  9. clickHandler: null
  10. }
  11. // When start of a taphold event is triggered.
  12. function startHandler(event)
  13. {
  14. var $elem = jQuery(this);
  15. // Merge the defaults and any user defined settings.
  16. settings = jQuery.extend({}, defaults, event.data);
  17. // If object also has click handler, store it and unbind. Taphold will trigger the
  18. // click itself, rather than normal propagation.
  19. if (typeof $elem.data("events") != "undefined"
  20. && typeof $elem.data("events").click != "undefined")
  21. {
  22. // Find the one without a namespace defined.
  23. for (var c in $elem.data("events").click)
  24. {
  25. if ($elem.data("events").click[c].namespace == "")
  26. {
  27. var handler = $elem.data("events").click[c].handler
  28. $elem.data("taphold_click_handler", handler);
  29. $elem.unbind("click", handler);
  30. break;
  31. }
  32. }
  33. }
  34. // Otherwise, if a custom click handler was explicitly defined, then store it instead.
  35. else if (typeof settings.clickHandler == "function")
  36. {
  37. $elem.data("taphold_click_handler", settings.clickHandler);
  38. }
  39. // Reset the flags
  40. $elem.data("taphold_triggered", false); // If a hold was triggered
  41. $elem.data("taphold_clicked", false); // If a click was triggered
  42. $elem.data("taphold_cancelled", false); // If event has been cancelled.
  43. // Set the timer for the hold event.
  44. $elem.data("taphold_timer",
  45. setTimeout(function()
  46. {
  47. // If event hasn't been cancelled/clicked already, then go ahead and trigger the hold.
  48. if (!$elem.data("taphold_cancelled")
  49. && !$elem.data("taphold_clicked"))
  50. {
  51. // Trigger the hold event, and set the flag to say it's been triggered.
  52. $elem.trigger(jQuery.extend(event, jQuery.Event("taphold")));
  53. $elem.data("taphold_triggered", true);
  54. }
  55. }, settings.duration));
  56. }
  57. // When user ends a tap or click, decide what we should do.
  58. function stopHandler(event)
  59. {
  60. var $elem = jQuery(this);
  61. // If taphold has been cancelled, then we're done.
  62. if ($elem.data("taphold_cancelled")) { return; }
  63. // Clear the hold timer. If it hasn't already triggered, then it's too late anyway.
  64. clearTimeout($elem.data("taphold_timer"));
  65. // If hold wasn't triggered and not already clicked, then was a click event.
  66. if (!$elem.data("taphold_triggered")
  67. && !$elem.data("taphold_clicked"))
  68. {
  69. // If click handler, trigger it.
  70. if (typeof $elem.data("taphold_click_handler") == "function")
  71. {
  72. $elem.data("taphold_click_handler")(jQuery.extend(event, jQuery.Event("click")));
  73. }
  74. // Set flag to say we've triggered the click event.
  75. $elem.data("taphold_clicked", true);
  76. }
  77. }
  78. // If a user prematurely leaves the boundary of the object we're working on.
  79. function leaveHandler(event)
  80. {
  81. // Cancel the event.
  82. $(this).data("taphold_cancelled", true);
  83. }
  84. // Determine if touch events are supported.
  85. var touchSupported = ("ontouchstart" in window) // Most browsers
  86. || ("onmsgesturechange" in window); // Microsoft
  87. var taphold = $.event.special.taphold =
  88. {
  89. setup: function(data)
  90. {
  91. $(this).bind((touchSupported ? "touchstart" : "mousedown"), data, startHandler)
  92. .bind((touchSupported ? "touchend" : "mouseup"), stopHandler)
  93. .bind((touchSupported ? "touchmove touchcancel" : "mouseleave"), leaveHandler);
  94. },
  95. teardown: function(namespaces)
  96. {
  97. $(this).unbind((touchSupported ? "touchstart" : "mousedown"), startHandler)
  98. .unbind((touchSupported ? "touchend" : "mouseup"), stopHandler)
  99. .unbind((touchSupported ? "touchmove touchcancel" : "mouseleave"), leaveHandler);
  100. }
  101. };
  102. })(jQuery);