Javascript Chrome扩展在YouTube中意外隐藏按钮
我已经构建了一个Chrome扩展,在初始页面加载时故意隐藏缩略图,效果很好。但它也会在单击一次后隐藏“加载更多”按钮,并阻止加载更多缩略图,即使需要加载更多视频/缩略图 以下是单击“加载更多”后执行的扩展代码部分,它隐藏了“加载更多”按钮: 当我在Chrome的调试器中逐步查看代码时,我发现每个新加载的缩略图周围的整个div都被隐藏了,而不仅仅是图像。因此,实际上,附加的拇指正在加载,但是整个div被隐藏,不仅仅是img元素,所有后续div都会一个接一个地向左滑动,直到看起来没有新的加载。最后的div隐藏实际上也隐藏了按钮,即使该按钮中没有图像。为什么要这样做Javascript Chrome扩展在YouTube中意外隐藏按钮,javascript,google-chrome-extension,youtube,Javascript,Google Chrome Extension,Youtube,我已经构建了一个Chrome扩展,在初始页面加载时故意隐藏缩略图,效果很好。但它也会在单击一次后隐藏“加载更多”按钮,并阻止加载更多缩略图,即使需要加载更多视频/缩略图 以下是单击“加载更多”后执行的扩展代码部分,它隐藏了“加载更多”按钮: 当我在Chrome的调试器中逐步查看代码时,我发现每个新加载的缩略图周围的整个div都被隐藏了,而不仅仅是图像。因此,实际上,附加的拇指正在加载,但是整个div被隐藏,不仅仅是img元素,所有后续div都会一个接一个地向左滑动,直到看起来没有新的加载。最后的
我如何改变这一点,使1额外的视频缩略图按预期加载和显示,并且仅隐藏其中的img元素;2“加载更多”按钮保持可见,直到确实没有更多的拇指可加载为止?MutationObserver回调最可能的问题是jQuery.htmlDOMnode方法将提供的DOMnode从页面文档移动到分离的非呈现节点qHTML 另外,为了不降低页面加载速度,MutationObserver回调必须非常快, 看见 也就是说,只在您想要的元素上使用jQuery,而不是在每个添加的节点上
onElementAdded('div[data-context-item-id]', document, function(elements) {
elements.forEach(function(element) {
var vID = element.dataset.contextItemId;
if (vID) {
console.log("dynamic vID: " + vID);
$(element).find('img').hide();
}
});
});
FWIW,如果目标只是使用数据上下文项id属性将图像隐藏在div元素中,那么您可以通过简单的一次性CSS样式注入来实现,或者通过手动添加元素:div[data context item id]img{display:none;}我用下面的方法解决了这个问题,我从wOxxOm的评论中得到了很多帮助,但不是发布的答案。它现在工作得很好,至少效率有所提高。wOxxOm,我对你的答案投了赞成票,我仍然欢迎你的任何评论。我试过你的。观察变化,它似乎不起作用,但我可能做错了
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;
if(newHTMLChunk.getElementsByTagName('div').length > 0){
if(newHTMLChunk.getElementsByTagName('div')[0]){
var vID = newHTMLChunk.getElementsByTagName('div')[0].getAttribute('data-context-item-id');
if(vID){
$("div[data-context-item-id='" + vID + "'] img").hide();
}
}
}
}
})
});
observer.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree:true
});
设置断点并正确调试代码。顺便说一句,你的MutationObserver回调非常低效。你如何使它更高效?只观察你需要的东西,不要在内部使用jQuery,不要重新创建html块。无论如何,这是一个单独的问题,一旦你修复了主节点,你就可以继续解决。注意,一些添加的节点是文本节点而不是html元素,所以首先检查类型:if!newHTMLChunk.tagName继续;您可能需要额外检查DocumentFragment。谢谢wOxxOm,我已经删除了一行有问题的代码,正在调试。请参阅上面的编辑。不,我需要一次只做一个,因为我还需要为ajax调用捕获youtube id。
<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>
onElementAdded('div[data-context-item-id]', document, function(elements) {
elements.forEach(function(element) {
var vID = element.dataset.contextItemId;
if (vID) {
console.log("dynamic vID: " + vID);
$(element).find('img').hide();
}
});
});
function onElementAdded(selector, baseNode, callback) {
new MutationObserver(function(mutations) {
var found = [];
for (var mutation, i = 0; (mutation = mutations[i++]); ) {
var addedNodes = mutation.addedNodes[i];
for (var node, j = 0; (node = addedNodes[j++]); ) {
// skip non-element nodes
if (!node.tagName) {
continue;
}
// does the added node itself match the selector?
if (node.matches(selector)) {
found.push(node);
continue;
}
// does the added node contain child elements matching the selector?
// (since qS is much faster than qSA it makes sense to use it first)
if (node.querySelector(selector)) {
var children = node.querySelectorAll(selector);
// prevent stack overflow
if (children.length < 1000) {
Array.prototype.push.apply(found, children);
} else {
found = found.concat(children);
}
}
}
}
if (found.length) {
callback(found);
}
}).observe(baseNode || document, {
childList: true,
subtree: true,
});
}
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;
if(newHTMLChunk.getElementsByTagName('div').length > 0){
if(newHTMLChunk.getElementsByTagName('div')[0]){
var vID = newHTMLChunk.getElementsByTagName('div')[0].getAttribute('data-context-item-id');
if(vID){
$("div[data-context-item-id='" + vID + "'] img").hide();
}
}
}
}
})
});
observer.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree:true
});