为什么浏览器停止显示复选框更新?

时间:2015-04-11 06:47:31

标签: javascript jquery html checkbox

我使用jQuery帮助选择表单中的一些匹配复选框元素。表单是动态创建的,但这里有一个精简版本,说明了我的观点:

http://jsfiddle.net/phinor/qj7uj3rc/

这是相关的JavaScript:

$(document).ready (function () {
    $('.lessoncount').on ('click', tickAlike);
});

function tickAlike ()
{
    var classes = $(this).attr('data-classes');

    if ($(this).siblings ('.tick_' + classes).attr ('checked'))
    {
        console.log ('ticking');
        $('.tick_' + classes).removeAttr ('checked');
    }
    else
    {
        console.log ('unticking');
        $('.tick_' + classes).attr ('checked', true);
    }
}

这个想法是复选框可以单独选择,或者如果&#34;标签&#34;单击,将选中或取消选中具有相同类的所有复选框以匹配旁边的框。因为我想要两种可能的行为,取决于他们是否点击了框或标签,我不能使用<label>标签。作为后续,由于独立选择,&#34;切换&#34;是不可行的。

这似乎适用于&#34; ticks&#34; &#34; unticks&#34;然后停下来。如果我检查Chrome中的复选框元素,我可以看到&#34;已选中&#34;正在添加和删除属性,但浏览器视图不再更新,并且不显示刻度。

这在Chrome,Firefox和IE的最新版本中是一致的,所以我猜测我做错了什么!

4 个答案:

答案 0 :(得分:0)

在修改布尔属性时,您应该使用.prop()而不是.attr(),例如checkeddisabledreadonlyselected等。使用.removeAttr().removeProp()将导致该属性永久删除,而不能进一步操纵。要了解.prop().attr()之间的区别,实际上a very good question (with a well-structured answer) asked on SO before

要以编程方式选中复选框,只需使用$selector.prop('checked',true)即可。要取消选中,请使用$selector.prop('checked',false)

另外,要检查复选框是否已选中(无双关语),您可以使用.is()方法执行此操作,即$selector.is(':checked')


$(document).ready(function () {
    $('.lessoncount').on('click', tickAlike);
});

function tickAlike ()
{
    var classes = $(this).attr('data-classes');
    if ($(this).siblings('.tick_' + classes).is(':checked'))
    {
        console.log('ticking');
        $('.tick_' + classes).prop('checked', false);
    }
    else
    {
        console.log('unticking');
        $('.tick_' + classes).prop('checked', true);
    }
}

工作演示:http://jsfiddle.net/teddyrised/qj7uj3rc/5/


更好:我可以看到包含每个复选框说明的<span>元素在其附带的复选框中是语义上精神错乱的,即没有办法为每个复选框提供上下文。为此目的创建了<label>元素。

您可能仍希望独立设置描述符的样式,因此我们可以将它们保存在<span>中,但我们可以使用<td>元素将每个<label>内的所有内容包装起来,这样单击文本复选框将触发相同的响应。

表体中行的修订标记看起来像这样:

