Firefox上的JavaScript TinyMCE / jQuery竞争条件
我有一个网站,其表格使用TinyMCE; 独立地,我使用jQuery。 当我从Firefox 3(MacOS X,Linux)上的登台服务器加载表单时,TinyMCE无法完成加载。 Firefox控制台中有一个错误,说t.getBody()
返回null
。 t.getBody()
,据我所知,从TinyMCE docs,是一个函数,返回文档的body元素,以检查某些function。 使用Safari时不会出现问题,也不会在使用从localhost运行的同一站点的Firefox时出现问题。
原始的,失败的JavaScript相关代码如下所示:
tinyMCE.init({ mode:"specific_textareas", editor_selector:"mce", theme:"simple", language:"pl" }); $(document).ready(function(){ /* jQuery initialization */ });
我尝试更改脚本加载顺序,将tinyMCE.init()
移动call to the
tag containing
$(document).ready()
call—before, after, and inside this call. No result. When tinyMCE.init()
was called from within
$(document).ready()
handler, the browser did hang on request—looks like it was too late to call the init function.tinyMCE.init() call to the
tag containing
$(document).ready()
call—before, after, and inside this call. No result. When tinyMCE.init()
was called from within
$(document).ready()
handler, the browser did hang on request—looks like it was too late to call the init function.tinyMCE.init()
call to the
tag containing
$(document).ready()
call—before, after, and inside this call. No result. When tinyMCE.init()
was called from within
$(document).ready()
handler, the browser did hang on request—looks like it was too late to call the init function.
然后,在谷歌搜索与jQuery一起使用TinyMCE之后,我将tinyMCE.init()
调用改为:
tinyMCE.init({ mode:"none", theme:"simple", language:"pl" });
并添加了以下jQuery调用$(document).ready()
处理程序:
$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });
还是一样的错误。 但是,当我添加警报(i)时,这里的东西开始看起来像真正的伏都教; 在tinyMCE.execCommand()调用之前,给出了警报,并正确初始化了TinyMCE textareas。 我认为这可能是等待用户解除警报引起的延迟问题,所以我通过更改仍在$(document).ready()处理程序内的调用来引入第二个延迟:
setTimeout('$(“。mce”)。each(function(i){tinyMCE.execCommand(“mceAddControl”,true,this.id);});',1000);
随着超时,TinyMCE textareas正确初始化,但它正在绕过真正的问题。 问题看起来像一个明显的竞争条件(特别是当我考虑在同一个浏览器上,但当服务器在localhost上时,问题不会发生)。 但是JavaScript执行是不是单线程? 有人可以告诉我这里发生了什么,实际问题在哪里,我能做些什么来实际修复它?
浏览器按照加载的顺序执行脚本,而不是写入。 你的直接脚本 – tinyMCE.init(...)
和$(document.ready(...));
– 可以在文件完成加载之前执行。
因此,问题可能是网络延迟 – 尤其是6个独立的脚本(每个脚本需要在浏览器和服务器之间进行不同的HTTP对话)。 因此,浏览器可能在tiny_mce.js完成解析并且tinyMCE
完全定义之前尝试执行tinyMCE.init()
。
如果没有Firebug, 那就去吧。 ;)
它有一个Net选项卡,可以显示加载所有脚本需要多长时间。
虽然您可能会认为setTimeout
是风管编带,但它实际上是一个不错的解决方案。 我看到的唯一问题是它假设1秒将永远修复。 快速连接,他们可以看到暂停。 连接速度慢而且等待时间不够长 – 您仍然会收到错误。
或者,您可以使用window.onload
– 假设jQuery尚未使用它。 (其他人可以validation吗?)
window.onload = function () { tinyMCE.init(...); $(document).ready(...); };
还有,那是直接复制吗?
它错过了结束ready
:
缺少标点符号会造成大量伤害。 解析器只是在它找到它之前继续阅读 – 弄乱它们之间的任何东西。
因为当我问自己同样的问题时,这是谷歌的第一页,这就是我发现的这个问题。
资源
tinyMCE中有一个回调函数,当组件加载并准备就绪时会触发该函数。 你可以像这样使用它:
tinyMCE.init({ ... setup : function(ed) { ed.onInit.add(function(ed) { console.log('Editor is loaded: ' + ed.id); }); } });
如果您使用的是jquery.tinymce.js
那么您不需要tiny_mce.js
因为TinyMCE会尝试使用ajax请求加载它。 如果你发现window.tinymce
(或简称tinymce
)是undefined
那么这意味着ajax尚未完成(这可能解释了为什么使用setTimeout
为你工作)。 这是典型的事件顺序:
- 使用脚本标记(或谷歌加载)加载
jquery.js
。 - 使用脚本标记加载TinyMCE的jQuery插件
jquery.tinymce.js
。 -
记录准备好的事件火灾; 这是你在
textarea
上调用.tinymce(settings)
的地方。 例如$('textarea').tinymce({ script_url: '/tiny_mce/tiny_mce.js' })
-
加载
tiny_mce.js
这一步是由TinyMCE的jQuery插件为你完成的,但它可能在文件就绪事件触发后发生。
有时您可能真的需要访问window.tinymce
,这是最安全的方法:
$(document).tinymce({‘script_url’:’/ tiny_mce / tiny_mce.js”setup’:function(){alert(tinymce);}});
TinyMCE甚至可以创建一个tinymce.Editor
对象并执行设置回调。 没有触发编辑器的事件,并且没有将为文档创建的编辑器对象添加到tinymce.editors
。
我还发现TinyMCE的ajax调用干扰了我的.ajaxStop
函数,所以我也使用了setTimeout
:
$(document).tinymce({‘script_url’:’/ tiny_mce / tiny_mce.js”setup’:function(){setTimeout(function(){$(document).ajaxStart(function(e){/ * stuff / } ;; $(document).ajaxStop(function(e){/ stuff * /});},0);}});