gpt4 book ai didi

javascript - 如何定义一个 CoffeeScript 类,在第一次实例化时加载 jQuery,然后触发回调?

转载 作者:行者123 更新时间:2023-11-28 21:15:54 25 4
gpt4 key购买 nike

我对使用 JavaScript 的经典 OOP 还很陌生;这似乎是一个一般的 OOP 问题,但理想情况下我正在寻找使用 CoffeeScript 的实际代码示例来帮助我学习。

我想定义一个可以由任何其他函数/类实例化的类,但仅在第一次实例化时才执行其主要功能。直接的用例是一个可以由其他类调用的 LoadjQuery 类,该类动态处理加载 jQuery,但每个文档只能加载一次。首先实例化此类的代码可以提供选项和设置(jQuery 版本、缩小/开发版本和回调),但如果 jQuery 已加载,则实例化该类的任何其他尝试都将立即触发回调,或者等待它完成加载,然后触发回调。

这是我到目前为止编写的代码(有效但未经测试)。我不确定这是否是最优雅的方式。例如,有没有办法避免使用 @jquery_loading 标志和/或等待 jQuery 完成加载的 setInterval ?前者的存在只是为了防止代码被多次执行,这就是我想找到一种更自然的方法,而不是依赖于标志和条件分支。后者似乎不必要且尴尬,我想到了一种类似于 Google Analytics 的 _gaq 队列的方法(其中构建了待处理操作的队列,一旦 Google Analytics 库加载,它就会通过队列;随后添加到队列中的内容会立即处理),但我不知道如何实现它,而且可能不需要那么复杂。

# load jQuery dynamically (see: http://code.google.com/apis/libraries/devguide.html#jquery)
class LoadjQuery

@jquery_loading = false
@jquery_loaded = false

constructor: (callback, version = 1, compressed = true) ->
if @jquery_loading # only load once per document
if @jquery_loaded
callback()
else
check_jquery = ->
if @jquery_loaded
clearInterval check_jquery
callback()
setInterval check_jquery, 100
else
@jquery_loading = true # set flag
script = document.createElement 'script'
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/#{version}/jquery#{if compressed then '.min' else ''}.js"
script.onload = -> # set up event handler to ensure that jQuery is loaded before the callback is executed
if not @jquery_loaded
@jquery_loaded = true # set flag
callback()
script.onreadystatechange = -> # alternative event handler needed for Opera and IE
if not @jquery_loaded and (script.readyState is 'loaded' or script.readyState is 'complete')
@jquery_loaded = true # set flag
callback()
(document.getElementsByTagName('head') or document.getElementsByTagName 'body')[0].appendChild script

我正在寻找的可能是单例吗?如果是这样,最佳实践实现是什么(我见过几种不同的方法),您能给出一个代码示例吗?

谢谢!

最佳答案

你把事情搞得太复杂了。

既然您已经在使用他们的 CDN,为什么不使用 Google 的加载程序呢?

<script type="text/javascript" src="https://www.google.com/jsapi?key=INSERT-YOUR-KEY"></script>
<script type="text/coffeescript">
google.load "jquery", "1.6.4"
</script>

这是一个简单的加载器实现:

# load scripts dynamically
class ScriptLoader

libraries =
jQuery: "http://ajax.googleapis.com/ajax/libs/jquery/$version/jquery.js"

constructor: (options..., callback) ->

[lib, version, compressed] = options
if @libraries[lib] then lib = @libraries[lib]

loadCallback = =>
return if @loaded
@loaded = true
callback()

s = document.createElement 'script'
s.onload = loadCallback
s.onreadystatechange = ->
loadCallback() if /loaded|complete/.test(s.readyState)

s.src = lib.replace('$version', version)
if compressed then lib = lib.replace('.js', '.min.js')

(document.getElementsByTagName('head')?[0] or document.body).appendChild s

你可以用它作为

new ScriptLoader 'jQuery', '1.6', -> alert window.jQuery

我正在遵循您的初始结构,但请记住,您不应该因为对象的副作用而实例化对象;最好有某种在内部使用它的工厂方法:

loadScript 'jQuery', '1.6', -> ...
# or
ScriptLoader.load 'jQuery', -> ...

关于javascript - 如何定义一个 CoffeeScript 类,在第一次实例化时加载 jQuery,然后触发回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7616880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com