<tr>
    <td>1-Mo</td>
    <td><label for="lesson_1_1"><input type="checkbox" name="lesson[1][1]" value="1" id="lesson_1_1" class="tick_1645_1646_1647_1648_1649_1650_2024"/> <span data-classes="1645_1646_1647_1648_1649_1650_2024" class="lessoncount">(7)</span></label></td>
    <td><label for="lesson_1_2"><input type="checkbox" name="lesson[1][2]" value="1" id="lesson_1_2" class="tick_1582_1583_1584_1585_1586_1587"/> <span data-classes="1582_1583_1584_1585_1586_1587" class="lessoncount">(6)</span></label></td>
    <td><label for="lesson_1_3"><input type="checkbox" name="lesson[1][3]" value="1" id="lesson_1_3" class="tick_1658_1673_1684_1700_1706_1736_1737_1769"/> <span data-classes="1658_1673_1684_1700_1706_1736_1737_1769" class="lessoncount">(8)</span></label></td>
    <td><label for="lesson_1_4"><input type="checkbox" name="lesson[1][4]" value="1" id="lesson_1_4" class="tick_1602_1603_1604_1605_1618_1628"/> <span data-classes="1602_1603_1604_1605_1618_1628" class="lessoncount">(6)</span></label></td>
    <td><label for="lesson_1_5"><input type="checkbox" name="lesson[1][5]" value="1" id="lesson_1_5" class="tick_"/> <span>(0)</span></label></td>
    <td><label for="lesson_1_6"><input type="checkbox" name="lesson[1][6]" value="1" id="lesson_1_6" class="tick_1659_1674_1701_1738_1755_1756"/> <span data-classes="1659_1674_1701_1738_1755_1756" class="lessoncount">(6)</span></label></td>
    <td><label for="lesson_1_7"><input type="checkbox" name="lesson[1][7]" value="1" id="lesson_1_7" class="tick_1719_1720_1721_1722_1723_2003"/> <span data-classes="1719_1720_1721_1722_1723_2003" class="lessoncount">(6)</span></label></td>
    <td>detail | clear</td>
  </tr>

使用稍微修改过的脚本即使在包裹<label>元素而不是文本范围内也可以收听点击:

$(document).ready(function () {
    $('table tbody label').on('click', tickAlike);
});

function tickAlike ()
{
    var classes = $(this).find('span.lessoncount').attr('data-classes');
    if ($(this).find('input[type="checkbox"]').is(':checked'))
    {
        console.log('ticking');
        $('.tick_' + classes).prop('checked', false);
    }
    else
    {
        console.log('unticking');
        $('.tick_' + classes).prop('checked', true);
    }
}

查看替代工作演示:http://jsfiddle.net/teddyrised/pb68gk2n/

答案 1 :(得分:0)

问题是,当您想要切换属性checked时,不应使用属性进行操作。

以下是更新和简化的代码:

$(document).ready(function () {
    $('.lessoncount').on('click', tickAlike);
});

function tickAlike() {
    var classes = $(this).data('classes');
    var $checkbox = $(this).siblings('.tick_' + classes).click();
    $('.tick_' + classes).prop('checked', $checkbox.is(':checked'));
}

演示: http://jsfiddle.net/qj7uj3rc/6/

然而,这仍然不理想:请注意点击复选框本身什么都不做。所以它可以改进。您需要使用label而不是span并将复选框包装到这些标签中。所以HTML应该是这样的:

<label data-classes="1645_1646_1647_1648_1649_1650_2024" class="lessoncount">
    <input type="checkbox" name="lesson[1][1]" value="1" id="lesson_1_1" class="tick_1645_1646_1647_1648_1649_1650_2024" /> (7)
</label>

然后在复选框上绑定onchange事件而不是spans:

$(document).ready(function () {
    $('.lessoncount :checkbox').on('change', tickAlike);
});

function tickAlike() {
    var classes = $(this).parent().data('classes');
    $('.tick_' + classes).not(this).prop('checked', this.checked);
}

答案 2 :(得分:0)

使用&#34;(&#39;:已检查&#39;)&#34;对于条件和使用&#34; .prop(&#39;已检查&#39;,false)&#34;和&#34; .prop(&#39;检查&#39;,true)&#34;为了更改支票输入。

以下是链接https://jsfiddle.net/qj7uj3rc/7/

if ($(this).siblings ('.tick_' + classes).is(':checked'))
{
    console.log ('ticking');
    $('.tick_' + classes).prop ('checked', false);
}
else
{
    console.log ('unticking');
    $('.tick_' + classes).prop ('checked', true);
}

答案 3 :(得分:-1)

如果您的表单是动态创建的,那么它的行为可能与静态不同。使用bind或live而不是单击动态创建的元素:

 $(".lessoncount" ).live( "click", function() {
  tickAlike();
});