• 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的菜鸟嘞.

  • 相关阅读:
    Mongo DB intro
    java class 初始化
    Java Multi-Thread
    Java Exception
    PHP基础2
    Java STL
    javascript getElemet 获取元素 (转)
    javascript 异常处理
    javascript 输出
    LinkButton跳转页面及传递参数(转载)
  • 原文地址:https://www.cnblogs.com/c9com/p/2892810.html
Copyright © 2020-2023  润新知