Gọi hàm javascript sau khi tập lệnh được tải


81

Tôi có một trang html nơi tôi đang thêm html tại động thông qua một đoạn mã javascript như bên dưới

<script type="text/javascript" src="/myapp/htmlCode"></script>

Tôi muốn gọi một hàm js, ví dụ như loadContent (); khi tập lệnh trên thêm html động.

Ai đó có thể giúp tôi làm thế nào tôi có thể làm điều đó?

Câu trả lời:


140

bạn có thể đạt được điều này mà không cần sử dụng javascript head.js.

function loadScript( url, callback ) {
  var script = document.createElement( "script" )
  script.type = "text/javascript";
  if(script.readyState) {  // only required for IE <9
    script.onreadystatechange = function() {
      if ( script.readyState === "loaded" || script.readyState === "complete" ) {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {  //Others
    script.onload = function() {
      callback();
    };
  }

  script.src = url;
  document.getElementsByTagName( "head" )[0].appendChild( script );
}


// call the function...
loadScript(pathtoscript, function() {
  alert('script ready!'); 
});

6
FYI: onloadổn cho IE phiên bản 9 trở lên - vì vậy chỉ cần cài đặt onloadcó lẽ là ổn đối với hầu hết mọi người hiện tại
Simon_Weaver

3
Lưu ý onloadsẽ bắt đầu gọi lại những phút kịch bản "tải" không phải khi thực hiện của nó thực sự kết thúc, mà là thất vọng
Ma Dude

@MaDude Bạn có thể tham khảo bất kỳ tài liệu nào về điều đó không?
kontrollanten

2
Các onloadbộ xử lý có thể không có thể được gọi khi kịch bản có không hoàn thành thi công, do Javascript là đơn luồng. Điều này có nghĩa là onloadtrình xử lý chỉ có thể được gọi TRƯỚC khi thực thi bắt đầu tập lệnh hoặc SAU KHI nó kết thúc thực thi. Cá nhân tôi chưa bao giờ thấy trường hợp trước đây xảy ra ... BAO GIỜ. Nếu ai đó biết về trường hợp onloadcó thể tái tạo trong đó trình xử lý có thể được gọi TRƯỚC KHI tập lệnh bắt đầu thực thi, vui lòng cho chúng tôi biết.
GetFree

Một tiện ích mở rộng đơn giản để tải một loạt các tập lệnh: function loadScripts (urls, callback) {var counter = 0 for (var i=0; i<urls.length; i++) { loadScript(urls[i], function () { if (++counter === urls.length) { callback() } }) } }
sree

27

Tôi đã gặp vấn đề tương tự ... Giải pháp của tôi (không có jQuery):

<script onload="loadedContent();" src ="/myapp/myCode.js"  ></script>

2
Xin lưu ý: Điều này sẽ không tương thích với các CSP nghiêm ngặt.
Bradley

12

thử một cái gì đó như thế này

var script = document.createElement('script');

if(script.readyState) {  //IE
script.onreadystatechange = function() {
  if ( script.readyState === "loaded" || script.readyState === "complete" ) {
    script.onreadystatechange = null;
    alert(jQuery);
  }
};
 } else{//others
script.onload = function() {
  alert(jQuery); 
}
}
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"
document.documentElement.appendChild(script);

11

Nếu bạn đang đọc bài đăng này vào năm 2020, có lẽ bạn đã quen với những Lời hứa hơn. Cách tiếp cận hiện đại hơn sẽ được ưu tiên nếu tất cả các trình duyệt mục tiêu của bạn hỗ trợ ES6 hoặc bạn đang sử dụng polyfill.

Giải pháp này hoạt động giống như câu trả lời @JaykeshPatel , nhưng nó dựa trên Promises:

// definition
function loadScript(scriptUrl) {
  const script = document.createElement('script');
  script.src = scriptUrl;
  document.body.appendChild(script);
  
  return new Promise((res, rej) => {
    script.onload = function() {
      res();
    }
    script.onerror = function () {
      rej();
    }
  });
}

// use
loadScript('http://your-cdn/jquery.js')
  .then(() => {
    console.log('Script loaded!');
  })
  .catch(() => {
    console.error('Script loading failed! Handle this error');
  });

Bạn có thể chuyển một số biến theo ngữ cảnh trong các đối số của lệnh resgọi lại hoặc nếu thư viện của bạn đã nhập một số ký hiệu chung, bạn có thể tham chiếu nó ở đó.

Ví dụ: vì jQuery giới thiệu $biểu tượng toàn cục, bạn có thể gọi res($)và tạo phạm vi cục bộ cho nó (hoàn hảo nếu bạn đang sử dụng TypeScript và bạn không muốn khai báo một biến mô-đun trong mỗi tệp, theo cách này bạn có thể viết const $ = await loadScript(..)).

Nếu bạn không muốn chuyển bất kỳ đối số nào, bạn chỉ có thể rút ngắn mã của mình như sau:

script.onload = res;
script.onerror = rej;

1
script.onLoad = res;// đơn giản hóa
Kunukn

1
@Kunukn cũng có một cái ngắn hơn return new Promise(res => script.onload = res). Nhưng gán một chức năng để onloadcó thể được dễ dàng hơn để đọc và cho phép bạn để vượt qua một cuộc tranh cãi về quyết tâm
Cristian Traina

4

thực sự bạn chỉ có thể đặt loadedContent()dòng cuối cùng của tập lệnh mà bạn đang tải (đây là một loại khái niệm đằng sau JSONP)


4

Câu trả lời của tôi là một phần mở rộng của câu trả lời Jaykesh Patel . Tôi đã triển khai mã này để tải nhiều javascript . Hy vọng điều này sẽ giúp ai đó:

// RECURSIVE LOAD SCRIPTS
function load_scripts( urls, final_callback, index=0 )
{
    if( typeof urls[index+1] === "undefined" )
    {
        load_script( urls[index], final_callback );
    }
    else
    {
        load_script( urls[index], function() {
            load_scripts( urls, final_callback, index+1 );
        } );
    }
}

// LOAD SCRIPT
function load_script( url, callback )
{
    var script = document.createElement( "script" );
    script.type = "text/javascript";
    if(script.readyState) // IE
    {
        script.onreadystatechange = function()
        {
            if ( script.readyState === "loaded" || script.readyState === "complete" )
            {
                script.onreadystatechange = null;
                callback();
            }
        };
    }
    else // Others
    {  
        script.onload = function() { callback(); };
    }
    script.src = url;
    document.getElementsByTagName( "head" )[0].appendChild( script );
    debug("javascript included: "+url);
}

// EXAMPLE  
var main = function()
{
    console.log("main function executed");
}
var js = [ "path/to/script-1", "path/to/script-2", "path/to/script-3" ];
load_scripts( js, main );

1

Kiểm tra head.js . Nó sẽ đạt được những gì bạn đang theo đuổi, cung cấp các lệnh gọi lại khi (các) tệp của bạn đã tải và thực thi thành công.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.