在 event.preventDefault 的情况下复选框无法正常工作,并且在使用 setTimeout 时才工作

Checkbox not working normally in case of event.preventDefault and just working when using setTimeout

我刚刚经历了一个场景,我需要自定义一个复选框,这样就不会立即选中,而是

  1. 当用户尝试勾选复选框时显示确认框。
  2. 如果用户单击“是”,复选框将被选中。
  3. 单击“否”时,复选框不会更改并保持未选中状态。

在进行这项工作时,我使用了 preventDefault 和 stopPropagation 来阻止复选框遵循默认行为并有条件地选中或取消选中它。

在下面的代码片段中,复选框首先被选中,但随后并没有取消选中,因为代码在使用 setTimeout 时工作正常,但在没有它的情况下并非如此。以下是模型:

$(document).ready(function() {
  $('#chkbx').off('click').on('click', function(e) {
    var $checkbox = $(this);
    e.preventDefault();
    e.stopPropagation();
    showConfirmation($checkbox.is(':checked') ? 1 : 0);
  });

  function showConfirmation(s_checked) {
    // Why this if block is making checkbox checked 
    if (s_checked) {
      setTimeout(function() {
        $('#chkbx').val(1);
        $('#chkbx').prop('checked', true);
      }, 3000);
      // While a similar code without delay is not working
    } else {
      $('#chkbx').val(0);
      $('#chkbx').prop('checked', false);
    }
    return true;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="chkbx" name="chkbx" />

请帮助我理解,这里出了什么问题,因为代码在不使用 setTimeout 时没有取消选中复选框。

event.preventDefault() 方法阻止默认操作。在单击复选框的情况下,默认操作是切换其 checked 状态,这在相关代码中已被阻止。使用 setTimeout 代码实际上是在单击事件完成后执行的,因此不会观察到 preventDefault。

但是,要实现此功能,您可以选择仅在确实要防止复选框切换时才使用 event.preventDefault()。查看以下代码段:

$(document).ready(function() {
  $('#chkbx').on('click', function(e) {
    var $checkbox = $(this);
    e.stopPropagation();
    
    if($checkbox.is(":checked")) {
      if(confirm('Do you want to check?')) {
        $checkbox.val(1);
      } else {
        // use `preventDefault()` to block checkbox checking when not confirmed
        e.preventDefault();
      }
    } else {
      $checkbox.val(0);
    }
  });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="checkbox" id="chkbx" name="chkbx" value="0"/> Checkbox Label</label>

我认为你在这里采取了错误的方法。除了 e.preventDefault() 和计时器,您可以只禁用复选框,直到您提到的“其他按钮”被按下。

$(document).ready(function() {
  var $checkbox = $("#chkbx");
  
  // Simply set up your button click event
  $('button').on('click', function(e) {
    $checkbox.removeAttr("disabled"); // Enable the checkbox
  });
  
  $checkbox.on("click", showConfirmation);

  function showConfirmation(event) {
    console.log("The checkbox is checked: " + event.target.checked);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click to enable</button>
<input type="checkbox" id="chkbx" name="chkbx" disabled>Some question