web插件开发浅谈

 

 

 

简单讲下这次写一个插件的背景:在协助同事完成数据导入工作的情况要得到一个需求,需求很简单,就是实现从Excel里复制一段内容然后可以将内容自动识别填写到表单里。虽然描述如此天马行空,也不明确有多少人有这样需求,但发现实现并不是难事。

 

作为一个码农,习惯性各种插件堆一起,然后写完代码,打包成遨游插件,同事欣喜若狂地用了起来,但用着用着各种问题飞奔而来。以下是我总结我开发的经历:

  1. 第一版,导入JQ包及写了一个JS文件,使用正则表达式简单分解字符串,及使用LocalStorage缓存内容,打包成遨游浏览器插件。(一开始我是设计用iframe的,但有跨域问题,出现跨域问题后我就终止了用iframe)
  2. 第二版,将第一版实现所有功能的JS制作成通用功能并以在线的形式利用导航条脚本注入方式加载到页面,处理了浏览器的兼容性IE8+、FF3.6+、Chrome等。

  3. 第三版,改造第二版,解决脚本对原页面污染问题,将所有JS以模块方式加载,使用Seajs加载。(我用了当前页面脚本注入和CSS加载,发现脚本存在执行污染问题,然后我用了考虑用RequireJS或Seajs解决,后来选了Seajs)

  4. 第四版,改造第三版,使用iframe对插件的功能HTML代码、CSS代码与JS代码隔绝。

 

其实作为一个程序员,如果只考虑需求,而不追求自己代码的改进,第一个版本基本可以满足需求了。但不重构的话,达不到通用的要求了。

然后css因为没办法,加载了bootstrap,必须污染,后来参考了firebug-lite,它是用iframe的,读了源码后,发现又被坑了,它是用iframe的但事件那些都原生JS写的,而我用JQ,应该说是JQ坑我,JQ会将iframe渲染成同一个执行域这样就坑了,我在iframe加载的CSS可以了,但JS却变成了在父域加载。国内搜到的基本是这种$("#mainiframe").contents().find("someID").html()就是contents()这个方法,这样执行的$等价于$(document).find(),我花了一周末去解决,最后在Google搜到了结果,所以执行的window对象是父文档,所有效果被应用到了父文档,以后我开发插件尽量用iframe隔绝CSSJS。我的远大理想是以后一些功能都做成挂件,就业务逻辑无关的功能,类似于分享条那样。

下面列出一些参考代码

第一版的核心参考代码

function SiseInsert(){
    //获取配置
    this.getConfig=function(){
        var init=globalConfig;
        if(window.localStorage.getItem("SiseInsert")==null){
            return init;
        }
        init=$.evalJSON(window.localStorage.getItem("SiseInsert"));
        return init;
    }
    //设置配置
    this.setConfig=function(config){
        window.localStorage.setItem("SiseInsert",$.toJSON(config));
    }

    this.displayConfig=function(){
      var conf=this.getConfig();
      $("#hackEgg input[type='text']").eq(0).val(conf.total);
      $("#hackEgg input[type='text']").eq(1).val(conf.current);
      $("#hackEgg input[type='text']").eq(2).val(conf.delay);
      $("#hackEgg input[type='text']").eq(3).val(conf.status);
      $("#hackEgg input[type='text']").eq(4).val(conf.regex);
      $("#hackEgg input[type='text']").eq(5).val(conf.replace);
      $("#hackEgg textarea").eq(0).val($.toJSON(conf.datasource));
}
    this.select=function(name,value){
        $("select[name='"+name+"']").find("option[text='"+value+"']").attr("selected",true);
    }
    this.input=function(name,value){
        $("input[name='"+name+"']").val(value);
    }
    this.radio=function(name,index){
        $("input[name='"+name+"']").eq(parseInt(index)).attr("checked",'checked');
    }
    this.insert=function(target,name,value){
        switch(target){
            case "input":
            this.input(name,value);
            break;
            case "select":
            this.select(name,value);
            case "radio":
                this.radio(name,value);
            break;
        }
    }
    this.insertAll=function(list){
        for(i=0;i<list.length;i++){
            this.insert(list[i].target,list[i].name,list[i].value);
        }
    }
}

