2015-02-09 3 views
7

Ok, quindi, il problema che sto affrontando è questo: il mio browser mobile Firefox non sta recuperando i valori corretti per window.innerWidth, document.documentElement.clientWidth, o anche la larghezza di uno div in stile per occupare l'intera finestra client dopo il caricamento della pagina.Valore errato per window.innerWidth durante l'evento onload in Firefox per Android?

Io non sono pazzo, il mio codice funziona bene in ogni altro browser! Per qualche motivo, Firefox inizializza questi valori con i valori predefiniti e quindi ottiene i valori corretti in seguito. Se in qualsiasi momento interrompo il mio JavaScript con un alert(), queste proprietà diventano magicamente accurate in seguito.

Ho setacciato Internet per una risposta e tutto quello che riesco a trovare è una soluzione alternativa: utilizzare window.setTimeout per ritardare l'utilizzo di queste proprietà finché non hanno il tempo di compilare correttamente. È pazzesco! Gli utenti vogliono velocità, non un ritardo in più solo per visualizzare il mio sito su un browser Firefox.

Quello che non capisco è che posso impostare uno div fino a riempire perfettamente la finestra del client prima che i valori diventino precisi. Lo faccio in css impostando la larghezza e l'altezza dell'ID del mio div al 100%. document.documentElement è praticamente lo stesso di document.getElementById("my_div"); dopo che tutti gli elementi del documento sono stati caricati, quindi, come fa il browser a sapere quanto deve essere grande il div quando non ha le dimensioni corrette della finestra del client in primo luogo?

Ho provato a eseguire il mio codice all'interno di un window.addEventListener("load",function(event_){ //My Code }); ma ancora questi valori non verranno generati. C'è un evento di caricamento della pagina che viene dopo window.onload?

Se qualcuno può dirmi perché solo Firefox mobile sembra mostrare questo strano comportamento ti darò un cinque mentale.

Ecco un po 'di codice di esempio per ricreare il problema:

<!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> 

mio Firefox per la versione Android è 35.0.1. La mia versione di Android è 4.4.4. Sul mio dispositivo, Firefox visualizza "980" nell'elemento output p, mostra l'avviso, quindi visualizza nuovamente "980". Dopo l'aggiornamento della pagina, i primi due passaggi rimangono gli stessi, ma l'output dopo l'avviso diventa 360. Ciò accade anche con document.documentElement.clientWidth. Nessuna proprietà che cerco sembra avere i valori corretti. Sembra che Firefox abbia una sorta di ritardo dopo il caricamento della pagina prima che abbia accesso alle dimensioni della finestra del client ...

Ho provato il plugin verge.airve.com senza JQuery e il suo feedback iniziale è rimasto a 980. Inoltre è stato inizializzato come 980 su Chrome, il che era strano, perché Chrome funzionava come previsto senza ...

Dopo tanto dibattito è stata trovata una soluzione! Firefox sembra ridimensionare la finestra dopo che è stata caricata (immagino per buona misura, chi lo sa davvero)! Quindi, aggiungendo un gestore di eventi resize oltre a window.onload, questo problema può essere evitato! Vedi la risposta accettata sotto per maggiori dettagli.

+0

È possibile utilizzare l'evento di ridimensionamento anziché caricare? – error

+1

Capisco che la compatibilità del browser possa essere frustrante, ma potresti pensare a un titolo più descrittivo? –

+0

Non sei pazzo, non hai lavorato con IE5! –

risposta

7

Assicurarsi che la misurazione sia eseguita quando il documento intero viene caricato e ridimensionato.

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

Dolce! Apparentemente in Firefox l'evento "resize" scocca ultimo, il che è strano. Il tuo codice restituisce la dimensione corretta della viewport all'interno dell'evento di ridimensionamento, ma il ridimensionamento non si attiva affatto su altri browser ... Non ho bisogno di usare 'Math.max', solo' document.documentElement'. – Frank

+0

In realtà, questo funziona molto bene per tutti i miei browser! Penso che sia strano che Firefox firmi l'evento resize dopo window.load, ma suppongo che la mia pagina debba avere comunque un gestore di eventi resize. Funziona bene anche quando ridimensiona il viewport con un metatag! Grazie mille! – Frank

0

posso confermare il problema, ad esempio in Firefox 38.0.1 su Android 4.1.2. Creato un js bin a scopo di test.

Vorrei controllare la finestra.innerWidth per manipolazioni DOM personalizzate su diverse risoluzioni (mobile, tablet e dimensioni del desktop), quindi sarebbe importante ottenere il valore window.innerWidth corretto nello stato document.ready() e non solo nel 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>

(volevo solo aggiungere un commento, e non rispondere, ma non reputazioni ancora farlo :-)

1

Il problema (innerWidth === 980) persiste per Firefox 40.0 in Android 4.4.4. Un'attesa di 1 msec è un'elusione. Sostituire

window.onload = myProgram;
da

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

Nel frattempo ho incontrato questo problema adattandosi un sito abbastanza elaborato per schermi di piccole dimensioni. Firefox obbedisce al CSS seguendo "@media only screen e (max-width: 768px)". Tuttavia, quando si tenta di impostare gestori di eventi in base alla larghezza del dispositivo, Firefox fallisce miseramente. Avevo bisogno del trucco di cui sopra con 0,5 secondi di attesa in tutti i punti in cui ho rilevato la larghezza del dispositivo. Questo tempo di attesa era necessario per Nexus 7 (2012), ma chissà cosa è necessario per altri dispositivi?

Problemi correlati