分类
CSS 总结

css技术沉淀

基础理论

元素的显示与隐藏

根据不同的需求选择隐藏方案

如果希望元素不可见,同时不占据空间,辅助设备无法访问,同时不渲染,使用script标签隐藏

<script type="text/html">
      <img src="./img/55.png" />
</script>

获取数据的方法使用 document.querySelector(‘script’).innerHTML 如果希望元素不可见,同时不占据空间,辅助设备无法访问,但资源有加载,DOM可访问,则可以直接使用display:none隐藏

.dn{
    display:none;
}

如果希望元素不可见,同时不占据空间,辅助设备无法访问,但显隐的时候可以有transition淡入淡出效果

.hidden {
    position: absolute;
    visibility: hidden;
}

如果希望元素不可见,不能点击,辅助设备无法访问,但占据空间保留则可以使用visibility:hidden隐藏

.vh {
    visibility: hidden;
}

如果希望元素不可见,不能点击,不占据空间,但键盘可访问,则可以使用clip裁剪隐藏

.clip {
    position: absolute;
    clip: rect(0 0 0 0);
}

案例:1.请帖生成封面。2.键盘使用快捷键但不显示按钮(使用accesskey) 如果希望元素不可见,不能点击,但占据空间,且键盘可访问,则可以使用relative隐藏。如果条件允许,也就是上一层层叠上下文之间设置了背景色,则可以使用更友好的z-index负值隐藏

.out {
    position: relative;
    left:-999em;
}
.lower {
    position: relative;
    z-index: -1;
}

如果希望元素不可见,但可以点击,而且不占据空间,则可以使用透明度

.opacity {
    position: absolute;
    opacity: 0;
}

如果希望元素不可见,但位置保留,依然可以点可以选,则直接让透明度为0

.opacity{
    opacity: 0;
}

如果希望元素在显示时有一个transition动画,可以使用max-height进行隐藏

.hidden {
    max-height: 0;
    overflow: hidden;
}

display与元素的显隐

基础了解:无法点击,无法使用屏幕阅读器等辅助设备访问,占据空间消失深层了解:img标签上或父元素设置display:none都会加载资源。但是background-image请求的资源在该标签上或父元素设置display:none都不会加载资源(safari和chrome验证),在计数中设置了display:none的元素不被计入。会对IntersectionObserver造成影响

?code=NTM0ZWY4ZWFhYTIxMjY0Yzk5MTljNGJhZjBjZmU5NDVfMEdiYnF1emVmcGxNcERWTkloWmwxMUlKVVlJWmhCOUpfVG9rZW46Ym94Y254ZGFjOFc1aGNWQ0dvV1piUWx0T3hmXzE2NDQxMjA3MTM6MTY0NDEyNDMxM19WNA - css技术沉淀
?code=ZjgwMGMyYzY0MmYzMDFmOTNhNzVlMmUzN2ZkYTBkNTdfYTA2eGlYdzFpMzFZUThYdGRoekVnRGJBdjhvTlR6OVBfVG9rZW46Ym94Y25oTFlpMU1SUTRZWHJHWkdNTE1mQ2RlXzE2NDQxMjA3MTM6MTY0NDEyNDMxM19WNA - css技术沉淀

visibility与元素的显隐

基础了解:无法点击,无法使用屏幕阅读器等辅助设备访问,占据空间不消失深层了解:visibility具有继承性,父级设置visibility:hidden后子级可以设置visibility:visible显示子元素。设置了visibility:hidden的元素会加载img资源也会加载background-image资源。同时也会被纳入计数。visibility属性被纳入transition的范围内,因此可利用该属性展示元素从隐藏到显示的过渡效果。但是该属性不会对IntersectionObserver造成影响,也就是说如果弹窗是从隐藏到显示使用了该属性的话,对它进行埋点是无效的。

文本的换行

word-break

当行尾放不下一个单词时,决定单词内部该怎么摆放(决定不断行单词的长度) nomal:默认值,默认的换行规则(CJK文本断行,英文单词不断行,空格断行) break-all:对于non-CJK(中日韩)文本,可在任意地方断行 keep-all:CJK文本不断行,non-CJK文本表现形式如同nomal

word-wrap

是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词断词(没有换行点的单词在句尾放不下时,决定单词是否断词) nomal:默认值,行只能在正常的单词断点处中断。(例如两个单词之间的空格)。 break-word:表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。

white-space

如何处理元素中的空白 nomal:默认值,连续的空白符被合并,换行符被当做空白符处理 nowrap:连续的空白符被合并,文本内的换行符无效(<br>有效) pre:连续的空白符会被保留,在遇到换行符或者<br>元素时才会换行 pre-wrap:连续的空白符会被保留,在遇到换行符或者<br>元素,或者为了填充行框盒子(line-box)时才会换行 pre-line:连续的空白符会被合并,在遇到换行符或者<br>元素,或者为了填充行框盒子(line-box)时才会换行

line-break

中文标点的换行规则,比如是避首标点,是避尾标点,通过此属性控制CJK文本标点的换行规则 auto:使用默认的换行规则。 loose: 使用限制性最小的换行规则分隔文本。通常用于短行,如在报纸上。 normal:使用最普通的换行规则。 strict: 使用最严格的换行规则。 anywhere:任意位置都可以作为换行点,包括任意的标点。

<wbr>

这是html元素,宽度不够,在我这里换行;宽度足够,还是一行显示

光标属性cursor

https://developer.mozilla.org/en-US/docs/Web/CSS/cursor

flex子项最终尺寸计算规则

一个flex子项的最终尺寸是基础尺寸(或内容尺寸),弹性增长或收缩,最大最小尺寸共同作用的结果 最终尺寸计算的优先级是: 最大最小尺寸限制>弹性增长或收缩>基础尺寸

  • 基础尺寸有flex-basis属性或width属性,以及box-sizing盒模型共同决定
  • 内容尺寸指最大内容宽度,当没有设置基础尺寸时会顶替基础尺寸的角色
  • 弹性增长指的是flex-grow属性,弹性收缩指的是flex-shrink属性
  • 最大尺寸主要受max-width属性显示;最小尺寸受最小内容宽度,width属性和min-width属性共同影响

flex容器,flex-wrap:nowrap,flex-direction:row;justify-content:flex-start;align-items:stretch;为默认值 flex: 0 1 auto 这是flex子项的默认值,代表flex-grow:0,flex-shrink:1,flex-basis: auto 最小尺寸计算规则

  • 如果min-width属性值不是auto,则元素的最小尺寸就是就是min-width的属性值,此时width属性无法影响最小尺寸,哪怕width的属性值大于min-width的属性值。
  • 比较width的属性的计算值和最小内容宽度的大小,较小的值就是元素的最小尺寸。
  • 如果width的属性值和min-width的属性值均为auto,则元素的最小尺寸就是最小内容宽度。
  • 如果flex子项设置了overflow:hidden,且最小尺寸是由是否最小内容宽度决定的,则最小尺寸无效。

基础尺寸计算规则

  • 如果flex-basis属性和width属性同时设置了具体的数值,width属性值会被忽略,优先使用flex-basis作为基础尺寸。
  • 如果flex-basis的属性值是初始值auto,则会使用width属性设置的长度值作为基础尺寸。
  • 如果flex-basis和width的属性值都是auto,则会使用flex子项的最大内容宽度作为基础尺寸

弹性增长或收缩何时作用

  • 如果容器尺寸足够并且子元素的属性值包含flex-grow不为0则启用弹性增长规则
  • 容器尺寸足够:在容器flex-wrap:wrap状态下,n个子元素的基础尺寸相加宽度少于容器宽度,n+1个子元素的基础尺寸相加大于容器,且这n个子元素中具有flex-grow不为0的元素,则这n个子元素具备弹性增长的条件。在容器flex-wrap:nowrap状态下,所有子元素基础尺寸相加宽度少于容器宽度。
  • 如果容器尺寸不足并且子元素的属性值包含flex-shrink不为0则启用弹性收缩规则
  • 容器尺寸不足:在容器flex-wrap:wrap状态下,子元素的基础尺寸大于容器宽度,且子元素的flow-shrink不为0,则这个子元素具备弹性收缩条件。在容器flex-wrap:nowrap状态下,所有子元素的基础宽度少于容器宽度,且至少有一个子元素的flex-shrink不为0,则flex-shrink不为0的子元素具备弹性收缩条件。
  • 弹性增长,增长的部分是可分配空间,计算规则是容器宽度-元素基础尺寸
  • 弹性收缩,收缩的部分是有flex-shrink不为0元素的宽度,最多可以收缩至元素最小尺寸。

