2015-02-09 34 views
7

OK, więc problem, przed którym stoję, polega na tym, że moja przeglądarka Firefox nie pobiera prawidłowych wartości dla window.innerWidth, document.documentElement.clientWidth, ani nawet o szerokości div, zaprojektowanej do przejęcia całego okna klienta po wczytaniu strony.Zła wartość dla window.innerWidth podczas zdarzenia onload w Firefoksie dla Androida?

Nie jestem szalona, ​​mój kod działa dobrze w każdej innej przeglądarce! Z jakiegoś powodu Firefox inicjuje te wartości z wartościami domyślnymi, a następnie pobiera poprawne wartości później. Jeśli w którymkolwiek momencie przerywam JavaScript przy pomocy alert(), te właściwości będą magicznie później poprawne.

Przeszukałem internet, szukając odpowiedzi, a jedyne, co mogę znaleźć, to obejście problemu: użyj window.setTimeout, aby opóźnić korzystanie z tych właściwości, dopóki nie będą miały czasu na wypełnienie. To jest szalone! Użytkownicy oczekują szybkości, a nie dodatkowego opóźnienia, aby przeglądać moją witrynę w przeglądarce Firefox.

Nie rozumiem, że mogę ustawić div, aby wypełnić okno klienta idealnie, zanim wartości staną się dokładne. Robię to w css, ustawiając szerokość i wysokość identyfikatora div na 100%. document.documentElement jest w zasadzie taki sam jak document.getElementById("my_div"); po załadowaniu wszystkich elementów dokumentu, więc w jaki sposób przeglądarka wie, jak duży powinien być div, gdy nie ma on właściwych wymiarów okna klienta?

