SaveConfig
在介绍配置的导出与导入之前, 我先来介绍一下这个项目的数据存储
我秉承着一种能不用到服务器就不用服务器,能不用数据库就不用数据库的原则,想到了 localStorage
可以作为一个本地的数据库使用,每次换浏览器或设备时,只需要将 localStorage
里的数据再导入一次就好啦,因此我把这个数据称为配置(Config)
首先我们得拥有配置,所以需要有一个把 localStorage
里数据一键导出保存为一个文件的功能
该功能我是参考的 MDN 文档,你们有兴趣可以了解一下:Web API——URL.createObjectURL():https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
我大致是这样实现的:
// 封装的下载数据函数 function downLoadFile(fileName, content) { var aTag = document.createElement('a'); // 获取 a 元素 var blob = new Blob([content]); // 将数据保存在 blob 对象中 aTag.download = fileName; // 设置保存的文件名称 aTag.href = URL.createObjectURL(blob); // 将数据保存在 href 属性中 aTag.click(); // 模拟点击 a 元素,进行下载 URL.revokeObjectURL(blob); // 删除内存中的 blob 对象的数据 } // 调用下载接口 function saveConfig() { downLoadFile('nav.config.json', window.localStorage.navInfos) }
ImportConfig
既然已经手握配置文件,那么走到哪里都不怕了~ 接下来要做的就是将配置文件导入 localStorage
中
该方法是参考了 MDN 文档了的,大家可以前去了解一下:Web API——FilerReader:https://developer.mozilla.org/en-US/docs/Web/API/FileReader
我大致是这样实现的:
// 导入配置 function importConfig() { let reader = new FileReader() // 创建 FileReader 对象 let files = document.querySelector('.file').value.files // 获取已上传的文件信息 reader.readAsText(files[0]) // 读取文件内容 reader.onload = function() { // 读取操作完成的处理函数 let data = this.result // 获取文件读取结果 window.localStorage.navInfos = data // 将文件数据存入 localStorage location.reload() // 刷新页面 } }
Scroll Animation
因为我们所有的 URL
都是在一个页面内的,并且搭配着侧边栏中的按钮进行标签的跳转,即在左侧点哪个标签,右侧的内容就跳到哪个标签。刚开始我是用锚点实现的,但后来发现这样的跳转太生硬了,所以就自己简单地实现了一下跳转动画
实现原理大概是这样:右侧内容中每个标签都有带有一个 id
,并且左侧的每个按钮也是对应着各自的 id
的,所以当点击了按钮时,先获取到对应 id
的元素 el
,并获取 el
离滚动页面顶部的距离,即 el.scrollTop
,然后同时获取一下当前位置离滚动页面离顶部的距离,如下图所示:
那么我们的跳转距离就是图中的 Location - Current
我大致是这样实现的:
// 跳转到指定标签 function toID(id) { const content = document.getElementById('content') // 获取滚动页面元素 const el = document.getElementById(`${id}`) // 获取对应id的标签元素 let start = content.scrollTop // 获取当前页面离顶部的距离 let end = el.offsetTop - 80 // 获取目标元素离顶部的距离(这里的80是减去了我顶部消息栏的高度,大家可以不用管) let each = start > end ? -1 * Math.abs(start - end) / 20 : Math.abs(start - end) / 20 // 考虑滚动方向并计算总共需要滚动的距离,同时将距离平分成20份 let count = 0 // 记录滚动次数 let timer = setInterval(() => { // 设置定时器,滚动20次 if(count < 20) { content.scrollTop += each count ++ } else { clearInterval(timer) } }, 10) }
我们来看看滚动的效果如何吧~
我感觉滚动还是挺丝滑的 🤔 如果大家有更简单方便、性能更好的方法可以推荐给我
Get Icons Interface
我前面一直说,本着能不用服务器就不用服务器,能不用数据库就不用数据库的原则,但是自动获取页面图标这个功能真的没有办法了,要在浏览器端访问别人的网页还要得到 icon URL
,几乎是不可能的,因为存在跨域问题,所以我就拿自己的服务器暴露了个接口出来用于获取目标网页的 icon
地址
代码这里我就不放上了,因为也比较简单,就是访问目标网页,得到 html
文档内容,从中筛选出 icon
的地址再返回就好了,要看代码的可以在项目源码中的 app.js
中去查看
这里还要强调的是,虽然我提供了一个接口用于自动获取对方网页的图标,但是有些网页对外部来路不明的请求都做了处理,例如返回一个 403 Forbiden
把我的请求给拒绝了,因此一些无法获得的图标或者无法加载的图标,我都是用一个默认图标统一替代,虽然之前我做过挺久的爬虫,想办法对 user-agent
、referer
等请求头都做了处理了,但还是无济于事,大家如果有好的办法也可以提供给我尝试
然后给大家简单演示一下如何使用的吧~
这个动图上好像有些模糊或者是样式的变动,都是因为 gif录制器的原因哈
其它
对于这个项目,因为刚出来半个月不到嘛,肯定还有需要改进的地方,我也已经列出了之后需要继续跟进的新功能:
URL
的拖拽、排列
- 页面账号信息存储功能
- 提供更多的网址
icon
的选择
- more ……
第一个功能什么意思呢,就是我现在的项目中是不支持添加好后的 URL
重新排序的,但我觉得这个功能是一定要有的,之后会加上,打算想办法做一个在编辑状态下拖拽即可完成排列的功能
第二个功能的目的是因为对于很多个网站,你也许会有不同的账号和密码,但现在最令人头疼的就是,总是记不住这个网站我的账号或密码是啥,导致每次都要多次尝试或找回密码,特别的麻烦;所以我想做一个鼠标移到对应网址上,有一个查看此网址对应我的账号密码的功能
第三个功能就是为了针对那些无法获取 icon
的网站导致我们导航栏中显示的图标为默认图标,比较丑,所以到时候可以支持大家自行选择喜欢的图标
更多的功能还请大家多提建议啦~
最后
有些小伙伴问,为啥不做一个账号登录的网址导航栏,这样到哪都不用带着配置文件了,只需要记住账号密码就可以了。我又要强调本项目的选择了,能不用服务器就不用服务器,能不用数据库就不用数据库,用你自己的本地的 localStorage
作为数据库存储,你不是更放心嘛,比如你收藏了一些奇奇怪怪的网站,反正就只有你知道,我反正肯定是不知道的 😏 而且细心的小伙伴有没有发现,我连静态页面都不是用的自己的服务器,直接部署在码云上的
自学前端这么久了,之前一直做着别人的项目或是模仿一些网站做一个项目,细数一下有这么几个:淘宝首页静态页面、蘑菇街移动端APP、node社区、elementUi组件以及组件文档展示等等,这次这个项目也算属于我自己的了,而且对于我来说是非常实用的一个小工具了,希望大家多多支持~ 给我提提意见,可以的话点个 star 🤞