對角另一面

谷歌插件Image downloader開發(fā)之popup

Image downloader的交互邏輯是這樣的:用戶點擊Image downloader的圖標(biāo),會向頁面(content script,見上一篇文章:谷歌插件Image downloader開發(fā)之 content script)發(fā)送收集圖片事件,頁面收集完圖片后,將對應(yīng)的圖片地址數(shù)組發(fā)送給popup頁處理。popup頁就是點擊谷歌插件圖標(biāo)所彈出來的頁面。Image downloader的popup頁是長成這樣的:

popup頁包含的功能

popup頁采用了vue1.0來做數(shù)據(jù)綁定,主要包含了以下功能:

1、顯示原始圖片大小
2、根據(jù)圖片大小篩選圖片
3、設(shè)置是否顯示img標(biāo)簽的圖片、是否顯示背景圖片,是否顯示自定義屬性的圖片
4、根據(jù)自定義屬性規(guī)則,收集所配置的自定義屬性的值
5、下載圖片

popup與content script的交互

圖片容器:

imgs: { // 圖片容器    attrImg: [], // 屬性圖    bgImg: [], // 背景圖    img: [], // img標(biāo)簽圖},/**
 * 向tab發(fā)送收集圖片信息,接收tab返回的圖片url列表
 * @param action {string} 值為'all'或'attr',如果為all,則收集所有圖片,為attr則只收集屬性圖
 * @param attr {string} 用;分隔開的屬性規(guī)則
 */sendMessage(action, attr) {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
        chrome.tabs.sendMessage(tabs[0].id, { action, attr }, (response) => {            if (action === 'all') {
                const attrImg = response.attrImg
                const bgImg = response.bgImg
                const img = response.img                    // 重置容器
                this.resetImgContainer('attrImg')                this.resetImgContainer('bgImg')                this.resetImgContainer('img')                    // 獲取圖片的寬高
                this.mapImg(this.imgs.attrImg, attrImg)                this.mapImg(this.imgs.bgImg, bgImg)                this.mapImg(this.imgs.img, img)
            } else {                this.resetImgContainer('attrImg')                this.mapImg(this.imgs.attrImg, response.attrImg)
            }
        });
    });
},

popup頁用了chrome的tabs的api,query查詢當(dāng)前頁簽,并用sendMessage向頁簽發(fā)送action和配置的屬性值,如果action為'all'則是收集所有圖片,如果為'attr',則只收集所配置的屬性圖片,resetImgContainer方法只是簡單地將容器置空,response是content script所返回的結(jié)果,mapImg方法用來獲取圖片的長和寬,下文會講到。

而在content script中,則用onMessage來接收popup的信息,并將收集到的圖片數(shù)組返回給popup

// 接收popup的指令,如果action為all,則獲取所有圖片url,如果為attr,則獲取屬性圖片
chrome.runtime.onMessage.addListener(({ action, attr }, sender, sendResponse) => {    if (attr) {
        configAttr = []
        configAttr.push(...initAttr)
        configAttr.push(...attr.split(','))
    } else {
        configAttr = []
        configAttr.push(...initAttr)
    }    if (action === 'all') {
        sendResponse({
            attrImg: [...new Set(getConfigAttrUrl())],
            bgImg: [...new Set(getBackgroundImage())],
            img: [...new Set(getImgUrl())]
        })
    }    if (action === 'attr') {
        sendResponse({
            attrImg: [...new Set(getConfigAttrUrl())],
        })
    }
});

上篇文章發(fā)在div.io上時,@幾米 提到了圖片去重的問題,所有在返回圖片是,用es6的Set方法去重,這個只處理同類型圖片的去重,不處理如背景圖片和圖片標(biāo)簽之間的重復(fù)圖片。

獲取屬性圖片

/**
 * 獲取屬性圖片
 */getAttrImg() {
    clearTimeout(this.progress)    this.progress = setTimeout(() => {        this.sendMessage('attr', this.attr)
    }, 500)
},

配置的屬性值發(fā)生變化時,向頁面發(fā)送獲取屬性圖片事件

顯示圖片原始大小

/**
 * 遍歷圖片,設(shè)置圖片的寬高屬性
 * @param container {array} 容器
 * @param imgs {array} 圖片url列表
 */mapImg(container, imgs) {
    imgs.forEach((src) => {
        this.imgNatureSize(container, src)
    })
},/**
 * 獲取圖片原始寬高,并將圖片push進容器
 * @param container {array} 容器
 * @param src {string} 圖片url
 */imgNatureSize(container, src) {    const size = {
        width: '',
        height: '',
    }
    let image = new Image()
    image.src = src
    image.onload = function() {
        container.push({
            src,
            width: image.width,
            height: image.height,
        })
    }
},

遍歷拿到的圖片,獲取圖片的寬和高,并將寬高屬性保存起來

下載圖片

/**
 * 下載圖片
 */downLoad(url) {
    chrome.downloads.download({ url }, () => {        console.log('下載成功')
    })
}

調(diào)用谷歌插件的download方法來進行圖片下載,本來想搞個批量下載的,但是沒有發(fā)現(xiàn)谷歌插件有提供批量下載的API,如果遍歷所選中的圖片列表,不斷調(diào)用download方法,會一下子彈出很多保存窗口,沒有什么意義,就作罷了。

最后,所有文章都會同步發(fā)送到微信公眾號上,歡迎關(guān)注,歡迎提意見: