2010-01-31 26 views
59

Tôi đang phát triển tiện ích con javascript phụ thuộc vào jQuery. Tiện ích có thể hoặc không được tải lên trang đã tải jQuery. Có nhiều vấn đề nảy sinh trong trường hợp này ...Cách nhúng tiện ích Javascript phụ thuộc vào jQuery vào một môi trường không xác định

  1. Nếu trang web không có jQuery, tôi phải tải jQuery của riêng mình. Có vẻ là một vấn đề thời gian tinh tế khi làm điều này, tuy nhiên. Ví dụ: nếu tiện ích của tôi tải và thực thi trước khi jQuery tải xong và thực thi, tôi nhận được lỗi jQuery is not defined.

  2. Nếu trang web có jQuery, tôi thường có thể làm việc với nó. Nếu phiên bản jQuery cũ, tuy nhiên, tôi muốn tải của riêng tôi. Tuy nhiên, nếu tôi tự nạp, tôi cần thực hiện nó theo cách không bị dẫm lên biến số $ của chúng. Nếu tôi đặt jQuery.noConflict() và bất kỳ tập lệnh nào của chúng đều phụ thuộc vào $ thì tôi vừa mới phá vỡ trang của chúng.

  3. Nếu trang web sử dụng một thư viện javascript khác (ví dụ: nguyên mẫu), tôi cũng cần phải nhạy cảm với biến số $ của mẫu thử nghiệm.

Vì tất cả những điều trên, dường như không phụ thuộc vào jQuery. Nhưng trước khi tôi đi xuống con đường đó, mà sẽ liên quan đến chủ yếu là viết lại mã widget của tôi, tôi muốn hỏi lời khuyên trước.

Bộ xương cơ bản của mã của tôi, trong đó có lỗi thời gian và đôi khi $ lỗi, sau:

<script type="text/javascript" charset="utf-8"> 
// <![CDATA 
if (typeof jQuery === 'undefined') { 
    var head = document.getElementsByTagName('head')[0]; 
    var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = '{{ URL }}/jquery.js'; 
    head.appendChild(script); 
} 
// ]]> 
</script> 
<script type="text/javascript" src="{{ URL }}/widget.js"></script> 

phụ tùng của tôi có cấu trúc sau:

(function($) { 
var mywidget = { 
    init: function() { 
    ... 
    } 
}; 
$(document).ready(function() { 
    mywidget.init(); 
}); 
})(jQuery); 

Nếu có bất kỳ con trỏ hoặc các nguồn lực để đạt được một widget có thể làm việc trong tất cả các môi trường được đề cập, chúng sẽ được đánh giá cao.

Trả lời

93

Sau khi xem xét một số câu trả lời và gợi ý, và việc tìm kiếm một số hữu ích Tin tặc jQuery, tôi đã kết thúc với một số thông tin như sau:

(function(window, document, version, callback) { 
    var j, d; 
    var loaded = false; 
    if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) { 
     var script = document.createElement("script"); 
     script.type = "text/javascript"; 
     script.src = "/media/jquery.js"; 
     script.onload = script.onreadystatechange = function() { 
      if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) { 
       callback((j = window.jQuery).noConflict(1), loaded = true); 
       j(script).remove(); 
      } 
     }; 
     (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script); 
    } 
})(window, document, "1.3", function($, jquery_loaded) { 
    // Widget code here 
}); 

Điều này sẽ tải jQuery nếu nó chưa được tải và đóng gói trong cuộc gọi để nó không xung đột với một jQuery đã tồn tại từ trước trên trang. Nó cũng kiểm tra rằng phiên bản tối thiểu có sẵn hoặc tải phiên bản đã biết khác - trong trường hợp này, v1.3. Nó sẽ gửi một giá trị boolean đến callback (widget của tôi) về việc jQuery có được tải hay không trong trường hợp có bất kỳ trình kích hoạt nào cần được thực hiện. Và chỉ sau khi jQuery được nạp nó gọi là widget của tôi, đi qua jQuery vào nó.

+3

câu trả lời chất lượng sách văn bản! – bjornl

+2

Không nhận được nhiều hơn thế, ước gì tôi có thể cho điểm nhiều hơn! –

+1

rất đẹp, cảm ơn nhiều. – TimDog

-1

Tôi sẽ tải xuống nguồn jQuery và sửa đổi đối tượng jQuery thành một đối tượng khác (jQueryCustom).

Và sau đó tìm trường hợp đặt biểu tượng $ làm đối tượng jQuery và nhận xét thường trình đó.

Tôi không biết làm thế nào dễ dàng hoặc khó khăn có thể được, nhưng tôi chắc chắn sẽ cho nó một thử.

(Ngoài ra, hãy kiểm tra tùy chọn thứ hai của bạn vì trang web không hoạt động, có thể có phiên bản jQuery cũ hơn tiện ích bạn cần).

