我正在尝试编写一个有点通用的模态对话框处理函数,因此我可以将控件传递给它来处理不同的操作。这听起来很简单,我认为它会。我正在尝试在一个对象中传递按钮处理函数,该对象循环通过ID将每个函数注册到按钮单击处理程序。它有效,但不是我期望的方式。这是代码(需要bootstrap 3):
function confirmation(question){
var modalTitle = 'Confirmation';
var modalContents = question;
var modalControls = '<button type="button" class="btn btn-primary" id="confirmYes">Confirm</button> <button type="button" class="btn btn-default" id="confirmNo">Cancel</button>';
var modalButtons = {
confirmNo: function(){
console.log('really, no!');
},
confirmYes: function(){
console.log('really, yes!');
}
}
standardModal(modalTitle,modalContents,modalControls,modalButtons);
}
function standardModal(modalTitle,modalContents,modalControls,modalButtons){
$('#standardModalTitle').html(modalTitle);
$('#standardModalBody').html(modalContents);
$('#standardModalControls').html(modalControls);
for (var prop in modalButtons){
if(!modalButtons.hasOwnProperty(prop)) continue;
$('#'+prop).click(function(e){
e.preventDefault();
modalButtons[prop]();
});
}
$('#standardModal').modal('show');
}
这是HTML:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<div class='modal fade' tabindex='-1' role='dialog' id='standardModal'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-header'>
<button type='button' class='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>×</span></button>
<h4 class='modal-title' id='standardModalTitle'></h4>
</div>
<div class='modal-body' id='standardModalBody'>
</div>
<div class='modal-footer' id='standardModalControls'>
<button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
</div>
</div>
</div>
</div>
当我运行确认时('这是一个问题?');我应该在对话框中有两个按钮,确认和取消。我希望Confirm运行modalButtons.confirmYes函数,而Cancel应该运行modalButtons.confirmNo。实际发生的是,两个按钮都调用了modalButtons中定义的最后一个函数。如果confirmYes是最后定义的函数,则它将针对两个按钮运行。
当我在那里抛出console.log语句时,变量输出是我每次都期望的...但是实际的函数调用是错误的。
我做错了什么?
答案 0 :(得分:1)
当您点击按钮并调用modalButtons[prop]()
时,prop
评估的内容是什么?记住javascript如何查找变量名称:
undefined
在我们的情况下,您点击该按钮,然后执行click
回调,javascript会尝试查找prop
的值:
prop
未在回调范围内定义,因此它会查看下一个外部范围prop
在回调的直接父范围内定义! prop
的价值是什么?好吧,它是你循环的最后一个值(数组的最后一个元素)。您要做的是定义一个始终指向prop
的预期值的变量。最简单的方法是用函数迭代器替换for
循环:
Object.keys(modalButtons).forEach(function (prop) {
// same loop code as before
})
不同之处在于,我们在父作用域中声明了一个名为prop
的新变量,而不是声明prop
一次并在循环的每个卷上更改其值。这是一个微妙的错误,但是你经常遇到的事情,所以了解它是如何工作的很重要。
这有帮助吗?
或者查看我对此similar question的回答,如果有帮助,请告诉我!