• chrome浏览器扩展的事件处理


    关于chrome扩展开发的栗子已经有很多了,问问度娘基本能满足你的欲望, 我想说的是扩展和页面间的数据传递问题。

    我们知道写扩展有个必须的文件就是“manifest.json”, 这个里面定义了一个和页面打交道的文件“content.js”, 该js可以访问页面中的任何元素;但不幸的是页面却无法访问content.js中的任何方法(写扩展页面的除外啊,我说的页面是浏览器中的普通页面)。那么问题就来了:怎么才能触发content.js中的事件呢?

    官方当然给出解决方案:content.js中写按钮的监听事件,比如一般button的click事件

    1 //bt1 是页面按钮id
    2 document.getElementById('bt1')..addEventListener(“click”,function(){
    3     //做一些自己的事情,和background.js打交道等等
    4 },false);

    这么做当然没有问题。

    但是……

    如果页面中没有bt1按钮呢 ?

    如果我不知道是哪个按钮调用的呢 ?

    或者说,content.js中有一个方法,需要页面上随时可以调用 。。。。

    解决办法就是,页面添加一个固定的按钮就叫bt1,其他的都不能叫这个名字,content.js这样就可以绑定事件了, 谁用谁调用一下bt1的click事件。

    其实还有个解决办法:自定义事件 , 看代码

    1 //页面中定义一个事件
    2 //name 事件名称,msg传递的消息值
    3  createCustomEvent:function(name,msg){
    4             var evt = document.createEvent("CustomEvent");
    5             evt.initCustomEvent(name, true, false, msg);
    6             document.dispatchEvent(evt);
    7 },

    content.js写一个事件监听

    1 //content.js中的监听方法
    2 //name要和页面name相同
    3 //evt 就是得到的结果
    4 document.addEventListener(name, function(evt) {
    5    var data =evt.detail;  //data就是上面的msg值
    6 
    7    //todo
    8   
    9 }

    这样整个流程就通了,页面随时可以创建一个事件来调用扩展方法。

    不过明白人已经看出来了,返回值呢? 是的,该方法只能传递值却不能得到结果,并且msg只能传递字符串,也没法定义回调。如果想得到返回值只能再content.js中也定义一个自定义事件,页面做监听,反过来使用上面的代码。(感觉很矬……)

    这还没有完, 该方案不支持并发。当有两个地方同时调用该方法时,页面监听事件无法区分那个的返回值,得到的结果根本无法使用。

    怎么办呢? 我又想到一个更矬的办法来,调用的时候传递一个回调,然后保存起来。

    说不明白,看代码吧。页面代码

    1 var  sendMessage=function(msg,callback){
    2     //获取一个自增序列当key,页面唯一
    3     var key=getIndex();  
    4     //保存到hashtable里面,evtMap是个自定义hashtable
    5     evtMap.add(key,callback);
    6     //'调用自定义事件,把key带上
    7      createCustomEvent(eventName,{"evtId":key,"msg":msg});
    8            
    9    }

    content.js可以得到这个key,回调的时候再把这个可以传过来,看看content.js

     1 document.addEventListener(listenerName, function(evt) {
     2 
     3     var data =evt.detail;
     4     //todo 得到msg
     5 
     6     var res={"evtId":data.evtId,"msg":msg }; //把页面传递的key再传回去
     7 
     8     var evt = document.createEvent("CustomEvent");
     9     evt.initCustomEvent(backEventName, true, false, res);  
    10     document.dispatchEvent(evt);
    11 
    12 }, false);

    再回到页面js代码

    1     document.addListener(listenerName,function(response){
    2        //通过key从hasttable中再次获取callback函数
    3     var evtId=response.evtId;
    4     var callback=evtMap.getValue(evtId);
    5     if (callback) {
    6         callback(response.msg);
    7     };
    8     });

    上面就是一种比较矬的解决扩展和页面数据交互的一种方案,如果哪位高手有更好的方案不舍赐教~!! 感谢

    下面把JS的Hashtable贴一下,其实度娘怀里就有 

      var HashTable=function(){
            var size = 0;
            var entry = new Object();
    
            this.add = function (key,value){
                if(!this.containsKey(key)){
                    size ++ ;
                }
                entry[key] = value;
            }
            this.getValue = function (key) {
                return this.containsKey(key) ? entry[key] : null;
            }
            this.remove = function(key){
                if( this.containsKey(key) && ( delete entry[key] ) ) {
                    size --;
                }
            }
            this.containsKey = function(key){
                return (key in entry);
            }
            this.containsValue = function(value){
                for(var prop in entry) {
                    if(entry[prop] == value){
                        return true;
                    }
                }
                return false;
            }
            this.getValues = function () {
                var values = new Array();
                for(var prop in entry) {
                    values.push(entry[prop]);
                }
                return values;
            }
            this.getKeys = function () {
                var keys = new Array();
                for(var prop in entry) {
                    keys.push(prop);
                }
                return keys;
            }
            this.getSize = function () {
                return size;
            }
            this.clear = function () {
                size = 0;
                entry = new Object();
            }
        }
    View Code
  • 相关阅读:
    Hubble.net 值得纪念的一天
    Hubble.net 0.5 版本开发完成
    计算任意数值的阶乘
    Hubble.net 建表语句 Create Table
    Linq to SQL 插入数据时的一个问题
    盘古分词中文人名识别算法介绍
    盘古分词功能简介
    最长不完全匹配子串频率计算eaglet 的解法
    背包分组问题的解法
    SharePoint 2010与2007的区别 配置基于表单的身份认证
  • 原文地址:https://www.cnblogs.com/freeton/p/4801123.html
Copyright © 2020-2023  润新知