【问题标题】:jQuery toggling the checked property on a checkboxjQuery在复选框上切换选中的属性
【发布时间】:2019-12-19 19:00:45
【问题描述】:

我想使用以下代码选中或取消选中按钮样式的复选框:

<ul id="ids_ul" class="nav nav-list">
    <li>
        <div class="btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-info group_toggle" id="id_label1" for="id_checkboxes1">
            <input type="checkbox" value="1" id="id_checkboxes1" name="ids[]" autocomplete="off"/> One</label>
        </div>
    </li>
    <li>
        <div class="btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-success group_toggle" id="id_label2" for="id_checkboxes2">
            <input type="checkbox" value="2" id="id_checkboxes2" name="ids[]" autocomplete="off"/> Two</label>
        </div>
    </li>
    <li>
        <div class="btn-group-toggle" data-toggle="buttons">
            <label class="btn btn-info group_toggle" id="id_label3" for="id_checkboxes3">
            <input type="checkbox" value="3" id="id_checkboxes3" name="ids[]" autocomplete="off"/> Three</label>
        </div>
    </li>
</ul>

let checkbox_state = "";
$(".group_toggle").click(function(){
    $(this).toggleClass("btn-info btn-success");
    checkbox_state = $(this).children("input:first");

    console.log("Initial checkbox_state: " + checkbox_state.prop("checked"));
    if($(checkbox_state).prop("checked") == true) {
        $(checkbox_state).prop("checked", false);
        console.log("Checked after click: " + checkbox_state.prop("checked"));
    } else {
        $(checkbox_state).prop("checked", true);
        console.log("Checked after click: " + checkbox_state.prop("checked"));
    }
});

Two 上点击四次后,日志显示:

Initial checkbox_state: true
Checked after click: false

Initial checkbox_state: true // why still true?
Checked after click: false

Initial checkbox_state: false
Checked after click: true

Initial checkbox_state: true
Checked after click: false

在第 3 次单击取消选中有效,但按钮类现在相反。 如果我点击OneThree 来选中复选框,它在第一次尝试时有效。

有人知道这里发生了什么吗?

有没有更优雅的方式来验证复选框属性checked

【问题讨论】:

    标签: javascript jquery html twitter-bootstrap-3


    【解决方案1】:

    您可以使用e.preventDefault() 来停止被点击元素的默认行为,这似乎会导致在使用 twitter-bootstrap-3 时触发两次点击事件

    另外,checkbox_state 似乎是一个令人困惑的元素名称,因为它实际上存储了复选框本身,而您使用 prop('checked') 来获取它的状态 - 我已经更新了它并将其更改为在函数内部,因为您不需要全局定义它

    $('.group_toggle').click(function(e) {
      e.preventDefault();
    
      $(this).toggleClass('btn-info btn-success');
    
      let $checkbox = $(this).children('input:first');
      let checked = $checkbox.prop('checked');
    
      console.log(`Initial checkbox_state: ${checked}`);
      
      // Invert checked state
      $checkbox.prop('checked', !checked);
      console.log(`Checked after click: ${$checkbox.prop('checked')}`);
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <ul id="ids_ul" class="nav nav-list">
      <li>
        <div class="btn-group-toggle" data-toggle="buttons">
          <label class="btn btn-info group_toggle" id="id_label1" for="id_checkboxes1">
            <input type="checkbox" value="1" id="id_checkboxes1" name="ids[]" autocomplete="off"/>One
          </label>
        </div>
      </li>
    
      <li>
        <div class="btn-group-toggle" data-toggle="buttons">
          <label class="btn btn-success group_toggle" id="id_label2" for="id_checkboxes2">
            <input type="checkbox" value="2" id="id_checkboxes2" name="ids[]" autocomplete="off"/>Two
          </label>
        </div>
      </li>
    
      <li>
        <div class="btn-group-toggle" data-toggle="buttons">
          <label class="btn btn-info group_toggle" id="id_label3" for="id_checkboxes3">
            <input type="checkbox" value="3" id="id_checkboxes3" name="ids[]" autocomplete="off"/>Three
          </label>
        </div>
      </li>
    </ul>

    【讨论】:

    • 请注意,如果它与 Bootstrap 相关,因为我在带有 jQ​​uery 且没有 Bootstrap 库的 sn-p 中重现了双击事件。也许是由于 jQuery data-toggle attribute。我无法弄清楚导致双重事件的原因。
    • 您可以将切换简化为$checkbox.prop('checked', !checked)。它将以这种方式自动将其值设置为与当前值相反的值。不需要if...else
    • 在 sn-p 中它工作得很好,但不适合我。我想我会在某个地方覆盖该属性,所以我必须搜索它。无论如何。感谢您的解决方案和@NathanMiller 提供的这个简短的甜蜜代码。
    • 我会做出 Nathan 建议的更改 - 感谢您指出这一点;很高兴你找到了你的解决方案@GePu
    【解决方案2】:

    稍微扩展@Light的回答

    我可以看到的问题是事件发生的顺序以及您尝试手动控制复选框的状态。当您使用标签包装复选框(或在标签上使用 for="#id" )时,只要单击标签,它就会将单击委托给复选框(这就是它被触发两次的原因)。另一件事是您的按钮初始状态不正确,按钮二具有类 btn-success 但未激活,并且未选中相关复选框。完整解决方案见下文

    let checkbox_state = "";
    $(".group_toggle").click(function(e){
    		e.preventDefault();
      	$(this).toggleClass("btn-info btn-success");
        checkbox_state = $(this).children("input:first");
    
        console.log("Initial checkbox_state: " + checkbox_state.prop("checked"));
        if($(checkbox_state).prop("checked") == true) {
            checkbox_state.prop('checked', false);
            console.log("Checked after click: " + checkbox_state.prop("checked"));
        } else {
            checkbox_state.prop('checked', true);
           	console.log("Checked after click: " + checkbox_state.prop("checked"));
        }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
    <ul id="ids_ul" class="nav">
        <li>
            <div class="btn-group-toggle" data-toggle="buttons">
                <label class="btn btn-info group_toggle" id="id_label1" for="id_checkboxes1">
                <input type="checkbox" value="1" id="id_checkboxes1" name="ids[]" autocomplete="off"/> One</label>
            </div>
        </li>
        <li>
            <div class="btn-group-toggle" data-toggle="buttons">
                <label class="btn btn-success group_toggle active" id="id_label2" for="id_checkboxes2">
                <input type="checkbox" value="2" id="id_checkboxes2" name="ids[]" autocomplete="off" checked=""/> Two</label>
            </div>
        </li>
        <li>
            <div class="btn-group-toggle" data-toggle="buttons">
                <label class="btn btn-info group_toggle" id="id_label3" for="id_checkboxes3">
                <input type="checkbox" value="3" id="id_checkboxes3" name="ids[]" autocomplete="off"/> Three</label>
            </div>
        </li>
    </ul>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-25
      • 2013-02-26
      • 1970-01-01
      • 2012-12-06
      • 2019-03-14
      • 1970-01-01
      • 2011-04-05
      • 2011-04-14
      相关资源
      最近更新 更多