使用 javascript 控制器中的复选框
我正在创建基于ajax 的应用程序。现在我正在使用客户端 javascript。我创建了根据应用程序逻辑正常工作的控制器,但我在更新包含复选框的视图时遇到问题。 这是我正在做的事情的简短示例:
<script type='text/javascript'>
var model = { 'chk1': true, 'chk2': false, 'chk3': false };
var Controller = {
'processCheck': function(chk, value) {
model[chk] = value;
if (chk == 'chk2')
model.chk2 = true;
if (chk == 'chk3' && value)
model.chk1 = false;
if (chk == 'chk1' && model.chk3)
model.chk1 = false;
Controller.updateView();
},
'updateView': function() {
$('#chk1').attr('checked', model.chk1);
$('#chk2').attr('checked', model.chk2);
$('#chk3').attr('checked', model.chk3);
}
}
</script>
<input id='chk1' type="checkbox" onclick="Controller.processCheck('chk1', $('#chk1').attr('checked')); return false;" />
<input id='chk2' type="checkbox" onclick="Controller.processCheck('chk2', $('#chk2').attr('checked')); return false;" />
<input id='chk3' type="checkbox" onclick="Controller.processCheck('chk3', $('#chk3').attr('checked')); return false;" />
所以逻辑非常简单。 当我们点击复选框时就会出现问题。它们更新不正确。 但是,如果我使用适当的参数调用控制器方法,然后检查模型,一切似乎都是正确的。 所以问题出在复选框中的单击事件。 我的输入字段和下拉菜单没有任何问题。
I'm creating ajax based application. Now I'm working with client side javascript. I created controller which works correctly according to application logic, but i have problems with updating views which contains checkboxes.
Here is short example of what I'm doing:
<script type='text/javascript'>
var model = { 'chk1': true, 'chk2': false, 'chk3': false };
var Controller = {
'processCheck': function(chk, value) {
model[chk] = value;
if (chk == 'chk2')
model.chk2 = true;
if (chk == 'chk3' && value)
model.chk1 = false;
if (chk == 'chk1' && model.chk3)
model.chk1 = false;
Controller.updateView();
},
'updateView': function() {
$('#chk1').attr('checked', model.chk1);
$('#chk2').attr('checked', model.chk2);
$('#chk3').attr('checked', model.chk3);
}
}
</script>
<input id='chk1' type="checkbox" onclick="Controller.processCheck('chk1', $('#chk1').attr('checked')); return false;" />
<input id='chk2' type="checkbox" onclick="Controller.processCheck('chk2', $('#chk2').attr('checked')); return false;" />
<input id='chk3' type="checkbox" onclick="Controller.processCheck('chk3', $('#chk3').attr('checked')); return false;" />
So logic is very simplified.
Problems occurs when we click on checkboxes. They are updated incorrectly.
But if I call controller methods with appropriate parameters, and then check model, all seems to be correct.
So problem is with click event in checkboxes.
I did not have any problems with input fields and dropdowns.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
checkbox
(和radio
)上的click
事件很奇怪且令人困惑。原则上,它发生在鼠标交互时,在单击导致复选框更改其状态之前。因此,应该可以
返回 false
或event.preventDefault
来取消进行状态更改的默认操作。在这种情况下,决不应该触及复选框的状态。然而,这并不是大多数浏览器中实际发生的情况。由于一些可以追溯到古代 Netscape 的历史怪癖,在
click
事件处理程序期间复选框的checked
属性实际上是新值。单击事件本身已经导致复选框更改状态。然后,如果您阻止默认操作(返回 false
),浏览器会说“哎呀,抱歉,该更改根本没有发生”,并且主动将复选框翻转回其旧值。这意味着,如果您碰巧在单击处理程序内的脚本中故意设置了复选框的状态,则该值将丢失,并被浏览器在原始单击更改上调回时钟的奇怪尝试所覆盖。
因此,与直觉相反,未能
返回 false
并阻止默认操作实际上会导致浏览器干扰更少!另一个修复是:而不是直接在点击处理程序中调用
updateView
。这使浏览器有机会在您从模型覆盖它之前翻转其状态。您甚至可以将除return false
之外的整个事件处理程序设置为 0 超时。理论上,正确的解决方案是使用
onchange
而不是onclick
。该事件明确发生在状态更改之后,因此您根本不必担心这种怪异及其浏览器兼容性。onchange
的问题是 IE 触发它的速度不够快;它在触发之前等待焦点移出复选框,就像文本输入一样。因此,至少在该浏览器上,为了保持一致性,您需要使用 0-timeout-on-click。The
click
event oncheckbox
(andradio
) is strange and confusing.In principle, it is happening at the point of mouse interaction, before the click has caused the checkbox to change its state. Consequently, it should be possible to
return false
orevent.preventDefault
to cancel the default action of making that state change. In this case the the checkbox's state should never be touched.However, this is not what actually happens in most browser. Out of some historical quirk stretching back to ancient Netscape, the
checked
property of the checkbox during theclick
event handler is in fact the new value. The click event itself already causes the checkbox to change state. Then if you prevent the default action (return false
), the browser says “oops, sorry, that change never happened after all” and actively flips the checkbox back to its old value.This means that if you happened to deliberately set the state of the checkbox from script inside the click handler, that value will be lost, overwritten by the browser's weird attempt to turn back the clock on the original click's change.
So, counter-intuitively, failing to
return false
and prevent the default action actually causes the browser to interfere less! Another fix is:instead of calling
updateView
directly in the click handler. This gives the browser the opportunity to flip back its state before you overwrite it from the model. You can even put the whole of the event handler other than thereturn false
on a 0-timeout.The proper solution would theoretically be to use
onchange
instead ofonclick
. This event unequivocally occurs after the state change, so you don't have to worry about this weirdness and its browser compatibility at all. The problem withonchange
is that IE doesn't fire it as fast as it should; it waits for focus to move out of the checkbox before firing, like on a text input. So at least on that browser, for consistency, you'd need the 0-timeout-on-click instead.Diodeus 走在正确的轨道上,
return false;
导致了您的问题。由于您的 updateView 函数每次都会设置所有检查,因此您无需担心它会被暂时检查,因为这一切都会比用户看到的速度更快。使用return false;
时,用户单击的复选框的updateView
函数中的checked
状态设置将被忽略。简而言之,从所有
onclick
函数中删除return false;
,您的代码就应该按照您想要的方式工作。Diodeus was on the right track, the
return false;
is causing your problems. Since yourupdateView
function sets all the checks everytime, you don't need to worry about it being momentarily checked, since it will all happen faster than the user can see anyhow. With thereturn false;
, the setting of thechecked
status in theupdateView
function for the checkbox that the user clicked will be ignored.In short, remove the
return false;
from all theonclick
functions, and your code should work the way you want.