最终尺寸计算规则-总结

  • 如果没有弹性收缩或增长,则元素在最大尺寸和最小尺寸范围内使用基础尺寸
  • 如果元素能够弹性增长或收缩,在容器宽度足够的情况下使用弹性增长规则,在容器宽度不足的情况下使用弹性收缩规则,同一行只可能应用一种规则

选择器

选择器优先值计算

选择器计算值计算细则
* {}01个0级统配选择器,优先级数值为0
dialog {}11个1级标签选择器,优先级数值为1
ui > li {}22个1级标签选择器,1个0级选择器,优先级数值为2
li > ol + ol {}33个1级标签选择器,2个0级选择器,优先级数值为3
.foo {}101个2级类名选择器,优先级数值为10
a:not([rel=nofollow]) {}111个2级属性选择器,1个1级标签选择器,1个0级否定伪类,优先级数值为11
a:hover {}111个1级标签选择器,1个2级伪类,优先级数值为11
ol li.foo {}122个1级标签选择器,1个2级类名选择器,优先级数值为12
li.foo.bar {}211个1级标签选择器,2个2级类名选择器,优先级数值为21
#foo {}1001个3级ID选择器,优先级数值为100
#foo .bar p {}1111个3级ID选择器,1个2级类名选择器,1个1级标签选择器,优先级数值为111

相同计算值下遵循后来居上原则,后面的优先级更高

命名灵感

从HTML标签寻找灵感

.cs-module-header {}
.cs-module-body {}
.cs-module-aside {}
.cs-module-main {}
.cs-module-nav {}
.cs-module-section {}
.cs-module-content {}
.cs-module-summary {}
.cs-module-detail {} // 详情
.cd-module-option {}
.cs-module-img {}
.cs-module-footer {}
.cs-module-ui {}
.cs-module-li {} // 列表子项
.cs-module-a {} // 链接
.cs-module-g {} // 组
.cs-module-desc {} // 描述
.cs-module-x {} // 容器盒子

从HTML特定属性值中寻找灵感

.cs-radio {}
.cs-checkbox {}
.cs-range {}
.cs-tspan-email {}
.cs-tspan-number {}
.cs-tspan-color {}
.cs-tspan-tel {}
.cs-tspan-date {}
.cs-tspan-url {}
.cs-tspan-time {}
.cs-tspan-file {}

从无障碍访问的role属性值中寻找灵感

.cs-grid {}
.cs-grid-cell {}
.cs-log {}
.cs-menu {}
.cs-menu-bar {}
.cs-menu-item {}
.cs-region {} // 不能被其他role描述,但是很重要的部分
.cs-banner {} // 横幅广告
.cs-slider {}
.cs-tab {}
.cs-tab-list {}
.cs-tab-pannel {}
.cs-tooltip {}
.cs-tree {}

从CSS伪类和HTML布尔属性中寻找灵感

.active {}
.disabled {}
.selected {}
.checked {}
.invalid {} // 出错状态

体验优化

图片加载失败体验优化

