2013-03-06 2 views
11

Sto utilizzando iScroll sul mio sito Web di attivazione mobile (utilizzando iPhone qui) per scorrere all'interno di un div.iframe impedisce lo scorrimento di iScroll sul cellulare Safari

In questo questo div, ho un iframe con un'altezza fissa come questo:

<body> 
    <div id="iscroller"> 
    <iframe id="theIframe"></iframe> 
    Other stuff 
    </div> 
</body> 

Ora, durante lo scorrimento all'interno del div, tutto funziona come previsto, ma non riesco a scorrere quando il gesto di scorrimento comincia l'iframe.

Il problema è descritto qui abbastanza bene: https://github.com/cubiq/iscroll/issues/41

Così, ho usato la soluzione css da questo incarico, applicando pointer-events:none al iframe.

opere Ora scorrimento perfettamente ma non riesco a fare clic su qualsiasi link che vengono definite all'interno del iframe perché tutti click/toccare eventi sul iframe sembra essere bloccato a causa di pointer-events: none.

Così, ho pensato:

"Ok, mentre l'utente scorre, ho bisogno pointer-events:none Se è non scorrimento (e invece facendo clic), devo impostare pointer-events:auto al fine di lasciare il clic./passano gli eventi di tocco. "

Quindi ho fatto questo:

CSS

#theIframe{pointer-events:none} 

JavaScript

$("#theIframe").bind("touchstart", function(){ 
    // Enable click before click is triggered 
    $(this).css("pointer-events", "auto"); 
}); 

$("#theIframe").bind("touchmove", function(){ 
    // Disable click/touch events while scrolling 
    $(this).css("pointer-events", "none"); 
}); 

anche l'aggiunta di questo non funziona:

Indipendentemente da ciò che faccio: uno scorrimento non funziona o il collegamento all'interno dell'iframe non funziona.

Non funziona. Qualche idea?

risposta

10

Ho trovato la soluzione perfetta. Funziona alla grande su iOS e Android.

L'idea di base è mettere uno strato div in cima a quell'iframe. In questo modo lo scorrimento funziona senza intoppi.

Se l'utente vuole toccare/click su un elemento in quel iframe ho semplicemente prendere quel clic sul livello, salvare il coordinate x e y e innescare un evento click sul contenuto del iframe a queste coordinate:

HTML:

<div id="wrapper"> 
    <div id="layer"></div> 
    <iframe id="theIframe"></iframe> 
</div> 
Other stuff 

CSS:

#layer{ 
    position:absolute; 
    opacity:0; 
    width:100%; 
    height:100%; 
    top:0; 
    left:0; 
    right:0; 
    bottom:0; 
    z-index:2 
} 

JavaScript:

$('#layer').click(function(event){ 
    var iframe = $('#theIframe').get(0); 
    var iframeDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document; 

    // Find click position (coordinates) 
    var x = event.offsetX; 
    var y = event.offsetY; 

    // Trigger click inside iframe 
    var link = iframeDoc.elementFromPoint(x, y); 
    var newEvent = iframeDoc.createEvent('HTMLEvents'); 
    newEvent.initEvent('click', true, true); 
    link.dispatchEvent(newEvent); 
}); 
+3

non c'è altro modo per farlo? questo è un modo intelligente per farlo, ma io non ho il controllo sull'iframe, e se cambia im vite, grazie amico :) – jycr753

+0

@ jycr753 Se il tuo utente non ha bisogno di cliccare i collegamenti all'interno dell'iframe, potresti usare attributo css 'pointer-events: none' invece. – Timo

+0

Grazie ho apprezzato – jycr753

1

ho trovato una soluzione per questo, capita di essere vicino a quello che altri ragazzi già citati su GitHub, ma questo può essere utile per chi vuole trovare una risoluzione di lavoro veloce per questo problema.

Sto presupponendo alcune cose, come se ci fosse solo un contenitore di iscroll, qui rappresentato come ID. Questo non è adeguatamente testato e necessita di un refactoring. Si sta lavorando nel mio progetto, ma ho cambiato un po 'qui per l'esempio, ma credo che si potrebbero facilmente capire che cosa dovete fare:

var $iscroll = $('#iscroll'); 

document.addEventListener('touchstart', function(e) { 

if ($iscroll.find('iframe').length > 0){ 

    $.each($iscroll.find('iframe'), function(k,v){ 

     var $parent = $(v).parent().first(); 

     if ($parent.find('.preventTouch').length == 0){ 

      $('<div class="preventTouch" style="position:absolute; z-index:2; width:100%; height:100%;"></div>') 
       .prependTo($parent); 

     }; 

     $parent 
      .css('position', 'relative').css('z-index', 1); 

    }); 

    $iscroll.find('.preventTouch').on('click', function(e){ 
     e.preventDefault(); 
     e.stopPropagation(); 
     return false; 
    }); 

}; 

}; 

document.addEventListener('touchend', function(e) { 

if ($iscroll.find('iframe').length > 0){ 

    setTimeout(function(){ 

     var $iscroll = $('#iscroll'); 

     $iscroll.find('.preventTouch').remove(); 
     $iscroll.find('iframe').css('z-index', ''); 
     $iscroll.find('.preventTouch').off('click'); 

    }, 400); 

}; 

}; 

Grazie per la visita!