2013-03-22 22 views
13

Aptalca bir soru sorma riski olsa da yine de denemeliyim.requirejs script'i çalıştırıyor progress

RequireJs yükleme bağımlılıkları yüklenirken bir ilerleme göstergesi görüntülemek mümkün mü? Örneğin

: Google aramalarında görünmedi orada bazı eklenti varsa

require(['jquery'], function($) { 

    // Well, jQuery loaded in quite some time due to a low-speed connection 
    // 
    // Or maybe I wanted to show an overlay to prevent user of clicking on UI widgets until the load is complete 
}); 

Ben RequireJS kaynağını değiştirerek başlamak istemiyoruz.

Yardımlarınız için teşekkürler.

cevap

8

Hayır, bu mümkün değil. RequrieJs, DOM'de yeni bir komut dosyası etiketi oluşturarak ve yük olayını dinleyerek modülü yükler. Başlangıç ​​ve son yükleme arasında güncelleme olayı yok. Yani, RequJ'nin değil DOM'nin bir kısıtlamasıdır.

+0

@explunit: Bu yanıta eklemek için bir şey, yorumunuz varsa. Cevabı düzenlemeyin. –

+0

Firebug veya Chrome dev araçlarındaki html baş bölgesini incelerseniz, RequireJs'in komut dosyaları ile ne yaptığını görebilir ve neden bir ilerleme göstergesinin bulunmasının mümkün olmadığını anlayabilirsiniz. – explunit

+0

Yardımlarınız için teşekkürler. Daha iyi bir yaklaşım düşünmeyi başardı - 'script yüklü' olayına güvenmek yerine bunu uygulama mantığına uygulayacağım. – crissdev

12

Çubuğun kendisi değil, bir döndürücü veya ilerleme göstergesi görüntülemek mümkündür. Ihtiyaçlarımın yükünü (şu anda yükleme veya boşta) alabilirim, ancak yüklenen/yüklenecek modüllerin% 'sini değil, çünkü bağımlılıkları her modül yüküne göre ayrıştırılır, ancak başlangıçta değil.

Ancak, her neyse, kullanıcı, en azından, basit bir çevirici ile, boş bir sayfadan çok daha iyi, kullanıcı beklerken.

Gereksinim duyulması gerekli değildir! Yani ..

biz

require.config({...}) 
require(["app"], function() { 

// main entry point to your hugde app's code 
}); 

ile dosya require.conf.js var varsayalım ve onu

<script data-main="require.conf" type="text/javascript" src="bower_components/requirejs/require.js"></script> 

Bu standard requirejs senaryodur kullanarak html ile yüklenir. en require.onResourceLoad denilen requirejs en fonksiyonunu yakalamak ve gerekli tüm büyü yapalım, en

<div id="requirejs-loading-panel"> 
    <div id="requirejs-loading-status"></div> 
    <div id="requirejs-loading-module-name"></div> 
</div> 

Tamam için göstergeyi ekleyelim. Her modül yükü üzerinde requirejs tarafından çağrılacak ve requirejs'in bağlamını dep tree ve diğer tüm personel ile birlikte geçirecektir. Requirejs'nin bir şey yükleyip yüklemediğini öğrenmek için içeriği kullanacağız. Zamanlanmış zamanlayıcı çağrısında yaptım çünkü onResourceLoad() yalnızca yükleme sırasında yüklenirken değil, yükleme sırasında çağrılır. Bu kod require.js.conf ilave edilmesi gerekmektedir:

