2011-12-13 9 views
6

estoy usando JavaScript para detectar grifos en una página que estoy mostrando en un UIWebView, así:solo toque en UIWebView, pero aún así apoyar la selección de texto y enlaces

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

estoy interceptando enlaces con mi delegado de vista web, y busque "interno: // toque". Cuando lo consigo, impido que la vista web se navegue y respondo al toque. Sin embargo, al hacerlo, pierdo la capacidad de seleccionar texto. Al tocar el enlace todavía funciona correctamente.

De hecho, si agrega un detector de eventos para 'clic', se elimina la capacidad de seleccionar texto, incluso si el controlador no intenta cambiar la ubicación del documento.

¿Alguna idea de lo que estoy haciendo mal?

Respuesta

5

Aparentemente, si pone un oyente clic en un elemento, ya no puede seleccionar texto dentro de ese elemento en iOS. Mi solución fue detectar los grifos usando una combinación de eventos touchstart, touchmove y touchend, junto con un temporizador para ignorar los multiples toques, y verificar la selección actual del documento para asegurarme de que no ocurra un evento de selección.

Aquí está el código JS utilicé:

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

No hay necesidad de utilizar Javascript para esto, que es una exageración cuando el UIGestureRecognizerDelegate tiene métodos adecuados. Todo lo que necesita hacer es asegurarse de que cuando se realiza la selección de texto, el reconocedor de tap no se active.

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

Eso se encarga de la selección del texto, y los enlaces deberían funcionar bien de todos modos (al menos lo hacen para mí).

+0

¡Gracias! ¡Me ayudó! –

Cuestiones relacionadas