构建 chrome 扩展以按 DOM 元素对打开的选项卡进行排序
Building chrome extension to sort open tabs by DOM element
我正在构建一个 chrome 扩展。目标是按视频时长(从低到高)对 YouTube 中所有打开的标签页进行排序。
我从 GitHub project, explained in this tutorial:
中找到了这段代码
popup.js
function byAlphabeticalURLOrder(tab1, tab2) {
if (tab1.url < tab2.url) {
return -1;
} else if (tab1.url > tab2.url) {
return 1;
}
return 0;
}
chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, (tabs) => {
tabs.sort(byAlphabeticalURLOrder);
for (let i = 0; i < tabs.length; i++) {
chrome.tabs.move(tabs[i].id, {index: i});
}
});
此代码非常适合按字母顺序排序。但是,我想调整它以按视频时长排序。
所以我写了这个文件来从所有打开的标签中获取视频持续时间,但仍然无法绕过“排序或移动标签”部分。
popup.js
chrome.tabs.query({
windowId: chrome.windows.WINDOW_ID_CURRENT
}, (tabs) => {
chrome.tabs.query({}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {
code: '(' + function () {
return {
seconds: document.querySelector("video").duration
};
} + ')()'
}, function (result) {
document.write(result[0].seconds + '<br>');
});
}
});
});
输出(以秒为单位的视频时长)-(出现在popup.html
):
1229.041
187.501
510.581
609.941
1473.821
955.481
5464.281
59.201
1787.701
1523.941
不清楚您尝试了什么,但您可以将这些值添加到现有循环中数组中的对象,然后在第二个循环中对该数组进行排序。因为 executeScript 是异步的,所以您需要等待第一个循环完成,这意味着解析承诺列表,然后根据视频长度对列表进行排序,然后移动选项卡。
这是我为 MV3 想出的。可能有更简洁的方法来做到这一点(我在这方面还很陌生):
*编辑:对代码组织进行了小幅编辑。附加功能到操作(即,在单击 Chrome 扩展图标按钮时运行)。
popup.js
chrome.action.onClicked.addListener(sortTabsbyDuration);
async function sortTabsbyDuration() {
async function createListEntry(tabId, i) {
return new Promise((resolve) => {
if (/\.youtube\.com\/watch\?/.test(tabs[i].url)) {
chrome.scripting.executeScript(
{ target: { tabId: tabId }, func: getYouTubeLength, args: [tabId] },
(returnValue) => {
resolve(returnValue[0].result);
}
);
} else {
resolve({
tabId: tabId,
vidLength: 9999999999,
});
}
});
}
function getYouTubeLength(aTab) {
let vidLength = document.querySelector("video").duration;
if (!vidLength) {
vidLength=1;
}
return {
tabId: aTab,
vidLength: vidLength,
};
}
// MAIN:
const tabs = await chrome.tabs.query({ currentWindow: true });
let promiseList = [];
for (var index = 0; index < tabs.length; index++) {
promiseList.push(createListEntry(tabs[index].id, index));
}
const promisesFinished = Promise.all(promiseList);
const sortedList = (await promisesFinished).sort((a, b) => {
return a.vidLength - b.vidLength;
});
console.log(sortedList);
for (let index = 0; index < sortedList.length; index++) {
await chrome.tabs.move(sortedList[index].tabId, { index: index });
}
}
manifest.json
{
"manifest_version": 3,
"name": "Sort Your Tubes",
"version": "0.0.0.2",
"action": {
"default_title": "Click to sort YouTube videos by video length."
},
"background": {
"service_worker": "popup.js"
},
"permissions": [
"tabs",
"scripting"
],
"host_permissions": [
"*://www.youtube.com/*"
]
}
我正在构建一个 chrome 扩展。目标是按视频时长(从低到高)对 YouTube 中所有打开的标签页进行排序。
我从 GitHub project, explained in this tutorial:
中找到了这段代码popup.js
function byAlphabeticalURLOrder(tab1, tab2) {
if (tab1.url < tab2.url) {
return -1;
} else if (tab1.url > tab2.url) {
return 1;
}
return 0;
}
chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, (tabs) => {
tabs.sort(byAlphabeticalURLOrder);
for (let i = 0; i < tabs.length; i++) {
chrome.tabs.move(tabs[i].id, {index: i});
}
});
此代码非常适合按字母顺序排序。但是,我想调整它以按视频时长排序。
所以我写了这个文件来从所有打开的标签中获取视频持续时间,但仍然无法绕过“排序或移动标签”部分。
popup.js
chrome.tabs.query({
windowId: chrome.windows.WINDOW_ID_CURRENT
}, (tabs) => {
chrome.tabs.query({}, function (tabs) {
for (var i = 0; i < tabs.length; i++) {
chrome.tabs.executeScript(tabs[i].id, {
code: '(' + function () {
return {
seconds: document.querySelector("video").duration
};
} + ')()'
}, function (result) {
document.write(result[0].seconds + '<br>');
});
}
});
});
输出(以秒为单位的视频时长)-(出现在popup.html
):
1229.041
187.501
510.581
609.941
1473.821
955.481
5464.281
59.201
1787.701
1523.941
不清楚您尝试了什么,但您可以将这些值添加到现有循环中数组中的对象,然后在第二个循环中对该数组进行排序。因为 executeScript 是异步的,所以您需要等待第一个循环完成,这意味着解析承诺列表,然后根据视频长度对列表进行排序,然后移动选项卡。
这是我为 MV3 想出的。可能有更简洁的方法来做到这一点(我在这方面还很陌生):
*编辑:对代码组织进行了小幅编辑。附加功能到操作(即,在单击 Chrome 扩展图标按钮时运行)。
popup.js
chrome.action.onClicked.addListener(sortTabsbyDuration);
async function sortTabsbyDuration() {
async function createListEntry(tabId, i) {
return new Promise((resolve) => {
if (/\.youtube\.com\/watch\?/.test(tabs[i].url)) {
chrome.scripting.executeScript(
{ target: { tabId: tabId }, func: getYouTubeLength, args: [tabId] },
(returnValue) => {
resolve(returnValue[0].result);
}
);
} else {
resolve({
tabId: tabId,
vidLength: 9999999999,
});
}
});
}
function getYouTubeLength(aTab) {
let vidLength = document.querySelector("video").duration;
if (!vidLength) {
vidLength=1;
}
return {
tabId: aTab,
vidLength: vidLength,
};
}
// MAIN:
const tabs = await chrome.tabs.query({ currentWindow: true });
let promiseList = [];
for (var index = 0; index < tabs.length; index++) {
promiseList.push(createListEntry(tabs[index].id, index));
}
const promisesFinished = Promise.all(promiseList);
const sortedList = (await promisesFinished).sort((a, b) => {
return a.vidLength - b.vidLength;
});
console.log(sortedList);
for (let index = 0; index < sortedList.length; index++) {
await chrome.tabs.move(sortedList[index].tabId, { index: index });
}
}
manifest.json
{
"manifest_version": 3,
"name": "Sort Your Tubes",
"version": "0.0.0.2",
"action": {
"default_title": "Click to sort YouTube videos by video length."
},
"background": {
"service_worker": "popup.js"
},
"permissions": [
"tabs",
"scripting"
],
"host_permissions": [
"*://www.youtube.com/*"
]
}