构建 chrome 扩展以按 DOM 元素对打开的选项卡进行排序

Posted

技术标签:

【中文标题】构建 chrome 扩展以按 DOM 元素对打开的选项卡进行排序【英文标题】:Building chrome extension to sort open tabs by DOM element 【发布时间】:2021-12-31 03:31:29 【问题描述】:

我正在构建一个 chrome 扩展。目标是按视频时长(从低到高)对 youtube 中所有打开的标签进行排序。

我从这个GitHub project 中找到了这段代码,在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

【问题讨论】:

【参考方案1】:

不清楚您尝试了什么,但您可以将这些值添加到现有循环中数组中的对象,然后在第二个循环中对该数组进行排序。因为 executeScript 是异步的,所以您需要等待第一个循环完成,这意味着解析一个 Promise 列表,然后根据 videolength 对列表进行排序,然后移动选项卡。

这是我为 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 );
  

ma​​nifest.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 扩展以按 DOM 元素对打开的选项卡进行排序的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 扩展:在加载的 Dom 上注入脚本

在 chrome 扩展中使用页面的 Angular JS

使用 Chrome 扩展操作 DOM

chrome扩展跟踪前端JavaScript,该JavaScript使用DOM/jQueryAPI在运行时操作html-DOM元素(例如,更改样式、附加事件侦听器)。

来自 Chrome 扩展的 Outlook 日历输入字段 DOM 操作

如何触发对 chrome 扩展按钮的点击?