EDITAR: ¿También estoy siguiendo consejos si hay una mejor manera de hacerlo?

Tengo una página web que muestra una hoja de tiempo para que el usuario la complete. La hoja de tiempo es para un mes, por lo que tiene tantas filas en el mes y también 5 columnas de datos, horas normales, horas extendidas, horas de turno, días festivos y total.

Tengo una lista desplegable que permite al usuario seleccionar el cuadro de texto de mes y año.

Cuando seleccionan un mes, el código deshabilita las filas inferiores si no son necesarias debido a que no tienen 31 días como ejemplo. También establece el color de fondo de cada fila dependiendo de si es un fin de semana (en un color diferente) o no.

El problema es que cuando se selecciona el mes, tarda entre 3 y 4 segundos en ejecutar el código y es molesto para el usuario, ya que no saben lo que está sucediendo.

¿Hay alguna forma de mejorar esto que puedas ver? El código se muestra a continuación.

    $('[id$=lstMonth]').change(function() {
        MonthChange();
    });         
});

function MonthChange() {

    var month = parseInt($('[id$=lstMonth]').val())-1;
    var year = $('[id$=txtYear]').val();
    var daysInMonth = GetDaysInMonth(month, year);
    var day, dte, bgcolor;

    for(day=28; day<=31; day+=1) {
        if(day > daysInMonth)
            DisableRow(day);
        else
            EnableRow(day);
    }

    for(day=1; day<=daysInMonth; day+=1) {
        dte = GetDate(day, month, year);
        bgcolor = GetInputFieldColor(dte, false);
        SetBackgroundColor(day, bgcolor);
    }
}

function SetBackgroundColor(day, bgcolor) {
    var selector = '[id$=txtNormal' + day + ']';

    $(selector).css("background-color", bgcolor);
    $(selector).parent().css("background-color", bgcolor);

    selector = '[id$=txtExtended' + day + ']';
    $(selector).css("background-color", bgcolor);
    $(selector).parent().css("background-color", bgcolor);

    selector = '[id$=txtShift' + day + ']';
    $(selector).css("background-color", bgcolor);
    $(selector).parent().css("background-color", bgcolor);

    selector = '[id$=txtHoliday' + day + ']';
    $(selector).css("background-color", bgcolor);
    $(selector).parent().css("background-color", bgcolor);

    selector = '[id$=txtTotal' + day + ']';
    $(selector).css("background-color", bgcolor);
    $(selector).parent().css("background-color", bgcolor);
}

function DisableRow(day) {
    var selector = '[id$=txtNormal' + day + ']';

    $(selector).css("background-color", "red");
}

function EnableRow(day) {
    var selector = '[id$=txtNormal' + day + ']';

    $(selector).css("background-color", "blue");
}
0
Malcolm 27 jul. 2009 a las 11:08

6 respuestas

La mejor respuesta

Está utilizando todo su código, selectores de atributos sin especificar el tipo de elemento.

Esto no funciona bien, ya que todos se inspeccionan sus elementos DOM, por ejemplo:

También está utilizando endsWith [id $ = xxx] esto es realmente necesario para su caso ??

Consideraría reescribir su función SetBackgroundColor como esto también para facilitar la lectura:

function SetBackgroundColor(day, bgcolor) {
  var types = ['Normal', 'Extended', 'Shift', 'Holiday'];

  $.each(types, function(index, type){
    var selector = 'input[id$=txt' + type + day + ']'; // change input to your
                                                       // element type
                //'#txt' + type + day; or if you don't need the endsWith selector
    $(selector).css("background-color", bgcolor)
               .parent()
               .css("background-color", bgcolor);
    // 1 selector call, and using chaining
  });
}
1
CMS 27 jul. 2009 a las 07:59

Si todos los elementos que está seleccionando son del mismo tipo, prefije el selector de atributos. Esto acelerará el partido.

E.g

$('input[id$=something]')
0
redsquare 27 jul. 2009 a las 07:59
bgcolor = GetInputFieldColor(dte, false);
SetBackgroundColor(day, bgcolor);

Sugeriría unir las funciones Get ... y Set ... en una, que obtiene solo los selectores DOM.

0
Thevs 27 jul. 2009 a las 07:54

Usaría el generador de perfiles en Firebug para ver dónde se pasa el tiempo en el código. Aquí hay otro hilo con alguna explicación sobre cómo usarlo.

0
Community 23 may. 2017 a las 12:19

¿Supongo que los campos que tienen el prefijo txt son todos cuadros de texto? Entonces, sus selectores CSS serán mucho más eficientes si especifica un nombre de etiqueta para el elemento que debe buscarse con la ID propuesta. Algo como esto:

selector = 'input[id$=txtExtended' + day + ']';

Y luego encadene las diferentes operaciones para que obtenga cada elemento solo una vez, como CMS propone en su respuesta.

El problema al especificar que no hay nombre de etiqueta es que jQuery tiene que buscar todos los elementos y verificar si su atributo de identificación corresponde al selector. Si especifica un nombre de etiqueta, se puede usar getElementsByTagName y solo se recuperarán los elementos que tengan el nombre de etiqueta especificado.

Otro aumento de rendimiento es buscar el elemento dado como hijo de otro elemento. Puede compararlo con especificar un cierto 'rango' en el que jQuery debe buscar todos los elementos que coincidan con el selector dado de esta manera:

$('input[id$=txtExtended' + day + ']', $element);

Si esto no aumenta el rendimiento lo suficiente, podría publicar el fragmento de HTML de una determinada fila, sería más fácil ver dónde se encuentra el problema de rendimiento.

1
Peter Eysermans 27 jul. 2009 a las 08:03
function SetBackgroundColor(day, bgcolor) {
        var selector = '[id$=txtNormal' + day + ']';    
        $(selector).css("background-color", bgcolor);
        $(selector).parent().css("background-color", bgcolor);
}

=>

function SetBackgroundColor(day, bgcolor) {
        var selector = '#txtNormal' + day;
        var obj = $(selector);
        obj.css("background-color", bgcolor);
        obj.parent().css("background-color", bgcolor);
}

Hay muchos consejos sobre cómo mejorar el rendimiento de jQuery.

2
Arnis Lapsa 27 jul. 2009 a las 07:12