前言
你好呀,首先很荣幸你能点开这篇文章。开设这个专栏的目的目前不为别的,就为记录每周在前端领域的知识整理和对旧项目的复盘,同时作为对自己的督促。倘若文章内容能给到你一点启发,你能给出一个表示认可的赞同或收藏,那就是我的意外收获了。同时也欢迎您对文章内可能出现的纰漏提出指正或者对文章内的相关知识提供更好的材料或个人见解,大家可以一起讨论一起学习。
关键词:浏览器事件、数据可视化、echarts
正文
tab键实现焦点转换背后的浏览器事件整理
整理原因
逛知乎web端时偶然触发到了键盘的tab键,发现可以实现焦点的切换,于是引发了我整理浏览器事件的想法。
参考资料
《JavaScript高级程序设计(第四版)》第十七章、Winter极客时间《重学前端》专栏《浏览器事件:为什么会有捕捉过程和冒泡过程》、CSDN上网友整理好的浏览器事件总结。
整理结果
事件与事件流的定义
在具体了解浏览器事件前我们先来了解事件,JavaScript 与 HTML 的交互是通过事件实现的,事件代表文档或浏览器窗口中某个有意义的时刻。可以使用仅在事件发生时执行的监听器(也叫处理程序)订阅事件。
有如下 HTML 页面:
<!DOCTYPE html>
<html>
<head>
<title>浏览器事件</title>
</head>
<body>
<div id="myDiv">点击我</div>
</body>
</html>
而事件流描述了页面接收事件的顺序,DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供了可能。然后,实际的目标元素接收到事件。最后一个阶段是冒泡,最迟要在这个阶段响应事件。以前面那个简单的 HTML 为例,点击div元素会以如下图所示的顺序触发事件。
在 DOM 事件流中,实际的目标(div元素)在捕获阶段不会接收到事件。这是因为捕获阶段从
document 到html再到body就结束了。下一阶段,即会在div元素上触发事件的“到达目标” 阶段,通常在事件处理时被认为是冒泡阶段的一部分(稍后讨论)。然后,冒泡阶段开始,事件反向传播至文档。
事件处理程序
事件处理程序的赋值和移除定义了两个方法:addEventListener()和 remove- EventListener()。这两个方法暴露在所有 DOM 节点上,它们接收 3 个参数:事件名、事件处理函数和一个布尔值,true 表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序。 ,可以这样写:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>button</button>
</body>
<script>
document.body.addEventListener("click", () => {
console.log("at catch status1")
}, true);
document.addEventListener("click", () => {
console.log("at catch status11")
}, true);
document.body.addEventListener("click", () => {
console.log("at bubble status2")
}, false)
document.addEventListener("click", () => {
console.log("at bubble status22")
}, false)
</script>
</html>
//控制台输出结果
at catch status1
at catch status11
at bubble status22
at bubble status2
//很清楚的对应了上图的执行顺序
举栗说明:之前用vue实现购物小程序时需要实现类似于下图这样的长按商品出阴影效果,当时组件结构为父组件:商品列表,内歉套子组件:商品卡片。当我设置长按商品卡片的监听事件时所有的卡片都出现了阴影。这颗小栗子体现了事件的冒泡。
解决办法:
1.在子组件对应的事件触发标签内加入:@事件名称.stop="需要阻止冒泡的函数或式子",如’@click.stop="doThis"’
2.event.stopPropagation( )
3.event.target
方法2、3栗子可参考网友博客:www.cnblogs.com/gopark/p/95…
浏览器事件
事件的来源一般来自输入设备如: 鼠标、键盘。 本文的小主角Tab键被用来切换到下一个可聚焦的元素,焦点系统占用了tab键,但是可以用JavaScript来阻止这个行为。 浏览器API也提供了API来操作焦点,如: document.body.focus(); document.body.blur(); 贴上CSDN上网友整理好的浏览器事件总结
echarts疫情可视化项目复盘
复盘原因
找前端暑期实习时某企业服务型公司技术栈要求中有一条是:具备前端建模能力(对应的业务需求即实现前端的数据可视化),于是在准备面试过程中复盘了2020年初在数据可视化方面的尝试:仿腾讯新闻用echarts实现中国疫情数据可视化——项目地址: github.com/lifan2000/e… (欢迎star,开箱前请阅读readme使用说明或阅读下方复盘结果中的开箱方法);
参考资料
echarts官网、《JavaScript高级程序设计(第四版)》第十八章、如何挑选数据可视化框架及平台——前端篇。
复盘结果
项目介绍
项目技术栈为jquery+HTML5+sass,使用的数据可视化库是echarts,打包工具为webpack。页面中列出了中国疫情现状数据和中国各省疫情可视化地图,地图可实现”现有疫情“和”累计确诊“两种模式的切换,鼠标移动到各省市即可显示具体数据。npm start正常启动后更新代码,页面可以实现同步更新。
可实现疫情地图实现代码位于/src/js/echarts.js;实现随浏览器宽度等比例缩放页面以及切换地图时按钮样式等其他前端交互效果的代码位于/src/js/front.js,均做了较为详细的中文注释可供参考,webpack详细配置位于/webpack.config.js。
注意:启动后由于接口响应时间较长,所以需要等待20s-30s左右拿到数据
项目地址: github.com/lifan2000/e…
项目参考架构地址:github.com/xxhomey19/b…
使用的接口地址:lab.isaaclin.cn/nCoV/api/ar…
对接口感兴趣的同学可以前往:lab.isaaclin.cn/nCoV/zh 了解接口项目和原作者
开箱方法
在新建的文件夹下使用:
$ git clone https://github.com/lifan2000/epidemicIntimeSituation
$ cd epidemicIntimeSituation
$ yarn install(或npm install)
$ npm start
三条命令完成后即自行在浏览器启动本地8080端口。
项目相关知识延伸
数据可视化
数据可视化可分为两大类,一类是面向开发者的可视化库,如D3和Echarts等;因一类是面向分析师和一般使用者的可视化平台Grafana、Superset 等。 这篇文章有详细介绍各大面向开发者的可视化库的优缺点和来源,涨知识了,分享给大家:如何挑选数据可视化框架及平台——前端篇
Echarts
本次项目使用的echarts由百度商业前端团队研发,在 2018 年进入 Apache 孵化器。官方文档比较详尽且实例也很好上手,推荐:
五分钟上手echarts快速入门。
HTML canvas元素
echarts实现了根据设定的参数在指定id的canvas元素作画的功能。创建原生的canvas需要设置其 width 和 height 属性,这样才能告诉浏览器在多大面积上绘图。出现在开始和结束标签之间的内容是后备数据,会在浏览器不支持canvas元素时显示。比如:
<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>
与其他元素一样,width 和 height 属性也可以在 DOM 节点上设置,因此可以随时修改。整个元素还可以通过 CSS 添加样式,并且元素在添加样式或实际绘制内容前是不可见的。 要在画布上绘制图形,首先要取得绘图上下文。使用 getContext()方法可以获取对绘图上下文的引用。对于平面图形,需要给这个方法传入参数"2d",表示要获取 2D 上下文对象:
let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas>
if (drawing.getContext) {
let context = drawing.getContext("2d");
// 其他代码
}
使用canvas元素时,最好先测试一下 getContext()方法是否存在。有些浏览器对 HTML 规范中没有的元素会创建默认 HTML 元素对象。这就意味着即使 drawing 包含一个有效的元素引用, getContext()方法也未必存在。 可以使用 toDataURL()方法导出canvas元素上的图像。这个方法接收一个参数:要生成图像的 MIME 类型(与用来创建图形的上下文无关)。例如,要从画布上导出一张 PNG 格式的图片,可以这样做:
let drawing = document.getElementById("drawing");
// 确保浏览器支持canvas
if (drawing.getContext) {
// 取得图像的数据 URI
let imgURI = drawing.toDataURL("image/png");
// 显示图片
let image = document.createElement("img"); image.src = imgURI; document.body.appendChild(image);
}
浏览器默认将图像编码为 PNG 格式,除非另行指定。Firefox 和 Opera 还支持传入"image/jpeg" 进行 JPEG 编码。因为这个方法是后来才增加到规范中的,所以支持的浏览器也是在后面的版本实现的, 包括 IE9、Firefox 3.5 和 Opera 10…… canvas元素常用于生成海报、绘制图像等功能,其余详细介绍可见菜鸟教程或《js高级程序设计》第十八章。
觉得与canvas有关的比较有意思的项目推荐: HTML5canvas实现绘图板、小程序如何生成海报分享朋友圈
后续
本周也会挑出一个之前自己做的旧项目复盘,同时如果有新的发现也很愿意记录下来分享给大家。祝大家这周学习工作愉快,我们下周一见:)