在 chrome 扩展中使用内容脚本插入 DOM 元素
Inserting DOM elements using content script in chrome extension
我正在尝试为 twitter 做一个扩展,但我一直坚持在这个部分插入 div 块(有点像 btn)
Manifest.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/*"]
}
]
}
Content.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是必经之路,至于如何使用,我更喜欢this Mozilla guide。
为了让 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);
}
出于以下几个原因,我将保留最后一部分:在决定如何在卡片中查找按钮行时,如果使用 类 作为 selector,如果类 改变,这是你无法控制的。在扩展 3rd 方网络应用程序时,这始终是一个挑战。我建议尝试找到一个更可靠的 selector(这就是为什么我之前使用标签名称文章来 select 卡片)。其次 buttons/card 结构周期性变化,所以这是另一个需要考虑的问题:你想在哪里插入这个自定义节点。最后,这种方法不需要 jQuery.
我正在尝试为 twitter 做一个扩展,但我一直坚持在这个部分插入 div 块(有点像 btn)
Manifest.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/*"]
}
]
}
Content.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是必经之路,至于如何使用,我更喜欢this Mozilla guide。
为了让 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);
}
出于以下几个原因,我将保留最后一部分:在决定如何在卡片中查找按钮行时,如果使用 类 作为 selector,如果类 改变,这是你无法控制的。在扩展 3rd 方网络应用程序时,这始终是一个挑战。我建议尝试找到一个更可靠的 selector(这就是为什么我之前使用标签名称文章来 select 卡片)。其次 buttons/card 结构周期性变化,所以这是另一个需要考虑的问题:你想在哪里插入这个自定义节点。最后,这种方法不需要 jQuery.