Javascript - 在循环中添加特定的按键事件

时间:2014-06-12 21:38:52

标签: javascript jquery html

我正在尝试将一个按键事件分配给for循环中的元素。我知道在for循环中动态分配事件存在问题,我已经解决了“click”事件的问题,但我对它如何适用于keypress感到茫然。 (可能是因为我真的不明白“点击”是如何开始的......关闭避免不是我完全得到的)

基本设置是有一个for循环,它将打印出许多不同的textareas和它们下面的div。按div将文本区域中的文本发送给正确的人。我希望发生的是,如果在文本区域内按下回车按钮,则应发送相同的消息。

for( var i in people){

 var message = $('<textarea></textarea>').appendTo(container);
 message.on( "keypress",  function(e) {
  if(e.keyCode==13){
   // code does make it in here ...
   sendMessage(people[i].name); // but this never gets run
  }
 });

 var messageButton= $('<div>Send</div>').appendTo(container);
 messageButton.on( "click", sendMessage(people[i].name) );                

}

var sendMessage = function(to) {
 return function(){
  /* do the sending of the message to the right person */
 }
}

任何人都可以帮我理解以下内容吗?

为什么点击功能首先起作用?我不明白为什么我们必须在功能块周围放回。

为什么按键功能不起作用?

在更一般的层面上,keypress如何开始工作。函数(e)不应该起作用,因为'e'不是什么东西,甚至设置在哪里?

3 个答案:

答案 0 :(得分:0)

代码中keypress的问题在于,它始终会将消息发送给人员中的最新人员,因为执行该消息时,i将包含最新值。< / p>

我可能会使用forEach代替:

people.forEach(function (person) {
    var message = $('<textarea></textarea>').appendTo(container);

    // you can use keypress - http://api.jquery.com/keypress/#keypress-eventData-handler
    // see the examples in the reference
    message.keypress(function (e) {                     
      if (e.which === 13) {
          // here you should invoke the function returned by the sendMessage
          sendMessage(person.name)();
      }
    });

    var messageButton= $('<div>Send</div>').appendTo(container);

    messageButton.click(sendMessage(person.name));                
  });

使用这种方法,您不需要将函数包装在sendMessage中,只需在相应的事件处理程序中调用原始函数。

答案 1 :(得分:0)

使用jQuery清理示例。您应该阅读有关jQuery和迭代闭包的更多信息,以便您可以轻松了解正在发生的事情。

$.each(people, function (person) {
  var $message = $('<textarea></textarea>').appendTo(container);
  var $button = $('<div>Send</div>').appendTo(container);
  var send = sendMessage(person.name);

  // Keypress handler
  $message.keypress(function (e) {                     
    if (e.which === 13) { // on enter do the following
      send();
    }
  });

  $button.click(send);                
});

答案 2 :(得分:0)

这是使用手写封闭的另一种解决方案:

http://jsfiddle.net/M5NsS/1/

var people = {
    'p1': {
        name: 'john'
    },
        'p2': {
        name: 'bob'
    },
        'p3': {
        name: 'jim'
    }
};

var container = $('#container');

for (var i in people) {

    (function (name) {
        var message = $('<textarea></textarea>').appendTo(container);
        message.keypress(function (e) {
            if (e.keyCode == 13) {
                sendMessage(name);
            }
        });

        var messageButton = $('<div>Send</div>').appendTo(container);
        messageButton.click(function () {
            sendMessage(name)
        });
    })(people[i].name);

}

function sendMessage(to) {
    console.log(to);
}

正如其他人所说的那样,问题在于该事件与最后一次引用“i”相关联。在循环。使用闭包解决了这个问题,同时仍然允许你使用for..in循环。

另外需要注意的是,如果在绑定后没有动态地将这些元素附加到DOM ,则没有理由使用jquery的.on()。您可以直接将.keypress()和.click()处理程序绑定到元素上,如我的小提琴和@AlexAtNet的答案所示。

但它很笨重,我会像其他人已经建议的那样使用jquerys $ .each。