require.onResourceLoad = function (context, map, depMaps) { 


    var loadingStatusEl = document.getElementById('requirejs-loading-status'), 
     loadingModuleNameEl = document.getElementById('requirejs-loading-module-name'); 
    var panel = document.getElementById('requirejs-loading-panel'); 

    if (loadingStatusEl && loadingModuleNameEl) { 


     if (!context) { // we well call onResourceLoad(false) by ourselves when requirejs is not loading anything => hide the indicator and exit 

      panel.style.display = "none"; 
      return; 
     } 

     panel.style.display = ""; // show indicator when any module is loaded and shedule requirejs status (loading/idle) check 
     clearTimeout(panel.ttimer); 
     panel.ttimer = setTimeout(function() { 


      var context = require.s.contexts._; 
      var inited = true; 
      for (name in context.registry) { 
       var m = context.registry[name]; 

       if (m.inited !== true) { 
        inited = false; 
        break; 
       } 

      } // here the "inited" variable will be true, if requirejs is "idle", false if "loading" 

      if (inited) { 
       require.onResourceLoad(false); // will fire if module loads in 400ms. TODO: reset this timer for slow module loading 
      } 

     }, 400) 
     if (map && map.name) { // we will add one dot ('.') and a currently loaded module name to the indicator 

      loadingStatusEl.innerHTML = loadingStatusEl.innerHTML += '.'; //add one more dot character 
      loadingModuleNameEl.innerHTML = map.name + (map.url ? ' at ' + map.url : ''); 
     } 
    } else { 


    } 


}; 

Bir problem şudur: Biz nedense çok modüller yüklemek için gereken nasıl bilemiyorum, bu yüzden yükleme ilerleme fiili% hesaplayamaz. Ancak, en azından bir şey yükleyip yüklemediğimizi (ve olayın şu anda modül adını yükleyip yüklemediğimizi) öğrenebilir ve bunu bir sinir kullanıcısına gösterebiliriz

+0

Teşekkürler. Bunu bir süre önce kullanırdım ve belki de gelecekteki gelişim için kullanacağım. – crissdev

+0

Burada bir hata var, sanırım: eğer (init! == true) m.inited olmalı! == true. Neden başka bir şeye ihtiyacın var? – Pietrko

+0

Başka bir şey: son modül yükleri ve son zamanlayıcı ayarlandığında durumu ele alalım. Eğer modül 400 ms sonra hala yükleniyorsa? O zaman asla need.onResourceLoad (false) 'ı alamıyoruz. – Pietrko

10

v. 2.1.19 RequireJS, onNodeCreated config özelliğine sahiptir. Buna bir işlev atarsanız, bir modül yüklemek için bir belgeye <script> öğesinin eklendiği her seferinde bu işlev çağrılır. Bu işlev node, config, moduleName ve url argümanlarıyla sağlanacaktır. Olay dinleyicilerini node'a ekleyerek, komut dosyasının ne zaman yüklenip yüklenmediğini algılayabilirsiniz.süreci yükleme başlar ve durur ve kullanıcıları bilgilendirmek için bu bilgileri kullanabilirsiniz zaman

Şimdi algılayabilir:

require.config({ 
    /* ... paths, shims, etc. */ 
    onNodeCreated: function(node, config, moduleName, url) { 
    console.log('module ' + moduleName + ' is about to be loaded'); 

    node.addEventListener('load', function() { 
     console.log('module ' + moduleName + ' has been loaded'); 
    }); 

    node.addEventListener('error', function() { 
     console.log('module ' + moduleName + ' could not be loaded'); 
    }); 
    }, 
}); 

IE < 9 için olay dinleyicileri eklemek için ek kod gerekiyordu.

Not: bu yalnızca RequireJS tarafından talep edilen modüller için geçerlidir. Eklentiler (requirejs/text ve benzeri) her biri kendi yükleme mekanizmasını kullanır ve onNodeCreated'u tetiklemez. Bazı tetik onXhr ve onXhrComplete olsa, bu yüzden de onları işleyebilir:

require.config({ 
    /* ... paths, shims, etc. */ 
    config: { 
    text: { 
     onXhr: function(xhr, url) { 
     console.log('file ' + url + ' is about to be loaded'); 
     }, 
     onXhrComplete: function(xhr, url) { 
     console.log('file ' + url + ' has been loaded'); 
     } 
    } 
    } 
}); 
+0

Teşekkürler @keleran. [Subresource Integrity] 'i (https://w3c.github.io/webappsec-subresource-integrity/) desteklemek için işlevsellik eklendi (https://github.com/jrburke/requirejs/issues/1361 adresine göre) – crissdev