Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在UIWebView中检测单个点击,但仍支持文本选择和链接_Javascript_Iphone_Ios_Uiwebview - Fatal编程技术网

Javascript 在UIWebView中检测单个点击,但仍支持文本选择和链接

Javascript 在UIWebView中检测单个点击,但仍支持文本选择和链接,javascript,iphone,ios,uiwebview,Javascript,Iphone,Ios,Uiwebview,我正在使用JavaScript检测在UIWebView中显示的页面中的点击,如下所示: <div id="wrapper"> <a href="http://apple.com">Apple</a> </div> <script> document.getElementById("wrapper").addEventListener('click', function() { document.location =

我正在使用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>

document.getElementById(“包装器”).addEventListener('click',function(){
document.location=internal://tap';
},假);
我正在拦截与我的web视图代理的链接,并查找“internal://tap". 当我得到这个信息时,我会阻止web视图导航,并对点击做出响应。然而,这样做,我失去了选择文本的能力。轻敲连杆仍能正常工作

事实上,仅仅为“click”添加一个事件侦听器就可以删除选择文本的功能,即使处理程序不尝试更改文档位置


你知道我做错了什么吗?

显然,如果你在一个元素上放置了一个点击监听器,你就不能再在iOS上选择该元素中的文本了。我的解决方案是使用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";
});
SingleTapDetector=函数(元素、处理程序){
this.element=元素;
this.handler=handler;
元素。addEventListener('touchstart',this,false);
};
SingleTapDetector.prototype.handleEvent=函数(事件){
开关(事件类型){
案例“touchstart”:this.onTouchStart(事件);break;
案例“touchmove”:this.onTouchMove(事件);break;
案例“touchend”:this.onTouchEnd(事件);break;
}
};
SingleTapDetector.prototype.onTouchStart=函数(事件){
this.element.addEventListener('touchend',this,false);
document.body.addEventListener('touchmove',this,false);
this.startX=this.currentX=event.touchs[0].clientX;
this.startY=this.currentY=event.touchs[0].clientY;
this.startTime=new Date().getTime();
};
SingleTapDetector.prototype.onTouchMove=函数(事件){
this.currentX=event.touch[0].clientX;
this.currentY=event.touchs[0].clientY;
};
SingleTapDetector.prototype.onTouchEnd=函数(事件){
var=这个;
//在这个序列中已经有一个或多个点击了吗?
如果(此.tapTimer){
//重置计时器以捕获此序列中的任何其他抽头
clearTimeout(这个.tapTimer);
this.tapTimer=setTimeout(函数(){
tapTimer=null;
}, 300);
}否则{
//确保用户没有移动太多
如果(Math.abs(this.currentX-this.startX)<4&&
Math.abs(this.currentY-this.startY)<4){
//确保这不是一个漫长的新闻

如果(new Date().getTime()-this.startTime不需要为此使用Javascript,那么当UIgestureRecognitizerDelegate具有足够的方法时,这就太过分了。您需要做的只是确保在进行文本选择时,不会触发点击识别器

- (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;
}

这就解决了文本选择问题,而且链接应该可以正常工作(至少对我来说是这样)。

谢谢!这对我很有帮助!