Firefox上的JavaScript TinyMCE/jQuery竞争条件

Mac*_*cki 7 javascript firefox jquery tinymce

我有一个网站,其表格使用TinyMCE; 独立地,我使用jQuery.当我从Firefox 3(MacOS X,Linux)上的登台服务器加载表单时,TinyMCE无法完成加载.Firefox控制台出错,说t.getBody()返回了null. t.getBody()据我所知,从TinyMCE docs,是一个函数返回文档的body元素,以检查某些功能.使用Safari时不会出现问题,也不会在使用从localhost运行的同一站点的Firefox时出现问题.

原始的,失败的JavaScript相关代码如下所示:

<script type="text/javascript" src="http://static.alfa.foo.pl/json2.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.ui.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
  tinyMCE.init({ mode:"specific_textareas", editor_selector:"mce", theme:"simple", language:"pl" });
</script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.jeditable.js"></script>
<script type="text/javascript" src="http://static.alfa.foo.pl/jquery.tinymce.js"></script>
<script type="text/javascript" charset="utf-8" src="http://static.alfa.foo.pl/foo.js"></script>
<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ });
</script>
Run Code Online (Sandbox Code Playgroud)

我尝试更改脚本加载顺序,移动 tinyMCE.init() call to the <script/> 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:

tinyMCE.init({ mode:"none", theme:"simple", language:"pl" });
Run Code Online (Sandbox Code Playgroud)

and added following jQuery call to the $(document).ready() handler:

$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });
Run Code Online (Sandbox Code Playgroud)

t.getBody() before the tinyMCE.execCommand()调用,发出警报,并正确初始化TinyMCE textareas.我认为这可能是等待用户解除警报引起的延迟问题,所以我通过将$(document).ready()处理程序中的调用更改为以下内容来引入第二个延迟:

setTimeout('$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });',1000);
Run Code Online (Sandbox Code Playgroud)

随着超时,TinyMCE textareas正确初始化,但它正在围绕真正的问题进行管道录制.问题看起来像一个明显的竞争条件(特别是当我考虑在同一个浏览器上,但当服务器在localhost上时,问题不会发生).但是JavaScript执行是不是单线程?有人可以告诉我这里发生了什么,实际问题在哪里,我能做些什么来实际修复它?

Jon*_*ski 5

浏览器按照加载的顺序执行脚本,而不是写入.您的直接脚本 - tinyMCE.init(...)$(document.ready(...));- 可以在文件加载完成之前执行.

因此,问题可能是网络延迟 - 特别是有6个独立的脚本(每个脚本需要在浏览器和服务器之间进行不同的HTTP对话).因此,浏览器可能tinyMCE.init()tiny_mce.js完成解析并tinyMCE完全定义之前尝试执行.

如果没有Firebug,那就去吧.;)
它有一个Net选项卡,可以显示加载所有脚本需要多长时间.


虽然您可能会认为它setTimeout是管道编带,但它实际上是一个不错的解决方案.我看到的唯一问题是它假定1秒将始终固定.快速连接,他们可以看到暂停.连接速度慢而且等待时间不够长 - 您仍然会收到错误消息.

或者,您可以使用window.onload- 假设jQuery尚未使用它.(其他人可以验证吗?)

window.onload = function () {
    tinyMCE.init(...);

    $(document).ready(...);
};
Run Code Online (Sandbox Code Playgroud)

还有,那是直接复制吗?

<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ }
</script>
Run Code Online (Sandbox Code Playgroud)

它错过了)结局ready:

<script type="text/javascript">
  $(document).ready(function(){
    /* jQuery initialization */ })
</script>
Run Code Online (Sandbox Code Playgroud)

缺少标点符号会造成大量伤害.解析器只是在找到它之前继续阅读 - 弄乱它们之间的任何东西.