1

如果我包含一个带有外部源的脚本,然后尝试使用 jQuery 进行解析 - 它会下载脚本,但不会将其加载到 DOM 中。我正在使用 using .append(),但这似乎是任何其他 jQuery DOM 插入方法的情况。

这是堆栈片段中的一个示例

$(function(){
  
  var selet2Html =
    '<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>' +
    '<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js" ><\/script>' +
    '<select class="select2">' +
    '  <option value="AK">Alaska</option>' +
    '  <option value="HI">Hawaii</option>' +
    '</select>' +
    '<script >' +
    '  $(function() {' +
    '    $(".select2").select2();' +
    '  });' +
    '<\/script>';
    
  $("body").append(selet2Html);
  
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

即使这会在网络选项卡中下载脚本:

网络活动

它仍然会返回以下错误(表明外部库 - select2 - 从未加载):

未捕获的类型错误:$(...).select2 不是函数

我不想使用$.getScript(),因为我实际上是用 动态加载这个字符串.load(),所以我不确定它是否会包含任何外部脚本。

我怎样才能让它加载外部库?

4

1 回答 1

0

所以 dandavis 是对的 - 在调用初始化程序之前,库需要时间加载。一个幼稚的实现可能只需要等待很短的时间,然后再试一次,如下所示:

setTimeout( function() {
  $(".select2").select2();
}, 2000);

Stack Snippets 中的简单演示:

$(function(){
  
  var selet2Html =
    '<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>' +
    '<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js" ><\/script>' +
    '<select class="select2">' +
    '  <option value="AK">Alaska</option>' +
    '  <option value="HI">Hawaii</option>' +
    '</select>' +
    '<script >' +
    '  setTimeout( function() {' +
    '    $(".select2").select2();' +
    '  }, 2000);' +
    '<\/script>';
   
  $("body").append(selet2Html);
  
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

更复杂的解决方案会等到$.fn.select2出现在 DOM 中。

进入OnAvailable

你可以这样称呼它:

onAvailable('$.fn.select2', function() {
  alert('we did it');
});

这是将轮询全局名称空间以弹出变量的函数。它使用了 Alnitak 的Object.byString解决方案,来自Accessing nested JavaScript objects with string key

function onAvailable(listenFor, callback) {
  var interval = window.setInterval(function() {
    if (Object.byString(window, listenFor)) {
      clearInterval(interval);
      callback()
    }
  }, 100);
};

Stack Snippets 中的高级演示

function onAvailable(listenFor, callback) {
  var interval = window.setInterval(function() {
    if (objectFromString(window, listenFor)) {
      clearInterval(interval);
      callback()
    }
  }, 100);
};

function objectFromString(o, s) {
  s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  s = s.replace(/^\./, '');           // strip a leading dot
  var a = s.split('.');
  for (var i = 0, n = a.length; i < n; ++i) {
    var k = a[i];
    if (k in o) {
      o = o[k];
    } else {
      return;
    }
  }
  return o;
}

$(function(){
  
  var selet2Html =
    '<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>' +
    '<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js" ><\/script>' +
    '<select class="select2">' +
    '  <option value="AK">Alaska</option>' +
    '  <option value="HI">Hawaii</option>' +
    '</select>' +
    '<script >' +
    '  onAvailable("$.fn.select2", function() {' +
    '    $(".select2").select2();' +
    '  });' +
    '<\/script>';
   
  $("body").append(selet2Html);
  
  
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

于 2015-07-01T13:08:41.943 回答