为什么当复选框间接改变时,onchange事件不会被触发?

5

我正在使用Prototype来监控复选框,以便我可以添加javascript检查。当单击包含复选框的tr或td时,应该选中复选框。
当您直接单击复选框时,将触发onchange事件,因此您会收到警报。当通过javascript更改复选框的值(当您单击tr或td时)时,不会触发onchange。为什么间接更改复选框时不触发onchange?

这是我使用的javascript代码。

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') {
                    $('compare-product'+this.id).checked = ($('compare-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('!');
                    }
                );
            }
        );
    }
);

我已经在Firefox和IE7中测试过,两者都不起作用。我不是在寻找解决方法,只是好奇为什么它不起作用。


如果是这样的话,如果在您的事件处理代码中更改了复选框的状态,会发生什么? - Dominic Rodger
我不明白你的意思。 - Robin
如果您在事件处理程序中更改状态,则将再次调用相同的事件处理程序。如果是这样,您可能会出现无限循环。 - Mattias Jakobsson
Mattias:正如你所看到的,我正在一个 onclick 处理程序中更改复选框的状态,该处理程序设置在 tr 上。我不明白它如何能够通过更改复选框的状态再次调用。 - Robin
2个回答

5

在UI框架中,这并不罕见。如果您以编程方式更改控件的状态,则假定您还能以编程方式触发它应该具有的任何副作用。这为程序员提供了更大的灵活性,并避免了在初始化或拆除过程中状态处于流动状态的错误。(例如,在初始化期间,您可能会在设置几个相关控件的状态之前设置一个控件的状态。如果第一个控件的更改处理程序立即触发,则它将在其他控件处于不一致状态时执行。)


0

你不能这样做的真正原因是因为它涉及到编程模型中的安全问题。通常情况下,未经用户启动的事件不会被链接。因此,虽然设置一个值是可以的,但是在该控件上设置任何事件并触发它们是不好的。

jamesdlin所说的毫无意义。

jamesdlin:

"例如,在初始化期间,您可能会先设置一个控件的状态,然后再设置几个依赖于它的控件的状态。如果第一个控件的更改处理程序立即触发,那么当其他控件处于不一致状态时,它将执行。"

无论是通过编程方式更改值还是单击控件,这都是正确的。在任何情况下,您都可能有其他依赖控件。


我的意思是,在初始化期间,某些控件可能尚未完全初始化(因此可能具有意外的值)。 - jamesdlin

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