使用内联脚本时未定义动态加载的jQuery [英] Dynamically loaded jQuery not defined when using inline script

查看:88
本文介绍了使用内联脚本时未定义动态加载的jQuery的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:

  • 通过html文件<head>部分中的一个文件javascripts.js将jQuery与其他脚本一起动态加载
  • 每个html文件都有自己的javascript代码,该代码在html文件的<body>部分的jQuery(document).ready()上执行
  • jQuery is dynamically loaded together with other scripts by one file javascripts.js in the <head> section of the html file
  • Each html file has it's own javascript code executed on jQuery(document).ready() in the <body> section of the html file

问题:

  • 错误:<body>部分中的 jQuery未定义
  • 不能修改html文件(+1000个存在相同问题的文件)
  • Error: jQuery is not defined for javascript in the <body> section
  • Modifying the html file is not an option (+1000 files with same problem)

示例html文件:

<html>
  <head>
    <title>JS test</title>
    <script src="javascripts.js" type="text/javascript"></script>
  </head>
<body>
  <input type="text" class="date">
  <script>
    jQuery(document).ready(function() {  // Error: jQuery not defined
      jQuery('.date').datepicker();
    });
  </script>
</body>
</html>

javascripts.js:

// Load jQuery before any other javascript file
function loadJS(src, callback) {
    var s = document.createElement('script');
    s.src = src;
    s.async = true;
    s.onreadystatechange = s.onload = function() {
        var state = s.readyState;
        console.log("state: "+state);
        if (!callback.done && (!state || /loaded|complete/.test(state))) {
            callback.done = true;
            callback();
        }
    };
    document.getElementsByTagName('head')[0].appendChild(s);
}

loadJS('javascripts/jquery-1.8.3.min.js', function() {
    var files = Array(
      'javascripts/functions.js',
      'javascripts/settings.js'
    );

    if (document.getElementsByTagName && document.createElement) {
        var head = document.getElementsByTagName('head')[0];

        for (i = 0; i < files.length; i++) {
            var script = document.createElement('script');
            script.setAttribute('type', 'text/javascript');
            script.setAttribute('src', files[i]);
            script.async = true;
            head.appendChild(script);
        }
    }
});

推荐答案

正如注释中所指出的,这种情况正在发生,因为您正在异步加载jQuery.异步意味着其余代码将被执行,因此在环境中存在jQuery之前,您的文档就绪处理程序(DRH)行正在运行.

This is happening, as many in the comments have pointed out, because you are loading jQuery asynchronously. Asynchronous means the rest of the code is executed, and so your document-ready handler (DRH) line is running before jQuery is present in the environment.

这是一种解决问题的真正方法.它涉及到临时替代jQuery,其工作只是记录DRH回调,直到jQuery到达为止.完成后,我们会将它们依次传递给jQuery.

Here's a really hacky way of resolving this. It involves making a temporary substitute of jQuery whose job is just to log the DRH callbacks until jQuery has arrived. When it does, we pass them in turn to jQuery.

JS:

//temporary jQuery substitute - just log incoming DRH callbacks
function jQuery(func) {
    if (func) drh_callbacks.push(func);
    return {ready: function(func) { drh_callbacks.push(func); }};
};
var $ = jQuery, drh_callbacks = [];

//asynchronously load jQuery
setTimeout(function() {
    var scr = document.createElement('script');
    scr.src = '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
    document.head.appendChild(scr);
    scr.onload = function() {
        $.each(drh_callbacks, function(i, func) { $(func); });
    };
}, 2000);

HTML:

jQuery(document).ready(function() { alert('jQuery has loaded!'); });

提琴: http://jsfiddle.net/y7aE3/

在此示例中,注意drh_callbacks是全局的,这显然是不好的.理想情况下,将其挂接到名称空间或诸如此类的名称上. mynamespace.drh_callbacks.

Note in this example drh_callbacks is global, which is obviously bad. Ideally hook it onto a namespace or something, e.g. mynamespace.drh_callbacks.

这篇关于使用内联脚本时未定义动态加载的jQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