如何将依赖于jQuery的Javascript小部件嵌入到未知环境中

rob*_*son 61 javascript jquery widget

我正在开发一个依赖于jQuery的javascript小部件.小部件可能会也可能不会加载到已加载jQuery的页面上.在这种情况下出现了许多问题......

  1. 如果网页没有jQuery,我必须加载自己的jQuery.然而,这样做时似乎有一个微妙的时间问题.例如,如果我的窗口小部件在jQuery完成加载和执行之前加载并执行,我会收到jQuery is not defined错误.

  2. 如果网页确实有jQuery,我通常可以使用它.但是,如果jQuery版本是旧版本,我想加载自己的版本.但是,如果我自己加载,我需要以不踩它们的$变量的方式来做.如果我设置jQuery.noConflict()并且他们的任何脚本依赖$,那么我刚刚打破了他们的页面.

  3. 如果网页使用另一个javascript库(例如原型),我也需要对原型的$变量敏感.

由于以上所有,似乎更容易不依赖于jQuery.但是在我走这条路之前,我想先重写我的小部件代码.

我的代码的基本框架,包括时序错误和有时$错误,如下:

<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>
Run Code Online (Sandbox Code Playgroud)

我的小部件具有以下结构:

(function($) {
 var mywidget = {
  init: function() {
   ...
  }
 };
 $(document).ready(function() {
   mywidget.init();
 });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

如果有任何指针或资源来实现可以在所有提到的环境中工作的小部件,那么他们将非常感激.

rob*_*son 97

在查看了一些答案和指针,并找到了一些有用的jQuery黑客之后,我最终得到了类似下面的内容:

(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
});
Run Code Online (Sandbox Code Playgroud)

这将加载jQuery(如果它尚未加载)并将其封装在回调中,因此它不会与页面上预先存在的jQuery冲突.它还会检查最低版本是否可用,或者加载已知版本 - 在本例中为v1.3.它向回调(我的小部件)发送一个布尔值,判断是否加载了jQuery,以防需要进行任何触发.只有在加载jQuery之后它才会调用我的小部件,将jQuery传递给它.

  • 教科书质量答案! (3认同)
  • 在错误形成的html(文件顶部的空白行)上运行时,看到了"HIERARCHY_REQUEST_ERR:DOM异常3"错误.将`document.documentElement.childNodes [0] .appendChild(script)`替换为`(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);`从下面看起来效果更好. (3认同)
  • 没有比这更好,希望我能给更多积分! (2认同)

Pav*_*uva 5

请参阅Alex Marandon 如何构建Web小部件(使用jQuery).

(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
Run Code Online (Sandbox Code Playgroud)