Javascript 完全防止复选框打勾/检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10610249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:07:15  来源:igfitidea点击:

Prevent checkbox from ticking/checking COMPLETELY

javascriptcheckbox

提问by Andrew

I have been asked to disable the "ticking" of a checkbox. I am not being asked to disablethe checkbox, but to simply disable the "ticking".

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

In other words, a user will thinkthat a checkbox is tickable, but it is not. Instead, clicking on the checkbox will cause a modal dialog to appear, giving the user more options to turn on or off the feature that the checkbox represents. If the options chosen in the dialog cause the feature to be turned on, then the checkbox will be ticked.

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

Now, the real problem is that for a split second, you can still see that the checkbox is being ticked.

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

I have tried an approach like this:

我尝试过这样的方法:

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

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

If you run this, the alert will appear, showing that the tick is visible (the alert is just there to demonstrate that it still does get ticked, in production, the alert is not there). On some users with slower machines and/or in browsers with slow renderers/javascript, users can see a very faint flicker (the flicker sometimes lasts for half a second, which is noticeable).

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

A tester in my team has flagged this as a defect and I am supposed to fix it. I'm not sure what else I can try to prevent the tick in the checkbox from flickering!

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

回答by Zoltan Toth

回答by paulpooch

Best solution I've come up with:

我想出的最佳解决方案:

$('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();
});

回答by Patartics Milán

From my point of view it is as simple as:

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

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

Works both for checked and unchecked boxes

适用于选中和未选中的框

回答by Bergi

This effect can't be suppressed I fear. As soon as you click on the checkbox, the state (and rendering) is changed. Then the event handlers will be called. If you do a event.preventDefault(), the checkbox will be reset afterall the handlers are executed. If your handler has a long execution time (easily testable with a modal alert()) and/or the rendering engine repaints before reseting, the box will flicker.

这个效果恐怕无法抑制。单击复选框后,状态(和渲染)就会更改。然后将调用事件处理程序。如果你做了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');
});

This solution will reduce the flickering to a minimum, but can't hinder it really. See Thr4wn's and RobG's answer for how to simulate a checkbox. I would prefer the following:

这种解决方案将闪烁减少到最低限度,但不能真正阻止它。有关如何模拟复选框的信息,请参阅 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);

回答by bossno

Isn't is simpler ? :

不是更简单吗?:

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

回答by Florian Leitgeb

It is very important to use return falseat the end.

return false最后使用非常重要。

Something like this:

像这样的东西:

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

回答by Alexander Bird

With CSS, you can change the image of the checkbox. See http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/and also CSS Styling Checkboxes.

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

I would disable the checkbox, but replace it with an image of a working checkbox. That way the checkbox doesn't look disabled, but won't be clickable.

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

回答by BCDeWitt

Wrap the checkbox with another element that somehow blocks pointer events (probably via CSS). Then, handle the wrapper's click event instead of the checkbox directly. This can be done a number of ways but here's a relatively simple example implementation:

用另一个以某种方式阻止指针事件(可能通过 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" />

Note: You could also add the wrapper elements programmatically, if you would like.

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

回答by RobG

Sounds to me like you are using the wrong interface element, a more suitable one would be a button that is disabled by default, but enabled when that option is available. The image displayed can be whatever you want.

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

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

When users have selected that feature, enable the button. The image on the button can be modified by CSS depending on whether it's enabled or not, or by the enable/disable function.

当用户选择了该功能时,启用该按钮。按钮上的图像可以通过 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>

回答by Tobiah Rex

TL:DR;

TL:博士;

HTML api's execute before JavaScript. So you must use JavaScript to undo HTML's changes.

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

e.target.checked = false

WHAT is the problem?

问题是什么?

Strictly speaking: we cannot "stop" the checkbox from being ticked. Why not? Because "being ticked" exactly means that the DOM's, HTML <input>element has a checkedproperty value of trueor false, which is immediately assigned by the HTML api

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

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

So it's worth explicitly mentioning this HTML api is called before scripts. Which is intuitive and should make sense, because all JavaScript files are themselves the assignment of a <script>element's attribute src, and the ancestral relationship in the DOM tree, between your <input>in question, and the <script>element running your JavaScript, is extremely importantto consider.

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

HOW to get our solution

如何获得我们的解决方案

The HTML assigned value has not yet been painted before we have a chance to intercept the control flow (via JS file like jQuery), so we simply re-assign the checkedproperty to a boolean value we want: false(in your case).

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

So in conclusion, we CAN, in-effect, "stop" the checkbox from being checked, by simply ensuring that the checkedproperty is falseon the next render and thus, won't see any changes.

因此,总而言之,我们可以通过简单地确保checked属性false在下一次渲染中来“停止”复选框被选中,从而不会看到任何更改。