javascript - For 循环不循环对象的值 - 对每个元素应用相同的处理程序

标签 javascript jquery for-loop

我编写了一个函数,旨在提供一种创建右键单击(上下文)菜单的简单方法。很好,但是您作为点击处理程序传递给它的函数不会应用于正确的菜单项。

当我调用该函数时,我将点击事件和一个包含菜单项名称及其处理函数的对象文字传递给它,如下所示:

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

我如何更改它以便在正确的位置应用处理程序?

Live JSFiddle demo

更新:

我已经尝试添加代码(使用 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/

相关文章:

java - Java、C 和 C++ 中循环变量的类型限制

javascript - Node/Express/Request - 尝试使用参数代理 POST 请求会抛出 "Write after end"

javascript - Nodemailer yahoo 登录不正确

javascript - Internet Explorer 11 (IE 11) 在 DOMParser 中使用 parseFromString 抛出语法错误

javascript - 侧面的 Highcharts X 轴标签

javascript - 如何在 Jquery selectize 中找到 EOL(行尾)?

javascript - D3 circle pack - 向节点添加标签

javascript - 当我使用 jQuery 单击另一个下拉菜单按钮时,如何关闭事件的下拉菜单?

php - 如何在循环中创建循环...? PHP-MySQLi

javascript - 在 JavaScript for 循环中休眠