谷歌Chrome浏览器扩展程序开发小记


Posted in Javascript onJanuary 06, 2016

根据公司的规定,每月八小时,弹性工作制。所以大家平时来的不太准时,如果有事,下班也就早些回去了。所以一个月下来工作时间可能不够,但是公司的考勤日历是这样的:

谷歌Chrome浏览器扩展程序开发小记

除了请假和法定节假日外,其他样式显示都是一样的,每次都要一个个估算这个月的大概工作时间,十分不方便。后来看到公司有人在用一个Chrome扩展程序,可以计算出一个月的工作时间,但是我觉得还是没有看到我想看的东西,因为除了每个月的累计工作时间外,我还想看到:平均每天工作时长、每一天的工作时长、20点以后的天数(20点以后下班的可以报销晚饭的,哈哈……)、22点以后下班的天数(报销打车费)……所以我决定还是自己写一个吧。

第一步,我先写了一个JS方法,然后通过F12开发者工具的Console复制粘贴运行。

公司用的OA系统没有引用jQuery库,所以我刚开始的想法是想动态引用jQuery类库,如下:

var script = document.createElement("script");

script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js";

document.body.appendChild(script);

但是遇到了问题:一个是$被占用,二是HR系统采用iframe嵌套,并且还有frame嵌套,结构很复杂。而console运行的代码是在最顶层运行的,后期的chrome扩展插件是运行在内部frame中的,可能这里的JS后面不能直接使用。虽然$被占用的问题可以通过jQuery.noConflict();来解决,但是jquery库和原来系统的JS库存在调用顺序的问题,而且在内部的frame中死活访问不到jQuery这个对象。最后我决定放弃使用jQuery,该用原生JavaScript。

JS代码如下:

/*
 * author:清明雨上
 * date:2016-1-5
 */
