48

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

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

现在,真正的问题是,在一瞬间,您仍然可以看到复选框被选中。

我尝试过这样的方法:

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

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

如果您运行此程序,将出现警报,显示刻度是可见的(警报只是在那里证明它仍然被打勾,在生产中,警报不存在)。在一些机器速度较慢的用户和/或渲染器/javascript 速度较慢的浏览器中,用户可以看到非常微弱的闪烁(闪烁有时会持续半秒,这一点很明显)。

我团队中的一名测试人员将此标记为缺陷,我应该修复它。我不确定还有什么方法可以防止复选框中的勾闪烁!

4

14 回答 14

20

尝试

event.stopPropagation();

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

于 2012-05-15T23:38:37.227 回答
19

我想出的最佳解决方案:

$('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();
});
于 2014-04-10T16:19:12.777 回答
19

从我的角度来看,它很简单:

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

适用于选中和未选中的框

于 2016-10-16T12:34:43.743 回答
10

这个效果恐怕无法抑制。一旦你点击复选框,状态(和渲染)就会改变。然后将调用事件处理程序。如果您执行 a ,则在执行所有处理程序event.preventDefault(),该复选框将被重置。如果您的处理程序有很长的执行时间(很容易使用 modal 进行测试)和/或渲染引擎在重置之前重新绘制,则该框将闪烁。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);
于 2012-05-16T00:20:17.107 回答
6

最后使用非常重要return false

像这样的东西:

$("#checkbox").click((e) => {
  e.stopPropagation();
  return false;
});
于 2018-04-10T12:56:18.160 回答
6

不是更简单吗?:

<input type="checkbox" onchange="this.checked = !this.checked">
于 2019-04-10T11:41:01.160 回答
6

TL:博士;

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

event.target.checked = false

问题是什么?

严格来说:我们不能“阻止”复选框被勾选。为什么不?因为“被打勾”正好意味着 DOM 的 HTML<input>元素的checked属性值为trueor ,它是由HTML apifalse立即分配的

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

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

如何获得我们的解决方案

在我们有机会拦截控制流(通过像 jQuery 之类的 JS 文件)之前,尚未绘制 HTML 分配的值,因此我们只需将checked属性重新分配给我们想要的布尔值:(false在您的情况下)。

因此,总而言之,我们实际上可以“停止”复选框被选中,只需确保该checked属性false在下一次渲染中,因此不会看到任何更改。

于 2020-04-20T22:10:07.277 回答
2

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

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

于 2012-05-15T23:38:57.063 回答
2

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

$('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" />

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

于 2015-07-31T16:28:26.010 回答
2

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

就像是:

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

您需要tabindex=-1阻止用户在复选框中切换并按空格键进行切换。

现在理论上你可以避免类并使用tabindex=-1来控制禁用,如下所示:

<script>
    input[type="checkbox"][tabindex="-1"] { pointer-events: none; }
</script>
于 2021-02-04T17:10:43.473 回答
1

在我看来,您使用了错误的界面元素,更合适的应该是默认禁用的按钮,但在该选项可用时启用。显示的图像可以是任何你想要的。

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

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

例如

<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>
于 2012-05-16T00:20:43.770 回答
1

只需将值还原回来

$('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
});
于 2019-08-23T15:16:41.847 回答
0

Event.preventDefault方法应该适用于changekeydownmousedown事件,但不适用于我的测试。

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

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

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

另请注意,添加tabindex="-1"属性不会HTMLElement.blur()从复选框中移除焦点,因此如果复选框在属性出现时是活动元素,则需要使用该方法或通过聚焦另一个元素来显式散焦它以防止基于键的输入添加。复选框是否是焦点元素可以用my_checkbox.isEqualNode(document.activeElement).

于 2017-04-24T04:53:50.170 回答
0

将此添加到 js 文件中的单击事件

event.stopPropagation();                  
于 2019-09-21T08:50:00.953 回答