New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scrollIntoView引发的思考 #9

Open
zhaoqize opened this Issue Jan 3, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@zhaoqize
Owner

zhaoqize commented Jan 3, 2018

起因

同事最近在开发h5页面的时候,遇到了点击输入框,而 输入框输入法 遮挡的问题。

这个问题只会只在 安卓手机 中出现。

想法

一出现这种问题,第一感觉就是认为页面的高度被改变压缩了。
首先想到的是用万能JavaScript去动态改变滚动高度(首先想到的是这两个方法scrollBy和scrollTo
搜索之后发现有这么两个东西

  • scrollIntoView

方法让当前的元素滚动到浏览器窗口的可视区域内

  • scrollIntoViewIfNeeded

是 Element.scrollIntoView() 的变体,如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动

解决方案

@Tao-Quixote 这个大兄弟已经说的很清楚了,具体见scrollIntoViewIfNeeded 与 scrollIntoView

下面摘录一部分:

根据MDN文档,Element.scrollIntoView是一个实验性质的方法,提示截图如下:

Element.scrollIntoViewIfNeeded是一个非标准的特性,建议不要在生产环境中使用,提示截图如下:

其实这两个特性,我个人感觉应用最多的场景应该是在移动端,当表单元素获得焦点的时候滚动到视野中,避免软键盘遮挡元素。鉴于Element.scrollIntoView无论设置什么参数,且不论是否在视野中都会滚动的特点,Element.scrollIntoViewIfNeeded特性应该比Element.scrollIntoView体验好。

虽然MDN文档中说Element.scrollIntoViewIfNeeded是非标准特性,但是在移动端的支持还是非常好的,以下截图来自caniuse:

但是反观Element.scrollIntoView这个实验特性,在移动端的支持并不是特别好,以下截图来自caniuse:

根据上面的比较应该可以得出结论:在移动避免软键盘遮挡表单元素时,应该使用Element.scrollIntoViewIfNeeded特性来实现元素滚动到视野中,不论是体验还是浏览器支持,该特性都好于Element.scrollIntoView特性。

scrollIntoViewIfNeeded不起作用

你以为这就完了?想法太美好!
在实际的使用中,发现scrollIntoViewIfNeeded有时候会不起作用!
这里需要注意一点:就是focus事件和键盘弹起是有交互时间的。
执行scrollIntoViewscrollIntoViewIfNeeded的时机应该是在键盘弹出之后。

// 伪代码
setTimeout(() => {
    element.scrollIntoView()
}, 400);

scrollBy和scrollTo区别

  • scrollBy() 方法可把内容滚动指定的像素数。
  • scrollTo() 方法可把内容滚动到指定的坐标。
    含义的描述很明显就能看出区别了,一个在现有基础上的增/减量,是一种相对的概念。另外一个是绝对量。

滚动的平滑度问题

无论是scrollBy还是scrollTo,他们到达制定的位置都非常生硬(瞬达),没有过渡的效果。
smoothscroll 这个库就很好的处理了这种情况。
具体的效果看这里:smoothscroll演示

当然作为一个非常好奇的人,就很想看看它是怎么在400多行代码中实现的这个效果,因为以前来说这种效果会用setTimeout这种方法来实现,虽然效率不是很好,但是最起码能实现这种功能。
这里我们能找到它使用requestAnimationFrame方法实现的。

参考:

@zhaoqize zhaoqize added the Tip label Jan 3, 2018

@zhaoqize zhaoqize added Blog and removed Tip labels Jan 30, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment