我有一个第三方脚本,该脚本将页面上的图片从场外加载到我的页面上。

我的页面开始为空:

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

  </div>


然后,第3方脚本会添加其他内容(例如相册的框架):

      <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')时,表示图像已加载,因此我可以
删除加载动画


码:

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");
  };

});

最佳答案

有一个选项可以让您完全执行所需的操作:观察元素的子树。只需将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)还应仔细检查是否在这种情况下加载了图像。

关于javascript - MutationObserver没有显示所有突变吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36025159/

10-12 13:41