【问题标题】:For loop doesn't loop values of an object - applies same handler to each elementFor 循环不会循环对象的值 - 将相同的处理程序应用于每个元素
【发布时间】:2014-08-19 09:20:18
【问题描述】:

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

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

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]);so 它会检查您传入的函数的类型,但仍然没有运气。console.log 也给了我正确的值,所以我不知道它为什么不循环。

【问题讨论】:

    标签: javascript jquery for-loop


    【解决方案1】:

    这里的常见陷阱。 JS 没有块范围 - 您的 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();
        });
    }
    

    【讨论】:

    • 嗯...本来以为每次迭代都需要重写,但是嘿。效果很好,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2021-08-24
    • 2022-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    相关资源
    最近更新 更多