最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is onchange on a checkbox not fired when the checkbox is changed indirectly - Stack Overflow

programmeradmin1浏览0评论

I'm using Prototype to monitor checkboxes, so I can add javascript checks to them. When the tr or td in which the checkbox is located is clicked, the checkbox should be checked.
When you click directly on a checkbox, the onchange event is fired, so you'll get an alert. When the checkbox' value is changed by javascript (when you click on the tr or td), onchange is not fired. Why is onchange not fired when the checkbox is changed indirectly?

This is the javascript I'm using.

Element.observe(window, 'load', function() {
        /* If a tr or td is clicked, change the value of the checkbox. */
        $$('#results tr').each(function(el) { 
            el.observe('click', function(e) {
                if(!e.target) { e.target = e.srcElement; }
                if(e.target.nodeName == 'TD' || e.target.nodeName == 'TR') {
                    $('pare-product'+this.id).checked = ($('pare-product'+this.id).checked === false) ? true : false;
                }
            });
        });
        /* Monitor if the status of a checkbox has changed. */
        $$('#results tr td input').each(function(el) {
                el.observe('change', function(e) {
                        alert('!');
                    }
                );
            }
        );
    }
);

I've tested it in Firefox and IE7, both are not working. I'm not looking for a workaround, I'm just curious to know why this doesn't work.

I'm using Prototype to monitor checkboxes, so I can add javascript checks to them. When the tr or td in which the checkbox is located is clicked, the checkbox should be checked.
When you click directly on a checkbox, the onchange event is fired, so you'll get an alert. When the checkbox' value is changed by javascript (when you click on the tr or td), onchange is not fired. Why is onchange not fired when the checkbox is changed indirectly?

This is the javascript I'm using.

Element.observe(window, 'load', function() {
        /* If a tr or td is clicked, change the value of the checkbox. */
        $$('#results tr').each(function(el) { 
            el.observe('click', function(e) {
                if(!e.target) { e.target = e.srcElement; }
                if(e.target.nodeName == 'TD' || e.target.nodeName == 'TR') {
                    $('pare-product'+this.id).checked = ($('pare-product'+this.id).checked === false) ? true : false;
                }
            });
        });
        /* Monitor if the status of a checkbox has changed. */
        $$('#results tr td input').each(function(el) {
                el.observe('change', function(e) {
                        alert('!');
                    }
                );
            }
        );
    }
);

I've tested it in Firefox and IE7, both are not working. I'm not looking for a workaround, I'm just curious to know why this doesn't work.

Share Improve this question asked Jan 29, 2010 at 10:16 RobinRobin 3136 silver badges17 bronze badges 4
  • If it were, what would happen if in your event handling code you changed the state of the checkbox? – Dominic Rodger Commented Jan 29, 2010 at 10:23
  • I don't understand what you mean. – Robin Commented Jan 29, 2010 at 10:31
  • If you change the state in your even handler then the same event handler will be called again. If so, you might have a infinity loop. – Mattias Jakobsson Commented Jan 29, 2010 at 10:35
  • Mattias: As you can see, I'm changing the state of the checkbox in a onclick handler, which is set on a tr. I don't see how it can be called again by changing the state of a checkbox. – Robin Commented Jan 29, 2010 at 10:54
Add a ment  | 

2 Answers 2

Reset to default 5

This isn't unmon in UI frameworks in general. If you change the state of a control programmatically, it's assumed that you're also capable of programmatically triggering whatever side-effects it's supposed to have. It gives programmers more flexibility, and it avoids bugs where the state is in flux during initialization or teardown. (For example, during initialization, you might set the state of one control before setting the state of several dependent ones. If the change handler for the first control fires immediately, it will execute while the other controls are in an inconsistent state.)

The real reason you can't do this is because it's security issue in the programming model. Events that were not user initiated are usually not chained. So although setting a value is fine, it's not fine to go ahead and fire any events that were set on that control.

What jamesdlin has said makes no sense.

Jamesdlin:

"For example, during initialization, you might set the state of one control before setting the state of several dependent ones. If the change handler for the first control fires immediately, it will execute while the other controls are in an inconsistent state."

This is true no matter if you set it programmatically change a value or whether you click on the control. In either case you may have dependent other controls.

发布评论

评论列表(0)

  1. 暂无评论