我正在制作一個簡單的 Chrome 擴展程式,它可以修改 YouTube 上推薦視頻的縮略圖上顯示的一些資訊。
為簡化起見,假設我想用頻道名稱(例如“PewDiePie”)替換視頻長度(例如“14:32”)。
假設我在任何 YouTube 視頻的頁面中(中間是視頻播放器,右側是縮略圖串列)。我可以進行一次替換:
function processNode(node: HTMLElement) {
const channelName = node
.closest('ytd-thumbnail')
?.parentElement?.querySelector('.ytd-channel-name')
?.querySelector('yt-formatted-string');
if (channelName?.textContent) node.textContent = channelName?.textContent;
}
async function replaceCurrentThumbnailTimes(): Promise<void> {
for (const node of document.querySelectorAll(
'span.ytd-thumbnail-overlay-time-status-renderer',
)) {
processNode(node as HTMLElement);
}
}
void replaceCurrentThumbnailTimes();
這可行,但是如果我導航到新頁面(例如通過單擊推薦串列中的任何視頻),則視頻長度不會更新。盡管更新了縮略圖以參考新視頻,但我更改的值保持不變。
例如,假設我打開一個 YouTube 視頻,旁邊的第一個縮略圖是 Alice 的視頻。Alice如我所愿,縮略圖上的時間被替換為 。接下來,我點擊其他視頻,第一個縮略圖現在是 Bob 的視頻。該縮略圖上的時間仍然是Alice,盡管它已經過時了。
我嘗試使用MutationObserverAPI,當新的縮略圖被添加到 DOM 時(例如,向下滾動頁面時),它可以作業,但是當現有的縮略圖元素被修改時,它也不起作用。這是我嘗試過的:
async function replaceFutureThumbnailTimes(): Promise<void> {
const observer = new MutationObserver((mutations) => {
// For each new node added, check if it's a video thumbnail time
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (
node instanceof HTMLElement &&
node.classList.contains(
'ytd-thumbnail-overlay-time-status-renderer',
) &&
node.getAttribute('id') === 'text'
) {
processNode(node);
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true,
attributes: true,
});
}
void replaceFutureThumbnailTimes();
我認為這可能與陰影/陰影 DOM 有關,但我不知道如何繞過它。
PS:為了讓其他人更容易復現,我把同樣的代碼放在pastebin上的純javascript中,這樣你就可以將它復制到chrome控制臺中:https ://pastebin.com/NWKfzCwQ
uj5u.com熱心網友回復:
正如@RoryMcCrossan 和@wOxxOm 在對問題的評論中所建議的那樣,確實是MutationObserver作品,我只是在濫用它。感謝他們倆!
在這種情況下,我需要監視屬性更改,并檢查 ,aria-label中具有 id 的節點的更改text。
這是實作此目的的javascript代碼:
async function replaceFutureThumbnailTimes() {
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
// If attributes were changed, check if it's the thumbnail time
if (
mutation.type === 'attributes' &&
mutation.attributeName === 'aria-label' &&
mutation.target.getAttribute('id') === 'text') {
processNode(mutation.target);
}
// For each new node added, check if it's a video thumbnail time
for (const node of mutation.addedNodes) {
if (
node instanceof HTMLElement &&
node.classList.contains(
'ytd-thumbnail-overlay-time-status-renderer',
) &&
node.getAttribute('id') === 'text'
) {
processNode(node);
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: false,
attributes: true,
});
}
void replaceFutureThumbnailTimes();
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/528587.html
標籤:javascript打字稿谷歌浏览器谷歌浏览器扩展YouTube
上一篇:Chrome錯誤“無法決議密文物件!”使用node.js的connect-mongo4.6.0來存盤Express會話資料
