2011-12-13 53 views
6

我使用JavaScript來檢測頁面,我表示一個UIWebView水龍頭,像這樣:檢測單一的水龍頭,但仍然支持文本選擇和鏈接

<div id="wrapper"> 
    <a href="http://apple.com">Apple</a> 
</div> 
<script> 
    document.getElementById("wrapper").addEventListener('click', function() { 
     document.location = 'internal://tap'; 
    }, false); 
</script> 

我攔截鏈接與我的網絡查看代理,並尋找「內部://點擊」。當我得到這些信息時,我會阻止網絡視圖進行導航,並對水龍頭做出響應。但是,這樣做,我失去了選擇文本的能力。點擊鏈接仍然可以正常工作。

實際上,即使處理程序不嘗試更改文檔位置,只需添加'click'的事件偵聽器即可刪除選擇文本的功能。

任何想法我做錯了什麼?

回答

5

顯然,如果您在某個元素上放置了點擊偵聽器,則無法再在該元素上選擇文本。我的解決方案是使用touchstart,touchmove和touchend事件的組合來檢測水龍頭,以及一個忽略多次水龍頭的計時器,並檢查當前的文檔選擇以確保選擇事件不會發生。

這裏的JS代碼我使用:

SingleTapDetector = function(element, handler) { 
    this.element = element; 
    this.handler = handler; 

    element.addEventListener('touchstart', this, false); 
}; 

SingleTapDetector.prototype.handleEvent = function(event) { 
    switch (event.type) { 
     case 'touchstart': this.onTouchStart(event); break; 
     case 'touchmove': this.onTouchMove(event); break; 
     case 'touchend': this.onTouchEnd(event); break; 
    } 
}; 

SingleTapDetector.prototype.onTouchStart = function(event) { 
    this.element.addEventListener('touchend', this, false); 
    document.body.addEventListener('touchmove', this, false); 

    this.startX = this.currentX = event.touches[0].clientX; 
    this.startY = this.currentY = event.touches[0].clientY; 
    this.startTime = new Date().getTime(); 
}; 

SingleTapDetector.prototype.onTouchMove = function(event) { 
    this.currentX = event.touches[0].clientX; 
    this.currentY = event.touches[0].clientY; 
}; 

SingleTapDetector.prototype.onTouchEnd = function(event) { 
    var that = this; 

    // Has there been one or more taps in this sequence already? 
    if (this.tapTimer) { 
     // Reset the timer to catch any additional taps in this sequence 
     clearTimeout(this.tapTimer); 
     this.tapTimer = setTimeout(function() { 
      that.tapTimer = null; 
     }, 300); 
    } else { 
     // Make sure the user didn't move too much 
     if (Math.abs(this.currentX - this.startX) < 4 && 
      Math.abs(this.currentY - this.startY) < 4) { 
      // Make sure this isn't a long press 
      if (new Date().getTime() - this.startTime <= 300) { 
       // Make sure this tap wasn't part of a selection event 
       if (window.getSelection() + '' == '') {      
        // Make sure this tap is in fact a single tap 
        this.tapTimer = setTimeout(function() { 
         that.tapTimer = null; 

         // This is a single tap 
         that.handler(event); 
        }, 300); 
       } 
      } 
     } 
    } 
}; 

new SingleTapDetector(document.body, function(event) { 
    document.location = "internal://tap"; 
}); 
3

沒有必要使用JavaScript這一點,這是矯枉過正當UIGestureRecognizerDelegate有足夠的方法。所有你需要做的是確保當文本選擇發生時,輕觸識別器不會被觸發。

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
    BOOL hasTap = ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] || 
       [otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]); 
    BOOL hasLongTouch = ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || 
        [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]); 
    if (hasTap && hasLongTouch) { 
     // user is selecting text 
     return NO; 
    } 
    return YES; 
} 

這需要照顧文本選擇,並鏈接應該很好地工作呢(至少他們爲我做的)。

+0

謝謝!它對我有幫助! – 2014-07-17 06:20:08