2010-11-05 18 views
5

Sono abbastanza nuovo a JavaScript, ma sono riusciti a scrivere una funzione XML di lavoro :)ottimizzare un funzione in Javascript

Speravo che qualcuno potrebbe per favore mi dia una carrellata di come ottimizzare la funzione. Al momento c'è una funzione diversa per il tempo di ogni stato, ma speravo di poterlo semplificare in qualche modo.

codice viene incollato qui: http://pastie.org/private/ffuvwgbeenhyo07vqkkcsw

Qualsiasi aiuto è molto apprezzato. Grazie!

EDIT: l'aggiunta di codice esempi di entrambi feed XML:

Funzione 1 (UV): http://pastie.org/private/jc9oxkexypn0cw5yaskiq

Funzione 2 (tempo): http://pastie.org/private/pnckz4k4yabgvtdbsjvvrq

+0

Sto vedendo un bel po 'di duplicazione, ma per quanto riguarda la qualità, direi che è abbastanza buono per qualcuno che sta imparando la lingua. – ChaosPandion

+0

A * lotto * di ripetizione. Inoltre, hai sicuramente intenzione di imbatterti in restrizioni interdominio se hai intenzione di provare effettivamente a eseguire quel codice su qualsiasi sito web diverso dal sito che ti sta fornendo le informazioni –

+0

Grazie! Sì, le funzioni sono praticamente le stesse tra le città, a parte il fatto che sono città "diverse" e richiedono diversi feed xml. Il dominio incrociato non è fortunatamente un problema, perché è per una webapp, pacchetto per iphone, quindi funzionerà da una directory locale. – Nelga

risposta

1

vorrei suggerire di creare un array che contiene gli elementi UV ID, suffissi e ids stazione meteo (StationID)

var areas = [ 
    {id:'sydney',suffix:'syd',stationid:'YSSY'}, 
    {id:'melbourne',suffix:'mel',stationid:'YMML'}, 
    {id:'brisbane',suffix:'bri',stationid:'YBBN'}, 
    {id:'perth',suffix:'per',stationid:'YPPH'}, 
    ... 
] 

e quindi per la UV

// FUNCTION 1 - UV 
function getUV() { 

    // BEGIN AUSTRALIAN UV FUNCTION 

    $.get('http://www.arpansa.gov.au/uvindex/realtime/xml/uvvalues.xml', function(d) { 

     //SYDNEY UV 
      $(areas).each(function(){ 
      var area = this; 
     $(d).find('location#'+area.name).each(function(){ 

      var $location = $(this); 
      var uvindex = $location.find('index').text(); 

      var areauv = areauv += '<span>' + uvindex + '</span>' ; 
      $('#uv-'+area.suffix).empty().append($(areauv)); // empty div first 

      if (uvindex <= 2.0) { 
       $('#risk-'+area.suffix).empty().append('Low'); 
       $('#curcon-'+area.suffix).empty().append('You can safely stay outdoors and use an SPF 15 moisturiser.'); 
      } else if (uvindex <= 5.0) { 
       $('#risk-'+area.suffix).empty().append('Moderate'); 
       $('#curcon-'+area.suffix).empty().append('Wear protective clothing outdoors and use an SPF 15 or SPF 30 moisturiser.'); 
      } else if (uvindex <= 7.0) { 
       $('#risk-'+area.suffix).empty().append('High'); 
       $('#curcon-'+area.suffix).empty().append('Wear protective clothing, limit your time outdoors and use an SPF 30 moisturiser.'); 
      } else if (uvindex <= 10.0) { 
       $('#risk-'+area.suffix).empty().append('Very High'); 
       $('#curcon-'+area.suffix).empty().append('Use caution, limit exposure to the sun and use an SPF 30 moisturiser.'); 
      } else if (uvindex <= 20.0) { 
       $('#risk-'+area.suffix).empty().append('Extreme'); 
       $('#curcon-'+area.suffix).empty().append('Use extreme caution, avoid exposure to the sun and use an SPF 30 moisturiser.'); 
      } else { 
       $('#risk-'+area.suffix).empty().append('Unavailable'); 
       $('#curcon-'+area.suffix).empty().append('Information is currently unavailable.'); 
      } 

     }); 
      }); 

     // END OF AUSTRALIAN UV FUNCTION 

    }); 
} 

e per la tempo

