2009-04-16 32 views
20

Tôi đã có một bookmarklet tải jQuery và một số thư viện js khác.Dấu trang chờ cho đến khi Javascript được tải

Làm thế nào để:

  • Chờ cho đến khi thư viện javascript Tôi đang sử dụng hiện có sẵn/nạp. Nếu tôi cố gắng sử dụng kịch bản trước khi nó tải xong, như sử dụng hàm $ với jQuery trước khi nó được nạp, một ngoại lệ không xác định được ném ra.
  • Đảm bảo rằng bookmarklet tôi tải sẽ không được lưu trữ (không sử dụng một tiêu đề máy chủ, hoặc rõ ràng, là rằng đây là một tập tin javascript: thẻ meta)

Có ai biết nếu onload cho động javascript được thêm vào hoạt động trong IE? (để mâu thuẫn với điều này post)

Giải pháp đơn giản nhất, giải pháp rõ ràng nhất cho những vấn đề này là gì?

+0

"Hãy đợi đến khi thư viện javascript có sẵn", hãy giải thích điều này. Bạn còn chờ gì nữa? –

Trả lời

24

Nó phụ thuộc vào cách bạn đang thực sự tải jQuery. Nếu bạn đang thêm một phần tử script vào trang, bạn có thể sử dụng cùng một kỹ thuật mà jQuery sử dụng để tự động tải một kịch bản lệnh.

EDIT: Tôi đã làm bài tập về nhà của mình và thực sự trích xuất một hàm loadScript từ mã jQuery để sử dụng trong bookmarklet của bạn. Nó thực sự có thể hữu ích cho nhiều người (kể cả tôi).

function loadScript(url, callback) 
{ 
    var head = document.getElementsByTagName("head")[0]; 
    var script = document.createElement("script"); 
    script.src = url; 

    // Attach handlers for all browsers 
    var done = false; 
    script.onload = script.onreadystatechange = function() 
    { 
     if(!done && (!this.readyState 
        || this.readyState == "loaded" 
        || this.readyState == "complete")) 
     { 
      done = true; 

      // Continue your code 
      callback(); 

      // Handle memory leak in IE 
      script.onload = script.onreadystatechange = null; 
      head.removeChild(script); 
     } 
    }; 

    head.appendChild(script); 
} 


// Usage: 
// This code loads jQuery and executes some code when jQuery is loaded 
loadScript("https://code.jquery.com/jquery-latest.js", function() 
{ 
    $('my_element').hide(); 
}); 
+2

tác phẩm nghệ thuật :) – vsync

+1

bạn không cần phải chỉ định type = "text/javascript" ? – vsync

+1

không còn nữa. Ngày nay các trình duyệt giả định các tập lệnh không được gõ là javascript – joeytwiddle

1

Để trả lời câu hỏi đầu tiên của bạn: Javascript được diễn giải tuần tự, vì vậy bất kỳ mã dấu trang nào sau đây sẽ không thực thi cho đến khi thư viện được tải (giả sử thư viện được giải thích thành công - không có lỗi cú pháp).

Để ngăn chặn các file từ việc lưu trữ, bạn có thể thêm một chuỗi truy vấn vô nghĩa ...

url = 'jquery.js?x=' + new Date().getTime(); 
+0

Rõ ràng, javascript được thêm động không hoạt động chính xác như bạn mô tả. Phần tử được thêm vào bởi hàm addElement DOM và trả về ngay lập tức. onLoad giúp, nhưng tôi bị quấy rầy bởi bài đăng này: http://answers.google.com/answers/threadview?id=595949 – cgp

+0

Nhận xét của bạn không chính xác, đặc biệt khi nói đến câu hỏi này. altCognito đã mô tả sự cố, hãy để tôi làm cho nó rõ ràng hơn một chút. Nếu tập lệnh của bạn tự động thêm thẻ tập lệnh, nội dung của thẻ động sẽ không được phân tích cú pháp cho đến khi bạn thoát khỏi thẻ tập lệnh hiện tại –

0

Tôi có một chút gần gũi hơn với this, nhưng không hoàn toàn. Nó sẽ là tốt đẹp để có một rời rạc, ví dụ về một bookmarklet đã chứng minh làm thế nào để tránh bộ nhớ đệm.

1

Tôi đã chú ý rằng trong Chrome thứ tự các tập lệnh được tải chưa được xác định, khi sử dụng kỹ thuật @Vincent Robert. Trong trường hợp này, một chút sửa đổi sẽ giúp:


(function() { 
    var callback = function() { 
     // Do you work 
    }; 
     // check for our library existence 
    if (typeof (MyLib) == 'undefined') { 
     var sources = [ 
       'http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js', 
      'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js', 
      'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js', 
      'http://myhost.com/javascripts/mylib.min.js']; 

     var loadNextScript = function() { 
      if (sources.length > 0) { 
       var script = document.createElement('script'); 
       script.src = sources.shift(); 
       document.body.appendChild(script); 

       var done = false; 
       script.onload = script.onreadystatechange = function() { 
        if (!done 
          && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { 
         done = true; 

         // Handle memory leak in IE 
         script.onload = script.onreadystatechange = null; 

         loadNextScript(); 
        } 
       } 
      } else { 
       callback(); 
      } 
     } 
     loadNextScript(); 

    } else { 
     callback(); 
    } 
})(); 
Các vấn đề liên quan