<img src="xxx.png" alt="图片封面" onerror="this.classList.add('error');">
img.error {
  display: inline-block;
  transform: scale(1);
  content: '';
  color: transparent;
}
/* 替换图片 */
img.error::before {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  background: #f5f5f5 url(break.svg) no-repeat center / 50% 50%;
}
/* alt 提示 */
img.error::after {
  content: attr(alt);
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;
  line-height: 2;
  background-color: rgba(0,0,0,.5);
  color: white;
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

点击体验优化

移动端按钮可点击范围放大

.mobi-btn {
    border: 8px solid transparent;
}

键盘体验优化

可访问性-焦点控制

tabindex = “-1” 元素可以被鼠标或JS focus但不能被键盘focus tabindex = “0” 最后一个被focus的元素 tabindex >= “1” 越小优先级越高 若进入网页没有点击则按照1,2,…,0若点击则定位到点击的主体,按下tab寻找到第一个有focus的元素,再次按下根据该元素的tabindex寻找下一个焦点:focus-visible 让我们知道元素的聚焦行为是键盘触发还是鼠标触发

// 鼠标触发
:focus:not(:focus-visible) {}
// 键盘触发
:focus:focus-visible {}

当前获得焦点的元素 document.activeElement 检测文档是否获取了焦点 document.hasFocus()

滚动体验优化

overscroll-behavior

overscroll-behavior: [ contain | none | auto ]{1,2} 当只有一个值时代表水平垂直方向都是该值,有两个值时第一个代表水平方向第二个代表垂直方向 auto:滚动到边缘后继续滚动外部的可滚动容器 contain:默认的滚动溢出行为只会表现在当前元素的内部,不会对相邻的滚动区域进行滚动。 none:相邻的滚动区域不会发生滚动,并且会阻止默认的滚动溢出行为。

scroll-behavior

在可滚动的容器上使用,常用于到达顶部 auto:默认值 smooth:平滑滚动,与ant-design的scrollToFirstError搭配效果佳

overflow-anchor

auto: 默认值,该行为会调整位置以最大程度的减少内容偏移(例如上方图片的突然加载会无感知) none:退出浏览器滚动锚定行为

隐藏滚动条,同时元素可滚动

.scroll-none {
    scrollbar-width: none;
}
// chrome 私有方法
.scroll-none::-webkit-scrollbar {
    width:0; height:0;
}

输入体验优化

cater-color属性改变插入光标颜色

cater-color: red

移动端唤起数字键盘

验证码:<input inputmode="numeric">

拉伸行为体验优化

rezize

none: 默认值,没有拉伸效果,可以用来种植textarea元素默认的拉伸行为 both:既可以水平方向拉伸,也可以垂直方向拉伸 horizontal:仅可以水平方向上拉伸 vertical:仅可以垂直方向上拉伸 生效条件 块级元素且overflow的属性值不是visible 限制拉伸范围 使用max-width,max-height,min-width,min-height属性

选择行为体验优化

user-select

text:默认值,文字和图片可以被选中 none:禁止图文被选中 all:被低估的一个属性值,设置了该属性的图文内容都会被选中,案例:点击内容复制全部内容,github的链接

?code=NjgzOTg4ZTFiNTE0N2EwZTllNDY1ZmI2NWUyMTQyN2VfRFo5OERxTFRqWEN5UldiU0d3a1FVQ0ZoNnU3UVhBNW9fVG9rZW46Ym94Y25NT0xpZjBRNjZhUUdqZG9HaWxSQk1oXzE2NDQxMjA3MTM6MTY0NDEyNDMxM19WNA - css技术沉淀

::selection

被选中时伪类,全局设置时可设置品牌颜色为背景,合适颜色为字体颜色

::selection {
    color: hunlijiColor;
    background: hunlijuBackgroundColor;
}

打印行为体验优化

控制打印样式的媒体查询

@media print {
    header{
        display:none;
    }
}

是否进行精确打印

color-adjust economy:默认值,可能会将背景不打印 exact:精确打印

table{
    -webkit-print-color-adjust: exact;
    color-adjust: exact;
}

使该元素另起一页打印

break-before:page

性能优化

will-change

will-change的作用有两个,一个是创建合成层,一个在真正的行为触发之前告诉浏览器:“我要变化了,你要做好准备” 如何正确的使用 will-change不应该被设置在默认状态中且需要及时销毁,理想中的应用场景应该是hover状态下

// good
.will-change-parent:hover .will-change{
    will-change:transform;
}
.will-change {
    transition: transform 0.3s;
}
.will-change:hover {
    transform: scale(1.5)
}
// bad
.will-change {
    transition: transform 0.3s;
}
.will-change:hover{
    will-change: transform;
    transform: scale(1.5);
}

如果点击按钮,某个元素执行动画,先执行的是mousedown事件,之后执行的是click事件

dom.onmousedown = function() {
    target.style.willChange = 'transform'
}
dom.onclick = function() {
    // target元素执行动画
}
target.onanimationend = function() {
    // 动画结束,用回调函数移除will-change属性
    this.style.willChange = 'auto'
}

创建合成层

无法复制加载中的内容

  • 合成层的位图会交由GPU合成,比CPU处理要快得多
  • 当需要repaint时,只需要repaint本身,不会影响其他层
  • 元素提升为合成层后,transform和opacity不会触发repaint,如果不是合成层则依旧会触发repaint

查看合成层

?code=ODdmMWM5MzQzMzczYjY0ZmJhZmQ3OWVlOTY5Y2M0ODBfbHo2eVFtRVNHUDRuZXZkNTdXcHFTQ2ZUbUhNRWVndUxfVG9rZW46Ym94Y25Pb0xNRHR0RDhTc0lDOUs0SlVrWmhjXzE2NDQxMjA3MTM6MTY0NDEyNDMxM19WNA - css技术沉淀

避免隐式创建合成层及优化

合成层比较占用内存,假如一个合成层的宽高为100px * 100px,则合成层占用内存的计算方式为100*100*3 = 30000Byte = 30KB 当元素交叠,处在下方的元素成为了合成层,上方的元素隐式变成了合成层

?code=OTU5N2U1YTIzZmFjOTY4YzQyODNiMmI2OWMzZmIyZWJfWDhhaHFTMTZYNFRtZGZiVjV2ekxRcldiNU4wRllJNXVfVG9rZW46Ym94Y25rdjYyUXZNMzJsVE9KZXV5a2F4VklZXzE2NDQxMjA3MTM6MTY0NDEyNDMxM19WNA - css技术沉淀
  • 可以将必须合成层的层级提升至较高层级,则其他交叠层级没有该层级高就不会隐式创建合成层
  • 动画使用transform实现,一方面如果不涉及到translateZ则不会创建合成层,一方面生成层叠上下文不会影响到别的层叠上下文渲染
  • 通过减少宽高再进行scale放大的方式可以有效减少合成层使用的内存

很少用的属性

将中文简体转换为繁体

苹方字体有效,老老实实做i18n吧哈哈

font-variant-east-asian: traditional;
分类
javascript 总结

约定俗成写代码守则

关于数据字典

数据字典的数据可以先用async获取,方便后面使用

数据字典前端要传后端code,后端不能存name,而是利用code获取name再传给前端

关于流程

如果写流程类的代码,就有节点的概念,每个节点都会有表单操作,每个节点都有它的特殊性去展示不同的页面,因此,节点不能写死,像1,2,3,4,5这样就写死了,建议1,3,5,7,9

关于echarts

记得合并模式,基础配置使用普通合并,后台传过来的数据用代替合并

定义一个resize监听器,改监听器可以用debounce,当监听到时更改resize:true,再监听resize,当它为true时给echars修改this.chart.resize({width: null})最后把resize改成false,resize这个值可放到公共store

每个图标一定要单独做成组件,组件里有一个config.js配置,这样容易复制,要是做在一起,这酸爽。。。。

关于公共组件

适合抽离的公共组件有1.上传 2.找人等常用又容易修改的组件3.严重占据代码量的组件

关于css

写好css很重要,知道在哪写css更重要,曾经在一个流程的vue文件下写css,后来这个流程复制了5遍。。。

css尽量别嵌套太深,不然找都不好找

关于用户体验

弹出框:点击按钮弹出,点击外部框消失或者点击按钮框消失

选择框:可搜索,可删除

分类
总结

FTS迁移时感悟

该系统是较为复杂的流程系统,最近它的流转引擎需要更改,所以前端需要配合迁移。重新审视代码吐槽一番。

吐槽点1:为什么我把每个节点的转发,转办,通知,同意等接口都写了一遍!

当时我把每个接口都写一遍是因为后台给的是不同的接口,就算是不同的接口,我也可以把接口地址作为变量写一个公共的方法啊!再说我觉得后台应该也是调用的一个公共方法,如果沟通好的话可能都不需要修改接口地址,而是只改接口内的参数。

吐槽点2:为什么我得前端判断按钮是否显示啊!

当初设计的时候有一个stepNo的概念,比如一个市场问题有17个步骤分六个模块,在原因分析模块有失效分析,责任认定,根本原因三块内容。这三块内容后面可能还有审批这步操作。我就根据stepNo分清它是在哪个步骤再决定按钮的显示。当然只有当事人在待办中看才能看到当前stepNo显示的按钮。这个设计我感觉没什么问题,但是我不能向后端获取按钮吗。只要约定好按钮的样式函数。

吐槽点3:为什么要用用户的loginName而不是id作为标识啊

有的节点需要判断下一个操作的用户是谁需要向后台传递后一位的操作者,但是用了loginName出了许多问题,比如人员同步是有问题,当时发生问题的根本原因是为了美观和登录方便去掉了同名用户后面的数字,呵呵。当然用loginName还有一个原因是当时的引擎只支持这个,想想也是,引擎数据库的用户id和公司内部的用户id不同步啊,因为引擎是别的公司的产品。

吐槽点4:为什么一个vue文件有两千行啊!

emmm,一个原因是当时在一个模块里的操作比较多,想上面的原因分析。又要初始化,又要填表,又要赋值,又要判断在stepNo做的操作。还有就是组件化做的不太好的原因。有些css还没有复用。毕竟是一年前做的系统,原谅一下自己。

总结

虽然当时代码写的烂,但是用户体验不错,也完成了需求(毕竟是定制开发)。说明项目的成功与否与客户是否满意有很大关系。

分类
总结

阶段性回顾(1)

记忆力一直不是我的强项,但有些东西总是值得回忆的。记录下前端生涯走过的路,获得的进步。多年以后再来看看也是一件十分有趣的事。

初战:一个复杂的流程系统

说它是初战是因为这是第一个,我作为唯一的前端负责开发的系统,在此之前也做了一些打杂性的工作,比如说学习了vue,改了改另一个系统的ui,参与了又另一个系统的接口联调及页面开发,也许是前端缺人,也许是同事老板的信任,也许两者都有,这个任务落到了我头上。

这个系统主要考验了我的程序思维,以这个系统中的一个流程来举例,一个流程至少有17个步骤,每个步骤可能由不同的人来操作,并且有并行的操作,即同一个步骤可能有多个人来完成,这样结果也就从单个变成了数组。同时,需要把这17个步骤放在6个页面当中,这就需要判断在这个页面中执行的是第几个步骤。在这样的一个流程中分为两条线路来操作,分别是填写流和审批流。当你处在填写流时,你可以执行的操作是提交,暂存,返回。竟然还有个暂存,这是不是意味着我还得把写的东西存下来,放进草稿。当你处在审批流时,你可以同意,驳回,转办,加签。这个加签也是比较烦的东西,因为加签后流程的步骤没有改变,但是加签的人可以输入意见然后提交,提交后在审批记录中有加签人的意见。而且这是一个长流程,在流程的后期你也得看到前面的流程。

总之,经过这个系统的洗礼,我感觉技术实力有了很大的进步,比如下载文件的操作、echart的操作(后期有报表)、判断超时时间是前端设置的时间超时取消调用还是后端的ngix服务器超时取消返回给前端(这样就能愉快的甩锅了)。再比如如何在页面切换时刷新,如何优化点击同一个流程时会返回已打开的流程而不是再次重新打开。熟悉了下ant-design-vue,和vue,vue-router,store等。

再战:一个订单系统

虽然上一个系统的业务十分之复杂,我也把它做了出来,但是一看单单一个页面的代码量,我的天!竟然有两千多行。显然这是不行的,在这个系统里,我得改正。于是组件化开始了。每个页面大致都有一个高级检索,于是把它做成了组件。在这个组件中添加了键盘快捷搜索,展开收起,页面自适应。把所有的搜索表单表单都放在一个组件内,通过name判断是否应该显示。这样我就能方便调用数据字典接口,为了更方便的调用数据字典,实现了只要在一个数组中加入一个单词,就能自动调用该单词的数据字典。

同时学习了一些组件通信的方法,比如如何暴露组件函数,作用域插槽的运用,子组件使用外部方法后接收结果进行再处理,利用这些知识做了一个动态增减表单项组件,成为了博客的内容。

git上的提升,能比较熟练的运用git操作,从之前的fix,merge提示记录改成符合angular团队规范的提交记录格式,从此每一个项目的gitlab都能成为航海日志,并且减少了分支至2条,一个是master一个是当前版本的分支。

一个比较快速的项目

这是一个知识教训库,在这个项目中的提升主要是弄清了env配置,组件运用更加全面,没有再出现一个页面复制到别的页面的情况。

用时三个星期,也算锻炼了自己快速实现的能力吧。

一个改密码的项目

在上一个项目和这个项目中间学习了一波webpack,所以这个项目的技术含量会有一些提升。首先此项目要在手机端和电脑端显示,通常我们会启动两个项目来分别写手机和电脑端。但是这个项目并不大,我用了一些css技巧识别了手机和pc的区别(没有用宽度识别)。在媒体查询下分别写他们的css,做到了一份代码,多端使用。然后就是国际化,rsa加密,并照着友商的改密码项目手写了一个人机校验插件,并把rsa功能放进该插件里。于是取名叫做rsa-verify,现在能从npm搜到。

优化的部分也从减少包体积入手,比如去掉不必要的包,cdn加速,从首页渲染速度入手的优化有包分割,ant-design-vue的按需引入,ant-design-icon的按需引入。

期间读了本身框架的路由逻辑,因此能比较从容的改路由白名单,防止地址随意跳转,也能配置与后台交互时header的属性。

空闲时学习的知识

正则

在改密码项目中修改密码用到的各种规则都是用正则办到的,正则就像一个好用的工具,就要系统的学习,之后对项目的影响也是潜移默化的。

svg

其中学习了svg如何绘制图形,如何制作smil动画,svg滤镜,其中使用了svg滤镜动画在改密码项目中做了一个噪音滤镜改造过的水波纹点击动效,不过惨遭ui删除555。到底啥时候能有他一展身手的机会啊。。。

canvas

只会照着api用,解决了一个后台传过来白底背景图片放到蓝色基调的页面不好看的问题。解决方案是这样的:白底=>黑底,就是图片数据扣到canvas上,形式是一串长一维数组,规律rgba,改rgb,值=|255-数据|。有了一个黑底的图片。放到页面上。再利用滤色模式screen规律,黑色碰上别的颜色计算出来的值都是那一个别的颜色。于是mix-mode-blend:screen;加上background-color:需要的颜色。其实还可用svg滤镜实现,feColorMatrix滤镜的luminanceToAlpha模式色调翻转,白边黑。feFlood蒙上需要的颜色。feBlend的mode设置为screen将两者的结果结合生成最终的滤镜效果。这种方式不需要改动页面,只需要在外边放个svg滤镜输出id。在该图片的类中加一个filter:url(#id)即可。

学习来源

阿里来的带我的师傅,姓康。也是我真正意义上的技术入门导师,所以我叫他师傅,而不是康师傅。

张鑫旭博客,张鑫旭css世界,张鑫旭选择器世界

mdn,css tricks,html草案,css草案

javascript高级程序设计第三版

下一步的方向

由于在大二起我就看了张鑫旭的博客一路走来,所以css基础应该算是不错的。我会从javascript入手再巩固一遍基础,我买了高性能javascript,和你不知道的javascript上中下这四本书来阅读。

会尝试滤镜的更多可能性。

从项目角度,希望解决service worker离线缓存带来的项目上线后再次上线用户需要清缓存才能看到更新的问题。