You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展开发:解决YouTube相关视频栏注入HTML被挤到底部的问题

Fixing Your Chrome Extension's Injected Content on YouTube

Hey there! I totally get why this is frustrating—you inject your header, it shows up for a second, then gets pushed down once YouTube loads those related videos. Let's break down what's happening and how to fix it.

Why This Happens

YouTube uses dynamic content loading (AJAX) for almost everything on the watch page, including the related videos section. Your current code runs once when document.ready fires, but after that, YouTube's scripts are still updating the #related DOM element as it loads video thumbnails and metadata. When those new elements get added, they end up pushing your injected <h1> to the bottom because the dynamic content is being inserted above it (or the section is re-rendered entirely).

The Solution: Use MutationObserver

Instead of injecting your content once, we can use the browser's MutationObserver API to watch for changes to the #related element. This way, whenever YouTube updates that section, we can re-position our injected content to stay at the top.

Here's how to modify your inject.js code:

// Helper function to wait for a specific DOM element to exist
function waitForElement(selector, callback) {
  const element = document.querySelector(selector);
  if (element) {
    callback(element);
  } else {
    // Check again in 100ms if the element isn't there yet
    setTimeout(() => waitForElement(selector, callback), 100);
  }
}

// Wait for the #related section to load first
waitForElement('#related', function(relatedSection) {
  // Create our injected header element (reuse this so we don't make duplicates)
  const injectedHeader = $('<h1>This was injected through jQuery.</h1>');
  
  // Insert it initially
  $(relatedSection).prepend(injectedHeader);
  
  // Set up an observer to watch for changes to the #related section's children
  const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function() {
      // Check if our header is still the first child of #related
      if (relatedSection.firstChild !== injectedHeader[0]) {
        // If not, move it back to the top
        $(relatedSection).prepend(injectedHeader);
      }
    });
  });
  
  // Configure the observer to watch for added/removed child elements
  const observerConfig = { childList: true };
  
  // Start watching the #related section
  observer.observe(relatedSection, observerConfig);
});

How This Works

  1. waitForElement: Ensures we don't try to inject content until the #related element actually exists on the page (since YouTube might load it after document.ready).
  2. Reusable Element: We create our <h1> once and reuse it, so we don't end up with duplicate headers every time the DOM updates.
  3. MutationObserver: This listens for any changes to the child elements of #related. Whenever YouTube adds new related videos, the observer triggers, and we check if our header is still at the top. If it's not, we move it back to the first position with prepend().

Bonus Tips

  • Stable Selectors: YouTube changes its DOM structure occasionally, so keep an eye on #related—if it stops working, you might need to update the selector to something more reliable (like a data attribute or a parent element that's less likely to change).
  • Handle Page Navigation: If you want your extension to work when users navigate between videos without reloading the page, you'll also need to listen for URL changes in the SPA. You can do this with window.addEventListener('popstate', ...) or by watching the history object.

内容的提问来源于stack exchange,提问作者jack novotny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:32:10