2010-11-05 36 views
5

功能我非常新的JavaScript,但已成功地編寫一個使用XML功能:)優化在Javascript

我希望有人能告訴我如何優化功能的破敗。目前,每個州的天氣都有不同的功能,但我希望我能以某種方式簡化它。

代碼被粘貼在這裏:http://pastie.org/private/ffuvwgbeenhyo07vqkkcsw

任何幫助是極大的讚賞。 謝謝!

編輯:BOTH XML的添加代碼實施例的資訊提供:

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

功能2(天氣):http://pastie.org/private/pnckz4k4yabgvtdbsjvvrq

+0

我看到相當多的重複,但質量明智我會說這是一個剛剛學習語言的人相當好。 – ChaosPandion 2010-11-05 01:23:47

+0

重複*很多*。此外,如果您要嘗試在除提供信息的網站以外的任何網站上運行該代碼,您肯定會碰到跨域限制 – 2010-11-05 01:33:09

+0

謝謝!是的,城市之間的功能基本相同 - 除了它們是「不同的」城市並需要不同的xml源。跨域是幸運的不是一個問題,因爲它是一個web應用程序,打包爲iPhone - 所以將從本地目錄工作。 – Nelga 2010-11-05 01:46:45

回答

1

我建議你創建包含UV元素ID,後綴數組和氣象站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'}, 
    ... 
] 

然後爲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 

    }); 
} 

併爲天氣

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

所有的工作都很好,只需在UV功能中將+ area.name改爲+ area.id即可使其工作! – Nelga 2010-11-30 02:17:59

0

你需要概括函數,使得每個方法可以支持任何城市。例如,現在我看不出你在爲布里斯班和墨爾本做什麼之間有什麼不同。警告是一樣的。

1

這應該足以讓你消除大量的重複。

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

是值得商榷的。 #sydney表示具有值爲sydney的屬性的元素具有模式類型ID。在HTML中,由於DOCTYPE,id="..."屬性的架構類型爲ID。但是這個XML文件沒有DOCTYPE,因此它的id="..."屬性沒有模式類型ID。因此getElementById('sydney')將不起作用,並且作爲選擇器的#sydney不應起作用。

它在實踐中有效,因爲當您使用find()時,jQuery會迴歸到它自己的'Sizzle'JavaScript選擇器匹配器,它只需查找id="..."屬性就好像它是HTML一樣。但是Sizzle很慢,你不應該依賴這個實現細節。使用顯式屬性選擇器location[id=sydney]對於XML文檔更好。

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

你在這裏有一個多餘的任務。您使用增強作業+=將某些內容添加到sydneyuv,然後再將結果分配給sydneyuv

此外,通常最好不要將來自輸入值的HTML字符串拼接在一起。如果uvindex中包含HTML特殊字符怎麼辦? (它可能不會,但沒有什麼能阻止你將它包括在內的網站)。沒有HTML轉義,你會有HTML注入和潛在的XSS安全漏洞。始終使用DOM風格的方法,例如jQuery中的text()attr(),或創建快捷方式:var $sydneyuv= $('<span/>', {text: uvindex});,而不是字符串吊銷。

我希望我能以某種方式簡化它。

當然。讓數據驅動的:

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

現在你可以用一個循環替換所有這些單獨的語句:

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

想必類似的,無論天氣如何一個人做的。

(我使用完整的城鎮ID在HTML文檔的ID,所以你不需要shorttown黑客攻擊。)

+1

我的目標是爲OP做點工作,讓他們學到一些東西! *(我是誰在開玩笑,我不想輸入所有這些......)* – ChaosPandion 2010-11-05 01:53:48

+0

heh。還有天氣要做,我感到無聊:-) – bobince 2010-11-05 01:56:26

+1

非常有幫助看到重做的代碼,並與我自己比較!別擔心,我在這裏學習我的屁股! :) – Nelga 2010-11-05 01:57:51

2

的簡化版本會是這個樣子:

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

使用對象來存儲信息,然後一個數組來存儲城市的名字。此外,而不是使用這樣的:

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

您可以使用它代替:

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

最後,請求XML信息跨域會引起問題。查看API是否以JSONP格式提供信息。 JSON也可以(稍微)更輕鬆地使用JavaScript。

+0

嗯,關於交叉AJAX的好點。我不知道腳本現在是如何「運行」的,因爲它不應該這樣。 – bobince 2010-11-05 02:03:02

+0

Heya,目前所有的工作都是從本地源碼加載(webapp打包爲iPhone應用程序)。 :) – Nelga 2010-11-05 02:12:43

+0

但是是的,你是對的......我打算髮佈一個webapp版本,所以當它被託管時,我想這個問題會變得更加明顯。 – Nelga 2010-11-05 02:13:23