代码之家  ›  专栏  ›  技术社区  ›  Serhiy Prysyazhnyy

使用javascript控制器中的复选框

  •  2
  • Serhiy Prysyazhnyy  · 技术社区  · 15 年前

    我正在创建基于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;" />
    

    所以逻辑非常简单。 单击复选框时会出现问题。它们更新不正确。 但是,如果我用适当的参数调用控制器方法,然后检查模型,所有这些似乎都是正确的。 所以问题在于复选框中的click事件。 我对输入字段和下拉列表没有任何问题。

    2 回复  |  直到 15 年前
        1
  •  3
  •   bobince    15 年前

    这个 click 事件打开 checkbox (和 radio )很奇怪很混乱。

    原则上,它发生在鼠标交互点,在单击导致复选框更改其状态之前。因此,应该可以 return false event.preventDefault 取消进行状态更改的默认操作。在这种情况下,不应触摸复选框的状态。

    然而,这并不是大多数浏览器中实际发生的事情。从一些历史怪癖中可以追溯到古代的网景 checked 点击 事件处理程序实际上是新值。单击事件本身已导致复选框更改状态。如果您阻止默认操作( 返回false ),浏览器说,对不起,这个变化根本就没有发生过 .

    这意味着,如果您碰巧在click处理程序的脚本中故意设置了复选框的状态,则该值将丢失,被浏览器奇怪地试图在原始click更改时返回时钟所覆盖。

    返回false 而阻止默认操作实际上会导致浏览器干扰减少!另一个解决方案是:

    setTimeout(Controller.updateView, 0);
    

    而不是打电话 updateView 之前 从模型中覆盖它。您甚至可以将整个事件处理程序 在0超时时。

    理论上正确的解决办法是 onchange onclick . 这个事件明确地发生在状态更改之后,所以您根本不必担心这种奇怪及其浏览器兼容性。问题在于 一旦改变 就是IE没有以应有的速度启动它;它会在启动之前等待焦点从复选框中移出,比如在文本输入上。因此,至少在浏览器上,为了保持一致性,您需要0-timeout-on-click。

        2
  •  0
  •   Community Mohan Dere    9 年前

    Diodeus return false; 引起你的问题。自从你 updateView 返回false; ,的设置 checked 中的状态 用户单击的复选框的函数将被忽略。

    简而言之,删除 从所有的 onclick