使用jQuery .on()进行范围设定

时间:2015-12-15 10:05:35

标签: javascript jquery

本周必须做一些UI工作......不是我习惯的东西!基本上我有一个对象数组(在这种情况下简化为整数),需要循环遍历它们以在页面上找到匹配的元素,并附加一个事件处理程序,其中包含来自该数组部分的数据。我认为这是一个范围问题 - 然后我玩了分配_local = this;似乎循环中的最后一项似乎附加到处理程序(即它总是说已经为所有按钮点击了最后一个值)

$(document).ready(function () {

var filters = [0,1,2,3];

// Works as expected 
// When button 0 is clicked log message is "btn0 clicked!"
// When button 1 is clicked log message is "btn1 clicked!"
// Etc

$('#btn0').on('click', function () {
    console.log("bt0 clicked");         
} );

$('#btn1').on('click', function () {
    console.log("bt1 clicked");         
} )

$('#btn2').on('click', function () {
    console.log("bt2 clicked");         
} )

$('#btn3').on('click', function () {
    console.log("bt3 clicked");         
} )



// Undefined all over the place
for (var i = 0; i < filters.length; i++) {
    $('#btn' + filters[i].toString()).on('click', function () {
        console.log("bt" + filters[i].toString() + " clicked");         
    } );
}
});

3 个答案:

答案 0 :(得分:1)

你是对的。你必须阅读closures在javascript中的工作原理。我建议使用let在ES6中附带一个简单的解决方案。您也不需要使用.toString。当您使用unary plus operator数字转换为幕后字符串("btn" + 1// btn1)时。

  'use strict';
  var filters = [0, 1, 2, 3];
  for (let i = 0; i < filters.length; i++) {
    $('#btn' + filters[i]).on('click', function() {
      console.log("bt" + filters[i] + " clicked");
    });
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='btn0'>bt0</button>
<button id='btn1'>bt1</button>
<button id='btn2'>bt2</button>
<button id='btn3'>bt3</button>

在ES6之前,您可以创建IIFE

var filters = [0, 1, 2, 3];
for (var i = 0; i < filters.length; i++) {
  (function(i) {
    $('#btn' + filters[i]).on('click', function() {
      console.log("bt" + filters[i] + " clicked");
    });
  })(i);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='btn0'>bt0</button>
<button id='btn1'>bt1</button>
<button id='btn2'>bt2</button>
<button id='btn3'>bt3</button>

答案 1 :(得分:0)

作为@Alex回答的替代方案。

您可以使用data()使用单个元素保留自定义,以后可以在通风处理程序中获取这些元素。

'use strict';
var filters = [0, 1, 2, 3];

for (var i = 0; i < filters.length; i++) {
  //Set data and class
  $('#btn' + filters[i]).data('item', filters[i]).addClass('btn');
}

//Bind Click handler
$('.btn').on('click', function() {
  snippet.log("bt" + $(this).data('item') + " clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<button id='btn0'>bt0</button>
<button id='btn1'>bt1</button>
<button id='btn2'>bt2</button>
<button id='btn3'>bt3</button>

答案 2 :(得分:0)

https://developer.mozilla.org/es/docs/Web/JavaScript/Closures

$(document).ready(function () {

  var filters = [0,1,2,3];

  for (var i = 0; i < filters.length; i++) {
      createOnclick(filters[i]);
  }
  
  function createOnclick(elm) {
    return function() {
        $('#btn' + elm.toString()).on('click', function () {
          console.log("bt" + elm.toString() + " clicked");         
        });
    
    }();
  }
  
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="btn0" value="0" />
<input type="button" id="btn1" value="1" />
<input type="button" id="btn2" value="2" />
<input type="button" id="btn3" value="3" />