2017-01-22 101 views
0

我已经构建了一个Chrome扩展程序,有意在初始页面加载时隐藏缩略图图像,并且效果很好。但是,在点击一次后,它也隐藏了“加载更多”按钮,并防止加载更多缩略图,即使应该加载更多的视频/缩略图。Chrome扩展程序在YouTube中意外隐藏按钮

这里是一个点击加载更多后执行我的扩展代码的部分,然后将其隐藏加载更多按钮:

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 
}); 

这里是什么样子页面加载完成后,与我的分机运行: enter image description here

点击加载更多的按钮后,请注意按钮消失,没有更多的竖起大拇指负荷: enter image description here

下面是YouTube的加载更多按钮的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&amp;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&amp;w=336&amp;…amp;jpg444=true&amp;jpgq=90&amp;sp=68&amp;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&amp;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隐藏也会隐藏该按钮。它为什么这样做?

我该如何改变它,以便(1)额外的视频缩略图加载并按预期方式显示,并且只隐藏里面的img元素;和(2)Load more按钮保持可见状态,直到确实没有更多的拇指加载?

+0

设置断点并正确调试代码。 BTW你的MutationObserver回调效率非常低。 – wOxxOm

+0

你会如何提高效率? – HerrimanCoder

+0

只观察你需要的东西,不要在里面使用jQuery,不要重新创建html块,[等](http://stackoverflow.com/a/39332340/)。无论如何,这是一个单独的问题,你可以追求一旦你修复主要问题。 – wOxxOm

回答

1

与MutationObserver回调最可能的问题是,jQuery的.html(DOMnode)方法从页的文件移动提供れ成分离(非渲染)节点qHTML

此外,MutationObserver回调必须非常快,以免减慢页面加载速度,
请参阅Performance of MutationObserver to detect nodes in entire DOM
也就是说,只在你想要的元素上使用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(); 
     } 
    }); 
}); 

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, 
    }); 
} 

FWIW,如果目标仅仅是隐藏与数据上下文项-ID的div元素里面的图片属性,那么你可以用一个简单的一次性的CSS样式注入做(在manifest.json或手动添加<style>元素):div[data-context-item-id] img { display: none; }

+0

不,我需要一次一个地做,因为我还需要捕获一个ajax调用的youtube id。 – HerrimanCoder

0

我用下面的方法解决了这个问题,在wOxxOm的评论(但不是发布的答案)的帮助下得到了很多帮助。它现在完美地工作,至少有点更高效。 wOxxOm,我赞成你的回答,并且我仍然欢迎你提出的任何意见。我尝试了你的.observe()更改,但它似乎不起作用,但我可能做错了。

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 
}); 
相关问题