Tải jQuery bằng Javascript và sử dụng jQuery


83

Tôi đang nối thư viện jQuery vào dom bằng cách sử dụng:

 var script = document.createElement('script');
 script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
 script.type = 'text/javascript';
 document.getElementsByTagName('head')[0].appendChild(script);

Tuy nhiên khi tôi chạy:

jQuery(document).ready(function(){...

Bảng điều khiển báo lỗi:

Uncaught ReferenceError: jQuery is not defined

Làm cách nào để tải jQuery động cũng như sử dụng nó khi nó ở trong dom?


2
Có lý do gì bạn muốn làm điều này so với cách tối ưu hóa hơn không?
Mã Maverick

Một số câu trả lời trong câu hỏi này có thể giúp bạn - stackoverflow.com/questions/7474354/...
mrtsherman

@Scott Có. Tôi có một ứng dụng trong đó khi cài đặt nó tải cả jquery cũng như script. Tôi cần tải jquery bên trong script để jquery không phá vỡ các chủ đề của người dùng. Tôi cần tải javascript có điều kiện vào một trang web nhất định trong chủ đề của họ. Xin hãy tin tưởng tôi về điều này.
ThomasReggi

Tại sao jQuery lại phá vỡ chủ đề của người dùng? Nếu việc tải jQuery (không ảnh hưởng đến css) có thể phá vỡ các chủ đề, thì bạn đang làm sai điều gì đó.
Anders Tornblad

Điểm tốt, nhưng, điều gì sẽ xảy ra nếu họ đang sử dụng phiên bản jQuery cũ hơn hoặc một thư viện khác?
ThomasReggi

Câu trả lời:


138

Có một JSFiddle đang hoạt động với một ví dụ nhỏ ở đây, minh họa chính xác những gì bạn đang tìm kiếm (trừ khi tôi hiểu sai yêu cầu của bạn) : http://jsfiddle.net/9N7Z2/188/

Có một số vấn đề với phương pháp tải javascript động đó. Khi nói đến các khung cơ bản, như jQuery, bạn có thể thực sự muốn tải chúng một cách tĩnh, bởi vì nếu không, bạn sẽ phải viết toàn bộ khung tải JavaScript ...

Bạn có thể sử dụng một số trình tải JavaScript hiện có hoặc viết mã của riêng bạn bằng cách xem for window.jQueryđể được xác định.

// Immediately-invoked function expression
(function() {
    // Load the script
    var script = document.createElement("SCRIPT");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
    script.type = 'text/javascript';
    script.onload = function() {
        var $ = window.jQuery;
        // Use $ here...
    };
    document.getElementsByTagName("head")[0].appendChild(script);
})();

Chỉ cần nhớ rằng nếu bạn cần hỗ trợ các trình duyệt thực sự cũ, như IE8, loadtrình xử lý sự kiện sẽ không thực thi. Trong trường hợp đó, bạn sẽ cần phải thăm dò xem có tồn tại khi window.jQuerysử dụng lặp lại hay không window.setTimeout. Có một JSFiddle hoạt động với phương thức đó tại đây: http://jsfiddle.net/9N7Z2/3/

Có rất nhiều người đã làm những việc bạn cần làm. Kiểm tra một số khung công tác Trình tải JavaScript hiện có, như:


Giải pháp này hoạt động, ngoại trừ trong WordPress. Có cách nào sửa đổi điều này để tải jQuery vào một đối tượng khác không?
Kraang Prime

@SanuelJackson Với Wordpress, bạn nên sử dụng wp_enqueue_script()hàm để bao gồm jQuery đúng cách. Tài liệu: codex.wordpress.org/Function_Reference/wp_enqueue_script Một số thông tin thêm tại đây: digwp.com/2009/06/including-jquery-in-wordpress-the-right-way hoặc tại đây: digwp.com/2011/09/using- thay-of-jquery-in-wordpress
Anders Tornblad

Vâng, những gì tôi đang nói là đoạn mã trên không hoạt động trên Wordpress vì nó cũng tải jQuery không đồng bộ. Ngay cả khi tập lệnh này được tải ở cuối trang (ngay trước khi đóng html), jQuery vẫn chưa được 'khởi tạo' hoàn toàn và do đó nó không thấy jQuery được tải và tiếp tục tải và thực hiện lệnh gọi lại. Sau khi được tải, nó kích hoạt những thứ khác được tải không đồng bộ phụ thuộc vào việc jQuery được tải theo một cách khác (ví dụ: $, jQuery, v.v.) hoặc phụ thuộc vào một phiên bản jQuery khác.
Kraang Prime

Nó là tuyệt vời trong các trường hợp khác mà tôi đã thử. Chỉ là ghi chú về vấn đề khó hiểu duy nhất với điều này. Nếu bằng cách nào đó nó có thể được điều chỉnh, nhưng tôi không nghĩ là có thể vì nó phụ thuộc vào việc phát hiện jQuery, tất nhiên là không được tải và do đó chỉ có thể tiếp tục với logic của - nếu không có jquery ... thì ..
Kraang Prime

1
Bạn không cần phải thực hiện thăm dò, bạn chỉ có thể sử dụng một dòng để đợi cho đến khi jquery tải bằng cách sử dụng sự kiện .onload như stackoverflow.com/a/42013269/3577695
aljgom

7

Có một cách khác để tải jQuery động ( nguồn ). Bạn cũng có thể sử dụng

document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');

Nó được coi là thực hành xấu để sử dụng document.write, nhưng vì lợi ích của việc hoàn thành, tốt hơn là nên đề cập đến nó.

Xem Tại sao document.write được coi là một "hoạt động xấu"? vì những lý do. Điểm chuyên nghiệpdocument.writekhông chặn trang của bạn tải các thử nghiệm khác, vì vậy không cần tạo hàm gọi lại.


1
Tôi đã đọc tài liệu mà bạn đã liên kết đến và đối với trường hợp sử dụng của tôi là tải thư viện jQuery cũ hơn cho IE8, việc sử dụng document.write có vẻ ổn. Nó hoạt động tốt cho tôi cho đến nay.
Alan

Đây là cách đơn giản nhất để làm điều này. Có vấn đề gì khi thực hiện việc này khi bắt đầu một tập lệnh khá lớn là một tệp JS riêng biệt không? Quá tốt để vượt qua.
Agustín Lado,

6

Trang web của Encosia khuyến nghị:

<script type="text/javascript" 
        src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  // You may specify partial version numbers, such as "1" or "1.3",
  //  with the same result. Doing so will automatically load the 
  //  latest version matching that partial revision pattern 
  //  (e.g. 1.3 would load 1.3.2 today and 1 would load 1.7.2).
  google.load("jquery", "1.7.2");

  google.setOnLoadCallback(function() {
    // Place init code here instead of $(document).ready()
  });
</script>

Nhưng ngay cả anh ấy cũng thừa nhận rằng nó chỉ không so với làm những điều sau đây khi nói đến hiệu suất tối ưu:

    <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script type="text/javascript"> window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js">\x3C/script>')</script>
    <script type="text/javascript" src="scripts.js"></scripts>
</body>
</html>

Tôi chỉ có thể tải một javascript. Điều này có nghĩa là tôi sẽ phải tải google jsapi động sau đó từ với jquery tải đó? Có vẻ thừa đối với trường hợp sử dụng của tôi.
ThomasReggi 11/12/12

1
Đây là những gì một trình tải jQuery làm. Bạn tham chiếu trình nạp và trình nạp sẽ đưa jQuery vào tài liệu cho bạn.
Mã Maverick

3

Bạn cần chạy mã của mình SAU KHI tải xong jQuery

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
script.onload = function(){
    // your jQuery code here
} 

hoặc nếu bạn đang chạy nó trong một chức năng không đồng bộ, bạn có thể sử dụng awaittrong đoạn mã trên

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
await script.onload
// your jQuery code here

Nếu bạn muốn kiểm tra trước nếu jQuery đã tồn tại trong trang, hãy thử điều này


0

Lý do bạn nhận được lỗi này là JavaScript không đợi tập lệnh được tải, vì vậy khi bạn chạy

jQuery(document).ready(function(){...

không đảm bảo rằng tập lệnh đã sẵn sàng (và sẽ không bao giờ có).

Đây không phải là giải pháp thanh lịch nhất nhưng nó hoàn toàn khả thi. Về cơ bản, bạn có thể kiểm tra sau mỗi 1 giây để xem quảng cáo đối tượng jQuery có chạy một hàm không khi nó được tải với mã của bạn trong đó. Tôi sẽ thêm thời gian chờ (giả sử clearTimeout sau khi nó được chạy 20 lần) cũng như để ngăn việc kiểm tra xảy ra vô thời hạn.

var jQueryIsReady = function(){
    //Your JQuery code here
}

var checkJquery = function(){
    if(typeof jQuery === "undefined"){
        return false;
    }else{
        clearTimeout(interval);
        jQueryIsReady();
    }
}
var interval = setInterval(checkJquery,1000);

0

Sử dụng request.js, bạn có thể làm điều tương tự theo cách an toàn hơn. Bạn chỉ có thể xác định sự phụ thuộc của mình trên jquery và sau đó thực thi mã bạn muốn bằng cách sử dụng phần phụ thuộc khi nó được tải mà không làm ô nhiễm không gian tên:

Tôi thường giới thiệu thư viện này để quản lý tất cả các phụ thuộc vào Javascript. Nó đơn giản và cho phép tối ưu hóa hiệu quả việc tải tài nguyên. Tuy nhiên, có một số biện pháp phòng ngừa bạn có thể cần thực hiện khi sử dụng nó với JQuery. Cách yêu thích của tôi để đối phó với chúng được giải thích trong repo github này và được phản ánh bằng mẫu mã sau:

<title>jQuery+RequireJS Sample Page</title>
   <script src="scripts/require.js"></script>
   <script>
   require({
       baseUrl: 'scripts',
       paths: {
           jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min'
       },
       priority: ['jquery']
    }, ['main']);
    </script>

0

HTML:

<html>
  <head>

  </head>
  <body>

    <div id='status'>jQuery is not loaded yet.</div>
    <input type='button' value='Click here to load it.' onclick='load()' />

  </body>
</html>   

Kịch bản:

   <script>

        load = function() {
          load.getScript("jquery-1.7.2.js");
          load.tryReady(0); // We will write this function later. It's responsible for waiting until jQuery loads before using it.
        }

        // dynamically load any javascript file.
        load.getScript = function(filename) {
          var script = document.createElement('script')
          script.setAttribute("type","text/javascript")
          script.setAttribute("src", filename)
          if (typeof script!="undefined")
          document.getElementsByTagName("head")[0].appendChild(script)
        }

        </script>

Phần khó khăn là chạy script sau khi script được tải ... Và tại sao script lại không được xác định! ??
Anders Tornblad

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.