如何处理带有不确定复选框的浏览器差异

Posted

技术标签:

【中文标题】如何处理带有不确定复选框的浏览器差异【英文标题】:How to deal with browser differences with indeterminate checkbox 【发布时间】:2012-04-23 08:35:14 【问题描述】:

入门: 可以将 html 复选框设置为 indeterminate,将其显示为既未选中也未选中。即使在这种不确定的状态下,仍然存在底层布尔值checked 状态。


单击不确定的复选框时,它会失去其indeterminate 状态。根据浏览器 (Firefox),它还可以切换 checked 属性。

This jsfiddle 说明了这种情况。在 Firefox 中,单击任一复选框会导致它们切换其初始底层 checked 状态。在 IE 中,checked 属性在第一次点击时保持不变。

我希望所有浏览器的行为都相同,即使这意味着额外的 javascript。不幸的是,indeterminate 属性设置为 false before onclick 处理程序(或 onchange 和 jquery change)被调用,所以我无法检测它是否被称为点击是否在 indeterminate 复选框上。

mouseupkeyup(用于空格键切换)事件显示之前的 indeterminate 状态,但我不想那么具体:它看起来很脆弱。

我可以在复选框上维护一个单独的属性(data-indeterminate 或类似的),但我想知道我是否缺少一个简单的解决方案,和/或其他人是否有类似的问题。

【问题讨论】:

我认为数据可能是要走的路。 Windows 版 Safari 在首次点击时也会单独留下 checked 是您正在寻找的三态复选框吗?我问是因为不确定的属性只是一个视觉属性。它旨在向用户表明可能需要更改复选框的值。 是的,我想三态是我所追求的:我们用它来表示一个节点的一些(但不是全部)子节点被选中。我只是希望所有浏览器在单击此类节点时表现相同。 @aaaidan: 阅读本文可能对您有所帮助css-tricks.com/indeterminate-checkboxes 【参考方案1】:

如果您希望在所有浏览器上单击时都选中一个不确定的复选框(或至少在 IE、Chrome 和 FF5+ 上),您需要正确初始化选中的属性,如图所示这里http://jsfiddle.net/K6nrT/6/。我写了以下函数来帮助你:

/// Gives a checkbox the inderminate state and the right
/// checked state so that it becomes checked on click
/// on click on IE, Chrome and Firefox 5+
function makeIndeterminate(checkbox)

    checkbox.checked = getCheckedStateForIndeterminate();
    checkbox.indeterminate = true;

以及依赖特征检测的有趣功能:

/// Determine the checked state to give to a checkbox
/// with indeterminate state, so that it becomes checked
/// on click on IE, Chrome and Firefox 5+
function getCheckedStateForIndeterminate()

    // Create a unchecked checkbox with indeterminate state
    var test = document.createElement("input");
    test.type = "checkbox";
    test.checked = false;
    test.indeterminate = true;

    // Try to click the checkbox
    var body = document.body;
    body.appendChild(test); // Required to work on FF
    test.click();
    body.removeChild(test); // Required to work on FF

    // Check if the checkbox is now checked and cache the result
    if (test.checked)
    
        getCheckedStateForIndeterminate = function ()  return false; ;
        return false;
    
    else
    
        getCheckedStateForIndeterminate = function ()  return true; ;
        return true;
    

没有图像技巧,没有 jQuery,没有额外的属性和事件处理。这仅依赖于简单的 JavaScript 初始化(请注意,不能在 HTML 标记中设置“indeterminate”属性,因此无论如何都需要 JavaScript 初始化)。

【讨论】:

为什么投反对票?请提供一个它不起作用的场景,以便我们改进它 顺便说一句,我确实认为您的问题被正确识别为重复。直到你的答案,我才真正接受了答案,但我们仍在为看起来完全相同的问题争论不休。 :) 请注意,在复选框离开不确定状态后,IE 上不会触发 change 事件。 jsfiddle.net/paska/K6nrT/20【参考方案2】:

这解决了我的问题

$(".checkbox").click(function()
    $(this).change();
);

【讨论】:

虽然这个答案可能是正确且有用的,但最好在其中附上一些解释来解释它如何帮助解决问题。如果有更改(可能不相关)导致它停止工作并且用户需要了解它曾经是如何工作的,这在未来变得特别有用。 当一个检查框被点击时,同时发生两个事件,一个是点击,一个是改变。现在在“不确定”状态的情况下,您没有任何点击事件。所以我的一些浏览器如果你点击一个“不确定”复选框,它会切换到“检查”(例如:chrome),但对于 IE,它将是“取消选中”。为了同步,此代码可能会有所帮助$(".checkbox").click(function(e) e.preventDefault(); $(this).change(); );【参考方案3】:

我不确定使用函数为不确定的复选框设置值是否会是好的解决方案,因为:

你将不得不改变你使用它们的每个地方, 如果用户在未单击复选框的情况下提交表单,则值 您的后端将收到会因浏览器而异。

但我喜欢用聪明的方法来确定浏览器的工作方式。 所以你可以检查isCheckedAfterIndeterminate() 而不是通常的window.navigator.userAgent.indexOf('Trident') >= 0 看看它是IE(或者可能是其他以不寻常方式工作的浏览器)。

所以我的解决方案是:

/// Determine the checked state to give to a checkbox
/// with indeterminate state, so that it becomes checked
/// on click on IE, Chrome and Firefox 5+
function isCheckedAfterIndeterminate()

    // Create a unchecked checkbox with indeterminate state
    var test = document.createElement("input");
    test.type = "checkbox";
    test.checked = false;
    test.indeterminate = true;

    // Try to click the checkbox
    var body = document.body;
    body.appendChild(test); // Required to work on FF
    test.click();
    body.removeChild(test); // Required to work on FF

    // Check if the checkbox is now checked and cache the result
    if (test.checked) 
        isCheckedAfterIndeterminate = function ()  return false; ;
        return false;
     else 
        isCheckedAfterIndeterminate = function ()  return true; ;
        return true;
    


// Fix indeterminate checkbox behavoiur for some browsers.
if ( isCheckedAfterIndeterminate() ) 
    $(function()
        $(document).on('mousedown', 'input', function()
            // Only fire the change event if the input is indeterminate.
            if ( this.indeterminate ) 
                this.indeterminate = false;
                $(this).trigger('change');
            
        );
    );

【讨论】:

【参考方案4】:

制作您自己的可点击图像并使用一些 java(script) 使其行为类似。 我怀疑有多少用户会理解这种状态,所以要小心你在哪里使用它。

【讨论】:

谢谢,我很高兴终于可以在这里帮助到某人。 很高兴这对 Connor 有所帮助,但我对使用图像而不是表单元素持保留态度,因为可访问性对我来说很重要。这也意味着您不能使用某些人可能喜欢的操作系统复选框。 是的,我认为这是共识,Connor:如果你想使用“内置”表单元素强制它在浏览器中表现相同,使用 javascript 维护某种数据不确定属性是唯一的选择。干杯! 我只是想知道 aaiden 记录了一个问题,而 Connor 为这个问题设置了赏金? @ConnorGurney 因为答案未被接受为最佳答案,user613326 只会得到一半,除非您手动奖励全部赏金!仅供参考。

以上是关于如何处理带有不确定复选框的浏览器差异的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 VBA 中的复选框值?

如何处理数据表中的复选框单击事件

在 Rails 中,如何处理多个选中的复选框,只在 , 或?

如何处理 Android 运行时权限中的“不再询问”复选框?

如何处理 Oracle APEX 报告中的复选框项目?

在 Selenium Webdriver 如何处理这种包含复选框的多选下拉列表