javascript - 在 chrome 扩展中使用内容脚本插入 DOM 元素
问题描述
我正在尝试为 twitter 做一个扩展,我被困在本节中插入 div 块(有点像 btn)
清单.json
{
"manifest_version": 3,
"name": "Twitter Saver",
"version": "0.0.1",
"description": "Twitter Saver| Save tweets.",
"permissions": ["tabs", "https://*.twitter.com/*"],
"icons": {
"128": "img/icon-app-128.png",
"256": "img/icon-app-128@2x.png"
},
"content_scripts": [
{
"html": ["save-dropdown.html"],
"js": ["js/jquery-3.6.0.min.js", "js/content.js"],
"matches": ["https://*.twitter.com/*"]
}
]
}
内容.js
$(
"<div>",{
class: "css-1dbjc4n r-18u37iz r-1h0z5md",
text: "HELLO WORLD"
}
).appendTo(".css-1dbjc4n.r-1ta3fxp.r-18u37iz.r-1wtj0ep.r-1s2bzr4.r-1mdbhws");
我研究了一些像MutationObserver这样的东西, 但在这里我得到了错误,因为参数不是节点
let react_root = $("#react-root");
let callback = function(changeList, observer) => {
console.log(changeList);
}
const observer = new MutationObserver();
observer.observe(callback, {childList: true});
Twitter在向下滚动时删除以前的帖子添加新帖子,并在滚动回顶部时添加以前的帖子删除新帖子
解决方案
对于 Twitter,MutationObserver 是必经之路,关于如何使用它,我更喜欢这个 Mozilla 指南。
要让 get 正常工作,请注意语法:这里在注册 MutationObserver 时,它说监视整个主体和后代,并appendCustomNode
在发生更改时调用函数。
// Step 1. Create an observer instance linked to the callback function
// const observer = new MutationObserver(callback);
// Step 2. Start observing the target node for configured mutations
// observer.observe(targetNode, config);
const observer = new MutationObserver(appendCustomNode);
observer.observe(document.body, {subtree: true, childList: true});
下一步是定义这个函数appendCustomNode
。
在计划如何将节点附加到卡片时,有必要考虑到您可能会多次看到同一个节点,这需要一个策略来仅附加一次自定义元素。选择一些足够随机的值,然后用该值标记所有以前看到的节点,将有助于实现这一点。这是一个例子:
const customTag = `tag-${Date.now()}` // your choice of a valid & unique value
function appendCustomNode(){
// find all timeline cards, their tag name is article
const cards = document.getElementsByTagName('article');
// check each card
for (let n = 0; n < cards.length; n++) {
const card = cards[n];
// check that cards is new / has not been seen before
if (!card.hasAttribute(customTag)) {
addButton(card);
// mark the card as "processed" by adding the custom tag
card.setAttribute(customTag, true);
}
}
}
最后实现将要添加到卡片的按钮附加到卡片的逻辑。这里的 card 属性表示一个时间轴项的 DOM 节点。
function addButton(card){
const myButton = document.createElement('div');
myButton.innerText = 'hello world';
// select the div of action buttons
// or wherever you want to insert your custom node
// SEE NOTE BELOW
const target = card.querySelector('....?....')
// append/prepend/insertAdjacentHTML the button here
target.append(myButton);
}
出于几个原因,我将保留最后一部分:当决定如何在卡片中找到按钮行时,如果使用类作为选择器,如果类发生更改,则实现会中断,这是您无法控制的。在扩展 3rd 方 Web 应用程序时,这始终是一个挑战。我建议尝试找到一个更可靠的选择器(这就是我之前使用标签名称文章来选择卡片的原因)。其次,按钮/卡片结构会定期更改,因此要考虑的另一点是:您要在哪里插入此自定义节点。最后,这种方法不需要 jQuery。
推荐阅读
- powershell - 运行脚本后保持电源外壳控制台打开
- javascript - 反应本机文本颜色不起作用
- javascript - 数组是否有 javascript 方法来知道最短元素?
- java - java中接受两种类型而不重复代码的单一方法
- excel - Outlook 共享帐户不会为所有用户同步
- plsql - PLSQL:CASE 结果中的多个值
- javascript - 我无法在 React 上实现 Lightbox Gallery
- azure-ad-b2c - Azure 广告 b2c 帐户锁定
- scala - Scala 隐式扩展接口
- reactjs - 无法在网站上显示图像 Webpack React-dom 意外语法