CSS3+JS 实现的便签应用
概述
详细
一、准备工作
1、开发工具Sublime+一个能打开网页的现代浏览器
3、使用 localStorage 存储便签
二、程序实现
1、首先,我们创建三个目录,第一个目录是 css ,用于存放 css 样式文件。第二个目录是 images ,用于存放程序中使用到的图标。第三个目录是 js ,用于存放程序中使用到的 js 文件,当然还有一个 index.html 存放在根目录下。
2、程序的实现思路很简单,我们只要在js中完成三个功能即可:
第一,就是获取DOM元素,用于为页面中的控件设置动作。
第二,建立 Note 控制中心,用于控制便签的存储,读取,修改和删除。
第三,页面初始化。
3、在讲代码之前,我们首先看看整个程序的运行效果。
HTML代码:其结构也很简单,在刚开始没有便签记录的时候,只需要有一个文本输入框和一个保存按钮即可,然后为便签记录设置一个无序列表,并且在 CSS 中为其制定样式,下面是我的 HTML 结构
1 2 3 4 5 6 7 8 9 10 11 12 13 | < article id="task-container"> < header > < h1 >备忘录</ h1 > </ header > < section id="task-input"> < input type="text" name="content" id="input-content" placeholder="请输入要保存的内容"> < button id="task-submit">保存</ button > </ section > < section id="task-list"> < ul id="list-content"> </ ul > </ section > </ article > |
CSS 代码主要关注三点:
第一点:样式重置,在这里使用了 normalize
第二点:动画效果,在删除便签,添加便签,编辑便签,删除便签时都有动画效果,这主要是为了改善用户体验
第三点:针对响应式,我这里设置的也比较简单,就是针对屏幕分辨率低于 700px 的时候,改变便签列表的宽度,以达到适应屏幕的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 | @media only screen and ( max-width : 700px ) { #task-container, aside#task-detail .detail-container{ width : 90% ; } aside#task-detail .detail-container { padding : 12px 8px ; } #delete-container { width : 80% ; } } |
还有一点值得注意的是,每个便签目录以一行的形式显示,如果字数超过一行该怎么办呢?很普遍的,大家都把超出的那部分用省略号代替,其核心代码如下所示
1 2 3 | white-space : nowrap ; text- overflow : ellipsis; overflow : hidden ; |
JS实现:关于JS 的实现,我们上面提到了需要关注三点,下面就来讲讲这三点的核心实现:
第一点,关于DOM元素如何获取就不在详细说了,直接使用 document.getElementById(name) 即可,关键是各个浏览器对事件的设置是不同的,所以为了兼容 Netscape 和 IE 阵营,我们需要手写兼容代码,毕竟我们没有使用 JQuery。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | var EventHandler = ( function () { function addHandler(element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false ); } else if (element.attachEvent) { element.attachEvent( "on" + type, handler); } else { element[ "on" + type] = handler; } } function removeHandler(element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false ); } else if (element.detachEvent) { element.detachEvent( "on" + type, handler); } else { element[ "on" + type] = null ; } } function getEvent(event) { return event? event : window.event; } function getTarget(event) { var event = getEvent(event); return event.target || event.srcElement; } return { "addHandler" : addHandler, "removeHandler" : removeHandler, "getEvent" : getEvent, "getTarget" : getTarget }; })(); |
第二点就是建立便签的控制中心,其实也很简单,只不过是 localStorage 的几个 api 使用而已,最主要的还是 setItem 和 getItem。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | var NoteControl = ( function () { var Note = function (title, desc) { this .title = title; this .desc = desc; this .date = "" ; }; var addNoteToDOM = function (note, noteKey) { var title = note.title; var liElement = document.createElement( "li" ); liElement.classList.add( "task-item" ); liElement.setAttribute( "id" , noteKey); liElement.innerHTML = '<span class="content">' + title + "</span>" + '<span class="edit"></span>' + '<span class="delete"></span>' ; listContent.insertBefore(liElement, listContent.firstElementChild); return liElement; }; var deleteFromDOM = function (liElement) { listContent.removeChild(liElement); }; var getKeysArray = function () { var keysArray = localStorage.getItem( "noteKeysArray" ); if (!keysArray) { keysArray = []; localStorage.setItem( "noteKeysArray" , keysArray); } else { keysArray = JSON.parse(keysArray); } return keysArray; }; function showAllNotes() { var noteKeysArray = getKeysArray(), length = noteKeysArray.length, note, key; for ( var i = 0; i < length; i++) { key = noteKeysArray[i]; note = JSON.parse(localStorage.getItem(key)); var liElement = addNoteToDOM(note, key); } } function saveNote(title, desc) { var note = new Note(title, desc), noteKey = "note_" + new Date().getTime(), keysArray = getKeysArray(); keysArray.push(noteKey); localStorage.setItem( "noteKeysArray" , JSON.stringify(keysArray)); localStorage.setItem(noteKey, JSON.stringify(note)); var liElement = addNoteToDOM(note, noteKey); } function deleteNote(liElement) { var keysArray = getKeysArray(), key = liElement.id, length = keysArray.length; localStorage.removeItem(key); for ( var i = 0; i < length; i++) { if (keysArray[i] === key) { keysArray.splice(i, 1); } } localStorage.setItem( "noteKeysArray" , JSON.stringify(keysArray)); deleteFromDOM(liElement); } function saveNoteById(id, note) { localStorage.setItem(id, JSON.stringify(note)); } function getNoteById(id) { return JSON.parse(localStorage.getItem(id)); } return { "saveNote" : saveNote, "showAllNotes" : showAllNotes, "deleteNote" : deleteNote, "getNoteById" : getNoteById, "saveNoteById" : saveNoteById }; })(); |
还有一点值得注意的是,上面的代码只是我们书写了自己使用的 api ,至于各个按钮的监听控制程序,还需要另外书写程序代码,比如我们监听保存按钮的事件需要像下面这样书写。
1 2 3 4 5 6 7 8 9 10 11 12 13 | function save() { var title = inputContent.value; if (title.trim() !== "" ) { NoteControl.saveNote(title, "" ); inputContent.classList.remove( "invalid" ); inputContent.setAttribute( "placeholder" , "请输入要保存的内容" ); } else { inputContent.classList.add( "invalid" ); inputContent.setAttribute( "placeholder" , "内容为空,请重新输入" ); } inputContent.value = "" ; } |
三、运行效果
下载附件后,双击index.html即可运行。
首先,看看该程序各个部分的截图
如果你觉得还不过瘾,你可以在线体验,体验地址如下:https://hwaphon.github.io/Html5LocalStorage/2.0/index.html
四、其他补充
-
关于每个便签目录的信息编辑,注意考虑闭包问题。
-
注意动态设置 input placeholder 的颜色
-
为了支持手机端,别忘记在 html 文件中添加如下代码
1 | < meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no,maximum-scale=1.0"> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?