【问题标题】:Tracking changes in DOM is slow to get triggered跟踪 DOM 中的更改触发缓慢
【发布时间】:2018-12-12 19:37:14
【问题描述】:

我有一段非常简单的代码,用于 twitch 聊天,它允许我直接在聊天中看到某人发布的图像。我没有进行极端验证,我只是想将任何图像链接转换为<img> 标签。

(function() {
'use strict';
$('.tw-flex-grow-1').on("DOMSubtreeModified",function(){
    $(".link-fragment").each(function(){
        if (($(this).text().indexOf(".jpg") > 0 ) || (($(this).text().indexOf(".png") > 0 )) || (($(this).text().indexOf(".gif") > 0 ))|| (($(this).text().indexOf(".jpeg") > 0 ))){
            $(this).html("<img src='" + $(this).text() + "' width='200px'/>");
        }
    });
});

})();

我发现 DomSubTreemodified 可以跟踪 div 中的更改。但我的问题是这件事很慢。它会完成它的工作,但它真的很慢,我不知道为什么。而且我知道,由于“.Each”,有很多消息它可能会很慢,但我稍后会解决这个问题,只有一条消息很慢。

这是错误的方法吗?如何更快地获得 domsubtreemodified 触发器?

编辑

遵循 cmets 中的建议:

(function() {
'use strict';
var targetNode = document.getElementsByClassName('tw-flex-grow-1')[0];

// Options for the observer (which mutations to observe)
var config = { attributes: true, childList: true, subtree: true };

// Callback function to execute when mutations are observed
var callback = function(mutationsList, observer) {
    for(var mutation of mutationsList) {
        alert("test");
        if (mutation.type == 'childList') {
            $(".link-fragment").each(function(){
                if (($(this).text().indexOf(".jpg") > 0 ) || (($(this).text().indexOf(".png") > 0 )) || (($(this).text().indexOf(".gif") > 0 ))|| (($(this).text().indexOf(".jpeg") > 0 ))){
                    $(this).html("<img src='" + $(this).text() + "' width='200px'/>");
                }
            });
        }
        else if (mutation.type == 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

})();

【问题讨论】:

标签: javascript jquery html google-chrome userscripts


【解决方案1】:

最大的问题可能是对于每个突变,您都在经历每个.link-fragment,即使您已经处理过它。您要做的只是查看新添加的节点(及其子节点)的内容并在其上运行您的代码。试试这个:

// Select the node that will be observed for mutations
var targetNode = document.getElementById('target');

// Options for the observer (which mutations to observe)
var config = { attributes: false, childList: true, subtree: true };

function alterNode(node) {
    if (node.textContent.indexOf('gif') !== -1) {
        const image = document.createElement('img');
        image.setAttribute('src', node.textContent);
        image.setAttribute('width', 200);
        image.setAttribute('height', 200);
        node.appendChild(image);
    }
}
// Callback function to execute when mutations are observed
var callback = function(mutationsList, observer) {
    for(var mutation of mutationsList) {
        mutation.addedNodes.forEach(function(node) {
            if (node.classList.contains('link-fragment')) {
                alterNode(node);               
            }
            node.querySelectorAll('.link-fragment').forEach(function(node) {
                alterNode(node);
            })
        });
    }
};

// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

document.getElementById('adder').addEventListener('click', function() {
     let imageLink = document.createElement('div');
     imageLink.classList.add('link-fragment');
     imageLink.textContent = 'https://media.giphy.com/media/l2R0aKwejYr8ycKAg/giphy.gif';
     document.getElementById('target').appendChild(imageLink);
});
<div id="target"></div>

<button id="adder">Add Image Link</button>

【讨论】:

  • 我做这样的事情: var targetNode = document.getElementsByClassName('chat-room')[0];得到我的目标节点。但这总是不返回任何节点。如果我检查 dom,我可以看到它在那里。我的用户脚本正在 dom 上运行准备就绪。知道有什么问题吗?
  • 好吧,我没有打扰,我现在把观察者放得很高,它看到了变化,我不介意表现。谢谢大佬。
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多