使用 jquery click 时为传入函数传参

jquery 在使用过程中确实非常顺手,不过也像其他工具一样, 新的工具带来了新的问题,最近就遇到了一个参数传递的问题。

1 问题

我们从这样一个 html 文件开始:

<html>

<head>
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>

<body id="body-id">

</body>

<script>
  $(document).ready(function () {
    var btn = $('<button>').text("button");
    btn.click(function () {
      alert("hello");
    });
    $('#body-id').append(btn);
  });
</script>

</html>

这个文档会在加载后向 <body> 添加一个 <button>, 点击按钮会有一个提示框,如果我们希望提示框的信息是根据参数变化的 ,我们可以这样做:

$(document).ready(function () {
  var btn = $('<button>').text("button");
  var msg = "this is a test";
  btn.click(function () {
    alert(msg);
  });
  $('#body-id').append(btn);
});

目前为止一切正常,那么如果我们要一次添加十个按钮呢?

$(document).ready(function () {
  for (var i = 0; i < 10; ++i) {
    var btn = $('<button>').text("button " + i);
    var msg = "this is button " + i;
    btn.click(function () {
      alert(msg);
    });
    $('#body-id').append(btn);
  }
});

十个按钮是出来了,但是每个按钮提示的信息都是 this is button 9, 这就是问题所在了,lambda 函数并没有按我们预期捕获正确的参数。

2 解决

我们可以用传入一个 event 的方式来保存我们需要的参数值。

$(document).ready(function () {
  for (var i = 0; i < 10; ++i) {
    var btn = $('<button>').text("button " + i);
    var msg = "this is button " + i;
    btn.click({msg: msg}, function (event) {
      alert(event.data.msg);
    });
    $('#body-id').append(btn);
  }
});

click 的调用方式略有不同,第一个参数传入我们需要保留的函数, 第二个参数传入的函数需要增加一个 event 参数, 这样我们可以透过 event.data 来获取到当时我们保存的值。