7

我有一个使用 TinyMCE 表单的网站;独立地,我使用 jQuery。当我从 Firefox 3(MacOS X、Linux)上的登台服务器加载表单时,TinyMCE 没有完成加载。Firefox 控制台出现错误,提示t.getBody()返回null. t.getBody(),据我从 TinyMCE 文档中了解到的,是一个返回文档正文元素以检查某些功能的函数。当我使用 Safari 时不会出现问题,当我使用 Firefox 和从 localhost 运行的同一站点时也不会出现问题。

原始的、失败的 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>

我尝试更改脚本加载顺序,移动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.

Then, after googling a bit about using TinyMCE together with jQuery, I changed tinyMCE.init() call to:

tinyMCE.init({ mode:"none", theme:"simple", language:"pl" });

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

$(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); });

Still the same error. But, and here's where things start to look like real voodoo, when I added alert(i); before the tinyMCE.execCommand()调用,发出警报,并且 TinyMCE 文本区域已正确初始化。我认为这可能是由于等待用户解除警报而引入的延迟问题,因此我通过将仍在 $(document).ready() 处理程序中的调用更改为以下内容来引入一秒钟的延迟:

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

随着超时,TinyMCE textareas 正确初始化,但它是围绕真正问题的管道胶带。这个问题看起来像是一个明显的竞争条件(特别是当我考虑在同一个浏览器上,但当服务器在本地主机上时,问题不会发生)。但是 JavaScript 执行不是单线程的吗?任何人都可以告诉我这里发生了什么,实际问题在哪里,以及我能做些什么来真正解决它?

4

3 回答 3

5

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

因此,问题可能是网络延迟——尤其是使用 6 个单独的脚本(每个脚本需要浏览器和服务器之间的不同 HTTP 对话)。因此,浏览器可能会在tiny_mce.js完成解析并完全定义tinyMCE.init()之前尝试执行。tinyMCE

如果没有 Firebug,请获取它。;)
它有一个Net选项卡,可以显示加载所有脚本需要多长时间。


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

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

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

    $(document).ready(...);
};

另外,那是直接复制的吗?

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

它缺少)结尾ready

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

缺少标点符号会造成很大的损害。解析器将继续阅读,直到找到它——弄乱中间的任何东西。

于 2008-12-07T03:17:15.393 回答
2

由于这是当我问自己同样的问题时进入谷歌的第一页,这就是我发现的关于这个问题的信息。

资源

tinyMCE 中有一个回调函数,该函数在组件加载并准备就绪时触发。你可以像这样使用它:

tinyMCE.init({
   ...
   setup : function(ed) {
      ed.onInit.add(function(ed) {
          console.log('Editor is loaded: ' + ed.id);
      });
   }
});
于 2010-02-19T14:41:31.460 回答
1

如果您正在使用jquery.tinymce.js,则不需要tiny_mce.js,因为 TinyMCE 将尝试使用 ajax 请求加载它。如果您发现window.tinymce(或简单地tinymce)是,undefined那么这意味着 ajax 尚未完成(这可能解释了为什么 usingsetTimeout对您有用)。这是典型的事件顺序:

  1. jquery.js使用脚本标签(或谷歌加载)加载。
  2. jquery.tinymce.js使用脚本标签加载 TinyMCE 的 jQuery 插件。
  3. 文档就绪事件触发;这是您调用s 的.tinymce(settings)地方。textarea例如 $('textarea').tinymce({ script_url: '/tiny_mce/tiny_mce.js' })

  4. 加载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); } });

于 2011-06-11T17:45:26.177 回答