作为一名前端,开发web页面是我们的本职工作。在完成一个页面开发的过程中,保存代码然后手动刷新页面查看效果,这样的动作需要重复无数次,虽然一次这样的动作可能只要花费几秒钟的时间,但是次数多了也挺浪费时间的。

社区有一款工具可以帮助前端在每次保存完代码后自动刷新浏览器页面——livereload。

自动刷新工具

目前有很多的工具都内置了自动刷新功能,以下列举几个常见的。

  1. 浏览器插件liveReload
  2. webpack的webpack-dev-server模块
  3. gulp的gulp-livereload模块
  4. grunt的grunt-livereload模块
  5. 全局模块puer

这样的工具有很多,个人觉得最方便的要数puer,只要全局安装并在工程根目录下运行即可,效果如下。

图1

自动刷新原理

社区里大多数的自动刷新工具都是使用livereload实现的,下面我们就分析一下它的内部原理是什么?

阅读本节需要先了解服务器推送和文件修改监听,如果你还没有学习,可以先看看以下文章。

  • 详解前端如何搭建一个websocket服务器
  • 前端如何实时监听本地代码文件的修改变动?——chokidar模块详解

场景:当在编辑器中修改文件内容并保存时,浏览器自动刷新页面;

分析:监听文件的修改,并且把修改的动作通知浏览器。监听操作可以用chokidar模块完成,通知操作可以用websocket来做。

根据以上的分析,我们要搭建一个小服务器,这个服务器可以访问被修改的文件、监听文件修改以及与浏览器通信。

浏览器这边通过websocket接收服务器传来的指令来刷新页面内容,页面刷新的逻辑可以封装在livereload.js中,这是一个单独的js文件,可以由html文件引入。

整个流程如下图。

图2

自动刷新实现

1、服务端代码实现

1)搭建服务器

图3

启动图3中的服务,通过localhost:3000可以访问图左侧html和css两个文件,这两个文件代表需要开发的代码。

2)再搭建一个服务器,用于页面访问livereload.js

图4

此处用于图7中html引入livereload.js。

3)搭建websocket服务器

本文搭建websocket服务器不再一步步手写,而是直接采用ws模块,如下:

图5

图5中封装了一个send方法,用于向页面发送刷新通知。

4)监听代码文件的变化

图6

chokidar模块监听代码文件的变化,其监听的目录和参数配置可以自定义。filterRefresh调用了图5中定义的send函数,用于发送指令,指令的数据格式也可以自定义,只要页面能解析出来即可。

2、浏览器端代码实现

1)开发页面中引入livereload.js

图7

这一步在webpack、fis3等构建工具中都是自动化插入的,无需手动操作。

2)livereload.js中实现websocket连接

图8

此处页面接收来自服务器的指令,然后把它解析出来执行即可。核心指令当然是reload,但是不同的资源刷新的方式有所不同,下面会详细介绍。

3)直接刷新页面

图9

4)刷新chrome插件

图10

5)更新img标签中的图片

图11

document.images可以获取文档中所有图片的dom对象,将每个图片地址加一个版本号即可刷新。

这里获取的图片可能不是本次修改的,那么如何获取当前被修改的文件呢?

如果图片是自动刷新服务的资源,那么它的src应该是localhost:3000/图片的路径/图片名称。

图6中websocket传给页面的数据中包含了文件在代码目录下的路径,如果被监听的目录下的图片被修改,那么它的路径(/home/用户名/图片的路径/图片名称)和src会有一段重合的部分,反之,就不会有重合的部分。这里就用这个小技巧来排除不需要更新的图片。

6)更新行内样式中的背景图

图12

图13

document.querySelectorAll(`[style*=${selector}]`)可以获取拥有style属性的dom,然后通过dom对象的style属性可以获取style属性包含的样式,再通过具体的css样式属性就可以获取具体的样式的值,最后通过正则将背景图匹配出来并加上版本号。

图14

7)更新内嵌和外链样式中的背景图

图15

图16

document.styleSheets可以获取所有的内嵌和外链样式,再通过cssRules和style属性可以获取一组样式表,剩下的处理就和图13一致了。

注意:如果遇到了import或者媒体查询media,需要做递归获取样式表,这里就不再嗷述了。

8)更新外链样式(不包含import)

图17

document.getElementsByTagName('link')可以获取所有的外链css,通过path和href的对比可以过滤出本次修改的css文件,然后将外链css的href加上版本号并重新生成一个link标签插在之前外链样式之后,待新css资源加载完成就可以删除之前的css资源了。

8)更新外链中import中的样式

图18

document.querySelectorAll('link')[i].sheet.cssRules[i].href 这样的写法可以获取到import进来的css的url。

图20

总结

浏览器自动刷新功能需要服务端和浏览器端配合实现,服务端的实现比较简单,最大的难点在于浏览器端对css的操作。如果每次只是暴力的刷新整个页面,不考虑对精准资源的刷新,可能无法保持页面中已存在的一些状态。

现在有条件的公司一般都会给程序员配备一台mac加一个大屏显示器,就像下面这样。

图21

