如何使MutationObserver更好地工作一次?

时间:2017-10-22 06:45:04

标签: javascript mutation-observers

我使用MutationObserver,所以我可以让div对变化作出反应。当它将更改更改为直接显示在div中时,但它只运行一次。如果我输入内容来分割输入div,则只显示第一个字符。我在MDN上发现了这个

“向元素添加一个观察者就像addEventListener一样,如果你多次观察该元素它没有区别。意思是如果你观察一个元素两次,观察回调不会发射两次,你也不必运行disconnect()两次。换句话说,一旦观察到一个元素,用同一个观察者实例再次观察它就什么也不做。但是如果回调对象不同,它当然会为它添加另一个观察者。“

但是我不知道如何解决这个问题。我尝试在第一个观察者的回调中创建一个新的观察者,希望它能创建一个观察者链,但这不起作用。别人怎么解决这个问题?

    <div contenteditable="true" class="input"></div>
    <div class="display"></div>

    <script>
        let input= document.getElementsByClassName("input")[0];
        let display= document.getElementsByClassName("display")[0];

        let config={attributes:true, childList:true, characterData:true};

        let observer= new MutationObserver(function(mutations){
                mutations.forEach(function(mutation){
                if(mutation.type==="childList"){
                    display.textContent=input.textContent;
                }
                });

        });         

        observer.observe(input,config); 
    </script>

1 个答案:

答案 0 :(得分:0)

您告诉观察者在输入上观察childList和characterData突变,但输入本身没有characterData。输入中的Text nodes具有characterData突变。

离开childList。有了它,只有在输入中添加或删除节点时才会触发您的观察者(当您键入第一个字符时,请按Enter或删除一行)。

要解决此问题,请通过将config更改为:

告诉观察者查看输入的后代
{attributes:false, childList:false, subtree: true, characterData:true}

并删除观察者回调中的条件,因为所有突变现在都是characterData。实际上你可以这样做:

let observer= new MutationObserver(function(mutations){
    display.textContent=input.textContent;
}); 

因为您不关心自上次以来发生了多少突变,只关注当前值。