【问题标题】:Dynamically load jQuery and then Typeahead.js动态加载 jQuery 然后 Typeahead.js
【发布时间】:2014-09-04 03:57:54
【问题描述】:

我正在尝试动态加载 jQuery,然后动态加载 Typeahead.js jQuery 插件。

我可以加载 jQuery,但 typeahead 插件似乎没有加载。代码的第一部分检查 jQuery 并在它不存在时动态加载它。

加载 jQuery 后,我尝试使用 $.getScript 加载 Typeahead,它在 jQuery 文档中用于加载 jQuery 插件。但是,Typehead 插件似乎没有加载,因为当我尝试调用 Bloodhound(Typeahead 中的建议引擎)时出现错误。

我确认下面显示的预输入代码通过将其放入 Rails 应用程序中有效。当与 jquery-rails gem 和资产管道一起使用时,typeahead 代码会正确地使用 JSON 响应填充我的输入框。但是,我不能依赖 Rails,当我尝试分离代码时,我无法以正确的顺序动态加载库。

任何帮助将不胜感激。

(function() {

    // Localize jQuery variable
    var jQuery;

    /******** Load jQuery if not present *********/
    if (window.jQuery === undefined) {
      var script_tag = document.createElement('script');
      script_tag.setAttribute("type","text/javascript");
      script_tag.setAttribute("src",
        "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/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
        var parentHead = (document.getElementsByTagName("head")[0] || document.documentElement)
        parentHead.insertBefore(script_tag, parentHead.firstChild);
    } 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);
      // Load Typeahead
      // Call our main function
      main();
    }

    /******** Our main function ********/
    function main() {
      jQuery(document).ready(function($) {

     /******* This is the call to load typeahead *******/
        var url = "https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"
        $.getScript(url, function(){
          var companies = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            limit: 3000,
            prefetch: {
              // url points to a json file that contains an array of country names, see
              // https://github.com/twitter/typeahead.js/blob/gh-pages/data/countries.json
              url: '/accounts.json',
            }
          });
          // kicks off the loading/processing of `local` and `prefetch`
          companies.initialize();

          // passing in `null` for the `options` arguments will result in the default
          // options being used
          $('#the-basics .search .typeahead').typeahead(null, {
            name: 'companies',
            displayKey: 'name',
            // `ttAdapter` wraps the suggestion engine in an adapter that
            // is compatible with the typeahead jQuery plugin
            source: companies.ttAdapter()
          });
        });
      });
    }
  })();

【问题讨论】:

  • 会发生什么?您是否看到任何错误消息?能否确认.getScript调用成功完成并调用回调?
  • 我收到 Bloodhound 的参考错误和 Typeahead.js 源代码中的错误。我确认调用了 $.getScript 方法,因为我在回调中到达了我的调试器,但 Typeahead 似乎没有加载。两个错误:1. Uncaught TypeError: Cannot read property 'isArray' of undefined 2. Uncaught ReferenceError: Bloodhound is not defined
  • isArray 错误来自尝试解析加载的预输入代码,并且是该脚本中第一次使用“$”。它表现得好像无法解决window.jQuery。看起来是时候在回调的顶部扔一个断点了,看看window.jQuery 的状态是什么。

标签: javascript jquery typeahead.js


【解决方案1】:

我之前尝试过编写依赖加载器,但它非常复杂,尤其是在跨浏览器方面。去年我遇到了与您类似的问题,我需要以非常特定的顺序加载 jQuery(也许)和一堆其他库。我可以让它在 Chrome 中工作,但不是 IE 等。每次我做出改变时,时间问题似乎都在蔓延!

在尝试了很多与你的代码不一样的代码后,我放弃了,最终找到:http://headjs.com/

从那时起,我几乎只使用 HeadJs,我的代码只有几行代码(与我之前构建的巨大怪物相反。)

不确定使用库是否适合您,但如果可以,我强烈推荐这个。

顺便说一句,请注意有一个“head.ready”事件将取代您通常的 Dom Ready。当您的库都已很好地加载并准备就绪时,此事件将触发!提示:您将需要使用 head.ready 来触发您的所有 JavaScript 操作!

【讨论】:

  • 感谢分享,但我没有选择使用 headjs.com 之类的东西。我需要能够在不在源代码中编写显式脚本标签的情况下传递此代码。
  • 明白。但是,headjs 是开源的……您可以查看 head.load.js 文件以深入了解开发人员如何实现这一目标。根据经验,我可以告诉你,每次在不同的浏览器和不同的用户连接速度下,时间都会给你带来麻烦!无论如何,如果它对您有所帮助,代码就在这里,并且似乎得到了很好的评论:cdnjs.cloudflare.com/ajax/libs/headjs/1.0.3/head.load.js
  • RequireJs 是另一个非常流行的库,它处理资产的加载,也是开源的。 requirejs.org/docs/release/2.1.14/comments/require.js - 似乎也得到了很好的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-02
相关资源
最近更新 更多