function getWeather() { 

     // BEGIN AUSTRALIA and NEW ZEALAND WEATHER FUNCTION 
      $(areas).each(function(){ 
       var area = this; 
     $.get('http://api.wxbug.net/getLiveCompactWeatherRSS.aspx?ACode=XXXPRIVATEXXX&stationid='+area.stationid+'&unittype=1&outputtype=1', function(d){ 
     $(d).find('weather').each(function(){ 

      var $weatherinfo = $(this); 
      var degrees = $weatherinfo.find('temp').text().replace(/\.0$/i, ""); 
      var conditions = $weatherinfo.find('current-condition').text(); 
      var icon = $weatherinfo.find('current-condition').attr('icon').replace(/\.gif$/i, ".png").split('http://deskwx.weatherbug.com/')[1]; 

      var temperature = temperature += '<span>' + degrees + '</span>' ; 
      $('#temp-'+area.suffix).empty().append($(temperature)); 

      var winformation = winformation += '<span>' + conditions + '</span>' ; 
      $('#info-'+area.suffix).empty().append($(winformation)); 

      var wicon = wicon += '<img src="' + icon + '" alt="Weather Unavailable" />' ; 
      $('#icon-'+area.suffix).empty().append($(wicon)); 

     }); 
     }); 
      }); 
} 
+0

Tutto ha funzionato alla perfezione, è bastato cambiare + area.nome + area.id nella funzione UV per farlo funzionare! – Nelga

0

È necessario generalizzare la funzione in modo che ogni metodo può supportare qualsiasi città. Per ora non vedo nulla di diverso tra quello che stai facendo per Brisbane e Melbourne, per esempio. Gli avvertimenti sono gli stessi.

1

Questo dovrebbe darvi abbastanza per rimuovere un sacco di duplicati.

var lte2 = { risk: "Low", curcon: "You can safely stay outdoors and use an SPF 15 moisturiser." }, 
    lte5 = { risk: "Moderate", curcon: "Wear protective clothing outdoors and use an SPF 15 or SPF 30 moisturiser." }, 
    lte7 = { risk: "High", curcon: "Wear protective clothing, limit your time outdoors and use an SPF 30 moisturiser." }, 
    uvWarningMap = { 
     0: lte2, 
     1: lte2, 
     2: lte2, 
     3: lte5, 
     4: lte5, 
     5: lte5, 
     6: lte7, 
     7: lte7 
    }; 
7
$(d).find('location#sydney') 

è discutibile. #sydney indica un elemento con un valore stimato sydney con il tipo di schema ID. In HTML, l'attributo id="..." ha il tipo di schema ID grazie a DOCTYPE. Ma questo file XML non ha DOCTYPE e quindi gli attributi id="..." non hanno il tipo di schema ID. Di conseguenza, getElementById('sydney') non funzionerà e #sydney come selettore non dovrebbe funzionare.

Funziona in pratica perché quando si utilizza find() jQuery torna al proprio "Sizzle" selezionatore JavaScript Selector, che cerca semplicemente gli attributi id="..." come se fosse HTML. Ma Sizzle è lento e non dovresti fare affidamento su questi dettagli di implementazione. L'utilizzo del selettore di attributo esplicito location[id=sydney] è migliore per un documento XML.

var sydneyuv = sydneyuv += '<span>' + uvindex + '</span>' ; 

Hai qui un incarico superfluo. Utilizzare l'assegnazione aumentata += per aggiungere qualcosa a sydneyuv e quindi assegnare nuovamente il risultato a sydneyuv.

