通过
编辑:更新详细信息以添加 Firefox/Chrome 行为的差异
我正在尝试创建一个将加载 jQuery 和 jQueryUI 的书签。 jQuery 加载使用 javascript,但我想既然 jQuery 已加载,我会继续使用它来加载 UI。 除了让它工作之外,我真的很想了解为什么这不起作用。我仍然在思考范围/闭包/等问题。但我只是不明白为什么在 Firefox 中 $ 不起作用,而“jQuery”却起作用! $ 在 Chrome 中工作正常,但我在那里遇到了不同的问题。
注释:
1) 在 FireBug/FireFox 中,我得到 '$("head") 未定义'
2) 在 Chrome 中,“$”工作正常,但 jQueryUI 调用失败,对象 [object Object] 没有方法 'dialog'
3) 回调保证 jQuery 在我尝试使用它时已加载。在 Firefox 中,如果我将“$”替换为“jQuery”(例如 jQuery("head) ),那么代码就可以工作!
4) 页面上没有其他库已在使用 $
5) 更令人沮丧的是,在 Firefox 中,如果我只是屈服并使用“jQuery”而不是“$”,然后设置 $("#jquilib").load() 的回调来调用第三个函数,jQueryUI 函数,如 .tabs() 和 .dialog() 不可用,即使回调本身是由可用的 jQueryUI 触发的!
6) 在 Chrome 中,如果我将 setTimeout() 设置为 100 毫秒,jQueryUI 问题就会消失。如果我降低到 1 毫秒或其他时间,问题仍然存在。
我正在使用这篇文章中的 getScript 函数: http://www .learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet。
下面是我的代码:
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
// Attach handlers for all browsers
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState
|| this.readyState == 'loaded'
|| this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
function initializejQueryUI(){
if (typeof jQuery.ui == 'undefined'){
// jQueryUI library & jQueryUI cupertino theme
$('head').append("<link href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/cupertino/jquery-ui.css' type='text/css' rel='stylesheet'>");
$('head').append("<script id='jquilib' type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js'></script>");
}
$("#jquilib").load($("<div>jQuery & UI Loaded!</div>").dialog());
}
getScript('https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js', initializejQueryUI); // call initializejQueryUI as callback when jQuery loads
Edit: Details updated to add differences in Firefox/Chrome behavior
I am trying to create a bookmarklet that will load both jQuery and jQueryUI. The jQuery load uses javascript, but I figured since jQuery was loaded I'd go ahead and use it for the UI loading. More than getting it to work I really want to understand why this doesn't work. I'm still wrapping my head around scope/closures/etc. But I just don't see why in firefox $ doesn't work but "jQuery" does! The $ works fine in Chrome but I get a DIFFERENT issue there.
Notes:
1) In FireBug/FireFox I get '$("head") is undefined'
2) In Chrome the "$" works fine, but the jQueryUI call fails with Object [object Object] has no method 'dialog'
3) the callback guarantees jQuery is loaded by the time I try to use it. In Firefox if I replace "$" with "jQuery" ( such as jQuery("head) ) then the code works!.
4) there are no other libraries on the page already using $
5) Even more frustrating, in Firefox if I just give in and use "jQuery" rather than "$" and then set the callback from $("#jquilib").load() to call a third function, jQueryUI functions such as .tabs() and .dialog() are unavailalble even though the callback itself was triggered by jQueryUI being available!
6) In Chrome the jQueryUI issue goes away if I use setTimeout() to 100ms. If I go down to 1ms or something than the issue persists.
I am using the getScript function from this post: http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet.
Below is my code:
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
// Attach handlers for all browsers
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState
|| this.readyState == 'loaded'
|| this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
function initializejQueryUI(){
if (typeof jQuery.ui == 'undefined'){
// jQueryUI library & jQueryUI cupertino theme
$('head').append("<link href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/cupertino/jquery-ui.css' type='text/css' rel='stylesheet'>");
$('head').append("<script id='jquilib' type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js'></script>");
}
$("#jquilib").load($("<div>jQuery & UI Loaded!</div>").dialog());
}
getScript('https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js', initializejQueryUI); // call initializejQueryUI as callback when jQuery loads
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,经过多次尝试错误后弄清楚了。我继续在 Chrome 中开发我的脚本,看起来我比 Firefox 走得更远。当我完成我的小书签时,我突发奇想在 Firefox 中尝试了它,它也在那里工作!这是我学到的:
1)
$("#jquilib").load($("
").dialog ());
调用不起作用,因为 jQuery 在处理脚本后删除了通过 DOM 追加添加的元素!重新使用 getScript() 函数来获取 jQueryUI 并将警报放入从回调调用的函数中会更容易。我遇到的选项卡创建问题(上述问题中的第 5 项)就是这个怪癖的结果。参考: http://api.jquery.com/append/ < br>搜索 Karl Swedberg 说“是的,这很正常”
2) Firebug 似乎在控制台中使用了“$”,导致了像我描述的情况上面“$”不起作用但是jQuery() 确实有效。似乎有一些规则控制何时释放“$”,因为如果我尝试再次运行脚本,jQuery 的 $ 快捷方式会突然起作用。这是最令人沮丧的部分,因为它看起来像是范围和/或时间问题!
Ok, figured it out after a lot of trial an error. I went ahead and continued developing my script in Chrome seems it seemed I got further than in Firefox. When I completed my bookmarklet I tried it on a whim in Firefox and it worked there too! Here's what I learned:
1) The
$("#jquilib").load($("<div>jQuery & UI Loaded!</div>").dialog());
call doesn't work because jQuery removes elements added via append from the DOM after processing the script! It was easier just to re-use thegetScript()
function to also get jQueryUI and put the alert in a function called from the callback. The tab creation issue I encountered (item #5 in the question above) was a result of this quirk.Reference: http://api.jquery.com/append/
Search for Karl Swedberg saying "yes, it's normal"
2) Firebug seems to make use of the "$" while in the console, leading a situation like my description above where "$" doesn't work but jQuery() does work. There seem to be some rules governing when it releases the "$" because if i just try running the script again jQuery's $ shortcut suddenly works. This was the most frustrating part because it made it appear like a scope and/or timing issue!