pekonchan
pekonchan
## 前言 最近在封装一个自定义滚动条容器,打算以后用它来取代常用的`div`标签,因为在Window上的浏览器的确比较丑,为了跟mac里的滚动条尽量保持一致,自己动手封一个。 写该篇文章目的有俩 1. 方便以后自己再做类似的工作好来个回顾,避免频繁查阅各种资料 2. 在动手时发现现有网络资源的一些不足之处,在这里加以补充和描述,希望后来之人在查阅资料时能看到这篇文章就能满足所需。 简单说下目前一些网络资料待加强的地方,我这里会针对这些问题弥补一下 - 只有容器内滚动(如鼠标滚轮滚动引起),自定义滚动条按比例移动的实现方案 - 只有点击自定义滚动条拖动,容器内容要滚动的实现方案 - 以上两个方案没有合并一起提供完整方案 - 各种计算标准,眼花缭乱,最好提供一更好理解的一些标准计算 - 有些方案是针对特定的场景,没有考虑全面,例如仅针对bod页面垂直滚动条,我们这里要考虑的是把所有滚动条都变成自定义 - 没有针对内容变化,继而改变滚动条高度 - 没有做一些兼容处理 ## 组件 开始文章之前,我想介绍一下我用`vue`封装的一个自定义容器组件。方便可能有些人可能只想找这么一个现成的解决方案组件,而不想细看其中的来龙去脉。 请戳 [npm地址](https://www.npmjs.com/package/vue-scroll-div) 而且,这个组件比下面讲解的解放方案会有更多优化工作,毕竟为了方便大家理解,过多的拓展优化我就不在这篇文章里一一介绍。 ###...
# 前言 当你的系统需要做权限验证时,往往有一个很常见的需求:系统的某些页面或者资源(按钮、操作等),需要该用户有对应的权限才能可见可用。 这就涉及到如何根据用户的权限来判断能否进入某个路由页面的问题了。 **网上有很多零散的方案,并没有横向对比几种方案,且很多细节没解释到位,此处提供完整的几个方案流程,并总结优缺点,你可自行选择** 本篇是针对`vue-router`来说明如何实现。 # 解决方案 根据各种资料,这里分为三种解决方案来分别描述其优缺点。 ## beforeEach中限制 你可以注册全部路由,在`router.beforeEach`中即进入路由前进行判断,即将进入的路由是有权限进入,不能的话手动重定向到某个静态路由(不需要权限就能进入的页面,即任何用户都能进入的页面,如404页或首页) 由于每个系统的权限方案不一样,判断条件也不一样,这里就仅仅简单举个例子,万变不离其宗,希望大家举一反三,触类旁通。 我们在`router.beforeEach`判断是否有权限进入,需要有三点: 1. 在路由配置中做标识,告知该路由需要的权限 2. 需要一处地方记录该用户所拥有的权限信息 3. 在`router.beforeEach`结合第1点和第2点进行判断 ### 1)路由配置中做标识 假设项目的权限是用ID来表示,即每个权限,用一个ID值来表示。 我采用路由配置的`props`项来做标识,`authorityId`值表示权限对应的ID值。 ```js import Vue from 'vue'; import...
# 前言 在前端站点上下载文件,这是一个极其普遍的需求,很早前就已经有各种解决方法了,为什么还写这么老的文章,只是最近在带一个新人,他似乎很多都一知半解,也遇到了我们必经问题之“不能下载txt、png等文件”的典型问题,我就给他总结下下载的几个方式。顺便分享出来,也许,真有人需要。 # form表单提交 这是以前常使用的传统方式,毕竟那个年代,没那么多好用的新特性呀。 道理也很简单,为一个下载按钮添加`click`事件,点击时动态生成一个表单,利用表单提交的功能来实现文件的下载(实际上表单的提交就是发送一个请求) 来看下如何生成一个表单,生成怎么样的一个表单: ```js /** * 下载文件 * @param {String} path - 请求的地址 * @param {String} fileName - 文件名 */ function downloadFile (downloadUrl, fileName) {...
在理解重排与重绘之前,首先要理解页面渲染的一个简单过程以及涉及到的一些基础知识 ### 页面渲染的简单过程 1. 浏览器把HTML源代码解析,并且创建一个DOM树(DOM tree) 2. 浏览器把CSS源代码解析,并且创建一个CSSOM树 3. 根据DOM树和CSSOM树生成渲染树(`render tree`) 4. 根据渲染树生成布局并将布局绘制到浏览器界面上 `render tree`和DOM树的关系可以这么描述: ``` DOM树可视部分会形成render tree,因为render tree也是基于样式的 ``` 如DOM树中的某些节点的样式是`display:none`的,那么该节点就不存在与`render tree`里了。 还有就是``标签内的信息由于浏览器页面可视区域不会显示出来,他们这些节点也不会存在于`render tree`里。 重排和重绘都会引起上述的第四步,要重新生成布局并绘制到浏览器上,此外,**更主要的是ui线程和js线程是互斥的,重排重绘的频繁触发,引起频繁的ui渲染,会导致js执行变慢。** ### 重排(reflow) 好了我们知道了一些背景知识后,来认识下重排。概念上理解: ``` 改变构成渲染树的信息,导致部分渲染树节点或全部渲染树需要重新分析并计算尺寸位置,叫做重排...
# 前言 开门见山,相信很多人现在还看防抖和节流的知识,基本上都是在准备面试的人儿吧?为了刷题的快速,节约时间,相信很多人都是匆匆看一些文章,掌握了最基础最基础的防抖节流函数,觉得这样是ok的。实际上这是正确的选择,但是面试官基本上从这些情况就知道你是一个什么水平了,浅而不深,临时抱佛脚刷题。 **此篇介绍一个稍微深入一点,但又便于理解的防抖节流函数**,起码别让面试官觉得你很初级对吧。如果你想找个更加全面的防抖节流,意味着你要花更多时间去理解它,如果你不是仅仅为了面试而做准备,建议你去看看loadash的防抖节流函数源码 # 是什么 防抖和节流,不知道你看了很多资料的描述后(基本上大同小异),会不会还是觉得似懂非懂。 我们知道,在一个高频触发的监听事件中,会不断触发所绑定的方法,如`onscroll`、`onmouseover`、`onkeyup`等,在你连续触发该事件,就会不断执行绑定方法。也许你绑定的事件不复杂,加上浏览器性能处理越来越好,你会觉得这没什么,但是,如果绑定的方法执行的内容比较复杂,涉及DOM重排重绘严重或者请求频繁,那么如此高频触发,必将带来性能和交互的严重不友好。 为了解决出现这种情况,防抖和节流,这两种方案为此诞生。 它们都是有一个时间规定,在这个规定下限制某个方法的执行时机。 它们有个共同点,就是指定时间内,只能执行一次。 **防抖** > 指定时间内,方法只能执行一次。而这个时间的计算,是从最后一次**触发监听事件**开始算起。 > 一般表现为,在一段连续触发的事件中,最终会转化为一次方法执行,就像防止抖动一样,你做一个事,防止你手抖不小心重复干了 **节流** > 指定时间内,方法只能执行一次。而这个时间的计算,是从上次**执行方法**开始算起。 > 一般表现为,在一段连续触发的事件中,根据你设定的时间间隔,降低触发频率,重复执行。 从上面的描述我们可以理解到,他们的区别在于,如何计算时间间隔。 ### 场景 我们从实际应用中,加深一下对他们的认识。 如在一个输入框内输入文字,你想在输入停止一段时间过后再去获取数据(如过滤),而不是每输入一个文字就去请求一次,那么这时候你就可以利用**防抖**,指定`keyup`事件不断触发的过程中不要重复发请求,到最后一次停止输入再去请求。 如你需要做无限加载,监听到滚动条到达底部就加载更多数据,这时候其实你不必要时时刻刻都执行`scroll`事件绑定的函数,这样没必要,只要把执行频率降低点同样可以达到效果,节约资源。这就是利用**节流**。 # 代码实现 基础的代码我这里不说了,一堆一堆资料都会讲到,我就当你已经掌握最简单的实现方式。...
## 前言 这是一个老套的需求,jq时代就很流行的交互需求。网络上也有不少资料,我这里写这篇文章的目的更主要是针对这些资料的不足,解决一些问题: - 吸顶和滚动导航的资料都是独立的,二者作为独立功能独立分析。我这里要把吸顶功能作为滚动导航的一个功能之一,作为一整套方案来分析。 - 吸顶和滚动导航的分析,大多数是站在顶部导航的立场上写方案的,但是其实该功能,可以出现在页面的任何位置上,这些资料所写的方案缺少场景的延伸。既然要延伸了,**很多细节是需要考虑的。** - 滚动导航的介绍,往往是对传统监听`scroll`方法和`position: sticky`方法独立介绍,让读者二选一。我这里,把两个方法融合一起,让浏览器自己判断采用哪个方法,尽量采取最简单优化的`sticky`方法。 - 亲自实践,揭开`sticky`的神秘面纱,给出不同于很多资料的见解,指出一些容易误导别人的描述。 - `sticky`和传统方式的相结合。 先来看下总体效果和本次的实践目标,本文已实现改图效果教程,来理解要表达的滚动导航+吸顶的方案,这样从实践中触发讲解,比纯粹将一个抽象出来的方案要更容易让人理解。  【这里最好放个gif看效果】 由于我时隔多年再一次做这个效果,从当年大热的jq,已经变成更多框架的时代,我最后封装了一个vue的组件可供大家选择使用。 ## 需求 这里举个相对复杂点的例子,**我们不要再拘泥于顶部导航栏的这种效果,那实现比较简单,实际上这种效果可以出现在页面任何局部地方**,虽然实现本质上是一样的,但是需要注意的小细节,还是很多的。 我们要实现的目标就是上面前言里的gif图效果  我们来看下图里的`html`结构 ```html 导航1 导航2 导航3 导航1内容 导航2内容...
## 前言 当我们想用某个css新特性时,总是会在意它的兼容性情况,或许我们会去搜索它的兼容性,哪些浏览器合适哪些不合适,在这些已知的情况下再选择是不是使用或如何使用,这是一个已知我们即将用于什么浏览器下作出的选择。 但我们往往不知道自己开发的页面用户会在哪个浏览器上进行打开,这时我们需要根据实际使用浏览器情况来判断采用何策略。这时就需要用js来判断,我们要使用css属性能否起效。 css属性的兼容性,是有两类的,一类是,css属性本身,如`position`;另一类是,css属性值,如,对于`position`属性的`sticky`值 ## 目标 我们想知道某个css属性(值)是否起效,一般被告知结果是“起效”或“不起效”。但是css属性存在浏览器私有属性一说,即会有加了浏览器前缀才会生效的css属性。 所以你更加需要知道,对于目前浏览器来说,哪个前缀或不需要前缀的css属性才会起效,而不仅仅是知道起效与否(自己每个前缀作为输入值进行校验,是繁琐的!网络上的很多资料往往会告诉你是否支持你指定的css,返回的boolean值) 所以下面的方法,**只需要你把css属性(值)作为输入值,不需要带上前缀,便能告知你,当前使用的浏览器支持哪个前缀的用法或压根不需要前缀。** ## 检查css属性名 该方法检查的是css的属性本身,即属性名,即写css的时候`:`的左侧。如果返回值是空,那么证明浏览器不支持该属性。 ```js /** * 告知浏览器支持的指定css属性情况 * @param {String} key - css属性,是属性的名字,不需要加前缀 * @returns {String} - 支持的属性情况 */ function...
# 前言 上传图片生成缩略图,这个需求很常见,网络上的文章也很多。但是大多数都是直接丢一堆代码出来,也不多解释,不说下注意点,不说明优缺点等,也缺乏场景的延伸。 **我这里所写的,不仅是生成缩略图这个需求,还把验证上传文件、删除已选文件、提交上传文件的一个完整的实际流程来展开此文章。** 因为网上很多就单纯地解决一个生成缩略图的方案,但是忽略实际场景的应用,很多时候还是存在一些不足,在zheli做些小优化和做下几个方法的对比,也有一些注意点提及出来,帮助大家避坑。我看很多文章,都仅只说生成缩略图,却不告知如何配合发送数据。 好记性不如烂笔头,人老了很多会忘记,趁我人老头秃前记一下为好。 # 需求 首先要明确需求,根据需求才能确定方案: > 点击上传工具,弹出上传文件对话框,可单选可多选文件,此次选择之后生成文件的罗略图(本文主要针对图片格式文件),之后每次的选择文件上传,都会在原本已选择的基础上新增。最后把每次选择的文件一并进行上传。 要注意的一点是,在此需求中,并不是每一次的选择文件,会覆盖上次选择的文件。而是会保留上次选择的结果,然后把每次选择的结果一并提交了。要进行删除已选的文件的话,就删除缩略图即代表删除了已选文件。 需求细节分点描述: 1. 记录每次选择结果,最后一并提交 2. 每次选择可多选 3. 对选择的文件进行校验 4. 根据所选的文件生成缩略图(随机 or 根据选择顺序) 5. 点击缩略图进行预览(在文章不展开说,因为单纯是css样式即可控制,没多大难度) 6. 删除缩略图代表删除已选文件 # 生成缩略图 要生成缩略图,无非就是展示“图”。“图”的展示有两种表现形式,一个是用`img`标签来直接展示图片,一个是用`background-image`样式来展示图片。所以这里的生成缩略图,可以往这两个方向走。...
# 前言 在开发中,要进行计算,你可能会遇到小数运算,运气好的话,你的测试测不到精度问题,但其实这是很严重的,以下两个典型例子先感受以下 ``` 0.1 + 0.2 = 0.30000000000000004 35.41 * 100 = 3540.9999999999995 ``` 是不是出乎你的意料? 写这篇文章的原因是网上找了些资料,要不就是介绍不全的,要不就是存在错误的(可能大家没发现),要不就是方案还有待加强的。于是我决定自己整理出一份较为全面而不误导别人的文章出来(**文章方案对网上大部分资料存在的缺陷进行弥补增强**),如果您发现不足,请告诉我,虚心请教。 以下我们了解原因以及寻找解决方案。 # 原因 ## js的数字存储情况 在计算机中存储的信息都是二进制来表示,我们都知道,js中数字类型只有`Number`,不像其他语言如`java`有`int`、`double`类型等。它的实现遵循 IEEE 754 标准,使用64位固定长度来表示,也就是标准的 double 双精度浮点数。 其中这64位数又分为三部分(从左往右看): -...