dinamik - acara onload Javascript - bagaimana untuk mengetahui jika skrip sudah dimuat?


Bagaimana saya boleh menggunakan javascript untuk menentukan jika HTMLScriptElement telah dimuat sepenuhnya?

Bagaimana saya boleh menentukan jika skrip yang dimuatkan secara dinamik telah selesai dimuat tanpa menggunakan acara onload atau onreadystate change?

Kod adalah seperti berikut:

   TOOL.loadScript = function (url, callback, reappend, deepSearch) {
      var head, curr, child, tempScript, alreadyAppended, queue, 
      alreadyHandled, script, handler, loadFunc; 

      head = document.getElementsByTagName("head")[0];
      tempScript = document.createElement("script");
      tempScript.src = url;
      alreadyAppended = false;

      queue = []; 

      if (deepSearch) {
         // search entire document
         queue.push(document.firstElementChild);
      }
      else { 
         // just search the head element
         queue.push(head); 
      }

      while (queue.length !== 0) { 
         curr = queue.shift();

         // add child nodes to queue
         child = curr.firstElementChild; 
         if (child !== null && child !== undefined) { 
            queue.push(child);
            child = child.nextElementSibling;
            while (child !== null && child !== undefined) { 
               queue.push(child);
               child = child.nextElementSibling;
            } 
         }

         if (curr.tagName !== null && curr.tagName !== undefined) {
            if (curr.tagName.toLowerCase() === "script" && curr.src === tempScript.src) {
               script = curr;
               alreadyAppended = true;
               break;
            }
         }
      }

      if (!alreadyAppended) { 
         script = document.createElement("script");
         script.type = "text/javascript"; 
         script.async = true; 
         script.src = url; 
      } 

      alreadyHandled = false; 

      handler = function (event) {
         console.log("handling event..."); 
         if (!alreadyHandled) { 
            if ((!event.readyState) || (event && (event.readyState === "loaded" || event.readyState === "complete"))) {  
               alreadyHandled = true; 
               callback.apply(script, [url]);
               if (loadFunc) { 
                  loadFunc.apply(script, arguments); 
               }
            }
         }
      }; 

      if (script.onreadystatechange === undefined) { 
         loadFunc = script.onload;
         script.onload = handler; 
      } 
      else { 
         loadFunc = script.onreadystatechange; 
         script.onreadystatechange = handler; 
      } 

Saya memerlukan bantuan di sini. Saya ingin fungsi callback dijalankan walaupun alreadyAppended === true dan skrip yang sama telah dimuatkan, tetapi hanya jika skrip itu benar-benar selesai dimuatkan.

      if (!alreadyAppended || (alreadyAppended && reappend)) { 
         head.appendChild(script); 
      } 
   };

INTI PENTING: Bagaimana saya menentukan jika skrip telah selesai dimuat? Sila tanya saya soalan jika diperlukan.

Terima kasih.

Jawapan #1

Kenapa tidak tambah id pada elemen skrip? Periksa untuk melihat jika id itu wujud sebelum meneruskan....

function includeJs(jsFilePath) {

  if (document.getElementById(jsFilePath+"_script")) {
    return;
  }
  var js = document.createElement("script");

  js.type = "text/javascript";
  js.id = jsFilePath+"_script";
  js.src = jsFilePath;

  document.body.appendChild(js); 
}

Jawapan #2

Pelaksanaan Malas: Buat satu array yang boleh anda gunakan untuk menolak sumber semua skrip yang dimuatkan kepadanya, dan semasa mereka dimuatkan, tolak mereka ke dalam senarai. Setiap kali, periksa untuk melihat jika src yang diberikan berada dalam array, dan jika ia berada, jalankan callback serta-merta.

Apa yang anda lakukan dengan kes itu apabila ia dilampirkan, tetapi tidak dimuat menjadi persoalannya. Jika anda mahu panggilan balik dijalankan, tetapi anda mahu ia dijalankan selepas ia dimuat, anda boleh membuat tatasusunan bersekutu dengan src sebagai kunci, dan elemen skrip sebagai nilai. Dari situ, buat onload atau onreadystatechange dijalankan dua kali dengan membungkus asalnya, seperti ini:

var temponload = element.onreadystatechange || element.onload;
if (element.onreadystatechange === undefined)
    element.onload = function(e) { temponload(); temponload(); };
else
    element.onreadystatechange = function (e) { temponload(); temponload(); };

Anda mempunyai kod lain yang mungkin perlu disambungkan ke ini, tetapi ini seharusnya dapat membantu anda memulakan dengan harapan.