【问题标题】:Mootools event causes infinite loop in IE7/IE8Mootools 事件导致 IE7/IE8 中的无限循环
【发布时间】:2012-04-28 06:29:11
【问题描述】:

我很难让它在 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>

【问题讨论】:

    标签: javascript internet-explorer mootools mootools-events


    【解决方案1】:

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

    跟踪初始提交和修复。

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

    1. new Event(e).stop(); 必须改写为:e.stop();
    2. implements 方法现在是一个修改键:Implements

    整个事情可以简化很多。这是一个示例重构,在某种程度上针对性能进行了优化,并且逻辑更清晰。

    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,它将尝试使事件冒泡。

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

    希望这足以让您走上正确的道路,如果您要在 jsfiddle 中构建一个具有最小 DOM 的示例,我将很乐意再次查看它。

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

    我建议改为点击事件,尽管这会使标签无效: http://jsfiddle.net/M2dFy/4/

    【讨论】:

    • 感谢您的回答!我稍后会开始研究它。使用 set 和 get 访问器不会触发事件气泡?
    • 我稍后会检查,谢谢。整个代码也使用了输入框和选择框。所以我不得不使用这两个事件(点击和更改)来让它工作。
    • hrm 更改会很烦人。您可以在函数中检查 event.type 并解决它也可能是属性更改的事实。在普通浏览器与 ie7/8 中检查此内容 - jsfiddle.net/8VMQs/1 - 我即将将此发布到 mootools 问题中,但由于 ibolmo 不在,不确定何时会被查看。
    • 在跟踪器上添加了一个错误 - github.com/mootools/mootools-core/issues/2352 - 虽然我想不出区分真实事件和伪冒泡事件的方法,但事件对象在 ie 和 ff 中是相同的变化:(
    • 谢谢。我现在用文本字段和观察者扩展了这个例子。您还可以看到这两个事件以及我为使其正常工作所做的工作。不是在 jsfiddle 工作,所以你去:pastebin.com/NKSdVEF6。不确定这是否是正确的方法......
    猜你喜欢
    • 2017-12-24
    • 1970-01-01
    • 2017-06-10
    • 2015-01-16
    • 1970-01-01
    • 2020-08-27
    • 2021-05-07
    • 2012-08-24
    相关资源
    最近更新 更多