JS处理元素focus页面不滚动不定位的问题

目录
文章目录隐藏
  1. 全新的 API 参数 preventScroll
  2. IE 浏览器下的处理
  3. 结语

有时候我们希望元素被 focus 的时候页面不发生滚动,例如我们点击一个按钮打开一个弹框,此时点击弹框中的关闭按钮隐藏弹框后,希望键盘的焦点回到之前的按钮上,我们就会执行如下 JavaScript 代码:

button.focus();

但是有时候会带来另外一个比较严重的体验问题,那就是如果弹框显示之后我们页面发生了滚动,原本点击的按钮跑到了屏幕显示区域之外,这个时候,按钮再次 focus 的时候就会触发按钮元素 scrollIntoView 重定位,浏览器发生滚动,表现为突然的跳动,体验很不好。

我们预期的目标是:按钮 focus,然后无论按钮在不在屏幕显示区内,都不会发现浏览器的滚动重定位。

如何实现呢?

全新的 API 参数 preventScroll

如果想要聚焦同时不发生滚动,其实很简单,使用一个全新的 API 参数 preventScroll 就可以了,例如:

button.focus({ 
    preventScroll: true 
});

preventScroll 是一个可选参数,默认值是 false,表示不阻止聚焦滚动。如果 preventScroll 参数值是 true 则表示只聚焦不滚动。

demo 页面有两个按钮,一个按钮点击直接 focus,另外一个是设置了{preventScroll:true}。

结果最终的效果如下 GIF 录屏所示:

JS 处理元素 focus 页面不滚动不定位的问题

兼容性

preventScroll 参数兼容性如下表:

preventScroll 参数兼容性

手头没有 Safari 浏览器,因此兼容性不详,欢迎大家反馈。

IE 浏览器下的处理

IE 浏览器不支持这个非常棒的 API,如果我们要让这个浏览器支持怎么办呢?

方法一:放弃 IE/Edge

IE/Egde 连自己都放弃自己投奔 Chrome 了,我们还有什么理由支持他呢!

方法二:polyfill

这里有个人写了个 focus 的polyfill,

然而,根据我在 IE 浏览器下的实地使用,有坑,效果很奇怪,因此,上面这个 polyfill 不建议使用。

方法三:临时补丁

拿垂直滚动距离,我们可以这样 JS 处理:

var y = window.pageYOffset;
button.focus({ 
    preventScroll: true 
});
// IE 浏览器的处理
if (window.pageYOffset != y) {
    setTimeout(function () {
        document.documentElement.scrollTop = y;
    }, 0)
}

但此方法并不完美,有一定概率页面会抖一下。

结语

我在实际项目中的处理方法就是方法一,直接忽略 IE 浏览器,即使项目要兼容 IE 浏览器,毕竟是体验增强的东西,使用 IE 浏览器的用户能够忍受的糟糕体验要比我们预想的大的多,因为 IE 浏览器本身就是个体验糟糕的产品。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » JS处理元素focus页面不滚动不定位的问题

发表回复