Angular 学习笔记 (Material table sticky 原理)
更新: 2020-02-02
mat table sticky 过早计算 width
mat table 非常早就会去计算 width 来做 left or right
如果你用原生的 table tr td 它会依据你的内容做调整. 这种情况下 mat table 就会算错了. 或者算早了.
如果你用 [class.xx] 去 set width 依然是来不及的.
所以基本上除了 hardcode 以为. 你怎样 set 都是迟了...
解决方法也蛮简单的就是在 after view 的时候去调用 table.updateStickyColumnWidth 就可以了.
或者是在 cell constructor 的阶段就用 renderer 去 set width 这样才来得及.
更新 : 2020-05-17
之前说 sticky 类似 relation + fixed 其实不完全正确. 这样理解其实不太好
几个概念要有 :
1. sticky scroll container
sticky element 会找到第一个 overflow auto 的 parent 作为它的 sticky container (它不管你是 vertical 还是 horizontal, 只要你能 scroll 就是你)
2. sticky max area container
sticky 的第一个 parent 就是 max area container 了. sticky 有没有空间就却决于这个了
3. sticky top,bottom, left, right
position sticky 必须要配上上面这些才能 working.
用图解释 :
中间长方形是我们的 viewport, 当 scroll 的时候,红色的 sticky top 会不会触发, 要看它的是否在 viewport 的前面
蓝色的 sticky bottom 会不会触发是 based on 它是否在 viewport 的下面
像黄色在中间的话,那么它是没有任何 sticky 的. 上下都不粘.
上面说的第一,二条是非常 limitation 的. sticky 的 first overflow 有可能是 horizontal 但是需求是更上一层的 vertical 才是 scroll container. 我们经常会遇到这种情况.
first parent 是 max area 更恐怖. 比如需求要做一个 animation, 你 wrap 它起来就 gg.com 了.
更新 : 2019-12-03
今天踩坑了, sticky 了解不够深
refer
http://www.ruanyifeng.com/blog/2019/11/css-position.html 阮一峰 sticky
https://medium.com/@elad/css-position-sticky-how-it-really-works-54cd01dc2d46 避坑.
sticky 的原理类似动态的 relation + fixed
然后又多了一个 max area in container 的概念.
一定要记得, sticky 的 parent 就是 sticky container, 它的 max area 尤其重要。
有些时候我们需要 div depend on parent or viewport 我们会 set 100%
这个时候如果 div 不是 scroll container 的话,那么通常就用不了 sticky left right 了。
因为一旦 sticky container 依赖 parent width 那么它就不可能依赖内容. 在做 table + paginator 的时候就会遇到这种场景. table row 不依赖 parent width 但是 paginatior 通常
需要 width 100%
sticky 就是一个东西会一直保持在可见范围
table 的 header 在 scroll 的时候一直贴在上方, column 一直贴在左右.
这种体验以前是很难实现的。
需要监听 scroll 然后去定位.
有了 sticky 我们就不需要去监听 scroll 了.
但是 sticky 也有不能满足的场景. 比如当有 2 个 element 需要被 sticky 的时候. 我们的 top value 就要计算了
比如有 a, b 两个 element
当 2 个都要 sticky 的时候, top a = 0, top b = a height.
b 依赖与 a 的高度. 这里的难点是我们需要 watch a 的高度,
比较先进的方法是用 Resize Observer
https://drafts.csswg.org/resize-observer/#resize-observer-interface
另一种方法是不使用 sticky,改用监听 scroll + transition
transition 和定位有一个很大的区别就是, transition 在移动后, 原本的位置是保留着的,感觉就像灵魂出窍一样,躯壳依然占据着那个位置.
定位则是整个跳脱了出来,原本的位置就被其它元素替代掉了.
同样的例子.
a, b 都 transition 后, 当 a 的高度变大时, 它的躯壳也跟着变大了,间接的推动了 b element
所以这时候 a 和 b 保持的距离就会时一致的. 用 sticky 的话,这里就会出现重叠的问题了。
这个做法在一种场景下会比上面的好, 就是当你有多个 sticky element 但是它们又刚好是 sibling 的情况下。
如果它们不巧中间有不需要 sticky 的 element, 那么这个方案依然需要监听 height,那么就没有多大的好处了。
总结 :
1. 超过 1 个 element 要 sticky 的话, 就需要前一个的 parent (难度加一点)
2. 超过 1 个 element 同时 element 的 height 会改变 (难度再加)
解决之道,要监听多个 element 的 resize, 然后设置 top value.
refer:
https://developers.google.com/web/updates/2016/10/resizeobserver