谷歌插件Image downloader开发之 content script

自己运营了一个公众号,在发文章的时候,需要在网上找一些图,而有些网站的图片可能隐藏在属性或者背景图中,要下载的时候经常审查元素,查看源码,不太方便,最近在看一些谷歌插件的api,便顺手做了一个插件Image downloader。源码放到了github上,顺便学习并用了一下git。地址:https://github.com/yeyuqiudeng/imageDownloader

功能

Image downloader有下面几个功能:

  • 收集所有的img标签src的图片链接
  • 收集所有的背景图片链接
  • 可以根据定义的规则,收集标签属性中的链接
  • 支持图片大小筛选
  • 显示图片的原始大小

预览

manifest.json

插件用到谷歌插件中的content script和popup。content script是注入到页面中的js,需要在manifest.json配置注入页面的规则,和注入那些js进入页面。在这个插件中,我的manifest.json是这样的:

{
  "manifest_version": 2,
  "name": "Image downloader",
  "description": "图片下载器,可以自定义属性下载规则",
  "version": "1.0",
  "browser_action": {
    "default_icon": "icon16.png",
    "default_popup": "/popup/popup.html"
  },
  "permissions": [
    "tabs", 
    "downloads"
  ],
  "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*"],
        "js": ["common.js", "inject.js"]
    }]
}

content_scripts的配置表示要将common.js和inject.js注入到所有http和https的网站

common公共方法

在common里我定义了两个方法,一个用来显示错误信息,一个方法将图片的相对路径补全,在cdn地址前面加上http。

方法如下:

// 显示错误信息
const showMsg = (msg) => {
    let myDate = new Date();
    let now = myDate.toLocaleString();
    console.log(now + "【" + msg + "】");
};
// 拼接相对路径及cdn
const concatUrl = (url, domain) => {
    let fullPath = url
    if (/^\/[^\/]+/.test(url)) { // 是否为相对路径
        fullPath = domain + url
    }
    if (/^\/\//.test(url)) { // 是否为cdn
        fullPath = 'http:' + url
    }
    return fullPath
}

不太熟悉正则,也不知道写得对不对。

其实这里不需要再要一个common.js的文件,只是上一次写插件的时候,公共的方法比较多,这次也将common.js留了下来。

content script

在注入页面的JS中,主要是三个方法,分别用来收集img标签的src地址,元素的背景图片和自定义属性规则的属性值

收集img标签的src值代码如下:

const getImgUrl = function() { // 获取所有图片的src值
    const allImg = document.querySelectorAll('img')
    const allImgUrl = []
    allImg.forEach((img) => {
        allImgUrl.push(concatUrl(img.src, domain))
    })
    return allImgUrl
}

其实就是获取img标签的集合,遍历集合并获取src的值,如果为相对路径或cdn路径,用concatUrl方法拼接成绝对路径,最后组成一个由url地址组成的数组。

获取背景图片的代码如下:

const getBackgroundImage = function() { // 获取背景图片
    const allDoms = document.querySelectorAll('*')
    const allBgImageUrl = []
    allDoms.forEach((element) => {
        let url = window.getComputedStyle(element)['background-image'].match(/url\("(.+)"\)$/)
        if (url && url[1]) {
            allBgImageUrl.push(concatUrl(url[1], domain))
        }
    })
    return allBgImageUrl
}

通过getComputedStyle方法来获取所有元素的backgroundImage属性值,并将url地址提取出来,如果一个backgroundImage中有多个url,只取第一个,后面的就舍弃了。这个方法也是返回一个由地址组成的数组。

获取配置属性值的代码如下:

let configAttr = ['data-src'] // 配置的属性
const getConfigAttrUrl = function() { //  获取所有配置属性的值
    const attrUrl = []
    if (configAttr.length > 0) {
        configAttr.forEach((attr) => {
            attrUrl.push(...getAllAttr(attr))
        })
    }
    return attrUrl
}
const getAllAttr = function(attr) { // 获取对应属性的值
    const attrs = []
    const allDoms = document.querySelectorAll('[' + attr + ']')
    allDoms.forEach((dom) => {
        const attrValue = dom.getAttribute(attr)
        attrs.push(concatUrl(attrValue, domain))
    })
    return attrs
}

configAttr用来配置需要获取元素属性的规则,这里用了数组来接收多个配置规则,默认收集所有元素的data-src属性值。为什么会内置这个规则呢?因为很多网站都用了这个属性啊。

getAllAttr是根据传进来的属性获取属性值,getConfigAttrUrl是遍历属性规则,收集所有属性规则下的所有属性值,返回一个属性值数组。

图片不会在进入页面后马上就进行收集,只会在用户点击插件时才开始收集当前页面的图片,并将收集到的数据发送给popup处理。content script怎样与popup交互,下一篇文章再说。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏听雨堂

电子签名实现的思路、困难及解决方案

        在办公自动化的流程中希望实现电子签名。         思路:             1、图片的存放:安全起见存放在库中为宜。最好不能被轻易下...

26650
来自专栏超然的博客

前端基础精简总结

ES5: String、Number、Boolean、Null、Undefined、Object ES6增: Symbol 其中,object为引用,其...

19840
来自专栏web开发

移动端图片放大滑动查看-插件photoswipe的使用

最近在开发项目的时候,遇到一个需求,需要移动端实现放大查看图片的功能,然后我就在网上搜索了一下资料,看到了photoswipe这个插件,后来试了试,确实挺好用的...

94950
来自专栏编程

AngularJS中使用表单输入的应用设计

在Angular中使用表单元素非常方便。正如我们在前面几个例子中看到的,你可以使用ng-model属性把元素绑定到你的模型属性上。这一机制对于所有标准的表单元素...

18760
来自专栏向治洪

Vue.js 2.5新特性介绍

TypeScript TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和...

32380
来自专栏Ryan Miao

照着官方文档学习react

准备 先要准备环境。搭建一个基于webpack的react环境:Hello ReactJS. 一些要点 我在想是否应该完整的记录照抄的过程呢。毕竟已经开始一段,...

37570
来自专栏Debian社区

Web前端知识体系精简

Web前端技术由html、css和javascript三大部分构成,是一个庞大而复杂的技术体系,其复杂程度不低于任何一门后端语言。而我们在学习它的时候往往是先从...

22030
来自专栏老九学堂

超详细的Web 前端知识体系,等你来挑战!

作为苦逼的IT行业,没日没夜的加班,妹纸也少的可怜,就算在一个班办公室或者一个部门,可能也只有一个妹纸,但估计也轮不到你来上,只能眼巴巴的放着光。可是程序猿一直...

41570
来自专栏向治洪

ios开发之xcode环境介绍

作为一个刚入门ios开发的人来说,对于ios开发,对于xcode一切都是那么的陌生,那么我们如何开始我们的第一步呢?首先对开发的ide是必须要了解的,其实要对开...

27660
来自专栏强仔仔

利用js实现输入框动态提示信息

为了提高和用户的交互性,现在的输入框往往都采用输入信息自动提示的功能,类似于百度输入框中的提示功能。 设计思路是:在输入框input的组件下面放置一个div,这...

73660

扫码关注云+社区

领取腾讯云代金券