阻止复选框勾选/检查完全

时间:2012-05-15 23:35:14

标签: javascript checkbox

我被要求禁用复选框的“滴答”。我没有被要求禁用复选框,而只是禁用“滴答”。

换句话说,用户认为复选框是可勾选的,但事实并非如此。相反,单击该复选框将显示模式对话框,为用户提供更多选项以打开或关闭复选框所代表的功能。如果在对话框中选择的选项导致功能打开,则勾选复选框。

现在,真正的问题是,对于拆分秒,您仍然可以看到勾选了复选框。

我尝试过这样的方法:

<input type='checkbox' onclick='return false' onkeydown='return false' />

$('input[type="checkbox"]').click(function(event) {
    event.preventDefault();
    alert('Break');
});

如果你运行这个,会出现警告,显示勾号是可见的(警报只是为了证明它仍然被勾选,在生产中,警报不存在)。对于速度较慢的机器和/或浏览器使用缓慢的渲染器/ javascript的用户,用户可以看到非常微弱的闪烁(闪烁有时持续半秒,这是显而易见的)。

我团队中的测试人员已将此标记为缺陷,我应该修复它。我不知道还有什么可以阻止复选框中的勾号闪烁!

14 个答案:

答案 0 :(得分:18)

尝试

event.stopPropagation();

http://jsfiddle.net/DrKfE/3/

答案 1 :(得分:15)

我想出的最佳解决方案:

$('input[type="checkbox"]').click(function(event) {
    var $checkbox = $(this);

    // Ensures this code runs AFTER the browser handles click however it wants.
    setTimeout(function() {
      $checkbox.removeAttr('checked');
    }, 0);

    event.preventDefault();
    event.stopPropagation();
});

答案 2 :(得分:8)

我害怕这种效果无法抑制。单击复选框后,状态(和渲染)将立即更改。然后将调用事件处理程序。如果您执行event.preventDefault(),则在执行所有处理程序后,将重置复选框。如果您的处理程序具有较长的执行时间(可以使用模态alert()轻松测试)和/或渲染引擎在重置之前重新绘制,则该框将闪烁。

$('input[type="checkbox"]').click(function(event) {
    this.checked = false; // reset first
    event.preventDefault();
    // event.stopPropagation() like in Zoltan's answer would also spare some
    // handler execution time, but is no more needed here

    // then do the heavy processing:
    alert('Break');
});

此解决方案可将闪烁降至最低,但不能真正阻碍它。有关如何模拟复选框的信息,请参阅Thr4wn和RobG的答案。我更喜欢以下内容:

<button id="settings" title="open extended settings">
    <img src="default_checkbox.png" />
</button>
document.getElementById("settings").addEventListener("click", function(e) {
    var img = this.getElementsByTagName("img")[0]);
    openExtendedSettingsDialog(function callbackTick() {
        img.src = "checked_checkbox.png";
    }, function callbackUntick() {
        img.src = "unchecked_checkbox.png";
    });
}, false);

答案 3 :(得分:7)

从我的观点来看,它很简单:

$(this).prop('checked', !$(this).prop('checked'));

适用于已选中和未选中的框

答案 4 :(得分:2)

使用CSS,您可以更改复选框的图像。请参阅http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/CSS Styling Checkboxes

我会禁用该复选框,但将其替换为工作复选框的图像。这样,复选框看起来不会被禁用,但不会被点击。

答案 5 :(得分:2)

用另一个阻止指针事件的元素(可能是通过CSS)包装复选框。然后,直接处理包装器的单击事件而不是复选框。这可以通过多种方式完成,但这是一个相对简单的示例实现:

$('input[type="checkbox"').parent('.disabled').click( function() {
    
    // Add in whatever functionality you need here
    
    alert('Break');
    
});
/* Insert an invisible element that covers the checkbox */
.disabled {
    position: relative;
}
.disabled::after {
    content: "";
    position: absolute;
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<!-- Only wrapped checkboxes are "disabled" -->
<input type="checkbox" />
<span class="disabled"><input type="checkbox" /></span>
<input type="checkbox" />
<span class="disabled"><input type="checkbox" /></span>
<span class="disabled"><input type="checkbox" /></span>
<input type="checkbox" />

注意:如果您愿意,也可以通过编程方式添加包装元素。

答案 6 :(得分:2)

不是更简单吗? :

<input type="checkbox" onchange="this.checked = !this.checked">

答案 7 :(得分:1)

听起来像是你使用了错误的界面元素,更合适的一个是默认禁用的按钮,但是当该选项可用时启用。显示的图像可以是您想要的任何内容。

<button disabled onclick="doSomething();">Some option</button>

当用户选择该功能时,启用该按钮。 CSS上可以修改按钮上的图像,具体取决于它是否启用,或启用/禁用功能。

e.g。

<script type="text/javascript">

function setOption(el) {
  var idMap = {option1:'b0', option2: 'b1'};
  document.getElementById(idMap[el.value]).disabled = !el.checked; 
}

</script>

<div><p>Select options</p>
  <input type="checkbox" onclick="setOption(this);" value="option1"> Option 1
  <br>
  <input type="checkbox" onclick="setOption(this);" value="option2"> Option 2
  <br>
</div>
<div>
  <button id="b0" onclick="alert('Select…');" disabled>Option 1 settings</button>
  <button id="b1" onclick="alert('Select…');" disabled>Option 2 settings</button>
</div>

答案 8 :(得分:1)

最后使用return false非常重要。

这样的事情:

$("#checkbox").click((e) => {
  e.stopPropagation();
  return false;
});

答案 9 :(得分:1)

TL:DR;

HTML api在JavaScript之前执行。因此,您必须使用JavaScript撤消HTML的更改。

event.target.checked = false

出什么问题了?

严格来说:我们不能“停止”复选框。为什么不?因为“被打勾”正好表示DOM的元素,所以HTML <input>元素的checked属性值为truefalse,由 HTML立即分配api

console.log(event.target.checked) // will be opposite of the previous value

因此值得一提的是,此HTML api在脚本之前被调用。这是直观的,应该是有道理的,因为所有JavaScript文件本身都是<script>元素的属性src的分配,以及您所讨论的<input>之间DOM树中的祖先关系,并且运行JavaScript的<script>元素是非常重要的要考虑的问题。

如何获得我们的解决方案

在我们有机会截取控制流之前(通过jQuery之类的JS文件),尚未绘制HTML分配的值,因此我们只需将checked属性重新分配为所需的布尔值即可: false(针对您的情况)。

因此,总而言之,我们可以通过简单地确保下一个渲染的checked属性为false来有效地“停止”该复选框。查看任何更改。

答案 10 :(得分:1)

为什么不简单地在您的 CSS 中添加一个设置 pointer-events: none; 的类?

类似于:

<style>
    input.lockedCbx { pointer-events: none; }
</style>
...
<input type="checkbox" class="lockedCbx" tabindex=-1 />
...

您需要使用 tabindex=-1 来防止用户使用 Tab 键进入复选框并按空格键进行切换。

现在理论上您可以避免使用该类并使用 tabindex=-1 来控制禁用:

<script>
    input[type="checkbox"][tabindex="-1"] { pointer-events: none; }
</script>

答案 11 :(得分:0)

Event.preventDefault方法适用于changekeydownmousedown个事件,但不在我的测试中。

我在Mozilla Firefox 53.0扩展程序中解决此问题的方法是切换启用/禁用应用于复选框的CSS声明pointer-events: none的HTML类。这解决了基于游标的情况,但不解决基于密钥的情况。请参阅https://www.w3.org/TR/SVG2/interact.html#PointerEventsProp

我通过添加/删除HTML tabindex="-1"属性来解决基于密钥的问题。请参阅https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex

请注意,禁用pointer-events会禁用在悬停时触发CSS游标的功能(例如cursor: not-allowed)。我的复选框已包含在span元素中,因此我向该span元素添加了一个HTML类,然后我将CSS cursor声明重新定位到。

另请注意,添加tabindex="-1"属性将从复选框中移除焦点,因此需要使用HTMLElement.blur()方法或通过关注另一个方法对其进行显式散焦如果复选框是添加属性时的活动元素,则阻止基于键的输入的元素。可以使用my_checkbox.isEqualNode(document.activeElement)来测试复选框是否是焦点元素。

答案 12 :(得分:0)

只需将值还原回

$('input[type="checkbox"]').on('change', function(e) {
    if (new Date().getDate() === 13) {
        $(this).prop('checked', !$(this).prop('checked'));
        e.preventDefault();
        return false;
     }
     // some code here
});

答案 13 :(得分:0)

将此添加到js文件中的click事件

event.stopPropagation();