jQuery radio input .on('change') triggered twice

Viewed 2549

I have the following code: http://jsfiddle.net/0Lp4oqn6/

On <input type='radio' name='radio' class='radio' value='on'>
Off <input type='radio' name='radio' class='radio' value='off'>

$('.radio').on('change', function() {
    alert( $(this).val() )
}).trigger('change')

It's a simple set of 2 radio inputs and an event handler for when the radio input value changes. There is also a .trigger('change') in order to trigger the event handler to happen once when the page loads.

When the page loads, the event handler is triggered twice. The first alert will say on and the second alert will say off. But when I manually click the radio buttons, the change handler is not triggered twice.

Why is the event handler being triggered twice when using .trigger('change')? Why is the behavior different when doing it manually? What is the proper way to programmatically trigger the event handler without it happening twice?

5 Answers

The event will be triggered on each element in the collection regardless of their checked state. Two radios means two events triggered

It would probably be best to only trigger it if one of them is actually checked and only trigger on that particular one.

You can use filter(':checked') to target the checked one, if there is one

When you manually change a radio the change event is only triggered on a checked one also

$('.radio').on('change', function() {
  console.log('Checked value =', $(this).val())
}).filter(':checked').trigger('change');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
On <input type='radio' name='radio' class='radio' value='on'> 
Off <input type='radio' name='radio' class='radio' value='off' checked>

use e.stopImmediatePropagation();

Try:

$('.radio').on('change', function(e) {
    e.stopImmediatePropagation();
    alert( $(this).val() )
}).trigger('change')

It's the chained .trigger('change') - just remove it.

since you need to call the change function on load, I would suggest

function onRadioChange() { ... }

$('.radio').on('change', onRadioChange);

onRadioChange();

On document load, the change triggers for .radio class. Since the radio class has 2 radio buttons it will trigger change for both of them as it identifies both with the same class. While doing it manually the event os being triggered on the radio button on which you have made a click and hence the event is triggered only for that button.

This can also work, using the stopImmediatePropagation:

$('.your_class_name').change(function(event) {
    event.stopImmediatePropagation();
    alert($(this).val());
});
Related