2010-11-16 53 views
7

Öğeleri seçebileceğiniz bir çoklu seçim listesi üzerinde çalışıyorum ve daha sonra bu öğeleri listenin içinde yeniden sıralamanıza izin veren bir "Yukarı" veya "Aşağı" düğmesini tıklatın.Neden bu javascript IE'de bu kadar yavaş çalışıyor?

basit bir müstakil örnek var:

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

Ancak Yukarı/Aşağı düğmesine IE7/8'de etkili olması için tam anlamıyla 3-8 saniye sürer. İlk tıklama bazen hızlı olacaktır ancak bundan sonra seçim listesinin yeni konumlarla güncellenmesi çok uzun zaman alacaktır (özellikle de birkaç öğeniz seçildiyse).

Bu sorun, Chrome/FF'de mevcut değil. Bu basit yeniden siparişin çok yoğun olacağını düşünmemiştim!

Hareket halindeyken/moveDown işlevlerini hızlandırmama yardımcı olacak herhangi bir bilgiye sahip olan var mı ?!

+0

Bu kodları döktüm ve bu kadar uzun sürmeli. Sistem kaynaklarını veya başka bir şeyi kapatıp kapatmadığını biliyor musunuz? –

+0

Şimdi, bu sizi şok edecek ama IE'nin JavaScript performansı yavaş/kötü. – Powerlord

+0

alt satır: IE yavaş. Açıkçası bende bırakırım; Tarayıcılarının berbat olduğunu gösteren kanıtlar varsa, kullanıcıların yeni sürüme geçmeleri için iyi bir teşvik oluşturur. (tüm ciddiyet içinde, bu muhtemelen bir seçenek değil, ve bir çalışma çözümü verildi, biliyorum ama marjinal olduğu durumlarda benim IE kullanıcıları acı çekmesine izin) – Spudley

cevap

4

Varolan DOM öğelerini etrafında taşımak yerine, IE için tüm çocukları da içeren <select> öğesinin tamamını yeniden oluşturun.

2

IE yavaş, yavaş, yavaş. Bu nedenle, gereksiz işlemleri en aza indirmek için kodunuzu kontrol etmelisiniz.

@Arron Digulla'nın fikri iyidir. Ama aynı zamanda aşağıdaki değişikliklerden işlemci süresini en aza indirmek olabilir:

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 
    } 

Eklendi: Hmmm, şimdi birden çok öğe seçilebilir görüyoruz. Öyleyse birden fazla eşya taşıman gerekiyor mu? Bu durumda break ifadesi doğru değil.

IE UI katmanı sizi hapsediyor mu? - IE, JS iş parçacığı sona erinceye kadar ekranın görünümünü güncellememeye eğilimlidir. Çözüm, zamanlayıcıyı 0 saniye ile çalıştırmaktır. Bu, IE oluşturma motoruna ulaşacak ve ekranın güncellenmesini sağlayacaktır.

+0

Evet, seçili çoklu öğelere izin vermem gerekiyor. Beni tuzağa düşüren UI tabakası olabilir. Fonksiyonu bir zamanlayıcı ile çalıştırmamı mı söylüyorsun? – Markus

+0

Bazı kodlar çalıştırıyorsunuz, ardından bir sonraki kod kümesini çağırmak için setTimeout'u kullanıyorsunuz. setTimeout IE UI güncellemesine izin verecek, sonra sizi arayacaktır. Bakınız: http://stackoverflow.com/questions/787500/why-is-jquery-ajax-so-slow-on-ie7/787568#787568 –

İlgili konular