使用按钮标签更改复选框的状态不再有效

时间:2015-06-22 04:17:18

标签: html css checkbox

直到最近,以下代码片段工作正常,复选框本身被CSS隐藏,点击按钮改变了复选框的状态,然后可以在表单提交时检测到,但是,最近(不确定何时) )这停止了工作,现在点击按钮什么都不做:

<label for="someCheckBox" class="someCheckBox">
    <input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
    <button type="button" title="Some CheckBox">Some CheckBox</button>
</label>

CSS:

#someCol label.someCheckBox button {
    background-color: black;
    color: #C0C0C0;
    height: 1.5em;
    margin: 10px 4px 0 0;
    border: 1px solid #C0C0C0;
    -moz-border-radius: .75em;
    -webkit-border-radius: .75em;
    border-radius: .75em;
    font-size: 1.0em;
    font-family:"Final Frontier";
    font-weight: bold;
    width: 40px;
}
#someCol label.someCheckBox button:hover {
    background-color: #C0C0C0;
    color: black;
    border: 1px solid #606060;
    cursor: pointer;
    -moz-animation-duration: 3s;
    -moz-animation-name: glow;
    -moz-animation-iteration-count: infinite;
    -moz-animation-play-state: running;
    -webkit-animation-duration: 3s;
    -webkit-animation-name: glow;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-play-state: running;
    animation-duration: 3s;
    animation-name: glow;
    animation-iteration-count: infinite;
    animation-play-state: running;
}
#someCol label.someCheckBox input {
    position:absolute;
    top:-20px;
}
#someCol label.someCheckBox input:checked + button {
    background-color: #C0C0C0;
    color: black;
    border: 1px solid #606060;
    box-shadow: 0 0 15px #C0C0C0;
    -webkit-box-shadow: 0 0 15px #C0C0C0;
}
#someCol label.someCheckBox button {
    width: 90px;
    margin: 10px 0 0 4px;
}

应该注意的是,我简单地尝试将这些按钮/复选框中的一个更新为文本标签而不是按钮,并且复选框状态确实按预期更改,但是,我希望按钮用于表单的外观,我有很多这样的工具,所以要改变它们需要做很多工作......

同样我最初更喜欢这种方法,因为它减少了JS使表单更加HTML友好的需要,所以尽管我可以编写一个脚本来改变复选框的状态,但它并没有为我的根本目的服务,而且,当以前工作时,需要做很多工作来纠正所有设置的按钮。

由于此前确实有效,而且我有时没有触及代码库,我不确定除了浏览器更新之外发生了什么变化,任何人都可以提供帮助,因为我已经撕掉我的头发了现在几个小时,无法弄清楚改变了什么......

2 个答案:

答案 0 :(得分:0)

没有得到答案,所以最简单的替代方案是添加JS onClick事件。这不是我希望它如何工作,但却是最快的解决方案:

<label for="someCheckBox" class="someCheckBox">
    <input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
    <button type="button" title="Some CheckBox" onclick="changeStateButton(\'someCheckBox\',\'check\');">Some CheckBox</button>
</label>

function changeStateButton(selID,selType){
    if (document.getElementById(selID) !== null && document.getElementById(selID) !== "undefined"){
        if (selType="check"){
            if (!document.getElementById(selID).checked) {
                document.getElementById(selID).checked = "checked";
            } else {
                document.getElementById(selID).checked = "";
            }
        } else if (selType="radio"){
            if (!document.getElementById(selID).checked) {
                document.getElementById(selID).checked = "checked";
            }
        }
    }
}

如果有人能够回答为什么它停止使用纯HTML方式,我仍然有兴趣听听。

答案 1 :(得分:0)

提出的解决方案似乎过于复杂和冗长。我倾向于利用这样一个事实:相关元素既是UI元素,也是响应鼠标事件的。

我还考虑使代码更智能,以便它不需要内联JS将按钮附加到其目标输入元素。也许通过保存目标id的属性,或者更好 - 您可以获得单击按钮(标签)的父级,然后获取它包含的(唯一)输入元素并对其执行操作。

要以我描述的第一种方式进行,你可以调用目标元素的click()函数,并用3行完成,如下所示:

