Compare commits
2 Commits
436a3cbcaa
...
50f4783eff
Author | SHA1 | Date |
---|---|---|
|
50f4783eff | 2 years ago |
|
5493a0527b | 2 years ago |
5 changed files with 160 additions and 6 deletions
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 7.1 KiB |
@ -0,0 +1,74 @@ |
|||||||
|
# 结合语义化、可读性和程序性能选择遍历方法 |
||||||
|
|
||||||
|
在实际开发中,经常会用到遍历方法对集合进行判断,过滤,筛选等. |
||||||
|
对于ES5年代,我们大多依托基于lodash封装的`BI.each,BI.map,BI.some,BI.filter`方法,ES6时代,原生的`forEach,map,filter`等方法经常被使用 |
||||||
|
我们这里分析一下如何结合语义化、可读性和性能选择合适的遍历方法 |
||||||
|
|
||||||
|
## BI.xxx和原生的遍历方法有什么区别? |
||||||
|
|
||||||
|
1. BI.xxx方法保留了JQuery年代遍历方法的使用习惯,迭代调用的函数参数顺序为`(index,value)`,因此现在大多情况下,我们推荐使用原生遍历方法 |
||||||
|
2. BI.each方法可以遍历对象,原生javascript并未提供相应方法,`for...in`和`for..of`都无法同时获取key-value |
||||||
|
|
||||||
|
## 语义化可读性的原则 |
||||||
|
|
||||||
|
1. 如果你需要将数组按照某种规则映射为另一个数组,就应该用map |
||||||
|
2. 如果你需要进行简单的遍历,用forEach |
||||||
|
3. 如果你需要提前中断迭代,那么使用some或every |
||||||
|
4. 如果你需要过滤出符合条件的项,用filter |
||||||
|
5. 如果你需要遍历数组累计计算出某个结果,那可以用reduce |
||||||
|
6. 如果你需要先根据条件过滤,再按照规则映射为新数组,那就用filter加一个map |
||||||
|
|
||||||
|
实际场景举例 |
||||||
|
```javascript |
||||||
|
// 利用some提前中断的特性减少遍历 |
||||||
|
const arr = [1, 3, 4, 7]; |
||||||
|
|
||||||
|
const hasEven = arr.some(v => v % 2 === 0); |
||||||
|
|
||||||
|
const allOdd = arr.every(v => v % 2 === 1); |
||||||
|
``` |
||||||
|
|
||||||
|
```javascript |
||||||
|
// 迭代累计结果,两种实现并无高低之分,但求简单易懂 |
||||||
|
const arr = [1, 3, 4, 7]; |
||||||
|
|
||||||
|
const allCount1 = arr.reduce((previousValue, currentValue) => previousValue + currentValue, 0); |
||||||
|
|
||||||
|
let allCount2 = 0; |
||||||
|
arr.forEach(v => allCount2 += v); |
||||||
|
``` |
||||||
|
|
||||||
|
## 既要有性能意识,又无需过度追求性能 |
||||||
|
|
||||||
|
绝大多数情况,我们无需考虑究竟是`forEach`更快,还是`for...in`更快,我们的主要目标是写出清晰,稳定,可持续的代码. |
||||||
|
|
||||||
|
与此同时,我们有尽量避免一些显而易见的代码缺陷,一个常见的误区是在遍历中重复进行额外的遍历. |
||||||
|
对于在循环遍历中可以保持不变的信息,可以在遍历之外提前计算好再使用 |
||||||
|
```javascript |
||||||
|
const arr1 = [ |
||||||
|
{ |
||||||
|
name: "xiaoming", |
||||||
|
age: 17 |
||||||
|
}, { |
||||||
|
name: "dashan", |
||||||
|
age: 28 |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
const arr2 = [14, 25, 36, 17]; |
||||||
|
|
||||||
|
// 每次都要进行map |
||||||
|
arr2.forEach(v => { |
||||||
|
if (arr1.map(j => j.age).includes(v)) { |
||||||
|
console.log(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// 对不变数据进行预先提取 |
||||||
|
const ages = arr1.map(j => j.age); |
||||||
|
arr2.forEach(v => { |
||||||
|
if (ages.includes(v)) { |
||||||
|
console.log(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
``` |
@ -0,0 +1,81 @@ |
|||||||
|
# z-index解析以及在FineUI中使用原则 |
||||||
|
|
||||||
|
z-index问题一直是前端开发人员的噩梦 |
||||||
|
|
||||||
|
代码review过程中反复强调z-index解析以及在FineUI中使用原则: |
||||||
|
|
||||||
|
<b>"不要滥用z-index,只有当你充分理解原理并确定要通过z-index解决的时候,方可使用"</b> |
||||||
|
|
||||||
|
从直觉上,z-index越大的元素排在上面是理所当然的,但是实际上这是不全面的,z-index不是全局的,设置了z-index的元素只会和与他处在同一stacking contexts的元素进行比较 |
||||||
|
|
||||||
|
可以思考一下,为什么我们的气泡默认的container属性是body呢,不可以放到当前的容器里面吗?因为stacking contexts的关系,即使弹出气泡的z-index很大,也会出现被遮住的情况 |
||||||
|
|
||||||
|
```javascript |
||||||
|
BI.createWidget({ |
||||||
|
type: "bi.horizontal_auto", |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "bi.label", |
||||||
|
text: "我的z-index是2", |
||||||
|
height: 50, |
||||||
|
width: 100, |
||||||
|
cls: "bi-background bi-border", |
||||||
|
css: { |
||||||
|
zIndex: 2, |
||||||
|
}, |
||||||
|
}, { |
||||||
|
type: "bi.horizontal_auto", |
||||||
|
css: { |
||||||
|
zIndex: 1, // 因为这里产生了一个stacking context,因此无论popup的z-index多高,他都会在label的下面 |
||||||
|
}, |
||||||
|
items: [ |
||||||
|
{ |
||||||
|
type: "bi.bubble_combo", |
||||||
|
width: 100, |
||||||
|
height: 30, |
||||||
|
el: { |
||||||
|
type: "bi.button", |
||||||
|
text: "点击弹出", |
||||||
|
}, |
||||||
|
container: this, // 默认container为body,这里手动改为当前元素 |
||||||
|
direction: "top", |
||||||
|
popup: { |
||||||
|
el: { |
||||||
|
type: "bi.label", |
||||||
|
text: "我的z-index是10000000", |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}); |
||||||
|
``` |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
## 创建stacking contexts的几种方式 |
||||||
|
|
||||||
|
详细场景可以参考MDN文档,这里只列举几个常见的 |
||||||
|
[the_stacking_context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context#the_stacking_context) |
||||||
|
|
||||||
|
- html根节点 |
||||||
|
- opacity的值小于1 |
||||||
|
- position:absolute 或 position:relative 且带有z-index属性 |
||||||
|
- position:fixed 或 position:sticky |
||||||
|
- 父容器是 display:flex 或 display:grid 且子元素自己带有z-index属性 |
||||||
|
- transform属性 |
||||||
|
- isolation: isolation 直接创建上下文 |
||||||
|
|
||||||
|
如果觉得通过查看代码不能够直观的分辨stacking contexts,那么推荐一个插件[CSS Stacking Context inspector](https://chrome.google.com/webstore/detail/css-stacking-context-insp/apjeljpachdcjkgnamgppgfkmddadcki) |
||||||
|
能够自动识别stacking context结构,并注明产生stacking context的原因 |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
## 在什么情况下需要使用z-index来解决问题呢 |
||||||
|
|
||||||
|
除FineUI内部使用z-index之外,常见业务开发中使用z-index的例子 |
||||||
|
|
||||||
|
1. 在某个元素上悬浮显示,且超出容器边界的,例如拖拽宽度的图标. |
||||||
|
2. 仪表板组件自由排列叠放布局 |
||||||
|
3. 没了 |
Loading…
Reference in new issue