2010-11-05 11 views
5

ich Javascript ganz neu bin, aber haben es geschafft, eine Arbeits xml Funktion zu schreiben :)zu optimieren, um eine Funktion in Javascript

Ich hatte gehofft, jemand mir einen Überblick über geben bitte konnte, wie die Funktion zu optimieren. Gegenwärtig gibt es eine andere Funktion für das Wetter jedes Staates, aber ich hatte gehofft, dass ich das irgendwie vereinfachen könnte.

-Code wird hier eingefügt: http://pastie.org/private/ffuvwgbeenhyo07vqkkcsw

Jede Hilfe wird sehr geschätzt. Vielen Dank!

EDIT: Hinzufügen von Code Beispiele für beide XML-Feeds:

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

Funktion 2 (Wetter): http://pastie.org/private/pnckz4k4yabgvtdbsjvvrq

+0

Ich sehe einiges an Duplizierung, aber qualitativ würde ich sagen, dass es ziemlich gut für jemanden ist, der nur die Sprache lernt. – ChaosPandion

+0

A * Menge * Wiederholung. Außerdem werden Sie definitiv in domänenübergreifende Beschränkungen stoßen, wenn Sie tatsächlich versuchen, diesen Code auf einer anderen Website als der Website auszuführen, die Ihnen die Informationen zur Verfügung stellt. –

+0

Danke! Ja, die Funktionen sind im Grunde zwischen den Städten gleich - abgesehen davon, dass sie unterschiedliche Städte sind und unterschiedliche XML-Feeds erfordern. Cross-Domain ist zum Glück kein Problem, denn es ist für eine Webapp, verpackt für iPhone - so wird von einem lokalen Dir arbeiten. – Nelga

Antwort

1

Ich würde vorschlagen, dass Sie ein Array erstellen, das den IDs UV Element hält, Suffixe und Wetterstation-IDs (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'}, 
    ... 
] 

und dann für die 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 

    }); 
} 

und für die Wetter

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

Alles hat super funktioniert, musste nur + area.name zu + area.id in der UV-Funktion ändern, damit es funktioniert! – Nelga

0

Sie müssen die Funktion verallgemeinern, so dass jede Methode kann jede Stadt unterstützen. Im Moment sehe ich zum Beispiel nichts anderes zwischen dem, was du für Brisbane und Melbourne machst. Die Warnungen sind gleich.

1

Dies sollte Ihnen genug geben, um eine ganze Reihe von Duplikaten zu entfernen.

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') 

ist fraglich. #sydney bedeutet ein Element mit einem Attribut sydney, das den Schematyp ID hat. In HTML hat das id="..." Attribut den Schematyp ID dank dem DOCTYPE. Diese XML-Datei hat jedoch keinen DOCTYPE und daher haben die id="..." Attribute keinen Schematyp ID. Folglich getElementById('sydney') wird nicht funktionieren, und #sydney als Selektor sollte nicht funktionieren.

Es funktioniert in der Praxis, denn wenn Sie find() verwenden, greift jQuery auf seinen eigenen "Sizzle" JavaScript-Selektor Matcher zurück, der einfach nach id="..." Attributen sucht, als ob es HTML wäre. Aber Sizzle ist langsam und Sie sollten sich nicht auf dieses Implementierungsdetail verlassen. Die Verwendung des expliziten Attributselektors location[id=sydney] ist besser für ein XML-Dokument.

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

Sie haben hier eine überflüssige Aufgabe. Verwenden Sie die erweiterte Zuordnung +=, um etwas zu sydneyuv hinzuzufügen, und weisen Sie das Ergebnis erneut sydneyuv zu.

Außerdem ist es im Allgemeinen am besten, keine HTML-Strings aus Eingabewerten zusammenzufassen. Was passiert, wenn uvindex HTML-Sonderzeichen enthält? (Es wird wahrscheinlich nicht, aber es gibt nichts, das die Seite stoppt, die Sie davon abkratzen, sie einzuschließen.) Ohne HTML-Entweichen Sie würden HTML-Einspritzung und möglicherweise XSS Sicherheitslöcher haben. Verwenden Sie immer DOM-style-Methoden, wie text() und attr() in jQuery, oder die Erstellungsverknüpfung: var $sydneyuv= $('<span/>', {text: uvindex}); anstelle von String-Schlingen.

Ich hatte gehofft, ich könnte das irgendwie vereinfachen.

Sicher.Machen Sie es datengetriebener:

$.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; 
     } 
    }); 
}); 

und vermutlich ähnlich für was auch immer das Wetter jemandes tun:

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.'} 
]; 

Jetzt haben Sie alle diese unterschiedlichen Aussagen mit einer Schleife ersetzen.

(ich die volle Stadt ID in dem HTML-Dokument-IDs verwenden würde, so dass Sie den shorttown Hack nicht brauchen.)

+1

Mein Ziel war es, etwas Arbeit für das OP zu lassen, damit sie etwas lernen! * (Wen mache ich Witze? Ich wollte das alles nicht tippen ...) * – ChaosPandion

+0

heh. Es gibt immer noch das Wetter zu tun, mir wurde langweilig :-) – bobince

+1

Unglaublich hilfreich, um den überarbeiteten Code zu sehen und mit meinem eigenen zu vergleichen! Mach dir keine Sorgen, ich lerne hier meinen Arsch! :) – Nelga

2

Eine vereinfachte Version würde wie folgt aussehen:

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); 
      } 
     } 
    }); 
} 

ein Objekt Mit den Nachrichten zu speichern, dann ein Array mit den Namen der Städte zu speichern. Auch anstelle der Verwendung dieser:

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

Sie können dies stattdessen verwenden:

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

Und schließlich XML-Informationen Cross-Domain beantragt wird, zu Problemen führen. Prüfen Sie, ob die API stattdessen die Informationen im JSONP-Format bereitstellt. JSON ist auch (etwas) einfacher mit JavaScript zu arbeiten.

+0

Hmm, guter Punkt über den Ursprung AJAX. Ich weiß nicht, wie das Skript im Moment "funktioniert", angesichts dessen: Es sollte nicht sein. – bobince

+0

Heya, alles funktioniert derzeit, weil es von einer lokalen Quelle geladen wird (Webapp als iPhone App verpackt). :) – Nelga

+0

Aber yeah du hast Recht ... Ich plane, eine webapp-Version zu veröffentlichen, also wenn es gehostet wird, denke ich, dass dieses Problem offensichtlicher wird. – Nelga

Verwandte Themen