2016-03-16 48 views
2

我有一個第三方腳本,在我的頁面上加載了一個圖片庫,圖片來自異地。MutationObserver不顯示所有突變?

我的頁面開始爲空:

<div class="container-fluid" id="cincopa"> 

    </div> 

的第三方腳本然後添加其他的東西(如照片庫的框架):

 <div class="container-fluid" id="cincopa"> 
     <div id="cp_widget_38cc1320-f4a4-407a-a80e-1747bd339b64"> 

     </div> 
     </div> 

於是最後的圖像加載:

 <div class="container-fluid" id="cincopa"> 
     <div id="cp_widget_38cc1320-f4a4-407a-a80e-1747bd339b64"> 
      <div class="galleria_images"> 
      <div class="galleria_image">SomeImage</div> 
      <div class="galleria_image">SomeImage</div> 
      <div class="galleria_image">SomeImage</div> 
      </div> 
     </div> 
     </div> 

我想:

  • 顯示加載動畫

  • 設置MutationObserver$('#cincopa')

  • 當它檢測到$('.galleria_image')已經被創建,則意味着圖像已被加載,所以可

  • 除去loading動畫

代碼:

var target = document.querySelector('#cincopa'); 

// create an observer instance 
var observer = new MutationObserver(function(mutations) { 
    console.log(mutations); 
    mutations.forEach(function(mutation) { 
     console.log(mutation.type); 
    }); 
}); 

// configuration of the observer: 
var config = { attributes: true, childList: true, characterData: true }; 

// start the observer, pass in the target node, as well as the observer options 
observer.observe(target, config); 

的問題是,MutationObserver只有控制檯日誌一個突變和MutationRecord徒有其陣列中的一個突變。當第三方腳本創建DOM元素時,我會期待大量的突變。

我誤解MutationObserver的工作原理嗎?

這裏的解決方案

// This is MeteorJS creating the loading spinning thing 
var loadingView = Blaze.render(Template.loading, $('#cincopa')[0]); 

// select the target node 
var target = document.querySelector('#cincopa'); 

// create an observer instance 
var observer = new MutationObserver(function(mutations) { 

    mutations.forEach(function(mutation) { 
    if(mutation.target.className === "galleria_image"){ 
     // a image has been loaded, so remove the loading spinner and 
     // kill the observer 
     Blaze.remove(loadingView); 
     observer.disconnect(); 
    } 
    }); 

}); 

// configuration of the observer: 
var config = { attributes: true, childList: true, characterData: true, subtree: true }; 

// start the observer, pass in the target node, as well as the observer options 
observer.observe(target, config); 

更新的解決方案

.forEach是愚蠢的,沒有打破循環的一個很好的方式,這意味着我獲得了多個命令到Blaze.remove()observer.disconnect(),即使在找到.galleria_image之後。

所以我用underscore代替:

// create an observer instance 
var observer = new MutationObserver(function(mutations) { 

    var loaded = _.find(mutations, function(mutation){ 
    console.log("observer running"); 
    return mutation.target.className === "galleria-image"; 
    }); 

    if(loaded){ 
    Blaze.remove(loadingView); 
    observer.disconnect(); 
    console.log("observer stopped"); 
    }; 

}); 

回答

2

有一個選項,讓你做你想要什麼:觀察元素的子樹。只需將subtree: true添加到您的config,MutationObserver即可。

// ... 
// In this case case only these two are needed, I believe. 
var config = { 
    childList: true, 
    subtree: true 
}; 
// ...observe 

這應該允許您在.gallaria_images已被插入時計算。作爲一個方面說明,你(OP)也應該仔細檢查圖像是否在加載時加載。

+0

謝謝!所有的好和OP更新與解決方案。我原本以爲只有'childList'是必需的。 – fuzzybabybunny