这是我的html表单:
<form method="post" id="new_message" action="?action=changeRate">
<div class="form-group">
<label for="from" class="col-sm-2 control-label">From</label>
<div class="col-sm-3">
<select name="from" id="from" class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<label for="to" class="col-sm-2 control-label">To</label>
<div class="col-sm-3">
<select name="to" id="to" class="form-control">
<option value=""></option>
</select>
</div>
</div>
<div class="form-group">
<label for="value" class="col-sm-2 control-label">Rate</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="ra" id="ra" placeholder="result" value="0">
</div>
</div>
<p><input type="button" value="Submit" name="commit" id ="commit"/> or <a class="close" href="/">Cancel</a></p>
</form>
这是我的jquery代码:
$('#to').on('change', function () {
var fr = $('#from').val();
var to = $('#to').val();
for (i = 0; i < rates.length; ++i){
if ((fr==rates[i].from) && to==rates[i].to) {
//the first i value is 0
console.log("i in if" + i);
$('input[name=ra]').val(rates[i].val);
$('#commit').click(function() {
//the second i value is always 3(same as array length)
console.log("i in commit " + i);
});
}
}
});
当我单击#commit按钮但是[i]索引增加到最大值时,我试图访问相同的[i]属性。如何在单击按钮时获得相同的索引?
答案 0 :(得分:2)
你对i
变量有一个闭包。这会导致i
成为click
回调触发时的最大值。
您可以尝试的是:
$('#to').on('change', function () {
var fr = $('#from').val();
var to = $('#to').val();
for (i = 0; i < rates.length; ++i){
if ((fr==rates[i].from) && to==rates[i].to) {
//the first i value is 0
console.log("i in if" + i);
$('input[name=ra]').val(rates[i].val);
(function(index) {
$('#commit').click(function() {
//the second i value is always 3(same as array length)
console.log("index in commit " + index);
});
})(i);
}
}
});
答案 1 :(得分:1)
你的循环结束后,我将成为最大值,但你的点击处理程序仍然指的是同一个i。创建点击处理程序时,循环过程中i的值不会保存为#34;除非您通过函数传递它。
function makeCommitFunction(i) {
return function () {
console.log("i in commit " + i);
};
}
$('#commit').click(makeCommitFunction(i));
答案 2 :(得分:1)
您正在for
循环中附加您的点击处理程序。即使您确定if条件只是一次,这也是一个坏主意。将click
处理程序移出change
处理程序以避免多次绑定并更容易阅读。
在循环中找到值后,您可以使用变量来存储位于上部块中的范围值(或索引),如下例所示。如您所见,foundIdx
将涵盖点击处理程序和更改处理程序。
或者,您可以使用.data()将索引(或该索引处的对象)附加到输入元素,以便您可以在任何需要的位置访问它。这类似val()
但不可见。
您的代码失败,因为您无法保证在代码找到费率的同时点击按钮。它快得多了:)这就是为什么你需要在找到它之后立即存储它,然后在某个时间使用该值,因为它会在那里等待你。
封装点击处理程序的封闭是另一种存储&#39;将变量的值复制到新创建的范围时的值。但这不是正确的方法,因为#to
元素上的每个更改都会导致新函数绑定到按钮的click
事件。
示例:
// One of the options 1, 2, 3 can be used
var myInput = $('input[name=ra]');
var foundIdx = null; // option 1
var i = null; // option 3
$('#commit').click(function() {
console.log("i (option 1) = " + myInput.data('i'));
console.log("i (option 2) = " + foundIdx);
console.log("i (option 3) = " + i);
console.log("the rate : " + JSON.stringify(myInput.data('rate')));
});
$('#to').on('change', function() {
var fr = $('#from').val();
var to = $('#to').val();
for (i = 0; i < rates.length; ++i) {
if ((fr == rates[i].from) && to == rates[i].to) {
myInput.val(rates[i].val);
foundIdx = i; // option 1
myInput.data('i', i); // option 2
// option 3 is already there as long as the i is defined above
}
}
});
以下是完整的上述代码改写,推荐更改并使用ES2015更新:
// declare the input variable here in the upper scope
// to access it from the both handlers
const myInput = $('input[name=ra]');
$('#commit').click(function() {
console.log("the rate : " + JSON.stringify(myInput.data('rate')));
// do we want to use the index?
// console.log("the index = " + myInput.data('idx'));
});
// we can assign the handler to
// multiple elements in case if we want it to run
// on both from & to change
$('#from, #to').on('change', function() {
const fr = $('#from').val();
const to = $('#to').val();
rates.forEach( (rate, idx) => {
if (rate.from == fr && rate.to == to) {
myInput.val(rate.val);
myInput.data('rate', rate);
// do we want to store the index?
// myInput.data('idx', idx);
}
}
});