使用jquery conextmenu

时间:2017-06-20 01:38:41

标签: javascript jquery

我正在从我的jquery-contextmenu sumbenu调用一个函数,根据点击的选项传递一个特定的参数。

我根据js对象生成该子菜单,该对象包含三个名称。当我点击其中一个时,它被调用,我的函数被调用该名称作为参数,然后它被打印在控制台上。

但它只用最后一个元素调用函数,我不知道为什么。当我点击“john”或“Matt”时,它只显示“你按下了Petter”。

就像这张图片一样:

enter image description here

即使我从未点击过“Petter”,它也会显示“你按下了Petter”。

代码(我可以把小提琴放在这里,但我没有找到jquery contextmenu链接,如果你分享给我,我会很高兴,如果它存在的话):

var obj = {"1":"john","2":"Matt","3":"Petter"};

function myFun(name){
    console.log("you pressed "+name);
}

$(function() {
$.contextMenu({
  selector: '.context-menu-one',
  autoHide: true,
  build: function($trigger, e) {
    var options = {
      items: {}
    }

    options.items["users"] = {name: "users", icon: "fa-circle", items: {}}

    for(var i in obj){
      options.items["users"].items[obj[i]] = {name: obj[i], icon: "fa-user", callback: function(){
        myFun(obj[i]);
      }}
    }

    return options;
  }
});
});

抱歉我的英文不好,谢谢。

2 个答案:

答案 0 :(得分:1)

这是由于javascript语言的封闭。回调中对变量i的引用将像以前一样存储并在范围外调用,但是,循环将会运行,i(全局作用域)将始终等于最后一个指数要修复此更改,您的循环就会像这样工作

for(var i in obj){
  (function(j) {
    options.items["users"].items[obj[j]] = {name: obj[j], icon: "fa-user", callback: function(){
        myFun(obj[j]);
      }
    }
  })(i);
}

这会在函数中创建一个新的作用域,它保持对循环的闭包,并使i的值保持等于当前正在迭代的索引,从而使菜单正常工作。

答案 1 :(得分:1)

for(var i in obj){
  options.items["users"].items[obj[i]] = {
    name: obj[i], 
    icon: "fa-user", 
    callback: function(){
      myFun(obj[i]); // here is the problem
    }
  }
}

问题是由js闭包引起的, i 变量是在 for 循环的每个回调中捕获的。 因此,当您单击菜单执行回调时, i 将始终相同,因为它们是相同的变量。 i 的值将是 循环完成时的值,在您的示例中为“3”。

以下是使用IIFE(立即调用函数表达式)来避免此问题的方法

for (var i in obj) {
  (function (i) {
     // here goes the code in your for loop
  })(i);
}