惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
Engineering at Meta
Engineering at Meta
量子位
A
About on SuperTechFans
阮一峰的网络日志
阮一峰的网络日志
Recent Announcements
Recent Announcements
博客园 - 司徒正美
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
腾讯CDC
Jina AI
Jina AI
C
Check Point Blog
H
Help Net Security
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
爱范儿
爱范儿
I
InfoQ

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
小tips: 元素focus页面不滚动不定位的JS处理 « 张鑫旭-鑫空...
张鑫旭,zhangxinxu · 2019-09-19 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8972
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

咖啡杯金属 focus滚动定位占位图

一、问题的由来

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

button.focus();

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

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

如何实现呢?

二、全新的API参数preventScroll

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

button.focus({ 
    preventScroll: true 
});

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

我们来看一个例子,您可以狠狠地点击这里:JS focus preventScroll参数使用demo

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

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

focus与滚动不定位的效果

兼容性

preventScroll参数兼容性如下表:

Chrome logo Firefox logo Internet Explorer logo Edge logo Opera logo Safari logo
64+ ✔ 68+ ✔ 51+ ✔

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

三、IE浏览器下的处理

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

方法一:放弃IE/Edge

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

方法二:polyfill

这里有个人写了个focus的polyfill:https://github.com/calvellido/focus-options-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浏览器本身就是个体验糟糕的产品。

四、短文也要结束语

focus()方法的API在文档中都是写作HTMLElement.focus(),说明所有的HTML元素都有focus方法,因为虽然普通元素默认是不能被focus的,但是如果我们设置合适的tabindex属性值,情况就会发生变化,可以被focus,更多更深入更有趣知识可以参见这篇文章:“HTML tabindex属性与web网页键盘无障碍访问”。

因此,我们直接下面这样使用都是不会报错的:

document.body.focus();
document.createElement('div').focus();

但是如果是其他方法,例如submit就会报错:

// 会出错,不支持
document.body.submit();
document.createElement('div').submit();

submit出错提示

好,就说这么多,比原本预计的多写了半小时。

本文为原创文章,欢迎分享,勿全文转载,如果内容你实在喜欢,可以加入收藏夹,永不过期,而且还会及时更新知识点以及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8972

(本篇完)