1/** 2 * @author Peter Slagter 3 * @author Ryan Fioravanti 4 * @source http://code.google.com/mobile/articles/fast_buttons.html 5 */ 6 7window.PbLib = window.PbLib || {}; 8PbLib.UI = PbLib.UI || {}; 9PbLib.UI.clickbuster = PbLib.UI.clickbuster || {}; 10 11/** Construct the FastButton with a reference to the element and click handler. */ 12PbLib.UI.FastTap = function(element, handler) { 13 this.element = element; 14 this.handler = handler; 15 16 element.addEventListener('touchstart', this, false); 17 element.addEventListener('click', this, false); 18}; 19 20PbLib.UI.FastTap.prototype.handleEvent = function(event) { 21 switch (event.type) { 22 case 'touchstart': 23 this.onTouchStart(event); 24 break; 25 case 'touchmove': 26 this.onTouchMove(event); 27 break; 28 case 'touchend': 29 this.onClick(event); 30 break; 31 case 'click': 32 this.onClick(event); 33 break; 34 } 35}; 36 37/** 38 * Save a reference to the touchstart coordinate and start listening to touchmove and touchend events. 39 * Calling stopPropagation guarantees that other behaviors don't get a chance to handle the same click event. 40 */ 41 42PbLib.UI.FastTap.prototype.onTouchStart = function(event) { 43 event.stopPropagation(); 44 45 this.element.addEventListener('touchend', this, false); 46 document.body.addEventListener('touchmove', this, false); 47 48 this.startX = event.touches[0].clientX; 49 this.startY = event.touches[0].clientY; 50}; 51 52/** When a touchmove event is invoked, check if the user has dragged past the threshold of 10px. */ 53PbLib.UI.FastTap.prototype.onTouchMove = function(event) { 54 if (Math.abs(event.touches[0].clientX - this.startX) > 10 || 55 Math.abs(event.touches[0].clientY - this.startY) > 10) { 56 this.reset(); 57 } 58}; 59 60/** Invoke the actual click handler and prevent ghost clicks if this was a touchend event. */ 61PbLib.UI.FastTap.prototype.onClick = function(event) { 62 event.stopPropagation(); 63 this.reset(); 64 this.handler(event); 65 66 if (event.type == 'touchend') { 67 PbLib.UI.clickbuster.preventGhostClick(this.startX, this.startY); 68 } 69}; 70 71PbLib.UI.FastTap.prototype.reset = function() { 72 this.element.removeEventListener('touchend', this, false); 73 document.body.removeEventListener('touchmove', this, false); 74}; 75 76PbLib.UI.FastTap.prototype.removeHandler = function() { 77 this.element.removeEventListener('touchstart', this, false); 78 this.element.removeEventListener('click', this, false); 79}; 80 81/** Call preventGhostClick to bust all click events that happen within 25px of the provided x, y coordinates in the next 2.5s. */ 82PbLib.UI.clickbuster.preventGhostClick = function(x, y) { 83 PbLib.UI.clickbuster.coordinates.push(x, y); 84 window.setTimeout(PbLib.UI.clickbuster.pop, 2500); 85}; 86 87PbLib.UI.clickbuster.pop = function () { 88 PbLib.UI.clickbuster.coordinates.splice(0, 2); 89}; 90 91/** 92 * If we catch a click event inside the given radius and time threshold then we call stopPropagation and preventDefault. 93 * Calling preventDefault will stop links from being activated. 94 */ 95 96PbLib.UI.clickbuster.onClick = function(event) { 97 for (var i = 0; i < PbLib.UI.clickbuster.coordinates.length; i += 2) { 98 var x = PbLib.UI.clickbuster.coordinates[i]; 99 var y = PbLib.UI.clickbuster.coordinates[i + 1]; 100 if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) { 101 event.stopPropagation(); 102 event.preventDefault(); 103 } 104 } 105}; 106 107if (document.addEventListener) { 108 document.addEventListener('click', PbLib.UI.clickbuster.onClick, true); 109} 110 111PbLib.UI.clickbuster.coordinates = [];
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.