2012-04-16 26 views
2

我在使用IE7(和IE8)時遇到困難。 它是一個非常複雜的腳本非常簡化的一部分。所以請記住,方法和結構不能改變太多。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> 

回答

3
在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/

+0

謝謝您的回答!我會在稍後開始處理它。使用set並獲取訪問器不會觸發事件泡泡? – Mike 2012-04-17 09:12:03

+0

刷新一下,看看http://jsfiddle.net/M2dFy/2/ – 2012-04-17 09:18:08

+0

不工作在IE8? – Mike 2012-04-17 09:23:02