网站开发中的Modal问题

最近在开发的网站基本上全是使用弹出的对话框(Modal)来进行 UI 交互的,所以对于 Modal 的处理也算积攒了一点经验。便想写下来供自己以后参考和学习。说实话,在目前响应式布局的主流开发方式下,Modal 非常不适合作为一个良好的交互方式。因为对于手机触屏用户非常不友好。当然,我开发的这个网站也没有考虑手机用户。当前的主流方式还是采用 SPA,JS 软路由切换页面来交互才是正解。

弹出对话框的方式基本是把对话框的z-index设置的比当前页面元素高,然后使用opacity: 0.5来半透明进行遮罩。但是,需要使用 Modal 的内容最好放在 body 的下层,而不是嵌套了好多层的某个 div 里面,因为子元素的z-index是不可能大于父元素的,会导致在某些情况下,其他元素比当前的 Modalz-index更高。

很多情况下,弹出的 Modal 内容过多导致会产生滚动条。这时如果不处理好会导致出现双重滚动条。一条是页面本身的内容过多产生的滚动条,还有一条是 Modal 自身的。双重滚动条还有一个问题是当你在 Modal 里面进行滚动的时候,页面内容本身也会被滚动,这会导致关闭 Modal 的时候发现页面的位置已不是打开的位置了,用户体验非常不好。这时候有两种解决方案。

第一个方案是页面本身采用position:fixed进行固定,并用 JS 记住滚动位置,但必须保持页面本身和 Modal 是并列关系。例:

<body>
  <div class="content"></div>
  <div class="modal"></div>
</body>
1
2
3
4

这样,Modal 采用position:absolute定位,当内容过长就会自动出现滚动条。但是当关闭 Modal 的时候,必须把网页内容的position:fixed属性去除,并用 JS 滚动到当初打开 Modal 的位置。如果 Modal 是透明的,那就必须在打开 Modal 的时候设置网页内容的topleft属性来保持位置不变。

第二个方案是,网页内容采用overflow: hidden来隐藏滚动条。Modal 采用position:fixed方案进行定位,但是这时候 Modal 不得不设置overflow: auto来进行滚动。 第二个方案对于网页内容和 Modal 的位置并没有特殊的要求,比较灵活,而且不需要 JS 的介入。

# 浏览器重绘

在一个方案中,由于网页内容被设置成了position:fixed,滚动条自然消失。所以滚动位置回到了浏览器的最上面才对。但是有时候遇到打开Modal的时候发现 Modal 打开之后滚动条不在最上方,这时候的原因是因为我们虽然设置了 CSS 进行了变更,但是浏览器没有进行重新绘制,我们可以使用会导致浏览器重绘的 JS API 来让浏览器更新滚动条信息,使得打开的 Modal 处于浏览器的最上方。

参考:

Force reflow (opens new window)

Github团队协作

社畜也快半年了,说实话工作确实没有学生生活有趣。每天基本都是坐在电脑前写代码,可能我是那种更喜欢新鲜生活的人吧。对于重复的生活很容易就厌倦了,但生活由不得自己,上班的理由很简单,仅仅是因为穷。学生时代写代码基本都是一个人单干,但进入公司就开始正式的团队协作,也算是学到很多团队合作的知识了吧。特别是利用 Github 进行高效的合作开发。

# Github 协作开发

首先是切换到需要开发的分支,这里我们假设要在dev分支上进行开发。

git checkout dev
1

然后,在 dev 分支上建立属于自己的分支。命名可以以功能命名也可以用解决的 issue 命名。例如:dev-add-page dev-issue20,之后再切换到自己建立的分支。

git branch dev-issue20
git checkout dev-issue20
1
2

这样,就可以在自己分支上开发了,开发之后 push 到服务器上,再请求pull request进行合并操作,在pull request的时候,可以让同事来进行代码 review 保证开发质量。

协作要用到的 Github 命令很简单,之后再说说经常用的其他命令。例如,当我们写了半天发现自己在错误的分支上进行了开发,该怎么处理呢?我们可以使用git stash命令来把临时修改隐藏起来。

git stash
git checkout dev-issue20
git stash pop
1
2
3

如果我们不小心在 dev 分支上直接进行了开发,可以使用上面的命令迅速把自己的修改切换到自己的分支上。

