【发布时间】:2017-01-22 14:44:02
【问题描述】:
我已经构建了一个 Chrome 扩展程序,它在初始页面加载时有意隐藏缩略图,效果很好。但它也会在单击一次后隐藏“加载更多”按钮并阻止加载更多缩略图,即使还有更多的视频/缩略图需要加载。
这是我点击Load more后执行的部分扩展代码,然后隐藏了Load more按钮:
var insertedNodes = [];
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
// loop through each chunk of html that changes on the page
for (var i = 0; i < mutation.addedNodes.length; i++){
newHTMLChunk = mutation.addedNodes[i];
if (!newHTMLChunk.tagName)
continue;
qHTML = $('<div/>').html(newHTMLChunk).contents();
var vID = qHTML.find('div').attr("data-context-item-id");
if(vID){
console.log("dynamic vID: " + vID);
qHTML.find('img').hide();
}
}
})
});
observer.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree:true
});
这是 YouTube 的 Load more 按钮的 html,它似乎没有任何可以匹配 img 选择器以隐藏的内容:
<span class="yt-uix-button-content">
<span class="load-more-loading hid">
<span class="yt-spinner">
<span class="yt-spinner-img yt-sprite" title="Loading icon"></span>
Loading...
</span>
</span>
<span class="load-more-text">
Load more
</span>
</span>
这是newHTMLChunk.innerHTML 的内容示例(请注意,只有 1 个 img 元素,这是我想要隐藏的元素,但不隐藏“加载更多”按钮,也不会阻止加载更多拇指):
<div class="yt-lockup clearfix yt-lockup-video yt-lockup-grid vve-check" data-context-item-id="n3Qb30awpLs" data-visibility-tracking="QLvJwrX0-4a6nwE=">
<div class="yt-lockup-dismissable">
<div class="yt-lockup-thumbnail">
<span class=" spf-link ux-thumb-wrap contains-addto">
<a href="/watch?v=n3Qb30awpLs" class="yt-uix-sessionlink" aria-hidden="true" data-sessionlink="ei=PdyEWNiaGozB-AOT64qQCA&feature=c4-videos-u">
<span class="video-thumb yt-thumb yt-thumb-196">
<span class="yt-thumb-default">
<span class="yt-thumb-clip">
<img onload=";__ytRIL(this)" alt="" aria-hidden="true" width="196" src="https://i.ytimg.com/vi/n3Qb30awpLs/hqdefault.jpg?custom=true&w=336&…amp;jpg444=true&jpgq=90&sp=68&sigh=CiLl7jzBOIIFewRt-KAOEs-bKwA" data-ytimg="1">
<span class="vertical-align"></span>
</span>
</span>
</span>
</a>
<span class="video-time" aria-hidden="true">
<span aria-label="103 seconds">1:43</span>
</span>
<span class="thumb-menu dark-overflow-action-menu video-actions">
<button class="yt-uix-button-reverse flip addto-watch-queue-menu spf-nolink hide-until-delayloaded yt-uix-button yt-uix-button-dark-overflow-action-menu yt-uix-button-size-default yt-uix-button-has-icon no-icon-markup yt-uix-button-empty" type="button" aria-haspopup="true" aria-expanded="false" onclick=";return false;">
<span class="yt-uix-button-arrow yt-sprite"></span>
<ul class="watch-queue-thumb-menu yt-uix-button-menu yt-uix-button-menu-dark-overflow-action-menu hid">
<li role="menuitem" class="overflow-menu-choice addto-watch-queue-menu-choice addto-watch-queue-play-next yt-uix-button-menu-item" data-action="play-next" onclick=";return false;" data-video-ids="n3Qb30awpLs">
<span class="addto-watch-queue-menu-text">Play next</span>
</li>
<li role="menuitem" class="overflow-menu-choice addto-watch-queue-menu-choice addto-watch-queue-play-now yt-uix-button-menu-item" data-action="play-now" onclick=";return false;" data-video-ids="n3Qb30awpLs">
<span class="addto-watch-queue-menu-text">Play now</span>
</li>
</ul>
</button>
</span>
<button class="yt-uix-button yt-uix-button-size-small yt-uix-button-default yt-uix-button-empty yt-uix-button-has-icon no-icon-markup addto-button video-actions spf-nolink hide-until-delayloaded addto-watch-later-button yt-uix-tooltip" type="button" onclick=";return false;" role="button" title="Watch Later" data-video-ids="n3Qb30awpLs"></button>
<button class="yt-uix-button yt-uix-button-size-small yt-uix-button-default yt-uix-button-empty yt-uix-button-has-icon no-icon-markup addto-button addto-queue-button video-actions spf-nolink hide-until-delayloaded addto-tv-queue-button yt-uix-tooltip" type="button" onclick=";return false;" title="Queue" data-video-ids="n3Qb30awpLs" data-style="tv-queue"></button>
</span>
</div>
<div class="yt-lockup-content">
<h3 class="yt-lockup-title ">
<a class="yt-uix-sessionlink yt-uix-tile-link spf-link yt-ui-ellipsis yt-ui-ellipsis-2" dir="ltr" title="Josh’s Afterlife Analogy" aria-describedby="description-id-407587" data-sessionlink="ei=PdyEWNiaGozB-AOT64qQCA&feature=c4-videos-u" href="/watch?v=n3Qb30awpLs">Josh’s Afterlife Analogy</a>
<span class="accessible-description" id="description-id-407587"> - Duration: 103 seconds.</span>
</h3>
<div class="yt-lockup-meta">
<ul class="yt-lockup-meta-info">
<li>16,475 views</li>
<li>2 months ago</li>
</ul>
</div>
</div>
</div>
<div class="yt-lockup-notifications-container hid" style="height:110px"></div>
</div>
当我在 Chrome 的调试器中逐步执行代码时,我发现每个新加载的缩略图周围的整个 div 都被隐藏了,而不仅仅是图像。所以,事实上,额外的拇指正在加载,但是整个 div 被隐藏(不仅仅是 img 元素),所有后续 div 一个接一个地向左滑动,直到看起来没有新加载。即使该按钮中没有图像,最终的 div hide 实际上也隐藏了该按钮。为什么要这样做?
如何更改此设置,以便 (1) 附加视频缩略图按预期加载和显示,并且仅隐藏内部的 img 元素; (2) Load more 按钮一直可见,直到真的没有更多的拇指要加载?
【问题讨论】:
-
设置断点并正确调试代码。顺便说一句,您的 MutationObserver 回调效率非常低。
-
如何提高效率?
-
只观察你需要的东西,不要在里面使用 jQuery,不要重新创建 html 块,and so on。无论如何,这是一个单独的问题,一旦您解决了主要问题,您就可以继续解决。
-
注意一些添加的节点是文本节点(不是 html 元素),所以首先检查类型:
if (!newHTMLChunk.tagName) continue;您可能需要额外检查 DocumentFragment。 -
感谢 wOxxOm,我已经删除了一个有问题的行并正在调试。请参阅上面的编辑。
标签: javascript google-chrome-extension youtube