如何在 jquery 确认为定义后 运行 内联脚本

How to run inline script AFTER jquery confirmed as defined

我在特定情况下工作,我正在尝试为 运行 制作一个光滑的滑块轮播。

我得到一个错误 $ is not defined.

除非我用

window.onload = function(e){
  $(document).ready(function () {
    $('.js-slick').slick({
      autoplay: true,
      autoplaySpeed: 5000,
      dots: true,
      fade: true,
      speed: 1000
    });
  });
};

问题是,这个滑块是页面上的第一个东西,所以我不能等到所有内容都加载完毕,因为它需要很长时间。

我无法更改脚本标签的顺序或确保 jQuery link 正确放置在头部等等。

我知道页面上的其他滑块工作正常,而且我也知道这个特定的滑块在加载正确的文件后工作正常

必须有一种方法来检查 $ 是否已定义,一直检查直到它被定义,然后 运行 脚本一旦确认。

使用服务员:

setTimeout(function wait(){
 if(!window.$) return setTimeout(wait, 100);

 // do stuff needing $ here:
 console.info("$=", $);
}, 100);
var timer = setInterval(checkjQuery, 5000);

function checkjQuery() {
  if(window.jQuery) {
    clearInterval(timer);
    callSlick();
    console.log('jQuery is loaded');
    return;
  } else {
    console.log('waiting');
  }
}

function callSlick() {
  $('.js-slick').slick({
      autoplay: true,
      autoplaySpeed: 5000,
      dots: true,
      fade: true,
      speed: 1000
    });
};

类似于 DanDavis 解决方案

IMO @dandavis 的回答最简单地解决了这个问题。

我想提供一种使简单的 "wait-er" 可重用的方法,并展示如何将其与您共享的代码集成。

一个可重复使用的等待器:

function waitUntil(getResource, callback) {
  // Copied from @dandavis' answer
  setTimeout(function wait() {
    const resource = getResource();
    if(!resource) return setTimeout(wait, 100);

    callback(resource);
  }, 100);
}

window.onload = function(e) {
  waitUntil(function () { return window.$; }, function () {
    $(document).ready(function () {
      $('.js-slick').slick({
        autoplay: true,
        autoplaySpeed: 5000,
        dots: true,
        fade: true,
        speed: 1000
      });
    });
  });
};

或者如果你愿意,你可以让它基于承诺:

function waitUntil(getResource) {
  return new Promise((resolve, reject) => {
    setTimeout(function wait() {
      const resource = getResource();
      if(!resource) return setTimeout(wait, 100);

      resolve(resource);
    }, 100);
  });
}

window.onload = function(e) {
  waitUntil(function () { return window.$; })
    .then(function () {
      $(document).ready(function () {
        $('.js-slick').slick({
          autoplay: true,
          autoplaySpeed: 5000,
          dots: true,
          fade: true,
          speed: 1000
        });
      });
    });
};