本周必须做一些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");
} );
}
});
答案 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" />