Javascript 在Bookmarklet中使用jqueryui

Javascript 在Bookmarklet中使用jqueryui,javascript,jquery,jquery-ui,bookmarklet,coffeescript,Javascript,Jquery,Jquery Ui,Bookmarklet,Coffeescript,在CoffeeScript中,尽管此代码与JavaScript几乎相同: tabs_html = "<div id='nm-container'><ul><li><a href='#tabs-1'>Guidelines</a></li><li><a href='#tabs-2'>Test</a></li></ul> <div id='t

在CoffeeScript中,尽管此代码与JavaScript几乎相同:

tabs_html = "<div id='nm-container'><ul><li><a href='#tabs-1'>Guidelines</a></li><li><a href='#tabs-2'>Test</a></li></ul>
            <div id='tabs-1'><p>something1</p></div><div id='tabs-2'><p>something2</p></div></div>"
$("#nm-toolbar").append(tabs_html)
$("#nm-container").tabs()

我怀疑问题在于您正在异步加载jQuery UI。线路

window.document.body.appendChild(s2)
开始加载jQuery UI,但在必须加载jQuery UI之前,您的代码将继续。这就解释了为什么代码中的
tabs()
调用失败,但在脚本有时间加载之后,从控制台执行调用时成功了

您应该能够通过使其余代码从回调中运行来修复此问题

s2.onreadystatechange = ->
  return unless @readyState is 'complete'
  # the rest of the code goes here

Edit:因此,您确实应该对
s1
执行相同的操作,否则
$->
调用可能会失败。它成功的事实表明,要么在浏览器中缓存了jQuery,要么页面上已经有jQuery。您还应该使用
noConflict
,以避免覆盖页面的现有jQuery版本。Acorn链接到的应用程序可以完成所有这些任务(并且比此答案中的代码更具跨浏览器性)。

这应该是可行的:

((window, document, requirements, callback) ->
    getScript = (url, callback) ->
        script = document.createElement('script')
        script.src = url
        head = document.documentElement.childNodes[0]
        done = false
        script.onload = script.onreadystatechange = ->
          if not done and (not (readyState = @readyState) or readyState == 'loaded' or readyState == 'complete')
            done = true
            callback()
            script.onload = script.onreadystatechange = null
            head.removeChild script

        head.appendChild script

    if not ($ = window.jQuery) or requirements['jq'] > $.fn.jquery
        getScript 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js', ->
            getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                callback window.jQuery.noConflict(1)
    else
        if not (jqui_version = window.jQuery.ui.version) or requirements['jqui'] > jqui_version
            getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                callback window.jQuery.noConflict(1)
        else
            callback window.jQuery.noConflict(1)

) window, document, {jq: '1.6.1', jqui: '1.8.7'}, ($) ->
    # Your code goes here:
    alert "jq: #{$.fn.jquery}, jqui: #{$.ui.version}"
如果使用上述代码,您可能希望取消选中CoffeeMarklet页面上的“AddjQuery”选项

更新: 添加了检查jQuery和jQuery UI是否存在的功能,因此不会不必要地加载它

尽管可以通过检查jQuery的正确版本是否已经像Ben Almans代码那样出现来改进它

归属:

((window, document, requirements, callback) ->
    getScript = (url, callback) ->
        script = document.createElement('script')
        script.src = url
        head = document.documentElement.childNodes[0]
        done = false
        script.onload = script.onreadystatechange = ->
          if not done and (not (readyState = @readyState) or readyState == 'loaded' or readyState == 'complete')
            done = true
            callback()
            script.onload = script.onreadystatechange = null
            head.removeChild script

        head.appendChild script

    if not ($ = window.jQuery) or requirements['jq'] > $.fn.jquery
        getScript 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js', ->
            getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                callback window.jQuery.noConflict(1)
    else
        if not (jqui_version = window.jQuery.ui.version) or requirements['jqui'] > jqui_version
            getScript 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js', ->
                callback window.jQuery.noConflict(1)
        else
            callback window.jQuery.noConflict(1)

) window, document, {jq: '1.6.1', jqui: '1.8.7'}, ($) ->
    # Your code goes here:
    alert "jq: #{$.fn.jquery}, jqui: #{$.ui.version}"

Beygi给出了一个又一个加载javascript资源的建议。

我不明白为什么需要第二行。(它仍然不起作用)。@Radagaisus-Hmm.如果在
onreadystatechange
回调的顶部添加
console.log@readyState
,你在控制台中看到了什么?我自己尝试过,问题似乎在于jQuery正在匿名函数中加载,因此当jQueryUI加载时,它找不到它。有没有一种方法可以让jQuery用户界面在包含jQuery的特定变量上运行?对我的解决方案@Trevor的风格有何评论?我使用CoffeeScript的时间不长,如果知道有什么我应该做的不同,那就太好了。CoffeeMarklet工具似乎使用了Ben Alman的jQuery加载解决方案,可以在这里看到它的未压缩形式:这很奇怪。当我只使用自动添加jQuery时,它不起作用;当我使用自己的代码时,它仍然不起作用,但一起加载jQuery。奇怪。我认为您需要修改Ben Alman的代码,以便在执行
.noConflict
之前加载jQuery UI。既然您提出了问题,下面是我如何设计代码的风格:主要是,我将函数嵌套降低到1级(如果您计算回调生成器,则为2级)。另外,不必使用
done
变量,只需检查
script.onload
是否为非空即可。假设我在网站上有jQuery 1.5,我从bookmarklet加载jQuery 1.6,这不会把事情搞砸吗?或者说没有冲突会解决这个问题吗?还要注意打字错误:windows而不是Window谢谢你指出了打字错误。不,它将使网页上的jQuery版本完全不受影响,因为我们使用的是
window.jQuery.noConflict(1)
。初始化jQuery时,它会保存以前使用的
$
的内容。当您调用
noConflict
时,它会将前面的内容作为
$
放回全局名称空间,然后在本地名称空间中有较新版本的jQuery。我希望我已经正确地解释了这一点,这是有意义的,这就是我收集它的工作原理。谢谢。更多说明:如果不是(jqui_version=window.jQuery.ui.version)或需求['jqui']>jqui_版本(a)非常模糊(b)工作不正常。一个对我有效的版本,但不是所有时候都有效(window.jQuery.ui==undefined),但我完全不能很好地理解这段代码=/