2014-06-28 41 views
3

我已经编写了一个旨在提供创建右键单击(上下文)菜单的简单方法的函数。很好,但是您作为点击处理程序传递给它的函数不适用于正确的菜单项。For循环不会循环一个对象的值 - 将相同的处理程序应用于每个元素

当我调用该函数,我通过它的点击事件和对象常量,其中包含菜单项的名称和它们的处理函数,像这样:

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

UPDATE:

我已经尝试添加代码(使用typeof(options[key]);所以检查函数的类型,你传递,但仍然没有运气console.log也给了我正确的价值观等等。我不知道为什么它不循环

回答

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

嗯...会认为它需要重写每个迭代,但嘿。它完美的作品,非常感谢。 – ArtOfCode

相关问题