function pageInit(){
    var operator=new SiseInsert();
    var text='\
            <div id="hackEgg" style="width:150px;height:1085px;position:absolute;left:0;top:0;background:#fff;z-index:10000;">\
                <div>总数<input style="width:100px" type="text"></div>\
                <div>当步<input style="width:100px" type="text"></div>\
                <div>延时<input style="width:100px" type="text"></div>\
                <div>状态<input style="width:100px" type="text"></div>\
                <div>正则<input style="width:100px" type="text"></div>\
                <div>替换<input style="width:100px" type="text"></div>\
                <div><input type="button" value="读取" /><input type="button" value="更新" /><input type="button" value="重建" /></div>\
                <div>数据<textarea style="width:100px" type="text"></textarea></div>\
                <div><input type="button" value="更新数据源" /></div>\
            </div>';
        $("body").append(text);

        operator.displayConfig();
        $("#hackEgg input[type='button']").eq(0).click(function(){
            operator.displayConfig();
        });
        $("#hackEgg input[type='button']").eq(1).click(function(){
            var conf=operator.getConfig();
            //conf.total=$("#hackEgg input").eq(0).val();
            conf.current=parseInt($("#hackEgg input").eq(1).val());
            conf.delay=parseInt($("#hackEgg input").eq(2).val());
            conf.status=parseInt($("#hackEgg input").eq(3).val());
            conf.regex=$("#hackEgg input").eq(4).val();
            conf.replace=$("#hackEgg input").eq(5).val();
            operator.setConfig(conf);
        });
        $("#hackEgg input[type='button']").eq(2).click(function(){
            window.localStorage.removeItem("SiseInsert");
            var conf=operator.getConfig();
            operator.setConfig(conf);
        });
        $("#hackEgg input[type='button']").eq(3).click(function(){
            var conf=operator.getConfig();
            var str=$("#hackEgg textarea").eq(0).val();
            var regex=new RegExp(conf.regex,"gm");
            str=str.replace(regex,conf.replace);
            str=str.replace(/[\r\n]/gm,"");
            str=str.replace(/,$/,"");
            str=str.replace(/""/gm,"\"");
            str="["+str+"]";
            conf.datasource=$.evalJSON(str);
            conf.total=conf.datasource.length;
            conf.current=0;
            operator.setConfig(conf);

            operator.displayConfig();
        });
}
/*********************************华丽分割线**************************/
var globalConfig={
    total:0,
    current:0,
    delay:0,
    status:0,
    regex:'^([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)\\t([^\\t]*?)$',
    replace:'[{"target":"input","name":"applyName","value":"$1"},{"target":"input","name":"manName","value":"$2"},{"target":"select","name":"manCardType","value":"$3"},{"target":"input","name":"manCardNo","value":"$4"},{"target":"select","name":"PropertySelection","value":"$5"},{"target":"input","name":"birth","value":"$6"},{"target":"input","name":"manMajor","value":"$7"},{"target":"select","name":"PropertySelection_0","value":"$8"},{"target":"input","name":"inputDate1","value":"$9"},{"target":"input","name":"inputDate2","value":"$10"},{"target":"input","name":"manSchool","value":"$11"},{"target":"input","name":"manGraduationTime","value":"$12"},{"target":"input","name":"manLinktype","value":"$13"},{"target":"input","name":"orgName","value":"$14"},{"target":"input","name":"trainProject","value":"$15"},{"target":"input","name":"inputDate3","value":"$16"},{"target":"input","name":"inputDate4","value":"$17"},{"target":"input","name":"trainMoney","value":"$18"},{"target":"select","name":"jobstatus","value":"$19"},{"target":"input","name":"jobCorpname","value":"$20"},{"target":"radio","name":"size","value":"$21"}],',
    datasource:[]
};

$(function(){
    if(window.location.href.indexOf("login.html")!=-1){
        var str='';
                         setTimeout(function(){
                            $("#loginId").html(str);
                         },0);
    }
    var operator=new SiseInsert();
    var conf=operator.getConfig();
    if(window.location.href.indexOf("Trainedit.html")!=-1){
        pageInit();//初始化页面
        conf.total=conf.datasource.length;
        //当前步有效
        if(conf.total>conf.current){
                if(conf.status==1){
                var person=conf.datasource[conf.current];
                operator.insertAll(person);
                setTimeout(function(){
                    conf.current=conf.current+1;
                    operator.setConfig(conf);
                    //提交
                    $("#manNo").val("身份证验证通过")
                    $("#Submit_0").eq(0).click();
                },conf.delay);
            }
        }
        else{
            if(conf.status==1){
                alert("已完成");
            }
        }
    }
    else if(window.location.href.indexOf("TrainCorpList,SrestoreList.html")!=-1){
        if(conf.status==1){
            window.location.href="Trainedit.html"
        }
        else if(conf.status==5000){
            window.close();
        }
    }
    else if(window.location.href.indexOf("TrainCorpList.html")!=-1){
            pageInit();//初始化页面
        if(conf.status==5000){
            var all=$("a[href^='/pages/train/org/TrainCorpList_delete']");
            $.each(all,function(i,c){
                window.open($(c).attr("href"),'','fullscreen=0,scrollbars=0');
            });
        }
    }
});

 最终版的参考代码结构


最终版的代码结构有点啰唆,使用请猛点这里,详细代码请开浏览器调试!

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值