【问题标题】:Using jQuery UI in a Bookmarklet在书签中使用 jQuery UI
【发布时间】:2011-07-10 21:18:05
【问题描述】:

在 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()

它不起作用。有趣的是,它在尝试最后一行时确实有效:来自控制台的$("#nm-container").tabs()。我在下面附上完整的代码。请注意,我正在使用 CoffeeMarklet 生成似乎仅适用于 chrome 的小书签。

s1 = window.document.createElement('script')
s1.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js'
window.document.body.appendChild(s1)

$ ->

    s2 = window.document.createElement('script')
    s2.src = 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js'
    window.document.body.appendChild(s2)

    jqueryUIcss = window.document.createElement('link')
    jqueryUIcss.rel = 'stylesheet'
    jqueryUIcss.type = 'text/css'
    jqueryUIcss.href = 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/blitzer/jquery-ui.css'
    window.document.head.appendChild(jqueryUIcss)

    if $("#nm-toolbar").length == 0
        toolbar = "<div id='nm-toolbar'></div>"
        $("body").append(toolbar)
        $("#nm-toolbar").css({
            'background':               '#fafafa',
            'height':                   '500px',
            'width':                    '400px',
            'position':                 'fixed',
            'bottom':                   '0px',
            'right':                    '20px',
            'padding':                  '5px'
        })

        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()

【问题讨论】:

  • CoffeeMarklet 工具似乎使用了 Ben Alman 的 jQuery 加载解决方案,可以在这里看到它的未压缩形式:benalman.com/code/javascript/jquery/…
  • 这很奇怪。当我只使用自动添加 jQuery 时它不起作用,当我使用我自己的代码时它仍然不起作用但它一起加载 jquery。奇怪。
  • 我认为您需要修改 Ben Alman 的代码,以便在执行 .noConflict 之前加载 jQuery UI。

标签: javascript jquery jquery-ui bookmarklet coffeescript


【解决方案1】:

我怀疑问题在于您正在异步加载 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

编辑:就此而言,您确实应该对s1 做同样的事情,否则$ -&gt; 调用可能会失败。它成功的事实表明您在浏览器中缓存了 jQuery,或者页面上已经有 jQuery。您还应该使用noConflict 来避免覆盖页面现有的jQuery 版本。 Acorn 链接到的 Run jQuery Code Bookmarklet 完成了所有这些事情(并且以比此答案中的代码更跨浏览器的方式)。

【讨论】:

  • 我不明白为什么需要第二行。 (它仍然不起作用)。
  • @Radagaisus 嗯。如果在onreadystatechange 回调的顶部添加console.log @readyState,您会在控制台中看到什么?
  • 我自己试了一下,似乎问题出在匿名函数内部加载了jQuery,因此加载jQueryUI时找不到它。有没有办法让 jQuery UI 在持有 jQuery 的特定变量上做它的事情?
  • 我的解决方案@Trevor 的风格有任何 cmets 吗?我使用 CoffeeScript 的时间不长,很高兴知道是否有什么我应该做的不同的事情。
【解决方案2】:

这应该可行:

((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 页面上的“添加 jQuery”选项

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

虽然它可以通过检查是否已经存在正确版本的 jQuery 来改进,就像 Ben Almans 代码一样。

归因:

Beygi给了a lovely snippet一个接一个的加载javascript资源。

【讨论】:

  • 既然你问了,这就是我如何为你的代码设置样式:gist.github.com/1059210 主要是,我将函数嵌套减少到 1 级(如果算上回调生成器,则为 2 级)。此外,您应该能够不使用done 变量,而只需检查script.onload 是否为非空。
  • 假设我在网站上有 jQuery 1.5,我从书签加载 jQuery 1.6,这会不会搞砸或者 noConflict 会解决这个问题?
  • 还要注意错字:windows 而不是 window
  • 感谢您指出错字。不,它不会影响网页上显示的 jQuery 版本,因为我们使用的是window.jQuery.noConflict(1)。初始化 jQuery 时,它会保存之前使用 $ 的任何内容。当您调用noConflict 时,它会将之前的内容作为$ 放回全局名称空间,然后您在本地名称空间中拥有更新版本的jQuery。我希望我已经正确地解释了这一点并且它是有道理的,这就是我收集它的方式。
  • 谢谢。更多注意事项:如果不是 (jqui_version = window.jQuery.ui.version) 或 requirements['jqui'] > jqui_version 是 (a) 相当模糊 (b) 无法正常工作。一个对我有用的版本,但不是所有时候,如果不是(window.jQuery.ui == undefined),但我完全不理解这段代码=/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多