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

发布于 2024-08-15 16:58:57 字数 1361 浏览 2 评论 0原文

我的 Javascript 混乱超出了我对这门语言的了解。

我正在为 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);

因为当 CKEditor 的“确定”按钮触发时,my_dynamic_value 超出了函数的作用域。

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

我可以使用一些作用域技巧,以便我可以从 okListener() 中访问 Iframe 中的内容吗?

我希望这足够清楚。如果不是,请发表评论,我会澄清。

I am having a Javascript kerfuffle that goes beyond my knowledge of the language.

I am creating a custom plugin for CKEditor. The plugin is an IFrame that opens in a DIV generated by CKEditor.

Inside the IFrame, I am displaying a number of images. If the user selects one of those images, the HTML code necessary to display that image is inserted into the CKEditor.

Dynamically doing this is where I'm stuck. I am connecting to the CKEditor instance from within the Iframe like so:

var CKEDITOR = window.parent.CKEDITOR;    

CKEditor offers an "OK listener" that triggers when the OK button (rendered by CKEDitor) is clicked. That OK listener is outside the IFrame.

Defining an OK listener that works with static values works:

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);

But I don't know my return value yet when I assign the OK listener, so I would need to do something like this:

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);

But this doesn't work because my_dynamic_value is outside the function's scope at the time it is fired by CKEditor's "OK" button.

I could of course, every time the user selects a different image in the list, update the okListener function and hard-code the current value using eval into it. But that feels like a horrible waste of resources to me.

Is there some scope trick I can use so I can access stuff from my Iframe from within okListener()?

I hope this is clear enough. If it isn't, comment and I will clarify.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独行侠 2024-08-22 16:58:57

但这不起作用,因为
my_dynamic_value 超出
函数当时的作用域
由 CKEditor 的“确定”按钮触发。

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

But this doesn't work because
my_dynamic_value is outside the
function's scope at the time it is
fired by CKEditor's "OK" button.

OK. Maybe it really doesn't work, but the explanation is wrong. In JavaScript, variables have lexical scope. This means that if my_dynamic_value is in the scope when your function (handler) is declared, then it remains there forever. What error message are you getting?

猫腻 2024-08-22 16:58:57

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

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 窗口访问 iframe 的全局变量(如 imgURLFunc 版本中所述)或将值绑定到局部变量(如使用 createOKListener 完成的)。

发生的情况是,全局变量(window 除外)被解析为 window 的属性(想象一下有一个 with (window) {...} 围绕代码块)。当 CKEditor 触发事件时,它是在 CKEDITOR 的上下文中执行的,即 window.parent (来自 iframe)。

You can write a function that creates the listener, passing in the dynamic value (as a function or a string, depending on how the rest of the script is written).

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}));

Or:

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));

I suspect what's going on is that the function is executing in the context of the top-level window; whether this is true or not depends on CKEditor's event implementation. If this is the case, then you can try accessing the iframe's global variables via the iframe window (as outlined in the imgURLFunc version) or binding the value to a local variable (as done with createOKListener).

What happens is that global variables (other than window) are resolved as properties of window (imagine there's a with (window) {...} around code blocks). When CKEditor fires an event, it does so in the context of CKEDITOR, which is window.parent (from the iframe).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文