现在在页面末尾/而不是在<head>
中加载脚本似乎是很常见的做法。问题是当你需要由于模板结构、变量访问等原因在正文中内联运行一些 jQuery 时,具体取决于项目。
以后定义jQuery后将函数排队运行的最简单方法(最好是vanilla JS)是什么?
有很多复杂的JS库来处理这个问题,我更喜欢一个零文档的脑死亡/可理解的过程。
是否有一个公认的"一行",在没有代码负载的情况下很有用?
这是 CoffeeScript 的第 1 轮有效,只是为了表明我正在自己付出一些努力来回答它。接下来,我将它转换为JS,并尝试提出一个更简单的api。
class root.DeferUntil
constructor: ({@deferredFunction, @deferralCheck} = {}) ->
@interval = setInterval @executeIfLoaded, 500
executeIfLoaded: =>
if not @executed and @deferralCheck()
@deferredFunction()
clearInterval @interval
new DeferUntil
deferredFunction: ->
console.log "Hi, #{$} shouldn't raise errors"
deferralCheck: ->
$ != undefined
我过去用过这样的东西:
window.Preload = $.extend [],
run: (e) -> e(window.$)
load: ->
@shift = @run
@push = @run
@run(func) for func in @
@splice(0, @length)
然后,您可以将函数推送到 Preload 数组中:
Preload.push ($) ->
# Do something with jQuery here
加载 jQuery 后:
Preload.load()
这将执行所有预加载函数,如果已经调用load()
,则推送到 Preload 的函数会立即执行。此模式对于所有类型的异步加载行为都很有用,在异步加载行为中,您希望仅在满足前提条件后运行某些函数,而不必知道前提条件是否满足。
如果你控制页面布局,那么最简单的方法可能是将函数调用放在页面末尾的jQuery之后。
如果你可以在你正在等待的jQuery脚本之后放置一些代码,但希望这些代码是通用的,而不是专门绑定到你的其他代码,那么你可以放这样的东西。
把它放在你的代码之前:
var readyFns = [];
function runReady() {
for (var i = 0; i < readyFns.length; i++) {
readyFns[i]();
}
}
function addReady(fn) {
readyFns.push(fn);
}
把这个放在jQuery脚本标签之后:
$(document).ready(runReady);
在你的代码中的任何地方(在第一个代码块之后,但在jQuery之前),你可以用这个来调度任何读取函数:
addReady(function() {
// put your code here
});
如果你真的想要一些不干涉的东西,你可以在加载jQuery时轮询。
(function() {
function check() {
if (window.jQuery) {
// put your jQuery code here
} else {
setTimeout(check, 1);
}
}
setTimeout(check, 1);
})();
使其他任何事情变得困难的是,您要做的是等待尚未解析的脚本标记加载。 由于尚未分析,因此无法在其上安装任何事件处理程序。