Próbowałem uruchomić mój kod wewnątrz window.addEventListener("load",function(event_){ //My Code });, ale nadal te wartości nie będą generowane. Czy istnieje zdarzenie ładowania strony przychodzące po window.onload?

Jeśli ktoś może mi powiedzieć, dlaczego tylko przeglądarka mobilna Firefoksa wydaje się wyświetlać to dziwne zachowanie, podam ci mentalną piątkę.

Oto kawałek kodu próbki do odtworzenia problemu:

<!DOCTYPE HTML> 
<html> 
    <head> 
     <!-- Added " after javascript during edit. --> 
     <script type="text/javascript"> 
      window.addEventListener("load",function(event_){ 
       var output=document.getElementById("output"); 
       /* Returns some default value like 980. */ 
       output.innerHTML=window.innerWidth; 

       alert("After this alert, the value will change."); 
       /* Returns an accurate value like 511. */ 
       output.innerHTML=window.innerWidth; 
      }); 
     </script> 
     <!-- Added title during edit. --> 
     <title>Title</title> 
    </head> 
    <body> 
     <p id="output">Default Output</p> 
    </body> 
</html> 

Mój Firefox dla systemu Android w wersji jest 35.0.1. Moja wersja Androida to 4.4.4. Na moim urządzeniu Firefox wyświetla "980" w wyjściowym elemencie p, pokazuje alert, a następnie ponownie wyświetla "980". Po odświeżeniu strony pierwsze dwa kroki pozostają takie same, ale wynik po ostrzeżeniu zmienia się na 360. Tak samo dzieje się z document.documentElement.clientWidth. Brak właściwości Próbuję uzyskać prawidłowe wartości. Wygląda na to, że Firefox ma pewne opóźnienie po wczytaniu strony, zanim uzyska dostęp do wymiarów okna klienta ...

Próbowałem wtyczki verge.airve.com bez JQuery, a początkowa informacja zwrotna pozostała na poziomie 980. Zainicjowano również jako 980 w Chrome, co było dziwne, ponieważ Chrome działał bez niego tak jak należy ...

Po długiej debacie znaleziono rozwiązanie! Firefox najwyraźniej zmienia rozmiar okna po jego załadowaniu (domyślam się, kto naprawdę wie)! Tak więc, dodając obsługę zdarzenia zmiany rozmiaru oprócz window.onload, ten problem można uniknąć! Zobacz akceptowaną odpowiedź poniżej, aby uzyskać więcej informacji.

+0

Czy można użyć zdarzenia zmiany rozmiaru zamiast obciążenia? – error

+1

Rozumiem, że zgodność przeglądarki może być frustrująca, ale czy mógłbyś wymyślić bardziej opisowy tytuł? –

+0

Nie jesteś szalony, nie pracowałeś z IE5! –

Odpowiedz

7

Upewnij się, że pomiar został wykonany po załadowaniu i zmianie rozmiaru całego dokumentu.

window.onload = showViewport; 
 
window.onresize = showViewport; 
 

 
function showViewport() { 
 
    var output=document.getElementById("output"); 
 
    var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 
 
    var height= Math.max(document.documentElement.clientHeight, window.innerHeight || 0) 
 
    output.innerHTML = "Viewport size is " + width + "x" + height; 
 
}
<body> 
 
    <p id="output">Default Output</p> 
 
</body>

+0

Słodki! Wygląda na to, że w Firefoksie wydarzenie "resize" wystrzeliło na zawsze, co jest dziwne. Twój kod zwraca prawidłowy rozmiar widoku wewnątrz zdarzenia zmiany rozmiaru, ale zmiana rozmiaru nie uruchamia się wcale w innych przeglądarkach ... Nie potrzebowałem używać 'Math.max', tylko' document.documentElement'. – Frank

+0

Właściwie to działa całkiem nieźle dla wszystkich moich przeglądarek! Sądzę, że to dziwne, że Firefox wystrzeliwuje to zdarzenie resize po window.load, ale myślę, że moja strona będzie musiała mieć obsługę zdarzenia zmiany rozmiaru. Działa to ładnie nawet podczas zmiany rozmiaru okna z metatagiem! Dziękuję Ci bardzo! – Frank

0

mogę potwierdzić ten problem, na przykład Firefox 38.0.1 na Androidzie 4.1.2. Utworzono js bin do celów testowych.

Chciałbym sprawdzić okno.innerWidth do niestandardowych manipulacji DOM w różnych rozdzielczościach (na urządzenia przenośne, tablety i komputery), więc ważne jest, aby uzyskać poprawną wartość window.innerWidth w dokumencie document.ready(), a nie tylko w window.load ().

$('#inline').html($(window).width()); 
 

 
$(document).ready(function() { 
 
    $('#ready').html(window.innerWidth); 
 
}); 
 

 
$(window).load(function() { 
 
    $('#load').html(window.innerWidth); 
 
}); 
 

 
setTimeout(function() { 
 
    $('#setTimeout').html(window.innerWidth); 
 
}, 1000);
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
 
    <title>JS Bin</title> 
 
</head> 
 
<body> 
 
    
 
    <p><span id="inline"></span></p> 
 
    <p>$(document).ready(): <span id="ready"></span></p> 
 
    <p>$(window).load(): <span id="load"></span></p> 
 
    <p>setTimeout(1000): <span id="setTimeout"></span></p> 
 
    
 
</body> 
 
</html>

(Chciałem tylko dodać komentarz, a nie odpowiedzieć, ale jeszcze nie reputacja to zrobić :-)

1

problem (innerWidth === 980) ustępuje dla przeglądarki Firefox 40.0 w systemie Android 4.4.4. Czas oczekiwania 1 ms to obejście. Wymienić

window.onload = myProgram;
przez

 window.onload = function() {setTimeout(myProgram, 1)};

W międzyczasie napotkał ten problem przy jednoczesnym dostosowaniu dość skomplikowaną stronę do małych ekranów. Firefox przestrzega CSS po "@media tylko ekranie i (max-szerokość: 768px)". Jednakże, gdy próbuje się ustawić programy obsługi zdarzeń w zależności od szerokości urządzenia, Firefox nie daje sobie rady. Potrzebowałem powyższej sztuczki z 0,5 sekundowym czekaniem we wszystkich miejscach, w których podniosłem szerokość urządzenia. Ten czas oczekiwania był konieczny dla Nexusa 7 (2012), ale kto wie, co jest potrzebne dla innych urządzeń?