变量外部事件处理程序的范围

时间:2009-12-20 23:50:50

标签: javascript scope ckeditor

我的Javascript kerfuffle超出了我对该语言的了解。

我正在为CKEditor创建一个自定义插件。该插件是一个IFrame,它在CKEditor生成的DIV中打开。

在IFrame中,我正在显示许多图像。如果用户选择其中一个图像,则显示该图像所需的HTML代码将插入到CKEditor中。

动态地执行此操作是我陷入困境的地方。我正在iframe中连接到CKEditor实例,如下所示:

var CKEDITOR = window.parent.CKEDITOR;    

CKEditor提供一个“OK侦听器”,当单击OK按钮(由CKEDitor呈现)时触发该侦听器。那个OK听众在IFrame之外。

定义一个使用静态值的OK侦听器:

var okListener = function(ev) {
   this._.editor.insertHtml('<img class="symbol" src="my_static_symbol.gif">');
   CKEDITOR.dialog.getCurrent().removeListener("ok", okListener);
};

// Assign OK listener
CKEDITOR.dialog.getCurrent().on("ok", okListener);

但是当我分配OK监听器时,我还不知道我的返回值,所以我需要做这样的事情:

var okListener = function(ev) {
   this._.editor.insertHtml('<img class="symbol" src="'+my_dynamic_value()+'">');
   CKEDITOR.dialog.getCurrent().removeListener("ok", okListener);
};

// Assign OK listener
CKEDITOR.dialog.getCurrent().on("ok", okListener);

但这不起作用,因为my_dynamic_value在CKEditor的“OK”按钮触发时超出了函数的范围。

我当然可以,每当用户在列表中选择不同的图像时,更新okListener函数并使用eval将当前值硬编码到其中。但这对我来说是一种可怕的资源浪费。

我可以使用一些范围技巧,以便我可以从okListener()中的iframe访问内容吗?

我希望这很清楚。如果不是,请评论,我会澄清。

2 个答案:

答案 0 :(得分:5)

  

但这不起作用,因为   my_dynamic_value在...之外   函数的范围   由CKEditor的“确定”按钮触发。

行。也许它真的不起作用,但解释是错误的。在JavaScript中,变量具有词法范围。这意味着如果my_dynamic_value在声明函数(处理程序)时在范围内,那么它将永远保留在那里。您收到了什么错误消息?

答案 1 :(得分:1)

您可以编写一个创建侦听器的函数,传入动态值(作为函数或字符串,具体取决于编写脚本的其余部分)。

function createOKListener(imgURLFunc) {
   return function(ev) {
      this._.editor.insertHtml('<img class="symbol" src="'+imgURLFunc()+'">');
      CKEDITOR.dialog.getCurrent().removeListener("ok", okListener);
   };
};

// Assign OK listener
CKEDITOR.dialog.getCurrent().on("ok", createOKListener(function() {iframeRef.path.to.imageURL}));

或者:

function createOKListener(imgURL) {
   return function(ev) {
      this._.editor.insertHtml('<img class="symbol" src="'+imgURL+'">');
      CKEDITOR.dialog.getCurrent().removeListener("ok", okListener);
   };
};

// Assign OK listener
CKEDITOR.dialog.getCurrent().on("ok", createOKListener(path.to.imageURL));

我怀疑正在发生的是该功能是在顶级窗口的上下文中执行的;这是否真实取决于CKEditor的事件实现。如果是这种情况,那么您可以尝试通过iframe窗口(如imgURLFunc版本中所述)访问iframe的全局变量,或者将值绑定到局部变量(与createOKListener一样)。

全局变量(window除外)被解析为window的属性(假设代码块周围有with (window) {...})。当CKEditor触发事件时,它会在CKEDITOR的上下文中执行,window.parent(来自iframe)。