Chrome Extension 動手實操


最近想玩下chrome的插件主要有兩個原因, 一個是前段時間對chrome new tab的功能太少很不滿意, 現有插件又不能滿足需求, 想自己搞個. 由於界面設計實在是我的障礙而且自身需求不急, 就沒動手; 另個是最近想在公司內網求一個ipad mini, 僧多粥少, 往往剛有一個賣的半小時內就被預訂了, 據此想借chrome的桌面提醒功能, 做一個能實時提醒的插件. 功能很簡單, 大致如下:

  1. 每x秒請求論壇前幾頁, 查到所有標"new"的新帖
  2. 根據帖子的title, 匹配我需要的關鍵字"pad mini"進行展示
  3. 桌面提醒, 展示帖子的樓主, 標題和地址, 應該是可點擊的能直接點過去
  4. 去重, 已經提醒過的帖子就不要提醒了

搞newtab的時候稍微看了下extension的文檔:

https://developer.chrome.com/extensions/docs.html

公司很多網站上不去, 這個還得用https而且還偶爾被強痛不欲生, 后來發現有很多鏡像, 比如這個:

https://sites.google.com/site/crxdoczh/reference/api_index/extension

資料不是最新, 但基本夠用. 

瀏覽下 "Getting Started" , 就開始上手了.

==========================================================================

一. 編寫manifest.json, 

{
    "name": "Iwant",
    "version": "1.0",
    "manifest_version": 2,
    "background" : {
        "persistent": false,
        "scripts": ["jquery-1.8.3.min.js", "iwant.js"]
    },
    "permissions": [
      "notifications",
      "storage",
      "cookies"
    ],
    "content_security_policy": "script-src 'self'; object-src 'self'"
}

這個沒什么難度, 照着抄就行, 注意以下幾點:

  1. 嚴格按照JSON格式, 比如最末不能有逗號 :(
  2. 我使用了本地的js, 所以要加content_security_policy策略
  3. 申請足夠的權限
  4. 沒有UI, 並且希望插件加載或chrome啟動時就可以執行, 看"backgroud"

基本就完事了, 先把 jquery下載下來, 新建個iwant.js的空文件, 可以調試了.

------------------------------------------------------------------------------

二. 調試

打開chrome的插件頁chrome://extensions/, 把開發者模式勾選上, 按照"Getting Started"的說明加載應用就好了.

注意插件的Inspect views連接, 點擊會新打開一個console, 這個console下已經包含了manifest.json指定的權限, 隨意調試.

------------------------------------------------------------------------------

三. 開工

 1 g_IWant = 'mini';
 2 g_wants = [];
 3 
 4 function _removeOutdated(shownurls){
 5     var now = new Date;
 6     for (url in shownurls){
 7         if (now - shownurls[url] > 86400000){
 8             delete shownurls[url];
 9         }
10     }
11 }
12 
13 function showWant(name, title, url){
14     if (title.indexOf(g_IWant) == -1){
15         return;
16     }
17     chrome.storage.local.get('shownurl', function(items){
18         if (!items.shownurl){
19             items.shownurl = {};
20         }
21         var shownurl = items.shownurl;
22         if (!shownurl[url]){
23             _removeOutdated(shownurl);
24             var want = {name:name, title:title, url:url};
25             if (g_wants.length > 10){
26                 g_wants.shift();
27             }
28             g_wants.push(want);
29             shownurl[url] = new Date;
30             chrome.storage.local.set(items);
31         }
32     })
33 }
34 
35 function findWant(pages){
36     if (pages <= 0){
37         return;
38     }
39     var xhr = new XMLHttpRequest();
40     xhr.open('GET', 'http://bbs.com/forum?page='+pages, true);
41     xhr.onreadystatechange = function(){
42         if (xhr.readyState == 4){
43             var html = xhr.responseText;
44             var body = html.substring(html.search('<body>'), html.search('</body>')+8);
45             $('#content table tr', $(body)).has('td img[src="http://bbs.com/img/new.gif"]').each(function(i, item){
46                 var $item = $(item);
47                 var url = $item.find('td:first a[href][title]').attr('href');
48                 var title = $item.find('td:first a[href][title]').text();
49                 var name = $item.find('td:eq(1)').text();
50                 showWant(name, title, url);
51             })
52             findWant(pages-1);
53         }
54     }
55     xhr.send();
56 }
57 
58 function showWantToNotification(){
59     var want = g_wants.shift();
60     if (!want) return;
61     var query = 'name='+encodeURI(want.name)+'&title='+encodeURI(want.title)+'&url='+encodeURI('http://bbs.com'+want.url);
62     var tip = webkitNotifications.createHTMLNotification('notify.html?'+query);
63     tip.replaceId = 'wanted';
64     tip.show();
65 }
66 
67 
68 setInterval(function(){findWant(2);}, 5000);
69 setInterval(function(){showWantToNotification();}, 5000);

 

  1. 做了兩個定時器, 一個爬頁面, 一個彈桌面通知, 保證每次顯示都能持續5秒;
  2. findWant函數提供了pages參數指定爬前幾頁, 根據實際情況, 一般也就前2頁有新帖
  3. showWant把合適的帖子插到全局列表中, 再在另一個定時中顯示通知

這里遇到點障礙, 桌面通知notification只支持兩種格式: plaintext或url. 需要可點擊, plaintext肯定不行的. 又不能再為了傳遞數據, 搭建一個服務器接收數據. 琢磨半天, 只好通過本地的js文件分解GET參數實現數據傳遞. 如showWantToNotification函數中指定的notify.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
    </head>
    <body>
        <div id="iw_content"></div>
        <script src="notify.js"></script>
    </body>
</html>

以及notify.js

var url = window.location.href;
var query = url.split('?')[1];
var params = {};
if (query){
    var names = query.split('&');
    names.forEach(function(param){
        var tuple = param.split('=');
        var key = tuple[0], value = decodeURI(tuple[1]);
        params[key] = value;
    })
}


if (params['name'] && params['title'] && params ['url']){
    var html = '';
    html += '<div>' + params['name'] + '</div>';
    html += '<div><a target="_blank" href="'+params['url']+'">'+params['title']+'</a></div>';
    document.getElementById('iw_content').innerHTML = html;
}

-----------------------------------------------

四. 調試上線

代碼寫差不多了, 就要調試通過了.

Extensions頁直接reload, 在控制台監控數據. 挺簡單一活, 遇到倆問題:

1. 在notificaion創建后斷點調試, notificaion直接蹦了..

2. 我的系統下notificaion里超鏈接上鼠標竟然不是pointer...

調試差不多就可以在Extensions頁打包了. 然后, 自己用還是給同事用, 隨心所欲啊.

 

==============================================================

總體來說, chrome下extension開發還是比較簡單有趣的, 文檔比較完整, 坑爹的地方也不多, 極照顧我這種不熟悉JS的菜鳥嘞.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM