querySelector 在 Chrome 扩展代码中不起作用

问题描述 投票:0回答:2

嗨,这是我第一次使用 JavaScript 和 HTML,所以我可能做错了什么:

我正在尝试使用 Chrome 扩展将新内容插入网页,我的代码有时可以工作,但有时却不能。 例如,当我尝试将文本插入任何 YouTube 页面时,我的代码可以 querySelect id="logo",但不能 querySelect id="secondary"。我对 JavaScript 和 HTML 都没有很好的了解,我完全被困在这里了。

这是我的manifest.json和content.js:

{
    "manifest_version": 3,
    "name": "tutorial",
    "version": "1.0",
    "description": "Add text to YouTube page",
    "content_scripts": [
      {
        "js": ["content.js"],
        "matches": [
          "https://www.youtube.com/*"
        ]
      }
    ]
}
if(document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded',afterDOMLoaded);
} else {
  console.log('DOM fully loaded and parsed');
  
  const object = document.querySelector('#secondary');

  if (object) {
    const newElement = document.createElement('div');
    newElement.innerText = 'Hello from the YouTube Element Injector!';
    object.insertAdjacentElement('afterbegin', newElement);
  } else {
    console.log('object is null');
  }
}

我的结果#logo

我的#secondary结果

我将不胜感激任何建议!谢谢

javascript html google-chrome-extension
2个回答
1
投票

我的代码执行时,YouTube 页面可能没有“#secondary”。如果在代码运行后将元素动态添加到页面,则可能会发生这种情况。

您可以通过使用 MutationObserver 来监视 DOM 的更改来解决这个问题

// Define a function to handle DOM mutations
function handleMutations(mutationsList, observer) {
  for (const mutation of mutationsList) {
    if (mutation.type === 'childList') {
      const obj = document.querySelector('#secondary');

      if (obj) {
        const el = document.createElement('div');
        el.innerText = 'Hello from the YouTube Element Injector!';
        obj.insertAdjacentElement('afterbegin', el);
        // you should disconnect() after insertion for performance
        observer.disconnect();
      }
    }
  }
}

// Create a new observer and start watching for mutations
const observer = new MutationObserver(handleMutations);
observer.observe(document.body, { childList: true });

这将创建一个 MutationObserver 并开始监视 document.body 上的更改。当添加或删除子元素(即“childList”突变)时,将调用

handleMutations
。在该功能中,您可以尝试选择
#secondary
并插入新的 div 元素。

请注意,您应该在插入新元素后调用observer.disconnect(),以阻止观察者监视进一步的突变。这是因为您只需要插入新元素一次,并且您不想在每次 DOM 更改时都不断插入它。

我希望这有帮助!如果您有任何疑问,请告诉我。


0
投票

根据您给出的示例,我假设您正在尝试探索 youtube.com DOM。

#secondary
节点似乎存在,但在第一次渲染期间不存在。

也许你可以尝试等待

readystate
改变

document.addEventListener("readystatechange", (event) => {
  if (document.readyState === "complete") {
    afterDOMLoaded(event);
  }
});

这里是 MDN 文档:https://developer.mozilla.org/en-US/docs/Web/API/Document/readystatechange_event

© www.soinside.com 2019 - 2024. All rights reserved.