需要复选框改变事件来响应通过程序编程实现的选中状态的更改

25
(jQuery 1.4.4)我有一个复选框,它有一个.change()监听器,当用户单击复选框时能正常工作,但现在我也需要在使用jQuery以编程方式更改复选框时触发它,使用.attr('checked','checked')。我很乐意使用其他方法使其工作。谢谢。
$('#foo').attr('checked', 'checked'); // programmatically change the checkbox to checked, this checks the box alright

$('#foo').change( function() {
  // this works when user checks the box but not when the above code runs
}
6个回答

25
如果你正在使用jQuery > 1.6,你可以通过定义一个 attrHook 来实现这一点。
jQuery.attrHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            el.checked = value;
            $(el).trigger('change');
        }
    }
};

正如评论中指出的那样,if 语句可以避免在新值与旧值相同时触发 change 事件。

... 不过实际上你应该使用 prop(),因此代码应该是这样的:

jQuery.propHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            el.checked = value;
            $(el).trigger('change');
        }
    }
};
你可以在这里看到它的运行效果:http://jsfiddle.net/2nKPY/ 对于 jQuery < 1.6(或者你不想添加一个 propHook),最好的方法就是覆盖 attr() 方法(或者升级 :))。
(function () {
    var existingAttr = jQuery.fn.attr;

    jQuery.fn.attr = function (attr) {
        var result = existingAttr.apply(this, arguments);

        if (result instanceof jQuery && attr == "checked") { // If we're dealing with a check-set operation.
            result.trigger('change');
        }

        return this;
    };    

}());

您可以在这里查看实际操作


太好了!可惜它对我的问题不起作用(我正在使用knockout,它不会使用jquery设置属性)。无论如何,将来可能会有用。 - GôTô

16

这样怎么样:

$('some selector').trigger('click');

这是我认为最好的选择。简单、干净、本地化。与 click() 不同,它没有任何奇怪的副作用,比如改变 dom 的状态。 - Jazzepi

9
使用jquery的click()方法来改变复选框的状态,而不是改变它的属性。
没有你所有的标记,我不确定这种方法是否适合,但我最近使用了这种方法并取得了良好的效果。

1
点击()不会切换状态吗?无论当前状态如何,我都需要将复选框设置为已选状态。 - bethesdaboys
是的,正如我所说,它取决于您的确切应用程序是否适合。您可以在运行之前检测其状态,但我不清楚确切的应用程序是什么。 - Jamie Hartnoll

4

只有当checked的值实际发生改变时,这个触发器才会被激活。在Matt的回答中,即使将相同的值分配给复选框,它也会被触发。

$.propHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            trigger = true;
        } else {
            trigger = false;
        }
        el.checked = value;
        if (trigger) {
            $(el).trigger('change');
        }
    }
};

1
我正在开发一个插件,根据复选框的状态交换图像,并且我也遇到了这个问题。
让我的情况更加复杂的是,我正在使用的大量预先存在的代码(工作中绕过?;)期望只有用户交互才会触发更改事件,因此在应该以编程方式检查/取消选中复选框时触发click()会导致其他事件触发,这些其他处理程序只应在用户更改值时运行。
我解决的方法是将我的图像更新处理程序绑定到“change”事件和我称为“updateicon”的自定义事件。然后,在propHooks.checked.set()中,我触发此“updateicon”事件。这会导致图标更新器以与用户单击输入时相同的方式更改图标,但不会导致先前绑定的更改/单击处理程序误发。
事件处理程序绑定:
input.on("change updateicon", toggleIconVisibility);

属性更改钩子:
jQuery.propHooks.checked = {
    set: function (el, value) {
        el.checked = value;
        $(el).trigger('updateicon');
    }
};

注意:在我的最新代码草案中,我运行$(el).filter(".iconified").trigger("updateicon"),以便仅在被我的插件“图标化”的元素上触发“updateicon”。

0
如果您使用的是相对较新版本的JQuery,则可以使用.prop()函数来编程更改复选框:
$(".myCheckbox").prop("checked", true);
$(".myCheckbox").prop("checked", false);

12
仍然不会触发"change"事件 - 您需要使用 $(".myCheckbox").prop("checked", true).trigger("change"); 或者使用Matts的代码和attrhooks。 - RemarkLima

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接