好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Chrome Extension 动手实操

Chrome Extension 动手实操

最近想玩下chrome的插件主要有两个原因, 一个是前段时间对chrome new tab的功能太少很不满意, 现有插件又不能满足需求, 想自己搞个. 由于界面设计实在是我的障碍而且自身需求不急, 就没动手; 另个是最近想在公司内网求一个ipad mini, 僧多粥少, 往往刚有一个卖的半小时内就被预订了, 据此想借chrome的桌面提醒功能, 做一个能实时提醒的插件. 功能很简单, 大致如下:

每x秒请求论坛前几页, 查到所有标"new"的新帖 根据帖子的title, 匹配我需要的关键字"pad mini"进行展示 桌面提醒, 展示帖子的楼主, 标题和地址, 应该是可点击的能直接点过去 去重, 已经提醒过的帖子就不要提醒了

搞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'" 
} 

这个没什么难度, 照着抄就行, 注意以下几点:

严格按照JSON格式, 比如最末不能有逗号 :( 我使用了本地的js, 所以要加content_security_policy策略 申请足够的权限 没有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);

做了两个定时器, 一个爬页面, 一个弹桌面通知, 保证每次显示都能持续5秒; findWant函数提供了pages参数指定爬前几页, 根据实际情况, 一般也就前2页有新帖 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的菜鸟嘞.

 

 

分类:  Chrome Extension

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Chrome Extension 动手实操的详细内容...

  阅读:40次