2013-02-06 78 views
0

我想實現快速按鈕的代碼我通過谷歌發現:HTML快速按鈕工作實例

Trying to implement Google's Fast Button

目前,我正在一個遺漏的類型錯誤:無法讀取空的特性「的addEventListener」 。有人可以告訴我如何實現這個快速按鈕邏輯和/或addEventListener。

答案:在加載頁面元素後定義NewButton。

<html> 
<head> 
<title>Button</title> 
<script src="/js/fastbutton.js"></script> 
<script type="text/javascript"> 
new FastButton(document.getElementById('fastButton'), function() { 
    num = num + 1; 
    document.getElementById("outputText").value = num; 
}); 

var num = 0; 

function slowButton() { 
    num = num + 1; 
    document.getElementById("outputText").value = num; 
} 
</script> 
</head> 
<body> 
Output: <input id="outputText" type="text"></input> 
<button id="fastButton">Fast Button</button> 
<button onclick="slowButton();">Slow Button</button> 
</body> 
</html> 

JS代碼:

(function() { 
    /** 
    * From: http://code.this.com/mobile/articles/fast_buttons.html 
    * Also see: https://stackoverflow.com/questions/6300136/trying-to-implement-googles-fast-button 
    */ 

    /** For IE8 and earlier compatibility: https://developer.mozilla.org/en/DOM/element.addEventListener */ 
    function addListener(el, type, listener, useCapture) { 
    if (el.addEventListener) { 
Uncaught TypeError: Cannot read property 'addEventListener' of null 
     el.addEventListener(type, listener, useCapture); 
     return { 
     destroy: function() { el.removeEventListener(type, listener, useCapture); } 
     }; 
    } else {  
     // see: https://stackoverflow.com/questions/5198845/javascript-this-losing-context-in-ie 
     var handler = function(e) { listener.handleEvent(window.event, listener); } 
     el.attachEvent('on' + type, handler); 

     return { 
     destroy: function() { el.detachEvent('on' + type, handler); } 
     }; 
    } 
    } 

    var isTouch = "ontouchstart" in window; 

    /* Construct the FastButton with a reference to the element and click handler. */ 
    this.FastButton = function(element, handler, useCapture) { 
    // collect functions to call to cleanup events 
    this.events = []; 
    this.touchEvents = []; 
    this.element = element; 
    this.handler = handler; 
    this.useCapture = useCapture; 
    if (isTouch) 
     this.events.push(addListener(element, 'touchstart', this, this.useCapture));  
    this.events.push(addListener(element, 'click', this, this.useCapture)); 
    }; 

    /* Remove event handling when no longer needed for this button */ 
    this.FastButton.prototype.destroy = function() { 
    for (i = this.events.length - 1; i >= 0; i -= 1) 
     this.events[i].destroy();  
    this.events = this.touchEvents = this.element = this.handler = this.fastButton = null; 
    }; 

    /* acts as an event dispatcher */ 
    this.FastButton.prototype.handleEvent = function(event) { 
    switch (event.type) { 
     case 'touchstart': this.onTouchStart(event); break; 
     case 'touchmove': this.onTouchMove(event); break; 
     case 'touchend': this.onClick(event); break; 
     case 'click': this.onClick(event); break; 
    } 
    }; 

    /* Save a reference to the touchstart coordinate and start listening to touchmove and 
    touchend events. Calling stopPropagation guarantees that other behaviors don’t get a 
    chance to handle the same click event. This is executed at the beginning of touch. */ 
    this.FastButton.prototype.onTouchStart = function(event) { 
    event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true); 
    this.touchEvents.push(addListener(this.element, 'touchend', this, this.useCapture)); 
    this.touchEvents.push(addListener(document.body, 'touchmove', this, this.useCapture)); 
    this.startX = event.touches[0].clientX; 
    this.startY = event.touches[0].clientY; 
    }; 

    /* When /if touchmove event is invoked, check if the user has dragged past the threshold of 10px. */ 
    this.FastButton.prototype.onTouchMove = function(event) { 
    if (Math.abs(event.touches[0].clientX - this.startX) > 10 || Math.abs(event.touches[0].clientY - this.startY) > 10) { 
     this.reset(); //if he did, then cancel the touch event 
    } 
    }; 

    /* Invoke the actual click handler and prevent ghost clicks if this was a touchend event. */ 
    this.FastButton.prototype.onClick = function(event) { 
    event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true); 
    this.reset(); 
    // Use .call to call the method so that we have the correct "this": https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call 
    var result = this.handler.call(this.element, event); 
    if (event.type == 'touchend') 
     clickbuster.preventGhostClick(this.startX, this.startY);  
    return result; 
    }; 

    this.FastButton.prototype.reset = function() { 
    for (i = this.touchEvents.length - 1; i >= 0; i -= 1) 
     this.touchEvents[i].destroy();  
    this.touchEvents = []; 
    }; 

    this.clickbuster = function() {} 

    /* Call preventGhostClick to bust all click events that happen within 25px of 
    the provided x, y coordinates in the next 2.5s. */ 
    this.clickbuster.preventGhostClick = function(x, y) { 
    clickbuster.coordinates.push(x, y); 
    window.setTimeout(clickbuster.pop, 2500); 
    }; 

    this.clickbuster.pop = function() { 
    clickbuster.coordinates.splice(0, 2); 
    }; 

    /* If we catch a click event inside the given radius and time threshold then we call 
    stopPropagation and preventDefault. Calling preventDefault will stop links 
    from being activated. */ 
    this.clickbuster.onClick = function(event) { 
    for (var i = 0; i < clickbuster.coordinates.length; i += 2) { 
     var x = clickbuster.coordinates[i]; 
     var y = clickbuster.coordinates[i + 1]; 
     if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) { 
     event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true); 
     event.preventDefault ? event.preventDefault() : (event.returnValue=false); 
     } 
    } 
    }; 

    if (isTouch) { 
    // Don't need to use our custom addListener function since we only bust clicks on touch devices 
    document.addEventListener('click', clickbuster.onClick, true); 
    clickbuster.coordinates = []; 
    } 
})(this); 

回答

0

謝謝gdoron。我需要做的就是在頁面上的元素之後定義對象。我使用<body onload="load()">來實現它。