2011-12-13 65 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