2012-08-17 13 views
7

Sto lavorando a un'applicazione Windows 8 Metro e ho trovato (anche nelle applicazioni di esempio in cui non ho toccato il codice) che mentre navighi tra le pagine, il livello superiore " default.html "acquisisce ogni singolo file js e css mai caricato durante l'esecuzione dell'applicazione.WinJS non scarica js/css

Questo mi causa un sacco di mal di testa mentre il mio css si scontrano tra le diverse pagine. Mi manca qualcosa o si tratta di un bug grave?

risposta

13

Non scaricare JavaScript e CSS è stata una scelta deliberata, non un incidente o una svista.

Prima di tutto, capire che i controlli di pagina sono puramente una costruzione JavaScript - il motore del browser non ne ha assolutamente conoscenza. Il browser vede solo una porzione di DOM generata dinamicamente dagli script.

La piattaforma Web non consente di scaricare file di script: una volta caricati nel contesto, sono lì per sempre.

Con i CSS, avrebbero potuto provare a rimuovere i tag, ma si apre una lattina di worm. A seconda di quali pagine di ordine sono state indirizzate, potresti trovare diversi stili applicati nella stessa app. Cosa succede se due pagine si riferiscono allo stesso foglio di stile? Aggiungi lo stesso tag link due volte? E quale rimuovi?

È un disastro. Invece, WinJS garantisce che gli script e i fogli di stile verranno caricati una volta sola una volta, la prima volta che vengono referenziati. Quindi puoi avere ogni pagina nella tua app di riferimento "myStyles.css" e verrà caricata una sola volta (e ci sarà solo un tag di stile).

Quindi cosa fai per evitare i problemi che stai vedendo? Prima di tutto, ricorda che stai creando un'app, non un sito web che creerà arbitrariamente nuovi contenuti. Decidi i tuoi stili e classi generali. Metti lo stile condiviso nel file default.css e fai riferimento al file default.html.

Per le singole pagine, la cosa più semplice da fare è precedere gli stili con il nome della pagina. Invece di:

<div class='intro'></div> 

fare

<div class='page1-intro'></div> 

Poi avrete la garanzia di evitare collisioni.

Se si fa riferimento a elementi di pagina per ID, beh, non farlo. L'utilizzo di ID nelle pagine causa tutti i tipi di stranezze potenziali (cosa succede se si esegue il rendering dello stesso controllo di pagina due volte nello stesso momento? Inoltre, l'ID non esiste fino a dopo che la pagina è stata caricata nel DOM, che significa data-win- i riferimenti alle opzioni per ID non funzionano). Ma se insisti, ancora una volta, considera il prefisso degli id ​​con la pagina.

Fondamentalmente, impostare spazi dei nomi ad-hoc per impedirti di scontrarsi. È molto più facile che estrarre manualmente i tag di collegamento e porterà a un'esperienza dell'app molto migliore rispetto alla navigazione completa.

+0

I file di script non sono un problema, è facile nominare le funzioni per non scontrarsi o semplicemente usare WinJS.Namespace, i file css possono tuttavia essere scaricati e sembra che sarebbe sensato. Così com'è, sembra che tutti abbiano appena accettato che il namespace di tutte le classi di css è la strada da percorrere, che è davvero un hack totale ... Almeno è stato intenzionale ma a lungo termine sono sicuro che è un'altra cosa che MS sta andando per ottenere critiche per. – Endophage

+0

Non sono sicuro di quale sia il problema oltre a caricare i file CSS quando viene caricata ogni pagina. Gli esempi ti dicono di assicurarti di assegnare un nome alle pagine; ha senso. Probabilmente si potrebbe usare LESS/SCSS per aiutare con il namespacing, come con Web Essentials o Web Workbench. – kamranicus

3

Non è un bug, fa parte del modello di app predefinito utilizzato da WinJS tempaltes. I modelli WinJS predefiniti utilizzano un modello a pagina singola, il che significa che tutto il contenuto viene caricato nel file default.html utilizzando un PageNavigatorControl. Di conseguenza, c'è un singolo DOM in memoria in ogni momento. Se hai seguito un modello simile in un normale browser, vedresti lo stesso comportamento.

È possibile, se lo si desidera, utilizzare una navigazione più tradizionale utilizzando più pagine e collegamenti href tradizionali. Questo non è l'approccio consigliato, ma se stai cercando di portare le risorse web esistenti create usando quel modello, può rendere le cose più facili.

+0

ottengo il modello singola pagina, ho solo pensato che MS era un po 'più intelligente e le risorse di pagine interne scaricato quando si navigato lontano da loro. – Endophage

0

È possibile risolvere questo problema interrogando il documento per gli elementi link che importano gli stili e disattivando quelli che non si desidera. Devi assicurarti di non disabilitare i file MS CSS e il file default.css nel tuo progetto, supponendo che tu lo usi per definire gli stili comuni per la tua app.

Ecco un esempio che mostra come farlo. Questo è un file chiamato page2.html che, quando caricato dal metodo WinJS.Pages.UI.render localizzerà e disabiliterà gli elementi link che non desidera. Si assicura che il file page2.css sia abilitato e mantiene un elenco dei file che semplicemente ignora.

(Ho inserito questo nella funzione di gestione ready, ma io tendo ad utilizzare questa tecnica nel gestore per gli eventi WinJS.Navigation e mi baso sulla denominazione di file coerente per ottenere il risultato desiderato).

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8" /> 
    <title>UnloadCSS</title> 

    <!-- WinJS references --> 
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" /> 
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script> 
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script> 

    <!-- UnloadCSS references --> 
    <link href="/css/page2.css" rel="stylesheet" /> 

<script> 
    WinJS.UI.Pages.define("/page2.html", { 
     ready: function() { 

      var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"]; 
      var myCSS = "/css/page2.css"; 

      WinJS.Utilities.query("link").forEach(function (linkElem) { 
       if (linkElem.href.indexOf(myCSS) > -1) { 
        linkElem.disabled = false; 
       } else { 
        var ignore = false; 
        ignoreList.forEach(function (ignoreItem) { 
         if (linkElem.href.indexOf(ignoreItem) > -1) { 
          ignore = true; 
         } 
        }); 
        if (!ignore) { 
         linkElem.disabled = true; 
        } 
       } 
      }); 
     } 
    }); 
</script> 
</head> 
<body> 
    <button>Change </button> 
</body> 
</html> 
+0

Sì, so che potrei farlo in quel modo, ma è esattamente quello che sto cercando di evitare di dover usare hard code. Potrei semplicemente passare all'implementazione multi-pagina e non avere css per le singole parti, ogni pagina master sarà un modello, con tutti i css in un singolo file, quindi le sotto-pagine caricate non ne avranno nessuna il proprio css. – Endophage

0

questa potrebbe essere una buona soluzione con un aproach nomi di convenzione:

var currentPage = Application.navigator.pageControl.uri.replace("ms-appx://" + Windows.ApplicationModel.Package.current.id.name.toLowerCase(), ""); 
var currentCss = currentPage.replace(".html", ".css"); 

var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"]; 

WinJS.Utilities.query("link").forEach(function (linkElem) { 
    if (linkElem.href.toLowerCase().indexOf(currentCss) > -1) { 
     linkElem.disabled = false; 
    } else { 
     var ignore = false; 
     ignoreList.forEach(function (ignoreItem) { 
     if (linkElem.href.toLowerCase().indexOf(ignoreItem.toLowerCase()) > -1) { 
      ignore = true; 
     }}); 
     if (!ignore) { 
      linkElem.disabled = true; 
     } 
     } 
});