2012-01-31 23 views
22

Se si visita questa pagina sul dispositivo iPad sull'ultima versione di iOS è possibile seguire insieme.Webkit overflow scrolling CSS bug su iPad

http://fiddle.jshell.net/will/8VJ58/10/show/light/

ho due elementi con la nuova -webkit-trabocco a scorrimento: tatto; proprietà e valore applicato. L'area grigia della mano sinistra ha un sacco di contenuti e scorrerà in verticale o orizzontale. La destra scorrerà solo in orizzontale.

Se si avvia in orizzontale (aggiornamento in orizzontale) è possibile scorrere entrambe le aree con lo scorrimento dell'inerzia. Funziona alla grande. Ora capovolgi il tuo iPad in verticale e solo l'area della mano sinistra scorrerà. Questo è come previsto. Ma quando si ritorna al paesaggio l'area della mano destra non scorrerà più affatto, mentre l'area della mano sinistra è immobile.

È ovvio come interrompere questo problema, ma non sempre il contenuto è sufficiente per riempire l'area.

Quindi qualche idea?

Grazie in anticipo,
Will :)

risposta

15

Sono in realtà avendo lo stesso problema esatto. L'ho ridotto al fatto che influisce sui DIV il cui contenuto non richiede più lo scorrimento quando l'orientamento viene modificato.

Nel tuo esempio. Il DIV a destra scorre in orizzontale, non è necessario scorrere in verticale, ma è necessario scorrere nuovamente. Ho provato questo quando entrambi i DIV (sinistro e destro) devono scorrere indipendentemente dall'orientamento e non è un problema.

UPDATE:

Io in realtà sembra di aver risolto questo!

Il problema sembra essere un problema di temporizzazione. Durante il ridimensionamento, il contenuto interno non è abbastanza grande da giustificare lo scorrimento sul DIV esterno che ha overflow. Dopo sprecare un giorno su questo, ho finalmente si avvicinò con questo hack:

<div id="header" style="position:fixed; height:100px">Header</div> 
<div id="content" style="overflow: auto; -webkit-overflow-scrolling: touch"> 
    <div id="contentInner"> 
     content that is not long enough to always scroll during different orientations 
    </div> 
</div> 

Ecco la mia logica ogni volta che la pagina viene ridimensionata:

function handleResize() 
    { 
     var iHeight = $(window).height() - $("#header").height(); 

     // Height needs to be set, to allow for scrolling - 
     //this is the fixed container that will scroll 
     $('#content').height(iHeight - 10); 

     // Temporarily blow out the inner content, to FORCE ipad to scroll during resizing 
     // This is a timing issue where the inner content is not big enough during resize post orientation to require the outer DIV to scroll 
     $('#contentInner').height(1000); 

     // Set the heights back to something normal 
     // We have to "pause" long enough for the re-orientation resize to finish 
     window.setTimeout(delayFix, 10); 
} 

function delayFix() 
{ 
    var iHeight = $(window).height() - $("#header").height(); 

    // Inner divs force the outer div to always have at least something to scroll. This makes the inner DIV always "rubber-band" and prevents 
    // the page from scrolling all over the place for no reason. 
    // The height of the inner guy needs to be AT LEAST as big as the container and actually a nip bigger to cause the 
    // scrollable area to 'rubber band' properly 
    $('#contentInner').height(iHeight + 20); 

} 
+0

Mi sono completamente dimenticato di questa domanda, in realtà ho finito per capirlo, con la stessa identica soluzione. Avrei dovuto rimettere il codice qui, ti ho risparmiato un po 'di tempo, oops! Grazie però :) – will

+0

Trovato in un altro modo se qualcuno è interessato ... Qualsiasi commento benvenuto. Vedi sotto. –

+0

Questo funziona davvero alla grande. Peccato che il glitch debba essere lì in primo luogo. –

19

Venendo in ritardo con una simile, ma la soluzione più semplice.

var $el = $('.myElementClass'); 

function setOverflow(){ 
    $el.css({webkitOverflowScrolling: 'touch', overflow: 'auto'}); 
} 

function resizeHandler(){ 
    $el.css({webkitOverflowScrolling: 'auto', overflow: 'hidden'}); 
    setTimeout(setOverflow,10); 
} 

[EDIT] Guardi fuori, dopo aver sperimentato (molto), ho scoperto che display:none dichiarazioni sarà sicuramente pausa la funzione webkit-overflow-scrolling: touch. Non utilizzarlo mai su elementi (o genitori di elementi) che si suppone supportino lo scorrimento a sfioramento.

+0

Decisamente molto più semplice! Una leggera variazione su questo (attivare una classe CSS separata invece di modificare manualmente le proprietà) è meglio per il ripristino delle proprietà di overflow originali. – Krease

+0

Penso di averlo provato, ma sono tornato a impostare manualmente le proprietà. Non so perché. –

+0

Grazie !! Ho avuto lo stesso problema su ipad4. Questo l'ha risolto. Ho avuto la stessa idea di ProVega, ma questa soluzione sembra più pulita. Molte grazie! Mi hai salvato un po '!! –

2

Ho riscontrato lo stesso bug su iPhone, iPod e iPad. Questo non è limitato a quest'ultimo solo.

ho provato tutto quello che è stato suggerito di essere una soluzione, ma alla fine la combinazione dolce finito per essere staccando l'elemento, aggiungendo al suo contenitore ed esplicitamente assegnando la propria altezza mentre si fa questo, in questo modo:

$(window).on('orientationchange', function(){ 
    var el = $('.troublemaker').detach(), 
     elh = el.height(); 
    setTimeout(el.css({'height':elh+'px'}).appendTo('.container'), 50); 
}); 
4

Sono stato in grado di utilizzare una "correzione" nota per forzare un aggiornamento di iOS6 per correggere questo problema senza dover utilizzare setTimeout.

$(window).on('orientationchange', function() 
{ 
    var $elem=$('[selector]'); 
    var orgDisplay=$elem.css('display'); 
    $elem.css('display','none'); 
    $elem.get(0).offsetHeight; 
    $elem.css('display',orgDisplay); 
}); 
+0

Mi piace la soluzione di "commutazione" dello stato di visualizzazione sul cambio di orientamento. Mi sembra che ci voglia meno risorse del ricalcolare l'altezza. –

+0

Mi piace anche questa soluzione. Sfortunatamente, non ha funzionato per me direttamente. Era necessario un ulteriore 'setTimeout' dopo' orientationchange'. Ancora preferibile impostare l'altezza in modo esplicito. – WrongAboutMostThings

+0

Mille upvotes a voi. –