var mydate = function() {
  //time2-time1
  function getTimeDiff(time1, time2) {
    var st1 = time1.split(':');
    var st2 = time2.split(':');
    return ((st2[0] | 0) * 60 + (st2[1] | 0)) - ((st1[0] | 0) * 60 + (st1[1] | 0) * 1);
  }

  var timeList = [];
  var mymain = window.parent.frames['Main'].document.getElementById('ctl00_cphMain_CalendarAC');
  var listAC = mymain.getElementsByClassName('listAC');
  for (var i = 0; i < listAC.length; i++) {
    var item = listAC[i];
    var t = {};
    t.timeSpan = item.getElementsByTagName('td')[1].innerText;
    t.remark = item.getElementsByTagName('td')[2].innerText;
    timeList.push(t);
  };

  var totalMin = 0;
  var noworkDays = 0; //请假天数
  var workDays = 0; //实际上班天数
  var workHourEveryday = [];
  var no8h = 0; //未满8小时天数
  var over20 = 0; //20点以后下班天数
  var over21 = 0; //21点以后下班天数
  var over22 = 0; //22点以后下班天数
  var over23 = 0; //23点以后下班天数
  for (var i = 0; i < timeList.length; i++) {
    var time = timeList[i];
    if (time.remark != '无') {
      noworkDays++;
      continue;
    }
    if (time.timeSpan == '无刷卡记录')
      continue;

    var splitTime = time.timeSpan.split('~');
    if (splitTime.length == 2) {
      //正常上下班
      var begin = splitTime[0];
      var end = splitTime[1];
      var thisMin = getTimeDiff(begin, end);
      totalMin += thisMin;
      workDays++;
      if (thisMin / 60 < 8) {
        workHourEveryday.push('<font color="red"><b style="font-size:15px">' + parseInt(thisMin / 60) + '</b>.' + thisMin % 60 + '</font>');
        no8h++;
      } else {
        workHourEveryday.push('<b style="font-size:15px">' + parseInt(thisMin / 60) + '</b>.' + thisMin % 60);
        var offworkHour = parseInt(end.split(':')[0]);
        if (offworkHour >= 20) {
          over20++;
        }
        if (offworkHour >= 21) {
          over21++;
        }
        if (offworkHour >= 22) {
          over22++;
        }
        if (offworkHour >= 23) {
          over23++;
        }
      }
    }
  };
  var myHour = parseInt(totalMin / 60); //本月工作累计小时数
  var otherMin = totalMin % 60; //本月工作出小时部分外的分钟数
  var avgHourOneDay = workDays == 0 ? '0.0' : '<b style="font-size:15px">'+(parseInt(myHour / workDays) + '</b>.' + (parseInt((myHour % workDays) * 60 / workDays) + parseInt(otherMin / workDays))); //平均每天工作时长

  var html = '<div class="alectest" style="background: #cbebfb;padding:7px;">\
        <div>出勤时间:<b style="font-size:15px;color:red">' + myHour + '</b>小时<font color="red">' + otherMin + '</font>分钟(平均<font color="red">' + avgHourOneDay + '</font>小时/天)</div>\
        <div>参考时间:' + workDays * 8 + '小时【' + workDays + '天】(除去请假和节假日,实际有打卡记录的天数)</div>\
        <div>请假/外出天数:' + noworkDays + '天</div>\
        <div>每天工作时间(格式:小时.分钟):' + workHourEveryday.join(',') + '</div>\
        <div>未满8小时天数:<b style="font-size:15px">' + no8h + '</b>天</div>\
        <div>20点以后下班天数:<b style="font-size:15px">' + over20 + '</b>天</div>\
        <div>21点以后下班天数:<b style="font-size:15px">' + over21 + '</b>天</div>\
        <div>22点以后下班天数:<b style="font-size:15px">' + over22 + '</b>天</div>\
        <div>23点以后下班天数:<b style="font-size:15px">' + over23 + '</b>天</div>\
       </div>'
  var alectest = mymain.parentNode.getElementsByClassName('alectest');
  if (alectest.length > 0) {
    // mymain.parentNode.removeChild(alectest[0]);
    alectest[0].innerHTML = html;
  } else {
    var div = document.createElement("div");
    div.innerHTML = html;
    var fragement = document.createDocumentFragment();
    while (div.childNodes[0]) {
      fragement.appendChild(div.childNodes[0]);
    }
    mymain.parentNode.insertBefore(fragement, mymain);
  }
  bindBtnClick();
}
var bindBtnClick = function() {
  window.parent.frames['Main'].document.getElementById('ctl00_cphTop_BtnQuery').addEventListener('click', function() {
    var inter = setInterval(function() {
      if (window.parent.frames['Main'].document.getElementById('ctl00_cphMain_CalendarAC') &&
        window.parent.frames['Main'].document.getElementById('ctl00_UpMaster').style.display == 'none') {
        clearInterval(inter);
        mydate();
      }
    }, 500);
  }, false);
}
bindBtnClick();

代码说明:监听考勤查询按钮的click事件,考勤信息加载完成后,执行我的JS方法。

第二步,开发Chrome扩展程序

参考资料:http://open.chrome.360.cn/extension_dev/content_scripts.html(查询manifest.json的content_scripts节点的各个属性说明)

manifest.json是必须的,最终内容如下:

{
 "manifest_version":2,
  "name": "Extension Name", 
 "version": "0.1.0", 
 "description": "插件描述",
 "icons": { "48": "icon.png" },
 "content_scripts": [
  {
   "all_frames" : true,
   "matches": ["http://*"],
   "js": ["haha.js"],
   "run_at": "document_end"
  }
 ]
}

另外,在同目录下放入一个icon.png图片,至此,所有文件都准备完毕,目录如下:

谷歌Chrome浏览器扩展程序开发小记

打开Chrome的扩展程序列表的开发者模式》大包扩展程序...,在扩展程序根目录中输入上面三个文件所在的父目录。

谷歌Chrome浏览器扩展程序开发小记

谷歌Chrome浏览器扩展程序开发小记

点击【打包扩展程序】即可。

说明:如果点击该按钮长时间未能反映,可以能是你的chrome不允许第三方非认证的扩展程序,解决方案是,点击chrome快捷方式右键》属性》目标输入框后面追加“ enable-easy-off-store-extension-install”,注意前面的空格。

