2010-11-05 31 views
5

Soy bastante nuevo en javascript, pero han conseguido escribir una función de trabajo xml :)optimizar una función en Javascript

Yo estaba esperando que alguien podría por favor, dame un resumen de cómo optimizar la función. En la actualidad hay una función diferente para el clima de cada estado, pero esperaba poder simplificar esto de alguna manera.

Código se pega aquí: http://pastie.org/private/ffuvwgbeenhyo07vqkkcsw

Cualquier ayuda es muy apreciada. ¡Gracias!

EDIT: Agregar código ejemplos de ambos flujos XML:

Función 1 (UV): http://pastie.org/private/jc9oxkexypn0cw5yaskiq

Función 2 (tiempo): http://pastie.org/private/pnckz4k4yabgvtdbsjvvrq

+0

Estoy viendo un poco de duplicación, pero en cuanto a calidad, diría que es bastante buena para alguien que acaba de aprender el idioma. – ChaosPandion

+0

A * lote * de repetición. Además, definitivamente te toparás con restricciones de dominios cruzados si vas a intentar ejecutar ese código en cualquier sitio web que no sea el que te proporciona la información –

+0

¡Gracias! Sí, las funciones son básicamente las mismas entre ciudades, aparte del hecho de que son ciudades "diferentes" y requieren diferentes alimentaciones xml. El dominio cruzado afortunadamente no es un problema porque es para una aplicación web empaquetada para iPhone, por lo que estará funcionando desde un directorio local. – Nelga

Respuesta

1

Yo sugeriría crear una matriz que contiene los elementos identificadores de UV, sufijos y identificadores de estación meteorológica (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'}, 
    ... 
] 

y luego para el 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 

    }); 
} 

y para el tiempo

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

Todo funcionó muy bien, solo tuvo que cambiar + area.name a + area.id en la función UV para que funcione! – Nelga

0

Es necesario generalizar la función de modo que cada método puede apoyar cualquier ciudad. En este momento, no veo nada diferente entre lo que estás haciendo para Brisbane y Melbourne, por ejemplo. Las advertencias son iguales.

1

Esto debería darle suficiente para eliminar un montón de duplicaciones.

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

es cuestionable. #sydney significa un elemento con un atributo con valor de sydney que tiene el tipo de esquema ID. En HTML, el atributo id="..." tiene el tipo de esquema ID gracias al DOCTYPE. Pero este archivo XML no tiene DOCTYPE y, por lo tanto, sus atributos id="..." no tienen el tipo de esquema ID. En consecuencia, getElementById('sydney') no funcionará, y #sydney como selector no debería funcionar.

Funciona en la práctica porque cuando usa find() jQuery vuelve a su propio selector de JavaScript "Sizzle" JavaScript, que simplemente busca los atributos id="..." como si fuera HTML. Pero Sizzle es lento y no deberías confiar en este detalle de implementación. Usar el selector de atributo explícito location[id=sydney] es mejor para un documento XML.

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

Tiene una tarea superflua aquí. Utiliza la asignación aumentada += para agregar algo a sydneyuv, y luego asigna el resultado al sydneyuv nuevamente.

Además, generalmente es mejor no unir cadenas de HTML a partir de valores de entrada. ¿Qué pasa si uvindex tiene caracteres HTML especiales? (Probablemente no sea así, pero no hay nada que impida que el sitio que estás utilizando incluya). Sin el escape de HTML, tendrías inyecciones de HTML y posiblemente agujeros de seguridad XSS. Utilice siempre métodos de estilo DOM, como text() y attr() en jQuery, o el atajo de creación: var $sydneyuv= $('<span/>', {text: uvindex});, con preferencia al sling de cadena.

Esperaba poder simplificar esto de alguna manera.

Sure.Que sea impulsado por los datos:

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

ya se puede sustituir todos esos estados separados con un bucle:

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

y presumiblemente similar para que sea de un tiempo haciendo.

(que haría uso de la Identificación plena ciudad en los ID de documento HTML, por lo que no es necesario el hack shorttown.)

+1

¡Mi objetivo era dejar un poco de trabajo para que los OP hicieran para que aprendieran algo! * (¿A quién estoy engañando? No quería escribir todo eso ...) * – ChaosPandion

+0

heh. Todavía hay tiempo para hacer, me aburrí :-) – bobince

+1

¡Increíblemente útil para ver el código revisado y compararlo con el mío! No te preocupes, estoy aprendiendo mi trasero aquí! :) – Nelga

2

Una versión simplificada sería algo como esto:

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

El uso de un objeto para almacenar los mensajes, a continuación, una matriz para almacenar los nombres de las ciudades. Además, en lugar de utilizar esto:

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

Puede utilizar este lugar:

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

Y, por último, solicitando información XML entre dominios causará problemas. Vea si la API proporciona la información en formato JSONP. JSON también es (un poco) más fácil trabajar con JavaScript.

+0

Hmm, buen punto sobre el AJAX de origen cruzado. No sé cómo está funcionando el guión en este momento, dado que no debería ser así. – bobince

+0

Heya, todo funciona actualmente porque se está cargando desde una fuente local (aplicación web empaquetada como aplicación iphone). :) – Nelga

+0

Pero sí, tienes razón ... Planeo lanzar una versión de aplicación web, por lo que cuando se aloje, creo que ese problema se hará más evidente. – Nelga