zhengrenzhe's blog   About

Chrome扩展该如何显示界面

一个Chrome扩展该如何向用户显示界面呢,经过一段时间的开发,我总结了如下几种方法:

以标签页的形式

这种交互形式常见于一些标签页应用,当用点击新建标签页按钮时,扩展会信件一个标签页以代替浏览器默认的,标签页的内容就是扩展所定义的。这些标签页相当于一个简化的网址导航,可以显示天气,时间,用户的收藏等信息。

popup页面

这种页面常见于一些对于用户交互不是那么重要,但要有能在任何页面显示的能力,相对于上一种,他无需新建标签页,而是点击Chrome右上角的小按钮后弹出一个小界面:

使用popup页面有几个方法,首先可以在 manifest.json文件中直接定义,或使用browserActionsetPopup方法指定popup页面。但使用popup页面需要注意的是,browserActiononClicked事件将无法使用,即使你定义了这个事件的回调,回调也不会被调用。

另外需要注意的是,当使用popup页面时,如果同时需要在页面中使用AngularJS进行视图切换,页面会出现严重的频闪,popup页面错位也时有发生,所以使用popup页面的一个最佳实践就是:不要在页面中使用AngularJS的视图切换

但是对于复杂的应用,势必会用到视图切换的功能,不能总是用js操作css进行页面部分的显示隐藏操作吧。这就有了第三种解决方案:

Content Script向页面中插入iframe

这种方式也是现在具有复杂交互的扩展所采取的主流形式,比如印象笔记-剪藏,pocket

这种方式的具体步骤如下:

1.在manifest.json文件中声明Content Script。详细说明可以看 官方文档

"content_scripts": [{
  "js": ["js/ext.init.js"],
  "css": ["css/ext.global.css"],
  "matches": ["*://*/*"],
  "all_frames": false,
  "run_at": "document_end"
}],

在这里要注意的是:如果没有对目标页面所有的iframe操作的需求,all_frames这个属性一定要为false,原因后面说。

2.不定义任何popup页面,使用browserAction.onClicked监听用户点击。用户点击后触发回调,此时可以有一些例如验证用户有效性的逻辑。

3.当onClicked事件回调被调用后,向content_scripts发送消息,让它在当前页面里插入iframe。 此时发送消息要使用chrome.tabssendMessage方法:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
  chrome.tabs.sendMessage(tabs[0].id, {'tabs': tabs[0], 'v': v, 'saved':saved}, function(res){
    try{
      res.status
    }catch(e){
      if(e){
        alert('您需要刷新此页面以使Onebm工作');
      }
    }
  });
});

在这里先进行tab的查询,使用{active: true, currentWindow: true}这个条件查询到当扩展图标被点击时用户正在看的标签页,之后返回该标签页信息。接着需要向该标签页的content_scripts发消息,tabs[0].id就是该标签页的id

4.在content_scripts设置接收信息并插入iframe的回调函数,同时需要对发送来源进行识别。

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
  // 对消息来源进行检测
    if( chrome.runtime.id !== sender.id){
      return false;
    };
    var ifr = document.getElementById('Onebm_Extension');
    // 显示扩展
    sendResponse({'status':'get message'});
    var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
    if (!location.ancestorOrigins.contains(extensionOrigin)) {
      var iframe = document.createElement('iframe');
      iframe.src = chrome.runtime.getURL('popup.html');
      iframe.id = "Onebm_Extension";
      window.top.document.body.appendChild(iframe);
    }
});

由于插入的是iframe,所以扩展的代码是存在于当前页面中的。

这里仍有几点需要注意

← JavaScript监听检测DOM更改  知乎 Hackers三道题 →