谷歌Chrome浏览器扩展程序开发小记

然后再尝试以上步骤就行了。

第三步,防止Chrome屏蔽非官方扩展程序 设置

Chrome会提示暂停非官方扩展程序,每次启动就有提示,很烦人。

谷歌Chrome浏览器扩展程序开发小记

查找资料:http://www.itechzero.com/prevent-chrome-shielding-unofficial-extensions-tutorial.html(防止Chrome屏蔽非官方扩展程序教程)

根据以上资料说明,可以轻松解决这个问题。

至此,该可扩展程序全部完成,结果图如下:

谷歌Chrome浏览器扩展程序开发小记

Javascript 相关文章推荐
DOMAssitant最新版 DOMAssistant 2.5发布
Dec 25 Javascript
基于jquery的关于动态创建DOM元素的问题
Dec 24 Javascript
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
Feb 27 Javascript
Jquery.Form 异步提交表单的简单实例
Mar 03 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
Jan 19 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
js和jquery实现监听键盘事件示例代码
Jun 24 Javascript
JavaScript模拟鼠标右键菜单效果
Dec 08 Javascript
Vue方法与事件处理器详解
Dec 01 Javascript
jQuery实现web页面樱花坠落的特效
Jun 01 jQuery
JS实现的字符串数组去重功能小结
Jun 17 Javascript
JS自定义对象创建与简单使用方法示例
Jan 15 Javascript
JavaScript类型系统之基本数据类型与包装类型
Jan 06 #Javascript
4种JavaScript实现简单tab选项卡切换的方法
Jan 06 #Javascript
js针对ip地址、子网掩码、网关的逻辑性判断
Jan 06 #Javascript
js判断当前页面在移动设备还是在PC端中打开
Jan 06 #Javascript
js判断当前页面用什么浏览器打开的方法
Jan 06 #Javascript
javascript中闭包(Closure)详解
Jan 06 #Javascript
果断收藏9个Javascript代码高亮脚本
Jan 06 #Javascript
You might like
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php Smarty 字符比较代码
2011/02/27 PHP
根据ip调用新浪api获取城市名并转成拼音
2014/03/07 PHP
XHTML下,JS浮动代码失效的问题
2009/11/12 Javascript
jQuery的css() 方法使用指南
2015/05/03 Javascript
uploadify多文件上传参数设置技巧
2015/11/16 Javascript
javascript用正则表达式过滤空格的实现代码
2016/06/14 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
getElementById().innerHTML与getElementById().value的区别
2016/10/27 Javascript
jquery 正整数数字校验正则表达式
2017/01/10 Javascript
jQuery为DOM动态追加事件的方法
2017/02/16 Javascript
纯js实现动态时间显示
2020/09/07 Javascript
js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
2018/01/09 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
js最全的数组的降维5种办法(小结)
2020/04/28 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
浅谈vue 多个变量同时赋相同值互相影响
2020/08/05 Javascript
深入解析Python中的集合类型操作符
2015/08/19 Python
python使用turtle绘制分形树
2018/06/22 Python
Python3爬虫学习之MySQL数据库存储爬取的信息详解
2018/12/12 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
python实现弹跳小球
2019/05/13 Python
如何通过雪花算法用Python实现一个简单的发号器
2019/07/03 Python
python装饰器代替set get方法实例
2019/12/19 Python
利用python中集合的唯一性实现去重
2020/02/11 Python
python中pow函数用法及功能说明
2020/12/04 Python
西雅图电动自行车公司:Rad Power Bikes
2020/02/02 全球购物
甜点店创业计划书
2014/01/27 职场文书
2015应届毕业生求职信范文
2015/03/20 职场文书
安全教育的主题班会
2015/08/13 职场文书
李白经典诗之一:全文无一“月”字,却句句有月
2019/07/12 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
创业计划书之美容店
2019/09/16 职场文书
假如给我三天光明:舟逆水而行,人遇挫而达 
2019/10/29 职场文书
分享一些Java的常用工具
2021/06/11 Java/Android