2011-12-13 9 views
6

Używam JavaScript do wykrywania krany na stronie mam pokazano w UIWebView, tak:Detect jeden kran w UIWebView, ale nadal wspierać wybór tekstu i linków

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

mam przechwytując linki z moim delegatem przeglądania stron internetowych i poszukaj "internal: // tap". Kiedy je otrzymam, uniemożliwiam przeglądanie stron internetowych i reaguję na dotknięcie. Jednak w ten sposób tracę możliwość wyboru tekstu. Kliknięcie linku nadal działa poprawnie.

W rzeczywistości samo dodanie detektora zdarzeń dla "kliknięcia" usuwa możliwość wyboru tekstu, nawet jeśli przewodnik nie próbuje zmienić lokalizacji dokumentu.

Każdy pomysł, co robię źle?

Odpowiedz

5

Wygląda na to, że po umieszczeniu detektora kliknięcia w elemencie nie można już wybierać tekstu w tym elemencie na iOS. Moje rozwiązanie polegało na wykryciu kranów za pomocą kombinacji zdarzeń touchstart, touchmove i touchend, wraz z zegarem, aby zignorować wielokrotne dotknięcia, oraz sprawdzenie aktualnego wyboru dokumentu, aby upewnić się, że zdarzenie wyboru się nie dzieje.

Oto kod JS użyłem:

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

Nie ma potrzeby używania Javascript za to, że to przesada, gdy UIGestureRecognizerDelegate posiada odpowiednie metody. Jedyne, co musisz zrobić, to upewnić się, że podczas wybierania tekstu, wykrywacz nie zostanie wyzwolony.

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

To dba o wybór tekstu, a linki i tak powinny działać dobrze (przynajmniej dla mnie).

+0

Dziękujemy! Pomogło mi to! –

Powiązane problemy