EDIT: Tôi vừa kiểm tra nguồn. Bạn chỉ cần thay thế jQuery bằng một chuỗi khác (ví dụ: jQcustom). Sau đó, hãy thử cho ý kiến ​​dòng này:

_$ = window.$ 

Và bạn thực hiện tham chiếu đến các tùy chỉnh jQuery như thế này:

jQcustom("#id").attr(...) 
1

Bạn có thể sử dụng document.write() để tùy chọn thêm Kịch bản jQuery cho trang? Điều đó sẽ buộc jQuery tải đồng bộ.Hãy thử điều này:

<script type="text/javascript" charset="utf-8"> 
// <![CDATA 
if (typeof jQuery === 'undefined') { 
    document.write('<script src="{{ URL }}/jquery.js"><' + '/script>'); 
} 
// ]]> 
</script> 
<script type="text/javascript" src="{{ URL }}/widget.js"></script> 

Nếu bạn muốn làm việc kiểm tra jQuery bên trong kịch bản widget của bạn sau đó tôi tin rằng các công trình sau đây qua trình duyệt:

(function() { 
function your_call($) { 
    // your widget code goes here 
} 
if (typeof jQuery !== 'undefined') your_call(jQuery); 
else { 
    var head = document.getElementsByTagName('head')[0]; 
    var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = '{{ URL }}/jquery.js'; 
    var onload = function() { 
    if (!script.readyState || script.readyState === "complete") your_call(jQuery); 
    } 
    if ("onreadystatechange" in script) script.onreadystatechange = onload; 
    else script.onload = onload; 
    head.appendChild(script); 
} 
})() 
+0

Tôi thực sự đã kết thúc với một cái gì đó rất giống nhau mà tôi sẽ cố gắng để gửi như câu trả lời khác (vì tôi là giới hạn số ký tự trong một chú thích). – robhudson

2

Điều gì xảy ra nếu bạn cũng muốn sử dụng một số plugin jQuery? Có an toàn không khi bạn tạo một tệp đơn lẻ với các phiên bản được rút gọn của plugin và cũng có thể tải những tệp đó, như dưới đây? (Được tải từ S3, trong ví dụ cụ thể này.)

(function(window, document, version, callback) { 
    var j, d; 
    var loaded = false; 
    if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) { 
    var script = document.createElement("script"); 
    script.type = "text/javascript"; 
    script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"; 
    script.onload = script.onreadystatechange = function() { 
     if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) { 
      window.jQuery.getScript('http://mydomain.s3.amazonaws.com/assets/jquery-plugins.js', function() { 
       callback((j = window.jQuery).noConflict(1), loaded = true); 
       j(script).remove(); 
      }); 
     } 
    }; 
    document.documentElement.childNodes[0].appendChild(script) 
    } 
})(window, document, "1.5.2", function($, jquery_loaded) { 
    // widget code goes here 
}); 
+0

Tôi đang cố gắng làm một cái gì đó rất giống với điều này. Bạn có thể giúp tôi khắc phục sự cố http://stackoverflow.com/questions/7817522/uncaught-typeerror-can-not-set-propery-function-name-of-undefined-for-widget/ – Bongs

5

Xem How to build a web widget (using jQuery) bởi Alex Marandon.

(function() { 

// Localize jQuery variable 
var jQuery; 

/******** Load jQuery if not present *********/ 
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') { 
    var script_tag = document.createElement('script'); 
    script_tag.setAttribute("type","text/javascript"); 
    script_tag.setAttribute("src", 
     "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"); 
    if (script_tag.readyState) { 
     script_tag.onreadystatechange = function() { // For old versions of IE 
      if (this.readyState == 'complete' || this.readyState == 'loaded') { 
       scriptLoadHandler(); 
      } 
     }; 
    } else { // Other browsers 
     script_tag.onload = scriptLoadHandler; 
    } 
    // Try to find the head, otherwise default to the documentElement 
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag); 
} else { 
    // The jQuery version on the window is the one we want to use 
    jQuery = window.jQuery; 
    main(); 
} 

/******** Called once jQuery has loaded ******/ 
function scriptLoadHandler() { 
    // Restore $ and window.jQuery to their previous values and store the 
    // new jQuery in our local jQuery variable 
    jQuery = window.jQuery.noConflict(true); 
    // Call our main function 
    main(); 
} 

/******** Our main function ********/ 
function main() { 
    jQuery(document).ready(function($) { 
     // We can use jQuery 1.4.2 here 
    }); 
} 

})(); // We call our anonymous function immediately 
0

Tôi biết đây là chủ đề cũ ... nhưng tôi đã nhận được nội dung nào đó nhanh hơn. Hãy thử trong widget của bạn

"init": function() 

mà sẽ sửa chữa những rắc rối

Các vấn đề liên quan