0

ユーザーがカスタム JavaScript 関数を定義し、その関数を適切に実行するボタンをユーザー インターフェイスに追加できるようにする Web アプリを作成しようとしています。

これがコードのサンプルです

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

次に、ループしてボタンを作成し、ユーザー インターフェイスに追加する小さな関数を作成しました。問題は、ボタンをクリックするよりも要素をユーザーインターフェイスに追加すると、何も機能しないことです...

これが私が試した方法の1つです

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

これで、私のループはすべてを正常に構築し、.on('click')機能するようになりましたが、最後に追加されたコマンドのテキストが常に表示されますか?

ここにhttp://jsfiddle.net/nbnEg/があり、何が起こるかを示しています。

4

4 に答える 4

2

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

于 2013-02-06T20:46:20.510 に答える
1

必要なのは関数でパラメーターを渡すことだけです。これを試してみてください

于 2013-02-06T20:42:02.680 に答える
0

buttons は一意である必要があるため (重複を作成する理由はありません)、ボタンidnamecustomCommands (この例では command1 と command2) に設定しています。この例は、相対属性 (data-*、name など) を使用するように簡単に変更できます。

のいずれかが押されるたびに、clickイベントリスナーを作成します。次に、指定された に関連付けられた関数を呼び出します。documentbuttonid

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

于 2013-02-06T20:53:22.807 に答える
0

これは(欠落している)閉鎖の問題です。イベント ハンドラーは、ループの最後の反復で command の値への参照を保持します。それを解決するには、すぐに呼び出される関数を使用して新しいスコープを作成します。

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]));
}
于 2013-02-06T20:48:11.820 に答える