JavaScript对象属性是"有时"未定义

时间:2013-05-16 14:38:45

标签: javascript oop dom tinymce

我很困惑。

我创建了以下脚本,该脚本位于http://tapmeister.com/test/dom.html。由于某些未知原因,tinymce.editors.ta1和tinymce.editors [0]显示为未定义,并且尝试在其下使用方法会导致错误。但是当我使用FireBug检查tinymce或tinymce.editors时,我会在DOM中看到它们。

所以,我创建了一个jsfiddle http://jsfiddle.net/JWyWM/来向stackoverflow上的人们展示。但是当我测试它时,tinymce.editors.ta1和tinymce.editors [0]不再是未定义的,并且这些方法可以正常工作。

发生什么事了?也许与公共/受保护/私人财产有关?如何访问tinymce.editors.ta1.hide()等方法?谢谢!!!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Testing</title>  
        <script src="http://tinymce.cachefly.net/4.0/tinymce.min.js"></script>
        <script type="text/javascript"> 
            tinymce.init({selector: "textarea#ta1"});
            tinymce.init({selector: "textarea#ta2"});
            console.log(tinymce);
            console.log(tinymce.editors);
            console.log(tinymce.editors.ta1);
            console.log(tinymce.editors[0]);
            //tinymce.editors.ta1.hide();
            //alert('pause');
            //tinymce.editors.ta1.show();
        </script>
    </head>

    <body>
        <form>
            <textarea id="ta1"></textarea>
            <textarea id="ta2"></textarea>
        </form>
    </body> 
</html>

2 个答案:

答案 0 :(得分:3)

当您致电init时,TinyMCE不会立即完成所有设置工作。它提供了一个回调函数setup,告诉您何时完成工作。

因此,如果您提供setup回调,则可以与编辑器实例进行交互。

以下是一个示例(我还将您的脚本移到了最后,which is best practice regardless):

Live Example | Live Source

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Testing</title>  
    </head>

    <body>
        <form>
            <textarea id="ta1"></textarea>
            <textarea id="ta2"></textarea>
        </form>
        <script src="http://tinymce.cachefly.net/4.0/tinymce.min.js"></script>
        <script type="text/javascript"> 
            tinymce.init({
                selector: "#ta1, #ta2",
                setup:    function(e) {
                    console.log("Editor " + e.id + " is ready");
                }
            });
        </script>
    </body> 
</html>

现在,如果您想要实际访问编辑器实例,奇怪的是TinyMCE不会将其添加到tinymce.editors,直到调用setup函数之后。但如果你投入短暂的收益,那么你就完全没有了。以上是更改setup函数的上述内容:

Live Copy | Live Source

setup:    function(e) {
  // Bizarrely, TinyMCE calls `setup` *before* adding
  // the relevant editor to `tinymce.editors`,
  // so we have to yield briefly
  console.log("Editor " + e.id + " is ready");
  if (e.id === "ta2") {
    console.log("It's ta2, I'll hide it in a moment.");
    setTimeout(function() {
      tinymce.editors[e.id].hide();
    }, 0);
  }
}

那为什么它适用于jsFiddle?好吧,jsFiddle有一个真正的脑死亡 令人惊讶的默认设置,即将所有脚本放在window#load回调函数中。在加载所有外部资源后,window#load在加载过程的后期发生非常。 (你可以看到在jsFiddle UI中,它是左边的第二个下拉列表。)显然,TinyMCE在那个时候已经完全准备好了,它不在循环的早期。

附注:99.9%的时间,使用id选择器提供标记名称绝对毫无意义,例如: textarea#ta1id值是唯一的,因此您不必限定它们,除非您明确希望避免匹配有时可能有一个标记名称的元素,或者其他时间有另一个标记名称,这是一个非常不寻常的用例。 / p>

答案 1 :(得分:-1)

在tinyMCE实际加载之前,您的脚本很可能正在运行。情况可能是它从测试站点加载得更快,这就是它运行的原因。

用作快速检查。