因为工作的关系,每天都要处理很多的琐事,因为比较忙碌,经常会忘记一些事情。所以做一个简单的todoList的想法应运而生。大概的功能就是添加待办事项,按预设的时间周期弹出提示。
需求很简单,但是要用什么实现呢?如果做成独立的应用,一定会随着时间的推移被逐渐丢弃在角落。
所以决定做成chrome的扩展程序,依托于浏览器,随时取用。
manifest.json
每一个chrome扩展都包含一个Manifest文件,这个文件可以告诉chrome关于这个扩展的相关信息,它是整个扩展的入口,也是chrome扩展必不可少的部分。
在manifest.json
中我们指定扩展的名称、版本,图标以及background
和popup
的路径等信息。
其中,popup
是点击浏览器右上角的扩展图标时显示的界面,background
是常驻后台的js文件,它们的具体用处下文再叙述。
{
"name": "todoList",
"description": "工作待办事项管理工具",
"version": "1.0.1",
"manifest_version": 2,
"icons": {
"16": "icon.png",
"48": "icon.png",
"128": "icon.png"
},
"browser_action": {
"default_popup": "popup.html" // 点击图标后弹出的界面
},
"background": {
"scripts": [
"background.js" // 常驻后台的js
]
},
"permissions": [
"contextMenus",
"notifications"
]
}
popup.html
当点击浏览器上的扩展图标时,我们希望显示todoList工具的主界面,这里正常书写html
和css
即可。
需要注意的是,chrome扩展只支持外部js,所以无法在popup.html
中书写任何的js逻辑。
css
代码这里就不再赘述了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入js -->
<script type="text/javascript" src="popup.js"></script>
</head>
<body style="width:500px;padding-top: 20px;">
<div class="centerView">
<div class="title">
<span class="title1">Todo</span><span class="title2">List</span>
</div>
<!-- 输入框添加栏 -->
<div class="infoView">
<textarea placeholder="请输入待办事项" name="inputTodoInfo"></textarea>
<div class="pflex infoView" style="justify-content:space-between">
<button class="addButton" id="addList">添加待办事项</button>
<div class="mainColor">
提醒周期
<select id="selectTime" class="mainColor">
<option value="">15分钟</option>
<option value="2">10分钟</option>
<option value="3">5分钟</option>
<option value="3">1分钟</option>
</select>
</div>
</div>
</div>
</div>
<div class="listDiv">
<div class="centerView">
<div class="title2">待办事项</div>
<!-- 待办事项列表,渲染列表 -->
<div id="todo">
</div>
</div>
</div>
</body>
</html>
界面大概是这样的:
popup.js
每添加一个待办事项,将数据存储入localstorage
中,当打开popup.html
时,先尝试读取localstorage
获取信息,并渲染。
在popup
中可以使用background
中的方法,我们把添加和获取方法都封装再来background
中,在popup中这样调用:
var bg = chrome.extension.getBackgroundPage(); // 核心api
bg.addList(todo)
popup.js
全部内容:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("addList").addEventListener("click", handler);
});
let todoList = []
function handler() {
let todoInfo = document.getElementsByName('inputTodoInfo')[0].value
if (todoInfo.length > 0) {
let selectTimeIndex = document.getElementById('selectTime').selectedIndex
let selectTime = [15, 10, 5, 1]
let todo = {
info: todoInfo,
createTime: (new Date()).getTime(),
nextTime: (new Date()).getTime() + (selectTime[selectTimeIndex] * 60 * 1000),
time: selectTime[selectTimeIndex]
}
var bg = chrome.extension.getBackgroundPage(); // 核心api
bg.addList(todo)
document.getElementsByName('inputTodoInfo')[0].value = ""
getList()
} else {
alert("还没有输入内容哦")
}
}
window.onload = function () {
getList()
}
function getList() {
let listDiv = document.getElementById("todo")
var bg = chrome.extension.getBackgroundPage(); // 核心api
todoList = bg.getList()
let todoView = ``
if (todoList.length > 0) {
for (let i = 0; i < todoList.length; i++) {
todoView += `
<div class="todo infoView">
<div class="centerView">
<div class="todoTitle">${todoList[i].info}</div>
<div class="infoView pflex">
<div style="width:50%">创建时间:</div>
<div style="width:50%">${timestampToTime(todoList[i].createTime)}</div>
</div>
<div class="infoView pflex">
<div style="width:50%">提醒周期:</div>
<div style="width:50%">${todoList[i].time}分钟</div>
</div>
<div class="infoView pflex" style="justify-content: flex-end;">
<button class="finish">完成待办</button>
</div>
</div>
</div>`
}
listDiv.innerHTML = todoView
let finishButton = document.getElementsByClassName("finish")
for (let i = 0; i < finishButton.length; i++) {
console.log(finishButton[i])
finishButton[i].onclick = function () {
finish(i)
};
}
} else {
listDiv.innerHTML = ""
}
}
function finish(i) {
todoList.splice(i, 1)
localStorage.setItem("todoList", JSON.stringify(todoList))
getList()
}
function timestampToTime(timestamp) {
var date = new Date(timestamp);
var Y = date.getFullYear() + '-';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y + M + D + h + m + s;
}
background.js
在Manifest中指定background域可以使扩展常驻后台。
在background.js
,我们每隔20秒遍历一次待办事项数组(处于性能考虑,没有必要每秒监听,所以提示时间可能会有二十秒的误差,但是使用上影响不大)。
window.setInterval(function () {
let todoList = []
let time = (new Date()).getTime()
let endTime = time + (1000 * 20)
if (localStorage.getItem("todoList")) {
todoList = JSON.parse(localStorage.getItem("todoList"))
console.log(todoList)
for (let i = 0; i < todoList.length; i++) {
console.log(time)
if (todoList[i].nextTime <= endTime) {
alert("别忘记哦," + todoList[i].info);
todoList[i].nextTime += (todoList[i].time * 60 * 1000)
}
}
localStorage.setItem("todoList", JSON.stringify(todoList))
}
}, 1000 * 20);
function addList(todo) {
let todoList = []
if (localStorage.getItem("todoList")) {
todoList = JSON.parse(localStorage.getItem("todoList"))
}
if (todoList.length >= 5) {
alert("宝贝,最多只支持五条哦")
} else {
todoList.push(todo)
console.log(todoList)
localStorage.setItem("todoList", JSON.stringify(todoList))
}
}
function getList() {
return JSON.parse(localStorage.getItem("todoList"))
}
测试
至此,我们的扩展程序已经基本完成了,一个简单的todoList。
在预设的提醒周期到了之后,会alert
出待办提示。且如果不完成待办
的话,就会一直每隔xx分钟(预设的时间),提示一次。
安装
在浏览器扩展程序页面,打开开发者模式
,将项目文件夹拖入即可。