一个屏幕打开编辑器,另外一个屏幕打开浏览器,保存代码后只要转一下头就能看见页面刷新,不用再在一个屏幕上切来切去,开发效率直线上升。

自动刷新的原理也是一个面试题,如果你理解了上面的实现原理,以后再碰见这道题,肯定so easy!

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

js 刷新页面但是不闪烁_前端开发还在手动刷新页面?手把手教你搭建一个自动刷新工具...相关推荐

  1. vue 前端显示图片加token_vue+node.js手把手教你搭建一个直播平台(二)

    上一期,帅气的小羽给老铁们介绍了直播平台的项目的后端搭建,这期就让小羽带大家来搭建一下前端的框架. 1.创建前端工程 毫无疑问,搭建一个项目的框架,那第一步肯定是得创建一个工程啦.cmd命令,输入vu ...

  2. axios下载图片 node_vue+node.js手把手教你搭建一个直播平台(二)

    上一期,帅气的小羽给老铁们介绍了直播平台的项目的后端搭建,这期就让小羽带大家来搭建一下前端的框架. 1.创建前端工程 毫无疑问,搭建一个项目的框架,那第一步肯定是得创建一个工程啦.cmd命令,输入vu ...

  3. vue+node.js手把手教你搭建一个直播平台(二)

    上一期,帅气的小羽给老铁们介绍了直播平台的项目的后端搭建,这期就让小羽带大家来搭建一下前端的框架. 1.创建前端工程 毫无疑问,搭建一个项目的框架,那第一步肯定是得创建一个工程啦.cmd命令,输入vu ...

  4. vue+node.js手把手教你搭建一个直播平台(一)

    上一期,帅气的小羽给老铁们简单介绍了项目的功能以及需要用到的一些环境和工具,现在就让我们荡起双桨,撸起袖子,准备开始敲代码啦!!! 先甩锅,小羽主要是搞前端开发的,所以这期张主要讲后端内容,可能讲的不 ...

  5. js访问对方手机文件夹_前端开发——解决vue首次访问太慢的问题

    一.问题:vue也算是现在流行的前端框架,vue打包时(npm run build),会生成一个index.html静态页面和一个静态文件夹,文件夹中有css,js,img等等,其中让我们注意的就是J ...

  6. vue+node.js手把手教你搭建一个直播平台(四)

    上一期,帅气的小羽给老铁们介绍了直播平台的项目的前端页面的初步切图,这期就让小羽带大家接入直播相关的api接口.敲黑板!敲黑板!敲黑板!重点来啦~ 1.api接口相关 在src目录下个新建api文件夹 ...

  7. vue+node.js手把手教你搭建一个直播平台(三)

    上一期,帅气的小羽给老铁们介绍了直播平台的项目的前端框架的搭建,这期就让小羽带大家切图,没错啦,就是老铁们心心念念的切图啦. 补充上期遗漏的内容 但是在正式开启这期内容前,先补充点上期的内容 配置全局 ...

  8. JS实现仿新浪微博大厅和腾讯微博首页滚动效果_前端开发

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. 人工智能实战小程序之语音_前端开发

    1. 人工智能实战小程序之准备工作 2. 人工智能实战小程序之语音_前端开发 今天这部分主要讲小程序前端功能的开发 由于我偏后端,css是我的弱项,可能很多人和我一样开发小程序不知道如何下手,希望本篇 ...

最新文章

  1. mysql whrere 占位_【MySQL】(4)操作数据表中的记录
  2. springmvc常用5种注解_砂石骨料线常用的5种破碎设备、5种筛分和制砂设备特点比较...
  3. 第五章 软件下载与安装(二、VM安装Ubuntu16.4)
  4. Oracle备份与恢复 expdp/impdp数据泵远程导入导出
  5. 李迟2011年4月知识积累
  6. IAR 的精确延时程序(转)
  7. linux内核中等待队列(wait_event,wake_up...)
  8. linux系统镜像怎么安装,linux系统安装,怎样安装linux系统制作方法
  9. Xshell免费学生版
  10. VS2010 安装OpenCV2.4.0教程
  11. QuickEdit-手机端强大的代码编辑器
  12. 通过http网页链接下载单词音频文件
  13. linux如何打开pkg软件,Linux系统pkg
  14. vs商业智能项目的安装
  15. c/c++ 头文件(.h)、源文件(.cpp)书写及接口与实现分离实例
  16. Face Swapping: Automatically Replacing Faces in Photographs论文阅读
  17. 运行 vue-typescript-admin-template 报错 error Command failed with signal “SIGABRT“. 切换node版本
  18. 雍正杀“舅”:握着领导把柄,隆科多必须死?
  19. 2008-2020年800+商业银行财务面板数据
  20. GIC/ITS代码分析(1)MADT表

热门文章

  1. GPU上的快速光谱图分区
  2. TensorRT 7.2.1 开发概要(上)
  3. 将人工智能模型压缩到微控制器中
  4. 卷积神经网络模型可解释性
  5. 2021年大数据Spark(二十九):SparkSQL案例四开窗函数
  6. python可视化来分析全国疫情
  7. Python:Scrapy Shell
  8. Android 接口回调
  9. git user name is not defined
  10. python学习day24 继承 派生