复选框按钮在多次快速单击时效果不佳

checkbox button does not work well when clicked on quickly multiple times

本文关键字:单击 按钮 复选框      更新时间:2023-09-26

我这里有一个jsfiddle:http://jsfiddle.net/zAFND/616

现在,如果您在IE(我使用IE9(和Firefox中打开小提琴,如果您双击复选框按钮,它会将其打开但不关闭。但是,如果您在opera,safarai和chrome中打开它,则双击或快速连续单击,则可以正常工作。

我的问题是如何允许快速连续点击在 Firefox 和 IE9 中正常工作?

法典:

.HTML:

<div id="ck-button"><label>
<input type="checkbox" name="options[]" id="optionA" value="A" /><span>A</span></label>
</div>

.CSS:

#ck-button {
    margin:8px;
    background-color:#EFEFEF;
    border:1px solid #D0D0D0;
    overflow:auto;
    float:left;
    position: relative;
}
#ck-button label {
    float:left;
    width:4.0em;
    cursor:pointer;
}
#ck-button label span {
    text-align:center;
    padding:3px 0px;
    display:block;
}
#ck-button label input {
    position:absolute;
    top:-20px;
}
#ck-button input:checked + span {
    background-color:green;
    color:white;
}

Jquery/javasscript:

 $(document).ready(function(){
            $("body").css("-webkit-user-select","none");
            $("body").css("-moz-user-select","none");
            $("body").css("-ms-user-select","none");
            $("body").css("-o-user-select","none");
            $("body").css("user-select","none");
    });

这是 Firefox 中的一个错误。请参阅错误 608180 - 双击/快速单击复选框标签无法按预期工作

由于历史原因(但在较新版本中已修复(,IE 有一个错误的事件模型,该模型跳过第二个mousedown并在双击时click事件。请参阅错误 263 - 当心 IE 中的双击。

我做了一个插件,修复了jQuery UI按钮小部件中的一些错误,以及不久前解决Firefox错误,应该不难适应你的非jQuery UI按钮。

提取了重要部分并将其调整为label s中的嵌套复选框:

(function () {
    var mdtarg, //last label mousedown target
        mdchecked, //checked property when mousedown fired
        fixedLabelSelector = '.fixedLabelCheckbox'; //edit as you see fit
    $(document).on('mousedown', fixedLabelSelector, function (e) {
        //only left clicks will toggle the label
        if (e.which !== 1) return;
        mdtarg = this;
        mdchecked = this.control ? this.control.checked : $(this).find('input')[0].checked;
        //reset mdtarg after mouseup finishes bubbling; prevents bugs with
        //incorrect mousedown-mouseup sequences e.g.
        //down IN label, up OUT, down OUT, up IN
        $(document).one('mouseup', function () {
            mdtarg = null;
        });
    }).on('mouseup', fixedLabelSelector, function (e) {
        if (e.which !== 1) return;
        if (mdtarg === this) {
            var ch = this.control || $(this).find('input')[0];
            //the click event is supposed to fire after the mouseup so
            //we wait until mouseup and click finish bubbling and check if it
            //had the desired effect
            setTimeout(function () {
                if (mdchecked === ch.checked) {
                    //else patch it manually
                    ch.checked = !ch.checked;
                    $(ch).change();
                }
            }, 0);
        }
    });
}());

小提琴在火狐中测试过。

您必须将 fixedLabelCheckbox 类添加到包含要使用上述代码修复的复选框的所有标签中。

无论您将脚本放在何处,它都可以工作,并且只要标签具有相应的委托类/选择器,它就会修复动态添加的复选框。

请注意,如果您使用的是其他库,这可能不会触发绑定在 jQuery 外部的更改处理程序。

如果您不想向标记添加额外的类,则可以使用此版本(更多代码和更少性能(:

(function ($) {
    function getControl(lbl) { //fallback for non-HTML5 browsers if necessary
        return lbl.control || (lbl.htmlFor ? $('input[id="'+lbl.htmlFor+'"]')[0] : $(lbl).find('input')[0]);
    }
    var mdtarg, //last label mousedown target
        mdchecked; //checked property when mousedown fired
    $(document).on('mousedown', 'label', function (e) {
        //only left clicks will toggle the label
        if (e.which !== 1) return;
        var ch = getControl(this);
        if (!ch || ch.type !== 'checkbox') return;
        mdtarg = this;
        mdchecked = ch.checked;
        //reset mdtarg after mouseup finishes bubbling; prevents bugs with
        //incorrect mousedown-mouseup sequences e.g.
        //down IN label, up OUT, down OUT, up IN
        $(document).one('mouseup', function () {
            mdtarg = null;
        });
    }).on('mouseup', 'label', function (e) {
        if (e.which !== 1) return;
        if (mdtarg === this) {
            var ch = getControl(this);
            //the click event is supposed to fire after the mouseup so
            //we wait until mouseup and click finish bubbling and check if it
            //had the desired effect
            setTimeout(function () {
                if (mdchecked === ch.checked) {
                    //else patch it manually
                    ch.checked = !ch.checked;
                    $(ch).change();
                }
            }, 0);
        }
    });
}(jQuery));

小提琴

从上面的代码中可以看出,此版本应同时使用 label 的 for 属性以及 label 内的嵌套输入,而无需添加任何额外的标记。


关于禁用选择:您可以按照问题中的注释将user-select放入 CSS 中,或者,如果还涉及不支持user-select的浏览器,请将此答案应用于要禁用选择的所有标签。

您可以添加浏览器检测,然后,如果是 IE 或 Firefox,则通过 JS 添加 ondblclick 事件以反转复选框。

您不能无条件地设置它,因为某些浏览器(Safari,Chrome(传输两个click和一个dblclick,而其他浏览器(IE,Firefox(仅传输一个click和一个dblclick。在前者上,两个click事件将反转字段两次。在后者上,只有一个click事件触发,因此场只反转一次;为了缓解这种情况,您需要dblclick反转字段,以便两次单击将其反转偶数次。

希望这有帮助!!