还有一种情况是,我们在自己的分支上进行开发的过程中,dev分支上合并了其他同事的代码,我们需要和dev分支保持一致。这时可以使用git pull origin dev分支来同步其他同事的代码,避免自己的代码和主分支产生冲突。

自己的分支在上传到服务器并合并之后通常服务器会删掉这个分支,但本地还是会保留。我们需要定期删掉自己本地已经合并的分支,这里推荐使用下面的命令。

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
1

正则表达式里面是不需要删除的分支。

有时候发现某个分支做的功能被砍掉了,然后需要删掉这个分支。可以使用下面的命令:

git push -d origin <branch_name>
git branch -d <branch_name>
1
2

分别删掉远程服务器和本地的分支。

有时候发现自己写的思路是错的,需要舍弃现在所有的修改,可以使用reset命令来重置。

git reset --hard
1

当然这个操作比较危险,你应该慎用。

当你需要移除所有新加的文件,但这些文件还没加入库当中。你可以使用clean命令来清除所有新加文件。

git clean -f
1

目前经常使用的就是这么多,如果大家有更好的学习Git命令的推荐资料,欢迎留言。谢谢!

参考:

Stack Overflow (opens new window)

高质量的 Git 中文教程 (opens new window)

Pro Git (opens new window)

CSS技巧和工作总结

工作确实是两点一线的生活。而且偶尔还加班,不过也算是正规的做一些东西了,个人成长来说也还不错。很多稍微有深度的知识也有所接触。于是想写点东西记录下自己的成长。以后再回顾的时候也算有所收获。

# CSS 层叠水平

CSS 的层叠看起来很简单,可以通过z-index来进行调整,但是实际上并没有那么简单。层叠水平总共有 7 阶,我们实际在使用中的时候要充分考虑。

  1. 形成堆叠上下文环境的元素的背景与边框
  2. 拥有负 z-index 的子堆叠上下文元素 (负的越高越堆叠层级越低)
  3. 正常流式布局,非 inline-block,无 position 定位(static 除外)的子元素
  4. 无 position 定位(static 除外)的 float 浮动元素
  5. 正常流式布局, inline-block 元素,无 position 定位(static 除外)的子元素(包括 display:table 和 display:inline )
  6. 拥有 z-index:0 的子堆叠上下文元素
  7. 拥有正 z-index: 的子堆叠上下文元素(正的越低越堆叠层级越低)

这里有个重点概念是堆叠上下文,那么元素是如何形成堆叠上下文呢?

  1. 根元素 (HTML)
  2. z-index 值不为 "auto"的 绝对/相对定位
  3. 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex
  4. opacity 属性值小于 1 的元素
  5. transform 属性值不为 "none"的元素
  6. mix-blend-mode 属性值不为 "normal"的元素
  7. filter 值不为“none”的元素
  8. perspective 值不为“none”的元素
  9. isolation 属性被设置为 "isolate"的元素
  10. position: fixed
  11. 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
  12. -webkit-overflow-scrolling 属性被设置 "touch"的元素

如果符合上面规则,会形成层叠上下文。层叠上下文的背景一定是最下面的,想要通过z-index来调整浮动在其他元素上方是不可能的。

# DOM Ready

如果巧妙的在 DOM 加载完成之后来执行 JS 呢,最简单的方法是把 JS 放在 body 的最下方。但这样处理有些麻烦,最简单的方法是使用setTimeout方法,设置延迟时间为 0。延迟时间为 0 并不意味着这段代码会立即执行,而是等到所有 JS 加载和执行完毕,DOM 也加载完毕的时候才执行。

# Safari Scroll

手机版 Safari 在滑动的时候如果有动画执行,会导致整个页面空白。当滑动结束的时候才会渲染。我们不得不采用给所有元素添加transform: translate3d(0,0,0)属性, 来使 Safari 强制使用 GPU 加速。

# CSS 动画性能加速

CSS 动画尽量使用transform: translate3d(0,0,0)来实现,因为 ransform3d api 会强制开启 GPU 加速提高页面的流畅度。在公司的项目中,从使用background-position进行动画效果换成transform之后,动画流畅度得到了显著的改善。

参考:

Stack Overflow (opens new window)

The stacking context (opens new window)

层叠顺序(stacking level)与堆栈上下文(stacking context)知多少? (opens new window)