Mootools事件在IE7 / IE8中导致无限循环

时间:2012-04-16 22:05:00

标签: javascript javascript-events mootools

我很难在IE7(和IE8)中使用它。 它是一个非常复杂的脚本的一个非常简化的部分。所以请记住,方法和结构不能改变太多。

在IE7中,当选择其中一个类型时,我得到一个无限循环。在FF,Chrome和IE9中它工作正常。它也适用于IE7 / IE8中的mootools 1.1库,但是由于我将它转换为Mootools 1.4,我得到了循环问题。

在框架中可能会发生某种事件委托更改。我真的不知道。 非常感谢任何帮助!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>eventz</title>
    <script src="https://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js" type="text/javascript"></script>  

    <script type="text/javascript">
        var eventz = new Class({
            options: {      

            },  
            initialize: function(options) {
                this.setOptions(options);               
                this.setup();
                this.jx = 0;    

            },
            setup: function() {
                this.makeEvents();
                // ...
            },

            makeEvents : function() {
                alert("init");

                var finputs =   $$('.trig');

                finputs.removeEvents('change');
                finputs.removeEvents('click');

                finputs.each(function(r) {                  

                    $(r).addEvents({
                        'change': function(e) {                 
                            //e.preventDefault();
                            alert(r.name);                                          

                            new Event(e).stop();                                    
                            this.refresh(r);  // this needs to stay as refresh calls some ajax stuff            
                        }.bind(this)
                    });     
                }.bind(this)); 

                // ...
            },

            // refresh is called from various methods
            refresh : function(el) {    

                if(el) {
                    // count types checkboxes
                    var ob_checked = 0;
                    $$('.otypes').each(function(r) {
                        // uncheck all if clicked on "All"
                        if(el.id == 'typ-0') {
                            r.checked = false;
                        }
                        r.checked == true ? ob_checked++ : 0 ;
                    })

                    // check "All" if non selected
                    if(ob_checked == 0) {
                        $('typ-0').checked = true;
                    }
                    // uncheck "All" if some selected
                    if(el.id != 'typ-0' && ob_checked != 0) {
                        $('typ-0').checked = false;
                    }

                    // ajax call ...
                }
            }
        });
        eventz.implement(new Options);  

        window.addEvent('domready', function(){
            c = new eventz();
        });

    </script>

  </head>
  <body>
    <fieldset class="types">        
        <input type="checkbox" class="trig" name="otypes[]" value="0" id="typ-0" checked="checked">All
        <input id="typ-14" value="14" name="otypes[]" type="checkbox" class="otypes trig">Type A
        <input id="typ-17" value="17" name="otypes[]" type="checkbox" class="otypes trig">Type B
    </fieldset> 
  </body>
</html>

1 个答案:

答案 0 :(得分:3)

基本上在MooTools 1.4.4+中,IE中的变更事件已经“标准化”:

跟踪初始提交和修复。

关于您的代码,需要进行一些更改:

  1. new Event(e).stop();必须重写为:e.stop();
  2. implements方法现在是一个mutator键:Implements
  3. 整个事情可以简化很多。这是一个示例重构,在某种程度上针对性能进行了优化,并具有更清晰的逻辑。

    http://jsfiddle.net/M2dFy/5/

    类似的东西:

    var eventz = new Class({
        options: {
    
        },
    
        Implements: [Options],
    
        initialize: function(options) {
            this.setOptions(options);
            this.setup();
            this.jx = 0;
    
        },
        setup: function() {
            this.makeEvents();
            // ...
        },
    
        makeEvents: function() {
            var finputs = $$('.trig');
    
            finputs.removeEvents('change');
            finputs.removeEvents('click');
    
            var self = this;
            this.type0 = $('typ-0');
            this.otypes = $$('.otypes');
            this.pause = false; // stop flag because of IE
    
            finputs.each(function(r) {
    
                r.addEvents({
                    click: function(e) {
                        this.pause || self.refresh(r); // this needs to stay as refresh calls some ajax stuff            
                    }
                });
            });
    
            // ...
        },
    
        // refresh is called from various methods
        refresh: function(el) {
            this.pause = true;
            if (el !== this.type0) {
                // count types checkboxes
                this.type0.set('checked', !this.otypes.some(function(other) {
                    return !!other.get("checked");
                }));
    
    
    
                // ajax call ...
            }
            else {
                this.otypes.set('checked', false);
            }
            this.pause = false;
        }
    });
    

    现在,鉴于您拥有的代码,当您更改.checked时,它会触发propertychange,这会尝试使事件冒泡。

    我建议您通过checked.set方法更改.get的所有访问权限,例如。 el.set('checked', true); / el.get('checked') - 对id或任何其他财产的类似用途。

    希望这足以让你走上正确的道路,如果你要在jsfiddle中用最小的DOM构建一个这样的例子,我将很高兴再看一遍。

    我这里没有IE(mac),但我怀疑点击非全部复选框可能会中断,因为这会触发。

    我建议移动到点击事件,但这会使标签无效:  http://jsfiddle.net/M2dFy/4/

相关问题