现在/不在<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
答案 0 :(得分:2)
我过去曾经使用过这样的东西:
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的函数会立即执行。此模式对于所有类型的异步加载行为都很有用,在这种行为中,只有在满足前提条件后才能运行某些函数,而不必知道是否满足前提条件。
答案 1 :(得分:1)
如果您正在控制页面布局,那么最简单的方法就是在页面末尾的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);
})();
让其他任何事情变得困难的是你要做的是等待脚本标签加载尚未解析的脚本标签。因为它尚未解析,所以无法在其上安装任何事件处理程序。