checkbox checked with prop() does not fire events

2020-02-05 11:46发布

boxes checked using jQuery prop() do not affect listeners attached to change handler.

My code is something like

HTML

<div>
    <label>
        <input type="checkbox" class="ch" />test</label>
    <label>
        <input type="checkbox" class="ch" />test</label>
    <label>
        <input type="checkbox" class="ch" />test</label>
    <input type="button" value="check the box" id="select" />
</div>

JS

 $("body").on("change", ".ch", function(){

  alert("checked");

});


$("body").on("click", "#select", function(){

  $(this).parent("div").find("input[type=checkbox]").prop("checked", true);

});

the alert fires when I click on the checkbox. How can I make it fire when the property of the checkbox changes? JSBIN

3条回答
乱世女痞
2楼-- · 2020-02-05 12:14

Trigger the event from inside your function:

$("body").on("click", "#select", function(){
  $(this).parent("div").find("input[type=checkbox]").prop("checked", true).trigger("change");
});
查看更多
3楼-- · 2020-02-05 12:24

You have to use .change() to trigger the change event listener:

$("body").on("change", ".ch", function () {
    alert("checked");
});


$("body").on("click", "#select", function () {
    $(this).parent("div").find("input[type=checkbox]").prop("checked", true).change();
});

JSBbin or Fiddle

Please note that this will fire many events. Three in the html example you have in jsBin.

查看更多
冷血范
4楼-- · 2020-02-05 12:32

In most cases, triggering the change event when you update a property should be the accepted answer, however, there are some instances where properties are adjusted, and you do not have the luxury to add a trigger function call. A common example is when a script is hosted externally.

The below snippet will use the current jQuery prop function to get and/or change the property value, but will also trigger two events, one before property is changed, and another for after the property has been changed. Both the property name and alternating value will also be passed.

jQuery(function(){
    var _oldProp = jQuery.fn.prop;
    jQuery.fn.extend({prop: function( prop, val ) {
        // Only trigger events when property is being changed
        if ( val !== undefined ) {
            this.trigger( 'propChange', [prop, val] );     // before change listener
            var oldVal = this.prop( prop );                // Get old Value
            var ret = _oldProp.call( this, prop, val );    // Update Property
            this.trigger( 'propChanged', [prop, oldVal] ); // after change listener
            return ret;
        }
        return _oldProp.call( this, prop );
    }});
});

Then in order to capture the change event, you can bind into either listener, and even compare the property name and old value (or new value if you hook into the before event) as required.

jQuery('input[type="checkbox"]').on('propChanged', function( event, prop, oldVal ) {
    if ( prop === 'checked' && oldVal !== jQuery(this).prop( prop ) ) {
        jQuery(this).trigger('change');
    }
});

This can be used for any property, and is also not just limited to checkboxes and change events. The same snippet above can also be copied to work with the jQuery(el).attr(attr,val) function.

查看更多
登录 后发表回答