insertBefore(包含在addEventListener中“单击”并通过MutationObserver调用元素属性值更改)被多次执行

时间:2015-12-03 17:47:47

标签: javascript greasemonkey mutation-observers

这是this question的延续。


我为kat.cr编写了一个Greasemonkey userscript,它在'等待反馈的Torrent'弹出窗口中添加了一些额外的按钮。

程序是这样的:(前提是您已登录并且您已经下载了一些“等待反馈”的种子)
单击FEEDBACK按钮后,会出现“等待反馈的Torrent”弹出窗口,
包含等待反馈的种子,
即例如style.display属性。元素#fancybox-wrapnone变为block (正如我在Firefox Inspector中注意到的那样)

我想改进脚本,所以,我正在尝试使用MutationObserver 为了监视上述元素的属性style.display的变化,并在发生更改后添加我的额外按钮。

我的代码是这样的:

document.querySelector('.showFeedback > a').addEventListener('click', function() {


    var observer = new MutationObserver(function(mutations) {
        if (mutations[0].target.style.display == 'block') {
            var parentElement = document.querySelector('div.buttonsline:nth-child(10)');
            var theFirstChild = parentElement.firstChild;
            var button = document.createElement('BUTTON');
            parentElement.insertBefore(button, theFirstChild);
            button.id = 'mybutton1';
            button.innerHTML = 'APPROVE SELECTED';
            document.querySelector('#mybutton1').className = 'siteButton bigButton';
        }
    }).observe(
        document.querySelector('#fancybox-wrap'), {
            attributes: true,
            attributeFilter: ['style']
        }
    );


});

问题是按钮被多次添加,而不是1.
为什么会这样?我怎样才能解决这个问题?

谢谢

1 个答案:

答案 0 :(得分:1)

显然,元素的样式已针对其他属性进行了更改,而不仅仅是display

检查旧的display值是否不是block(需要attributeOldValue参数):

new MutationObserver(function(mutations) {
    if (mutations[0].target.style.display == 'block' && 
        !mutations[0].oldValue.match(/display:\s*block/)) {
        ...............
    }
}).observe(document.querySelector('#fancybox-wrap'), {
    attributeOldValue: true,
    attributeFilter: ['style']
});

或查看按钮ID:

if (mutations[0].target.style.display == 'block' && 
    !document.querySelector('#mybutton1')) {

或在第一次成功运行后断开观察者:

new MutationObserver(function(mutations, observer) {
    if (mutations[0].target.style.display == 'block') {
        observer.disconnect();
        ...........
    }
})...........

此外,不需要var observer =,因为它作为参数传递给回调。