2012-05-17 23 views
6

IE 8'de Yığın Taşması hatasına neden olan basit bir işlev var. Sorun IE 7 veya 6'yı test etmeme rağmen başka bir tarayıcıda görünmüyor.Neden jQuery işlevim IE 8'de 'Yığın Taşması' hatasına neden oluyor?

Tam hata şu şekildedir: -

SCRIPT28: Out of stack space 
jquery.min.js, line 2 character 7498 
SCRIPT2343: Stack overflow at line: 2 

söz konusu işlevi:

:

function switchImage(size, objid, prefix, fullimage){ 

    if(size !== 'full'){ 
     var image = prefix + size + '/' + size +'_' + fullimage; 
    } 
    else { 
     var image = prefix + size + '/' + fullimage; 
    } 

    $('#' + objid).data('type', size) 
     .append('<img id="preload" src="' + image + '" style="display:none;" />') 
      .find('#preload').load(function(){ 
       $('#' + objid).find('img').attr('src', image); 
       $(this).remove(); 
      }); 
} 

Bu işlevin amacını açıklayacak kullanım durumunda genel bir bakış vermek

Bir kullanıcı bir resmi yeniden boyutlandırdığında (jqueryUI yeniden boyutlandırma kullanılarak), genişlik/yükseklik başka bir işlevle karşılaştırılır.

Görüntü belli bir boyutta büyürse, görebileceğiniz gibi, gizli bir <img> öğesinin DOM'a, görüntünün daha yüksek çözünürlüklü bir sürümünün 'src' özniteliğine sahip olduğunu ekler (veya daha düşük) görüntü kullanıcı tarafından küçültülmüş olmasına ise.

dolu sonra görünür öğesinin src özniteliği güncellenir ve gizli eleman kaldırılır.

Bu kullanıcı boyutlandırır olarak görüntülerin mükemmel dinamik geçiş kanıtladı onları .... süreç boyunca görüntü kalitesi iyi tutmak

IE 8'de soruna neden olan sorunu çözmek için çalışıyorum görünmüyor. Bu işlev kaldırıldığında hata oluşmaz ve hata mevcut olsa da işlev gerektiği gibi çalışır (her ne kadar IE'de performansın yeniden boyutlandırılmasına rağmen 8).

Herhangi bir yardım

büyük takdir.

GÜNCELLEME: aşağıdaki fonksiyonu yeniden yazarak orijinal sorunu çözmüş görünüyor: - Gördüğünüz gibi

function switchImage(size, objid, prefix, fullimage){ 

    var $el = $('#' + objid); 

    if(size !== 'full'){ 
     var image = prefix + size + '/' + size +'_' + fullimage; 
    } 
    else { 
     var image = prefix + size + '/' + fullimage; 
    } 

    $el.data('type', size); 

    $('<img id="preload" src="' + image + '" style="display:none;" />') 
     .appendTo($el) 
      .one('load', function(){ 
       $('#' + objid).find('img').attr('src', image); 
        $(this).remove(); 
       }); 
} 

, tek fark ben .appendTo kullanıyorum olmasıdır() yük olayının yalnızca bir kez oluştuğundan emin olmak için .append() yerine jQuery .one() yöntemini kullanın. Öğe doğrudan sonradan kaldırılsa da neden bunun bir fark yaratması gerektiğini anlamıyorum.

Gerçekten kimsenin bu yüzden gelecekte bu tür sorunları önlemek öğrenebilirsiniz bu konuda herhangi bir ışık tutabilir görmek için ilgi olacaktır. Şerefe. Eğer $(this).remove() olmasaydı

+0

JQuery'nin hatalı olmayan bir sürümünü kullandığınızda ne olur? En azından bu şekilde hata için daha anlamlı bir referans alırsınız. – RobG

+0

Aynı şey olur .... İnanıyorum ya da soruyu gönderdikten sonra beş dakika değil ... Bunu çözdüm. Ama neden hiçbir fikrim yok ... Soruyu güncelleyeceğim, çünkü bu küçük yeniden yazmanın neden bir fark yarattığını anlamak isterim. – gordyr

+0

@gordyr Bize bazı bağlam vermek için switchImage() işlevini çağıran kodu verebilir misiniz? –

cevap

3

Başlangıçtaki fonksiyonu sonsuz döngüye düz kaçardı. Esasen sen preload görüntünün kendisi de dahil olmak üzere tümimg etiketlerini src niteliğini batıyordu yaptıklarını. yürütme

Ben nitelik hem preload görüntüye ayarlandıktan sonra IE8'de, bu öncelikle 'yük' olay işleyicisi çağrılan olduğunu tahmin ediyorum

önce (sonsuz Firebug döngü console.log('loaded') ile $(this).remove() değiştirip izlemek) diğer tarayıcılar bu şekilde sonsuz bir döngü önlenir önyükleme görüntü, çıkarılması ilk sahip ilk tüm işlevi yerine bitmiş olabilir ancak, (bellek taşması açıklayan) $(this).remove() sonraki hattı.(Bu bir tahmin)

İlk sürüme bir maymun yaması sadece .find('img') yerine .find('img:not(#preload)') kullanmak olacaktır.

Düzeltme belgeniz de sonsuz döngüyü engeller, çünkü .one() yalnızca bir kez çalışmasını sağlar.

Ama sonuçta aşağıdaki işlevi planı ayrı olacaktır:

function switchImage(size, objid, prefix, fullimage){ 

    var $el = $('#' + objid), 
     $image = $el.find('img'), 
     $preload = $('<img>'); 

    if(size !== 'full'){ 
     var image = prefix + size + '/' + size +'_' + fullimage; 
    } 
    else { 
     var image = prefix + size + '/' + fullimage; 
    } 

    $el.data('type', size); 

    $preload 
     .on('load', function() { 
      $image.attr('src', image); 
     }) 
     .attr('src', image); 
} 

Ayrıca önceden yüklenen resim aslında açıkça amaca hizmet etmek DOM eklenecek gerekmez unutmayın.

İlgili konular