简体   繁体   English

jQuery将自定义函数绑定到附加元素

[英]jQuery bind custom function to appended element

I am trying to create a web app that will allow a user to define a custom JavaScript function and then add a button to their user interface that well preform that function. 我正在尝试创建一个Web应用程序,该应用程序将允许用户定义自定义JavaScript函数,然后向其用户界面添加一个很好地执行该功能的按钮。

Here is a sample of the code 这是代码示例

var customCommands = {
  command1: {
    text: 'Hello Console',
    cFunctionRun: function() {
      console.log('hello Console!');
    }
  },
  command2: {
    text: 'Hello World',
    cFunctionRun: function() {
      alert('hello World!');
    }
  }
}

Then I wrote a small function that loops though and builds the buttons and adds them to the user interface. 然后,我编写了一个小函数,该函数循环并构建按钮并将其添加到用户界面。 The problem is when I append the elements to the user interface than click on the buttons nothing works... 问题是当我将元素附加到用户界面上而不是单击按钮时,什么都不起作用...

Here is one of the methods I tried 这是我尝试过的方法之一

for (var cmd in customCommands) {
    command = customCommands[cmd];
    button = $('<button/>').html(command.text).on('click', 
      function(){ 
        console.log(command.text); 
        command.cFunctionRun(); 
      }
    );
}
buttonContainer.append(button);

Now my loop builds everything just fine and even the .on('click') works, but it always displays the text of the lasted added command? 现在,我的循环可以很好地构建所有内容,甚至.on('click')可以正常运行,但是它始终显示最后添加的命令的文本吗?

here is http://jsfiddle.net/nbnEg/ to show what happens. 这是http://jsfiddle.net/nbnEg/以显示发生了什么。

When you actually click, the command variable points to last command (as the whole loop has already run). 实际单击时,命令变量指向最后一个命令(因为整个循环已在运行)。 You should maintain data state per button which tells it which command to invoke. 您应该维护每个按钮的数据状态,该状态告诉它要调用哪个命令。 You should do this. 你应该做这个。

for(var i in customCommands) {
  if(customCommands.hasOwnProperty(i)){ //this is a pretty important check
    var command = customCommands[i];
    button = $('<button/>').html(command.text).data("command_name", command).on('click', function(){ 
      console.log($(this).data("command_name").text); 
      $(this).data("command_name").cFunctionRun(); 
    });

    $("body").append(button);
  }
}

JSFiddle JSFiddle

您所需要的只是通过函数传递参数,您应该尝试一下

It's a (missing) closure problem. 这是(缺少)关闭问题。 The event handler will keep a reference to the value of command on the last iteration of the loop. 事件处理程序将在循环的最后一次迭代中保留对command值的引用。 To solve it you can create a new scope, using an immediately invoked function: 为了解决这个问题,您可以使用立即调用的函数创建一个新的作用域:

for(var cmd in customCommands) {
    (function(command){
        button = $('<button/>').html(command.text).on('click', 
          function(){ 
            console.log(command.text); 
            command.cFunctionRun(); 
          }
        );
        buttonContainer.append(button);
    }(customCommands[cmd]));
}

Since the button s should be unique (no reason for creating duplicates), I'm setting the button id to the name of the customCommands (command1 and command2 in this example). 由于button s应该是唯一的 (没有理由创建重复项),因此我将按钮id设置为customCommands的name (在本示例中为command1和command2)。 This example could easily be adapted to use any of the relative attributes (data-*, name, etc...). 该示例可以轻松地修改为使用任何相对属性(data-*,name等)。

Create a click event listener on document for whenever one of your button s are pressed. 每当按下button之一时,就在document上创建click事件侦听器。 Then call the function associated with the given id . 然后调用与给定id关联的函数。

$(document).on("click", "button", function(){
    customCommands[this.id].cFunctionRun();
});

for(var command in customCommands){
    var button = $('<button id="' + command +'"/>').html(customCommands[command].text);
    $("body").append(button);
}

EXAMPLE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM