在本文中,我们将讨论浏览器扩展——它们是什么、它们如何工作,以及如何构建。

我们将通过实际编写自己的扩展(超级有趣!)来完成,它允许我们通过单击一个按钮将任何代码片段复制到剪贴板。

开始之前:

  • 你需要对 JavaScript 有基本的了解
  • 你需要 Firefox 浏览器(或任何其他浏览器也可以)

什么是浏览器扩展

浏览器扩展是你添加到浏览器中的内容,它通过扩展浏览器的容量来增强你的浏览体验。

例如,考虑一下你可能已在设备上安装的广告拦截器,这可以通过在你上网时屏蔽广告来改善你的浏览体验。

如何编写浏览器扩展

现在让我们从编写一个非常基本的扩展开始。

首先,我们将创建一个文件夹,在其中创建一个名为 manifest.json 的文件。

什么是 manifest 文件?

manifest 文件是任何浏览器扩展中的必备文件。此文件包含有关扩展程序的基本数据,如名称、版本等。

现在在 manifest.json 文件中复制以下代码段:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
}

如何加载扩展文件

对于 Firefox 用户,请按照以下步骤操作。

在地址栏中,搜索:

about:debugging#/runtime/this-firefox

你将看到一个 Load Temporary Add-on(加载临时加载项)的选项。单击该选项并从目录中选择 manifest.json 文件。

对于 Chrome 用户,在地址栏中搜索:

chrome://extensions.
  • 启用开发者模式并切换到它
  • 单击 Load unpacked 按钮并选择扩展目录

太棒了,你已成功安装扩展程序。但该扩展目前没有做任何事情。现在让我们为扩展添加一些功能。为此,我们将像这样编辑 manifest.json 文件:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
    {
     "matches":["<all_urls>"],
     "js":["main.js"]
    }
  ]
}

在上面的代码中,我们向 manifest.json 添加了一个内容脚本。内容脚本可以操作网页的文档对象模型。我们可以使用内容脚本将 JS(和 CSS)注入到网页中。

"matches" 包含应添加内容脚本的域和子域列表,js 是要加载的 JS 文件的数组。

现在在同一目录中创建一个 main.js 文件,并添加以下代码:

alert("The test extension is up and running")

现在重新加载扩展程序,当你访问任何 URL 时,你将看到一条警报消息。

不要忘记在编辑代码时重新加载扩展。

如何自定义你的浏览器扩展

现在让我们为扩展程序添加更多有趣的东西。

我们现在要做的是创建一个网络扩展程序,将我们访问的网页的所有图像更改为我们选择的图像。

为此,只需将任何图像添加到当前目录,并将 main.js 文件更改为:

console.log("The extension is up and running");

var images = document.getElementsByTagName('img')

for (elt of images){
   elt.src = `${browser.runtime.getURL("pp.jpg")}`
   elt.alt = 'an alt text'
}

让我们看看这里发生了什么:

var images = document.getElementsByTagName('img')

这行代码选择了网页中所有带有 img 标签的元素。

然后我们使用 for 循环遍历数组图像,在 runtime.getURL 函数的帮助下将所有 img 元素的 src 属性更改为一个 URL。

这里 pp.jpg 是我的设备当前目录下的图片文件名。

我们通过将 manifest.json 文件编辑为以下内容来通知我们的内容脚本关于 pp.jpg 文件:

{
  "manifest_version":2,
  "version":"1.0",
  "name":"Test",
  "content_scripts":[
   {
    "matches":["<all_urls>"],
    "js":["main.js"]
   }
  ],
  "web_accessible_resources": [
        "pp.jpg"
  ]
}

然后只需重新加载扩展程序,并访问你喜欢的任何 URL。现在你应该看到所有图像都被更改为当前工作目录中的图像。

如何将图标添加到你的扩展程序

manifest.json 文件中添加以下代码:

"icons": {
  "48": "icon-48.png",
  "96": "icon-96.png"
}

如何向扩展程序添加工具栏按钮

现在我们将在浏览器的工具栏中添加一个按钮,用户可以使用此按钮与扩展程序交互。

要添加工具栏按钮,请将以下几行添加到 manifest.json 文件中:

"browser_action":{
   "default_icon":{
     "19":"icon-19.png",
     "38":"icon-38.png"
   }
  }

所有图像文件都应该存在于你的当前目录中。

现在,如果我们重新加载扩展程序,应该会在浏览器的工具栏中看到扩展程序的图标。

如何为工具栏按钮添加监听事件

也许我们想在用户点击按钮时做一些事情——假设我们想在每次点击按钮时打开一个新标签。

为此,我们将再次将以下内容添加到 manifest.json 文件中:

"background":{
        "scripts":["background.js"]
  },
  "permissions":[
      "tabs"
  ]

然后我们将在当前工作目录中创建一个名为 background.js 的新文件,并在文件中添加以下几行:

function openTab(){
    
    var newTab = browser.tabs.create({
        url:'https://twitter.com/abhilekh_gautam',
        active:true
    })
}

browser.browserAction.onClicked.addListener(openTab)

现在重新加载扩展!

每当有人单击该按钮时,它都会调用 openTab 函数,打开一个带有链接到我的 Twitter 个人资料的 URL 的新选项卡。此外,当设置为 true 时,活动键使新创建的选项卡成为当前选项卡。

请注意,你可以在后台脚本中使用浏览器提供的 API。有关 API 的更多信息,请参阅文章:JavaScript API

现在我们已经了解了浏览器扩展的一些基础知识,让我们创建一个我们作为开发人员可以在日常生活中使用的扩展。

项目

好的,现在我们要写一些日常生活中用得上的东西。我们将创建一个扩展程序,允许你通过单击从 StackOverflow 复制代码片段。 因此,我们的扩展程序将向网页添加一个 Copy 按钮,该按钮将代码复制到剪贴板。

Demo

demo

首先,我们将创建一个新文件夹/目录,我们将在其中添加一个 manifest.json 文件。

将以下代码添加到文件中:


  "manifest_version":2,
  "version":"1.0",
  "name":"copy code",
  "content_scripts":[
    {
     "matches":["*://*.stackoverflow.com/*"],
     "js":["main.js"]
    }
  ]
}

查看 content script 中的 matches——扩展仅适用于 StackOverflow 的域名和子域名。

现在在同一目录中创建另一个名为 main.js 的 JavaScript 文件,并添加以下代码:

var arr =document.getElementsByClassName("s-code-block")

for(let i = 0 ; i < arr.length ; i++){
 var btn = document.createElement("button")
 btn.classList.add("copy_code_button")
 btn.appendChild(document.createTextNode("Copy"))
 arr[i].appendChild(btn)
 //styling the button
 btn.style.position = "relative"
 
 if(arr[i].scrollWidth === arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetHeight)
  btn.style.left = `${arr[i].offsetWidth - 70}px`

  else if(arr[i].scrollWidth != arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetWidth)
   btn.style.left = `${arr[i].offsetWidth - 200}px`
 else 
   btn.style.left = `${arr[i].offsetWidth - 150}px`
  
 if(arr[i].scrollHeight === arr[i].offsetHeight)
   btn.style.bottom = `${arr[i].offsetHeight - 50}px`
   
 else
   btn.style.bottom = `${arr[i].scrollHeight - 50}px`
 //end of styling the button
   
   console.log("Appended")
}

首先,我选择了所有类名为 s-code-block 的元素——但为什么呢? 这是因为当我检查 StackOverflow 的站点时,发现所有代码片段都保存在一个具有该名称的类中。

然后我们遍历所有这些元素,并在这些元素中添加一个按钮。最后,我们正确定位和设置按钮样式(样式尚不完美——这只是一个开始)。

当我们使用上面的过程加载扩展并访问 StackOverflow 时,应该看到一个 copy 按钮。

如何为按钮添加功能

现在,当单击按钮时,我们希望将整个片段复制到剪贴板。为此,请将以下代码行添加到 main.js 文件中:

var button = document.querySelectorAll(".copy_code_button")
 button.forEach((elm)=>{
  elm.addEventListener('click',(e)=>{
    navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)
    alert("Copied to Clipboard")
  })
 })

首先,我们使用 querySelectorAll 选择添加到站点的所有按钮。然后我们在点击按钮时监听 click 事件。

navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)

上面的代码将代码复制到我们的剪贴板。每当复制片段时,我们都会通过消息 Copied to clipboard 来提醒用户,这样就完成了。

结语

Web 扩展可以通过多种方式发挥作用,我希望在本文的帮助下,你能够编写自己的扩展。

所有代码都可以在这个 GitHub 仓库中找到。如果你想建议一些好的样式或新功能(如剪贴板历史记录等),欢迎创建 pull request。

Happy Coding!

原文:How to Write Your Own Browser Extension [Example Project Included],作者:Abhilekh Gautam