function myChange(tgtId)
{
    var tgtElem = byId(tgtId);
    if (tgtElem != undefined)
        tgtElem.click();
}

此功能是您已经使用的功能的替代品,也可以使您的html更整洁并且不易出错,无需传递第二个变量。虽然它仍然需要通过内联javascript附加。

也许一个更简洁的解决方案是编写一个处理程序,它可以解决按钮与哪个元素配对,因为它们是同一个父级的唯一兄弟。它还意味着你可以在一个非常小的循环中设置任意数量的它们,同样保持你的html清洁。

首先,执行检查/取消检查的功能。

function myChange2(evt)
{
    var clickedButton = this;
    var containingLabel = clickedButton.parentNode;
    var tgtElem = containingLabel.getElementsByTagName('input')[0];
    if (tgtElem != undefined)
        tgtElem.click();
}

我们找出导致函数被调用的元素,获取它的父元素然后获取它包含的按钮列表中的第一个元素(应该只有一个,但函数返回一个列表,NodeList是具体)。然后我们只需单击该元素,允许浏览器处理状态的变化。

最后,我们需要一种方法将函数连接到需要它的所有元素。我们将使用querySelectorAll,因为它允许我们使用css选择器,这极大地简化了获取我们实际感兴趣的元素列表的过程。我使用>字符来表示元素必须是标签的直接子元素 - 它不会以包含在标签中包含的另一个元素中的按钮为目标。 (您可以在我添加的第一个复选框中看到此效果,方法是在标签内的跨区中包含一个按钮。)然后,我们会附加该事件,以便我们访问this关键字在处理程序函数中,它允许代码知道哪个按钮导致它被调用。

这是一个完整的例子 - 我已经更改了标签的类别,以便将事件附加到我添加的事件中,不会干扰已经存在的事件。我还从每个按钮中删除了type='button'属性 - 如果您正在使用输入(类型按钮),则只需要此属性。我还从复选框中删除了value属性,因为它已选中或未选中 - 浏览器会为我们处理此问题。单选按钮需要它,但复选框不需要它。

关于我在评论部分中关于转义'字符的评论 - 您可以用双引号括起单引号,或者相反。当它被相同类型的引号括起来时,你只需要转义引用。

因此,如果没有使用斜杠转义,'"'就可以了,"'"也是如此。 您只需要'''""",每个'\''"\""

<!DOCTYPE html>
<html>
<head>
<script>
function byId(id){ return document.getElementById(id); }
window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
    var elemsToInit = document.querySelectorAll('label.btnProxy > button');
    var i, n = elemsToInit.length;
    for (i=0;i<n;i++)
    {
        elemsToInit[i].addEventListener('click', myChange2, false);
    }
}

function myChange(tgtId, tgtType)
{
    var tgtElem = byId(tgtId);
    if (tgtElem != undefined)
        tgtElem.click();
}

function myChange2(evt)
{
    var clickedButton = this;
    var containingLabel = clickedButton.parentNode;
    var tgtElem = containingLabel.getElementsByTagName('input')[0];
    if (tgtElem != undefined)
        tgtElem.click();
}

</script>
</head>
<body>
    <label for="someCheckBox" class="someCheckBox">
        <input type="checkbox" id="someCheckBox" name="someCheckBox" value="checkBox" />
        <button type="button" title="Some CheckBox" onclick="myChange('someCheckBox','check');">Some CheckBox</button>
    </label>

    <hr>

    <label class="btnProxy"><input type="checkbox"/><button>Toggle</button><span><button>I'm Inert!</button></span></label>
    <br>
    <label class="btnProxy"><input type="checkbox"/><button>Toggle</button><button>I work too!</button></label>
    <br>
    <label class="btnProxy"><input type="checkbox"/><button>Toggle</button></label>

    <hr>

    <label class="btnProxy"><input type="radio" name='gender' value='alien'/><button>Select</button></label>
    <br>
    <label class="btnProxy"><input type="radio" name='gender' value='female'/><button>Select</button></label>
    <br>
    <label class="btnProxy"><input type="radio" name='gender' value='male'/><button>Select</button></label>

</body>
</html>