Inoltre, in genere è meglio non unire insieme stringhe di HTML dai valori di input. Cosa fare se uvindex contiene caratteri speciali HTML? (Probabilmente non lo farà, ma non c'è nulla che impedisca al sito che stai cercando di includerli.) Senza la funzione di escape dell'HTML potresti avere buchi di sicurezza in HTML-injection e potenzialmente XSS. Utilizza sempre metodi in stile DOM, come text() e attr() in jQuery, o la scorciatoia di creazione: var $sydneyuv= $('<span/>', {text: uvindex});, preferibilmente a slittamento delle stringhe.

Speravo di poterlo semplificare in qualche modo.

Sicuro.Rendono su dati:

var towns= ['sydney', 'melbourne', 'brisbane', 'perth', 'adelaide', 'darwin']; 
var uvlevels= [ 
    {uvlevel: 2, risk: 'Low',   curcon: 'You can safely stay outdoors and use an SPF 15 moisturiser.'}, 
    {uvlevel: 5, risk: 'Moderate', curcon: 'Wear protective clothing outdoors and use an SPF 15 or SPF 30 moisturiser.'}, 
    {uvlevel: 7, risk: 'High',  curcon: 'Wear protective clothing, limit your time outdoors and use an SPF 30 moisturiser.'}, 
    {uvlevel: 10, risk: 'Very high', curcon: 'Use caution, limit exposure to the sun and use an SPF 30 moisturiser.'}, 
    {uvlevel: 20, risk: 'Extreme',  curcon: 'Use extreme caution, avoid exposure to the sun and use an SPF 30 moisturiser.'}, 
    {uvlevel: null, risk: 'Unavailable', curcon: 'Information is currently unavailable.'} 
]; 

ora che è possibile sostituire tutte quelle dichiarazioni separate con un ciclo:

$.each(towns, function() { 
    var $location= $(d).find('location[id='+this+']'); 
    var uv= $location.find('index').text(); 
    var shorttown= this.slice(0, 3); 
    $('#uv-'+shortttown).empty().append($('<span/>', {text: uv})); 
    $.each(uvlevels, function() { 
     if (this.uvlevel===null || uv<=this.uvlevel) { 
      $('#risk-'+shorttown).text(this.risk); 
      $('#curcon-'+shorttown).text(this.curcon); 
      return false; 
     } 
    }); 
}); 

e presumibilmente simile per qualsiasi tempo uno sta facendo.

(userei l'ID piena città gli ID di documento HTML, quindi non è necessario il shorttown mod.)

+1

Il mio obiettivo era di lasciare un po 'di lavoro affinché l'OP facesse in modo che imparassero qualcosa! * (Chi sto prendendo in giro non volevo scrivere tutto questo ...) * – ChaosPandion

+0

heh. C'è ancora tempo da fare, mi sono annoiato :-) – bobince

+1

Incredibilmente utile vedere il codice rilavorato e confrontarlo con il mio! Non preoccuparti, sto imparando il mio culo qui! :) – Nelga

2

Una versione semplificata sarebbe simile a questa:

var cities = ['sydney', 'melbourne', 'brisbane', 'perth', 'adelaide', 'darwin'], 
    risks = { 
     2: { 
      risk: 'Low', 
      curcon: 'You can safely stay outdoors and use an SPF 15 moisturiser.' 
     } 
     5: { 
      risk: 'Moderate', 
      curcon: 'Wear protective clothing outdoors and use an SPF 15 or SPF 30 moisturiser.' 
     } 
     7: { 
      risk: 'High', 
      curcon: 'Use caution, limit exposure to the sun and use an SPF 30 moisturiser.' 
     } 
     10: { 
      risk: 'Very High', 
      curcon: 'Use caution, limit exposure to the sun and use an SPF 30 moisturiser.' 
     } 
     20: { 
      risk: 'Extreme', 
      curcon: 'Use extreme caution, avoid exposure to the sun and use an SPF 30 moisturiser.' 
     } 
    }; 

for(var i = 0; i < cities.length; i++){ 
    var shortCityName = cities[i].substring(0, 3); 

    $(d).find('location#sydney').each(function(){ 
     var $location = $(this); 
     var uvindex = parseInt($location.find('index').text(), 10); 

     $('#uv-' + shortCityName).html('<span>' + uvindex + '</span>'); 

     for(var i in risks){ 
      if(uvindex < risks[i]){ 
       $('#risk-' + shortCityName).html(risks[i].risk); 
       $('#curcon-' + shortCityName).html(risks[i].curcon); 
      } 
     } 
    }); 
} 

L'utilizzo di un oggetto per memorizzare i messaggi, quindi un array per memorizzare i nomi delle città. Inoltre, invece di utilizzare questo:

var wicon = wicon += '<img src="' + icon + '" alt="Weather Unavailable" />' ; 

È possibile utilizzare questo invece:

var wicon = $('<img /').attr({ 
    src: icon, 
    alt: 'Weather Unavailable' 
}); 

E, infine, la richiesta di informazioni XML cross-domain causerà problemi. Verifica se l'API fornisce invece le informazioni in formato JSONP. JSON è anche (leggermente) più facile da usare con l'uso di JavaScript.

+0

Hmm, buon punto sulla cross-origine AJAX. Non so come la sceneggiatura stia 'lavorando' al momento, dato che: non dovrebbe essere. – bobince

+0

Heya, tutto funziona attualmente perché viene caricato da una fonte locale (webapp impacchettato come app per iphone). :) – Nelga

+0

Ma sì, hai ragione ... Ho intenzione di rilasciare una versione webapp, quindi quando è ospitata, credo che il problema diventerà più evidente. – Nelga