我编写了一个函数,旨在提供一种创建右键单击(上下文)菜单的简单方法。很好,但是您作为点击处理程序传递给它的函数不会应用于正确的菜单项。
当我调用该函数时,我将点击事件和一个包含菜单项名称及其处理函数的对象文字传递给它,如下所示:
context.menu(e,{
"Hello": function() {
alert("Hi");
},
"World": function() {
alert("Hello world!");
},
});
据推测,对象字面量在 for
循环中循环,每个处理函数都应用于相应的菜单项。但是,似乎传入的第一个处理函数已应用于所有菜单项。
函数是这样的:
this.menu = function(e,options) {
e.preventDefault();
var x = e.clientX;
var y = e.clientY;
var id = math.floor(math.random()*8192);
id = "menu-"+id;
var menu = "<div class='menu-wrapper'></div>";
menu = $(menu);
menu.attr("id",id);
var i = 0;
for(var key in options) {
var option = $("<span class='menu-item' id='menu-item-"+i+"'>"+key+"</span>");
var fn = options[key];
option.appendTo(menu);
option.on("click",function() {
// $(this).css("background","yellow"); - just a test, not needed any more
fn.call();
});
i++;
}
menu.appendTo("body");
menu.css({
top: y,
left: x,
});
$(document).click(function() {
$("#"+id).remove();
});
$("#"+id).click(function(e) {
e.stopPropagation();
});
}
我如何更改它以便在正确的位置应用处理程序?
更新:
我已经尝试添加代码(使用 typeof(options[key]);
所以它会检查你传入的函数的类型,但仍然没有成功。console.log
code> 也给了我正确的值,所以我不知道为什么它不循环。
最佳答案
此处常见的陷阱。 JS 没有 block 作用域 - 你的 fn
变量在每次迭代中都会被重写。尝试将其包裹在闭包中。
this.menu = function(e,options) {
e.preventDefault();
var x = e.clientX;
var y = e.clientY;
var id = math.floor(math.random()*8192);
id = "menu-"+id;
var menu = "<div class='menu-wrapper'></div>";
menu = $(menu);
menu.attr("id",id);
var i = 0;
for(var key in options) {
(function(key){ // start closure
var option = $("<span class='menu-item' id='menu-item-"+i+"'>"+key+"</span>");
var fn = options[key];
option.appendTo(menu);
option.on("click",function() {
// $(this).css("background","yellow"); - just a test, not needed any more
fn.call();
});
})(key); // end closure
i++;
}
menu.appendTo("body");
menu.css({
top: y,
left: x,
});
$(document).click(function() {
$("#"+id).remove();
});
$("#"+id).click(function(e) {
e.stopPropagation();
});
}
关于javascript - For 循环不循环对象的值 - 对每个元素应用相同的处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24465806/