【问题标题】:MOOTOOLS variable scopeMOOTOOLS 变量范围
【发布时间】:2011-03-10 17:25:34
【问题描述】:

我正在使用 mootools: 在使用 addEvent 时,我不知道如何使用变量。

我想使用 for next 循环在循环中设置值:

for (x=0;x<num;x++){
var onclickText = 'function (){onclick="addPageMoveEvent('+x+'"); }';
$('pageNum'+x).addEvent('click', onclickText);
}

>

我搜索了论坛,但没有找到任何帮助。

任何帮助都会很棒。

谢谢

【问题讨论】:

  • 到底出了什么问题?
  • 首先,for (x=0;x&lt;num;x++) 应该是for (var x=0;x&lt;num;x++)。那个确切的问题花了我三个小时才解决一次。
  • 不理解“var”问题。我认为 var 只是关于变量的范围,即全局或非全局。为什么会有所不同?
  • 因为如果它是全局的并且没有足够的注意,则此代码的所有调用都将创建对x 的引用,从而导致每个链接都执行相同的操作。如果x 是本地的,则不会保留其值,即将创建对名为x 的不同事物的引用。但是随着闭包的复杂性增加,无论如何这并不重要。

标签: javascript variables scope mootools closures


【解决方案1】:

警告:第一个示例将不起作用!继续阅读以获得解释。

您将onclick HTML 语法与 MooTools addEvent 混淆了。试试

for (var x=0;x<num;x++){
    $('pageNum'+x).addEvent('click', 'addPageMoveEvent('+x+');');
}

这更简单,更干净,但可能仍然无法满足您的需求。这段代码会在每次点击链接时调用函数addPageMoveEvent...这是你想要的吗?

由于 MooTools 不允许上述方法,您必须使用以下方法:

以编程方式更有趣且危险性更低的方法是:

factory = function (x) { return function() { addPageMoveEvent(x); }; };
for (var x=0;x<num;x++){
    $('pageNum'+x).addEvent('click', factory(x));
}

这使用工厂来创建包含 x... 值的闭包。相当复杂的代码,但它是最纯粹的方式。它还避免使用由于您提供addEvent 字符串而发生的可怕eval。 (看来 MooTools 无论如何都不喜欢其他选项。)

【讨论】:

  • 谢谢,我尝试了纯粹主义者的方法,它奏效了!!谢谢。你能否向我证实我的理解。我认为它将 factory(0) factory(1) 等添加到元素中,然后它将工厂值作为 x 传递?
  • 如果我理解正确的话,是的。例如,它调用factory(1)。 factory 执行并返回一个函数,该函数在执行时调用 addPageMoveEvent(1)。然后将此函数传递给addEvent 调用。当事件触发时,这个函数被调用,这反过来又会进行正确的addPageMoveEvent 调用。本质上,factory 是一个函数工厂函数,它制造一个函数,该函数调用另一个函数,传递传递给工厂的变量的 value。 ... 多读几遍 :) 希望这会有所帮助。
【解决方案2】:

MooTools 中的addEvent 方法接受两个参数:

myElement.addEvent(type, fn);

参数:

  • type -(字符串)要监控的事件名称(“click”、“load”等),不带“on”前缀。
  • fn - (function) 要执行的函数。

它不需要字符串,传递"myFunction()" 或"function() { myFunction(); }" 等字符串将不起作用。

由于您在循环中,并且变量x 将共享环境,因此您需要将其值包装在另一个闭包中。一种方法是使用额外的闭包:

$("pagenum" + x).addEvent("click", (function(value) {
    return function() { addPageMoveEvent(value); }
})(x));

查看 StackOverflow 上的所有 questions,了解在循环中创建闭包的特殊问题。

这篇 MDC 文章也值得一看 - Creating closures in loops: A common mistake

【讨论】:

  • 糟糕,我习惯了更灵活的 jQuery。我会更新我的答案。我喜欢 MooTools 胜过任何其他框架,但我越来越觉得它相当死板。
  • 感谢@MvanGuest :) 老实说,我还没有看到bind 或jQuery 中的click 等速记函数之一接受可执行的JavaScript 代码字符串。
  • 很奇怪。我一定在哪里见过类似的东西,MooTools 和 jQuery 是我熟悉的唯一框架……如果我找到了,我会告诉你的。
【解决方案3】:

mootools pass 方法的一个用例。

for (x=0;x<num;x++){
  $('pageNum'+x).addEvent('click', addPageMoveEvent.pass(x));
}

Pass 在内部创建一个闭包,将 x 保存在他的范围内,因此当点击事件被触发时,它具有正确的值,导致它与 for 循环不同。

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 2012-05-10
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    相关资源
    最近更新 更多