2017-01-22 90 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 
}); 
相關問題