admin管理员组

文章数量:1336415

I am trying to allow clicking on a div that contains a checkbox to cause that checkbox to be selected. Whenever the checkbox is selected, its parent div changes color. When unselected, the parent div's background color goes back to the original one.

Problem: The behavior when clicking on the checkbox's div is correct. However, when clicking on the checkbox directly, the behavior is opposite of what is desired. I suspect this is due to double clicking: The checkbox's own click handler fires, as well as the click handler for its parent div. I may be wrong here. How can I fix it?

JS

// Click checkbox when its container is clicked
$("anizer_listing_checkbox_container_container").click(function(event) {
    if (event.target.type !== 'checkbox') {
      $(':checkbox', this).trigger('click');
    }
});

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function() {
    if($(this).attr('checked')) {
        $(this).parent().parent().parent().css('background-color', "#FAFAFA");
    } else {
        $(this).parent().parent().parent().css('background-color', "#FFF");
    }
});

HTML

<div class="organizer_listing">

    <div class="organizer_listing_checkbox_container_container">
        <div class="organizer_listing_checkbox_container" data-listing_id=1234>
            <input type="checkbox" class="organizer_listing_checkbox" />
        </div>
    </div>

</div>

EDIT: Swapped the background colors + e.stopPropagation()

// Click checkbox when its container is clicked
$("anizer_listing_checkbox_container_container").click(function(event) {
    $(':checkbox', this).trigger('click');
});

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function(e) {
    e.stopPropagation();
    if($(this).attr('checked')) {
        $(this).parent().parent().parent().css('background-color', "#FAFAFA");
    } else {
        $(this).parent().parent().parent().css('background-color', "#FFF");
    }
});

I am trying to allow clicking on a div that contains a checkbox to cause that checkbox to be selected. Whenever the checkbox is selected, its parent div changes color. When unselected, the parent div's background color goes back to the original one.

Problem: The behavior when clicking on the checkbox's div is correct. However, when clicking on the checkbox directly, the behavior is opposite of what is desired. I suspect this is due to double clicking: The checkbox's own click handler fires, as well as the click handler for its parent div. I may be wrong here. How can I fix it?

JS

// Click checkbox when its container is clicked
$("anizer_listing_checkbox_container_container").click(function(event) {
    if (event.target.type !== 'checkbox') {
      $(':checkbox', this).trigger('click');
    }
});

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function() {
    if($(this).attr('checked')) {
        $(this).parent().parent().parent().css('background-color', "#FAFAFA");
    } else {
        $(this).parent().parent().parent().css('background-color', "#FFF");
    }
});

HTML

<div class="organizer_listing">

    <div class="organizer_listing_checkbox_container_container">
        <div class="organizer_listing_checkbox_container" data-listing_id=1234>
            <input type="checkbox" class="organizer_listing_checkbox" />
        </div>
    </div>

</div>

EDIT: Swapped the background colors + e.stopPropagation()

// Click checkbox when its container is clicked
$("anizer_listing_checkbox_container_container").click(function(event) {
    $(':checkbox', this).trigger('click');
});

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function(e) {
    e.stopPropagation();
    if($(this).attr('checked')) {
        $(this).parent().parent().parent().css('background-color', "#FAFAFA");
    } else {
        $(this).parent().parent().parent().css('background-color', "#FFF");
    }
});
Share Improve this question edited Jan 14, 2012 at 22:59 Nyxynyx asked Jan 14, 2012 at 22:48 NyxynyxNyxynyx 63.7k163 gold badges507 silver badges856 bronze badges 2
  • Take a look at this question that was asked about ten minutes before yours, as well as its answers. Seems like it's the same issue. – Anthony Grist Commented Jan 14, 2012 at 22:53
  • Use this.checked instead of $(this).attr('checked'). For readability, you should use $(this).closest('anizer_listing') instead of 3x parent(). Finally, you should replace click with change, because it's also possible to change the state via the keyboard. – Rob W Commented Jan 14, 2012 at 23:12
Add a ment  | 

4 Answers 4

Reset to default 2

You might want to try using a label and then use a change handler on the check box. Clicking on a label associated with a checkbox is functionally the same as clicking on the checkbox. By using a change handler, you process all the events where the value of the checkbox changes.

<style>
   anizer_listing_checkbox_container {
       display: block;
   }
</style>

<script type="text/javascript">
   $(function() {
       $("anizer_listing_checkbox").on('change',function() {
           if ($(this).attr('checked')) {
               $(this).parent().parent().parent().css('background-color', "#FAFAFA");
           } else {
               $(this).parent().parent().parent().css('background-color', "#FFF");
           }
       });
    });
</style>

<div class="organizer_listing">

    <div class="organizer_listing_checkbox_container_container">
        <label class="organizer_listing_checkbox_container" for="listing_checkbox_0" data-listing_id=1234>
            <input id="listing_checkbox_0" type="checkbox" class="organizer_listing_checkbox" />
        </label>
    </div>

</div>

I kind of went crazy and rewrote most of the code (demo):

var update = function($el){
    // cycle through all elements
    $el.each(function(){
        var bkgd = $(this).prop('checked') ? "#FAFAFA" : "#FFF";
        $(this).closest('anizer_listing_checkbox_container_container')
            .css('background-color', bkgd);
    });
};

// Click checkbox when its container is clicked
$("anizer_listing_checkbox_container_container").click(function(event) {
    var check = $(':checkbox', this);
    check.prop('checked', !check.prop('checked') );
    update( check );
});

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function(e) {
    e.stopPropagation();
    update( $(this) );
});

// update on initialization
update( $("anizer_listing_checkbox") );

Use the on() to bind events (jQuery 1.7+). The following method will:

  • Toggle colours on change of the checkbox (Use change instead of click to allow keyboard-initiated state changes).
  • Toggle the check state on clicking the <div>

Demo: http://jsfiddle/sPb9f/1/

// Click checkbox when its container is clicked
$('anizer_listing').on('click', 'anizer_listing_checkbox_container_container', function(event) {
    if ($(event.target).hasClass('organizer_listing_checkbox')) {
        return; // Do nothing (checkbox)
    }
    $(':checkbox', this).each(function(){
        this.checked = !this.checked; // Swap check state
    }).trigger('change');
}).on('change', 'anizer_listing_checkbox', function(event) {
    // Highlight row on selecting Checkbox
    var $this = $(this),
        $main_listing = $this.closest('anizer_listing');
    if (this.checked) {
        $main_listing.css('background-color', "red");
    } else {
        $main_listing.css('background-color', "yellow");
    }
});

You have just to stop propagation:

// Highlight row on selecting Checkbox
$("anizer_listing_checkbox").click(function(e) {
    e.stopPropagation();//so the click will not propagate to the div parent

    if($(this).attr('checked')) {
        $(this).parent().parent().parent().css('background-color', "#FFF");
    } else {
        $(this).parent().parent().parent().css('background-color', "#FAFAFA");
    }
});

本文标签: javascriptAvoid double clicking when using jQuery to mark checkboxStack Overflow