2010-11-16 3 views
7

Sto lavorando per avere un elenco a selezione multipla in cui è possibile avere elementi selezionati e quindi fare clic su un pulsante "Su" o "Giù" che ti consentirà di riordinare tali elementi all'interno dell'elenco.Perché questo javascript è così lento in IE quando tutto ciò che fa è modificare un elenco di selezione?

Ho un semplice esempio autonomo:

<html> 
    <head> 
     <title>Example</title> 
    <script src="https://www.google.com/jsapi"></script> 
    <script> 
     google.load('jquery', '1.4.1'); 
    </script> 
    </head> 
    <body> 
     <select id="selectedDataPoints" multiple="multiple"> 
      <option>Pig</option> 
      <option>Duck</option> 
      <option>Dog</option> 
      <option>Zebra</option> 
      <option>Snake</option> 
      <option>Giraffe</option> 
      <option>Cow</option> 
     </select> 
    <input type="button" id="btnReorderUp" value="Up" /> 
    <input type="button" id="btnReorderDown" value="Down" /> 
    </body> 
</html> 

<script type="text/javascript"> 
    var DataPointSelector = (function() { 

    var $selectedList = $('#selectedDataPoints'); 

     $('#btnReorderUp').click(function(e) { 
      moveUp(); 
      e.preventDefault(); 
     }); 

     $('#btnReorderDown').click(function(e) { 
      moveDown(); 
      e.preventDefault(); 
     }); 

    function moveUp() { 
      var select = $selectedList[0]; 
      for (var i = 1, n = select.options.length; i < n; i++) 
       if (select.options[i].selected && !select.options[i - 1].selected) 
       select.insertBefore(select.options[i], select.options[i - 1]); 
     } 

     function moveDown() { 
      var select = $selectedList[0]; 
      for (var i = select.options.length - 1; i > 0; i--) 
       if (select.options[i].selected && !select.options[i + 1].selected) 
        select.insertBefore(select.options[i + 1], select.options[i]);   
     } 

    }()); 
</script> 

Tuttavia, il pulsante Su/Giù prende letteralmente 3-8 secondi per entrare in vigore in IE7/8. Il primo clic sarà talvolta veloce, ma dopo ci vorrà molto tempo affinché l'elenco selezionato si aggiorni con le nuove posizioni (specialmente se hai selezionato un paio di elementi).

Questo problema non è presente in Chrome/FF. Non avrei pensato che questo semplice riordino sarebbe stato così intenso!

Qualcuno ha qualche informazione che potrebbe essere utilizzata per aiutarmi ad accelerare le funzioni moveUp/moveDown ?!

+0

Ho passato attraverso quel codice e ci vuole tanto tempo. Sai se limita le risorse di sistema o qualcos'altro? –

+0

Ora, questo ti scioccherà, ma le prestazioni JavaScript di IE sono lente/scarse. – Powerlord

+0

bottom line: IE è lento. Francamente lo lascerei a quello; è un buon incentivo per le persone ad aggiornare se hanno prove evidenti che il loro browser fa schifo. (in tutta serietà, so che probabilmente non è un'opzione, e ti è stata data una soluzione funzionante, ma nei casi in cui è marginale la mia opinione è solo lasciare che gli utenti IE soffrano) – Spudley

risposta

4

Invece di spostare gli elementi DOM esistenti in giro, ricreare l'intero elemento <select> compresi tutti i bambini per IE.

2

IE è lento, lento, lento. Quindi dovresti controllare il tuo codice per minimizzare le operazioni non necessarie.

@Arron L'idea di Digulla è buona. Ma si potrebbe anche ridurre al minimo il tempo di processore dalle seguenti modifiche:

function moveUp() { 
    var select = $selectedList[0]; 
    for (var i = 1, n = select.options.length; i < n; i++) 
    var selected = select.options[i], 
     selectedPrior = select.options[i - 1]; 
     // Don't locate obj/array element more than once 
    if (selected.selected && !selectedPrior.selected) { 
     select.insertBefore(selected, selectedPrior); 
     break; // Since we have found the right elements, don't do 
    }  // any further checking 
    } 

Aggiunto: Hmmm, ora vedo che le voci multiple possono essere selezionate. Quindi è necessario spostare più oggetti, sì? In quel caso l'affermazione di rottura non è giusta.

Il layer IE UI ti cattura? - IE non tende ad aggiornare l'aspetto dello schermo finché il thread JS non è terminato. La soluzione alternativa è eseguire il timer con 0 sec. Ciò si tradurrà nel motore di rendering di IE e consentirà l'aggiornamento dello schermo.

+0

Sì, ho bisogno di consentire più elementi selezionati. Molto bene potrebbe essere il livello dell'interfaccia utente che mi intrappola. Stai dicendo che dovrei eseguire la funzione con un timer? – Markus

+0

Esegui del codice, quindi usa setTimeout per chiamare il prossimo blocco di codice. setTimeout consentirà l'aggiornamento dell'interfaccia utente di IE, quindi ti chiamerà. Vedi: http://stackoverflow.com/questions/787500/why-is-jquery-ajax-so-slow-on-ie7/787568#787568 –