2012-01-31 10 views
22

Jeśli odwiedzasz tę stronę na swoim urządzeniu iPad w najnowszej wersji iOS, możesz śledzić dalej.Przepełnienie przycisku przewijania Webkit Błąd CSS na iPadzie

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

że dwa elementy z nowym -webkit przepełnienia przewijania: dotyku; zastosowana właściwość i wartość. Obszar po lewej stronie ma dużo treści i będzie przewijany w układzie pionowym lub poziomym. Prawo będzie tylko przewijać w poziomie.

Jeśli zaczniesz krajobraz (odświeżanie w poziomie), możesz przewijać oba obszary za pomocą przewijania bezwładności. Działa świetnie. Odwróć iPada do portretu i przewiń tylko obszar lewej ręki. To jest zgodnie z przeznaczeniem. Ale kiedy wrócisz do krajobrazu, obszar prawej ręki nie będzie już w ogóle przewijał, podczas gdy obszar lewej dłoni będzie w porządku.

To oczywiste, jak temu zapobiec, ale nie zawsze mam zawartość, aby wypełnić obszar.

Jakieś pomysły?

Dzięki z góry,
Will :)

Odpowiedz

15

ja faktycznie mający dokładnie ten sam problem. Zawęziłem to do faktu, że wpływa na DIV, których treść nie wymaga już przewijania, gdy orientacja jest zmieniona.

W twoim przykładzie. DIV z prawej strony przewija się w pejzażu, NIE POTRZEBUJE przewijać portretu, ale potem musi przewijać ponownie. Przetestowałem to, gdy oba DIV (lewy i prawy) muszą przewijać niezależnie od orientacji i nie stanowi to problemu.

AKTUALIZACJA:

Rzeczywiście, naprawiłem to!

Problem wydaje się być problemem z czasem. Podczas zmiany rozmiaru wewnętrzna zawartość nie jest wystarczająco duża, aby zapewnić przewijanie na zewnętrznym DIV, który ma przepełnienie. Po marnować dzień na to, w końcu wpadł na ten 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> 

Oto moja logika, gdy strona zmienia rozmiar:

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

Całkowicie zapomniałem o tym pytaniu, tak naprawdę znalazłem to samo, z takim samym rozwiązaniem jak ty. Powinienem był umieścić kod z powrotem tutaj, zaoszczędziłem ci trochę czasu, oops! Dzięki jednak :) – will

+0

Znaleźć inny sposób, jeśli ktoś jest zainteresowany ... Wszelkie komentarze mile widziane. Zobacz poniżej. –

+0

To naprawdę działa świetnie. Szkoda, że ​​błąd musi tam być. –

19

Coming późno z podobną, ale prostsze rozwiązanie.

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

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

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

[EDIT] Uważaj, po eksperymenty (dużo), okazało się, że display:none deklaracje pewnością przerwa funkcja webkit-overflow-scrolling: touch. Nigdy nie używaj go na elementach (lub rodzicach elementów), które mają obsługiwać przewijanie dotykiem.

+0

Zdecydowanie o wiele prostsze! Niewielka różnica w tym (przełączanie oddzielnej klasy css zamiast ręcznego modyfikowania właściwości) jest lepsza dla przywracania oryginalnych właściwości przepełnienia. – Krease

+0

Myślę, że też tego próbowałem, ale wróciłem do ręcznego ustawiania właściwości. Nie pewny dlaczego. –

+0

Dzięki! Miałem ten sam problem na iPadzie4. To naprawiło to. Miałem taki sam pomysł jak ProVega, ale to rozwiązanie wydaje się czystsze. Wielkie dzięki! Uratowałeś mi trochę czasu !! –

2

Doświadczyłem tego samego błędu na iPhonie, iPodzie i iPadzie. Nie dotyczy to tylko tych drugich.

Próbowałem wszystkiego, co sugerowano się być rozwiązaniem, ale ostatecznie słodka kombinacja zakończył się odłączenie elementu, dołączając go do pojemnika i wyraźnie przypisując mu własną wysokość podczas gdy to robi, tak jak poniżej:

$(window).on('orientationchange', function(){ 
    var el = $('.troublemaker').detach(), 
     elh = el.height(); 
    setTimeout(el.css({'height':elh+'px'}).appendTo('.container'), 50); 
}); 
4
Udało mi się użyć znanej "poprawki", aby wymusić odświeżenie systemu iOS6 w celu rozwiązania tego problemu bez konieczności korzystania z funkcji 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

Podoba mi się rozwiązanie "przełączania" stanu wyświetlania przy zmianie orientacji. Mam wrażenie, że zajmuje mniej zasobów niż przeliczenie wysokości. –

+0

Podoba mi się również to rozwiązanie. Niestety nie zadziałało to bezpośrednio u mnie. Wymagane było dodatkowe 'setTimeout' po' orientationchange'. Jeszcze bardziej preferowane jest wyraźne ustawienie wysokości. – WrongAboutMostThings

+0

Tysiąc reboków dla ciebie. –

Powiązane problemy