Open chenxiaochun opened 6 years ago
Chrome69 刚刚发布,翻了一下它的官方文档。所以,这篇文章就是向大家介绍一下它新支持的一些有趣功能特性。
写这篇文章的目的也仅仅是对新技术的一种了解和探索,各位也不要看完之后,就急着应用到自己的项目中去;或者看完之后,就开始纠结各种浏览器的兼容性问题。我个人认为,在项目中使用技术要保守一点,尽量选择那些比较熟悉的技术方案,但是,学习新技术还是应该尽量激进。
CSS Scroll Snap 用来创建平滑的滚动体验,并且还可以控制元素每次滚动操作之后的停止位置。这个新特性非常合适用在图片轮播和滚动分页的操作效果。
拿图片轮播举例,我需要给滚动的容器添加scroll-snap-type: x mandatory;,mandatory的意思就是“强制的”,也就是强制里面的元素以水平方向滚动。然后给里面滚动的每一张图片添加scroll-snap-align: center;。然后当用户滚动轮播的时候,每一张图片就能恰好顺滑的滚动到完美的位置上。
scroll-snap-type: x mandatory;
mandatory
scroll-snap-align: center;
#gallery { scroll-snap-type: x mandatory; overflow-x: scroll; display: flex; } #gallery img { scroll-snap-align: center; }
即使每一张图片的尺寸都不一样或者超出了滚动容器的大小,这个功能依然能工作的很好。
查看示例:https://codepen.io/sjzcxc/pen/PdKrzv?editors=1100 查看 google 官方提供的示例:https://snap.glitch.me/carousel.html 源代码:https://glitch.com/edit/#!/snap?path=carousel.html:186:0
现在越来越多的手机都有那个“刘海儿”。于是浏览器添加了一些额外的外边距以处理这个区域。
默认显示效果:
viewport-fit=cover告诉浏览器展开预留的那个“刘海儿”区域。但是你会发现有些内容会被遮挡,并且下面的导航条也会变得非常难用。
viewport-fit=cover
<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>
那怎么才能在加上上面的元标签之后,也能防止内容不被遮挡呢?
为了实现这个效果,需要使用 css 函数:env(),以及四个内置的环境变量:
env()
safe-area-inset-left safe-area-inset-right safe-area-inset-top safe-area-inset-bottom
.post { padding: 12px; padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
可以用这个 api 以异步的方式获得一个锁,然后直到你的任务完成之后,再去释放它。当其它任务占用这把锁的时候,获得这把锁的其它任务,只能是等待上一个任务释放这把锁之后,再能继续执行。这个特性非常适合用于管理公共资源的使用。
注意:这个 api 只能在 https 协议中才能获取到。
例如,当一个应用在多个 tab 页运行的时候,可以用来确保当前只有一个 tab 页在获取数据.
navigator.locks.request("network_sync_lock", async lock=>{ await new Promise(resolve => { setTimeout(() =>{ console.log('我正在获取一个数据!') resolve(); }, 3000); }) }) navigator.locks.request('network_sync_lock', async lock => { await new Promise(resolve => { setTimeout(() => { console.log('等第一个任务完成之后,我才能继续!'); resolve(); }, 3000) }) });
第一个 tab 页获得一把锁之后,开始异步的请求数据。如果另一个 tab 页也想获得相同的锁,它就必须排队。当第一个任务把锁释放之后,后面排队的任务才会被授权使用锁,并被执行。查看示例:https://codepen.io/sjzcxc/pen/GXMJzX?editors=1010
可以给request传递一个对象参数,用来控制锁的执行状态。
request
model
exclusive
shared
navigator.locks.request("network_sync_lock",{mode: 'shared'}, async lock=>{ await new Promise(resolve => { setTimeout(() =>{ console.log('我正在获取一个数据!') resolve(); }, 3000); }) }) navigator.locks.request('network_sync_lock',{mode: 'exclusive'}, async lock => { await new Promise(resolve => { setTimeout(() => { console.log('等第一个任务完成之后,我才能继续!'); resolve(); }, 3000) }) });
实验发现,只要第一个任务把锁置为shared的状态,那么第二个任务是否需要等待上一个任务释放锁,完全是由自己决定的。
signal
AbortSignal
var controller = new AbortController(); var signal = controller.signal; navigator.locks.request("network_sync_lock",{signal: signal}, async lock=>{ await new Promise(resolve => { setTimeout(() =>{ console.log('执行第一个任务!') resolve(); }, 3000); }) }) navigator.locks.request('network_sync_lock', async lock => { await new Promise(resolve => { setTimeout(() => { console.log('执行第二个任务!'); resolve(); }, 3000) }) }); signal.onabort = () => { if(signal.aborted){ console.log('任务被中止!'); } } controller.abort();
ifAvailable
false
true
如下示例所示,我们给第二个任务设置了ifAvailable: true,经过 3 秒钟之后,会同时看到两条 log 信息。
ifAvailable: true
navigator.locks.request("network_sync_lock", async lock => { await new Promise(resolve => { setTimeout(() => { console.log('执行第一个任务!') resolve(); }, 3000); }) }) navigator.locks.request('network_sync_lock', { ifAvailable: true }, async lock => { await new Promise(resolve => { setTimeout(() => { console.log('执行第二个任务!'); resolve(); }, 3000) }) });
查看示例:conic-gradient。另外,之前写过一篇关于线性渐变和放射性渐变的文章,可以点击链接查看。
<input value="text"> <button>toggleAttribute</button>
var button = document.querySelector("button"); var input = document.querySelector("input"); button.addEventListener("click", function(){ input.toggleAttribute("readonly"); });
toggleAttribute的第二个参数是一个布尔值。设置为true时表示给当前元素添加属性,为false时表示删除属性。
toggleAttribute
flat()
const array = [1, [2, [3]]]; array.flat(); // → [1, 2, [3]]
flatMap()
[2, 3, 4].flatMap((x) => [x, x * 2]); // → [2, 4, 3, 6, 4, 8]
OffscreenCanvas
以前在 worker 中是无法使用 canvas 的,因为无法在 worker 中操作 DOM 元素。现在OffscreenCanvas的出现,就是为了实现无需依赖于 DOM 操作的在 worker 中绘制 canvas。
大家都知道,浏览器的执行时是单线程的,如果一个任务耗时过长,就会使页面出现卡顿,影响用户体验。因此将那些复杂的 canvas 绘制工作从主线程移到一个 worker 里面,不影响主线程的程序运行,可以极大提高执行效率和用户体验。
worker.js:
function getGradientColor(percent) { const canvas = new OffscreenCanvas(100, 1); const ctx = canvas.getContext("2d"); const gradient = ctx.createLinearGradient(0, 0, canvas.width, 0); gradient.addColorStop(0, "red"); gradient.addColorStop(1, "blue"); ctx.fillStyle = gradient; ctx.fillRect(0, 0, ctx.canvas.width, 1); const imgd = ctx.getImageData(0, 0, ctx.canvas.width, 1); const colors = imgd.data.slice(percent * 4, percent * 4 + 4); return `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, ${colors[3]})`; } postMessage(getGradientColor(40));
主文件:
<body> <script> var worker = new Worker('worker.js'); worker.onmessage = event => { console.log(event.data); } </script> </body>
你在地址栏中输入www.a.www.b.com回车之后,它显示的是a.b.com。这明显是有问题的,例如钓鱼网站就可能利用这个漏洞欺骗用户。今天测试发现Chrome 已经默认修复了这个问题,所以,大家只要知道有这么个开关就可以了。
www.a.www.b.com
a.b.com
chrome://flags#omnibox-ui-hide-steady-state-url-scheme-and-subdomains
Chrome69 刚刚发布,翻了一下它的官方文档。所以,这篇文章就是向大家介绍一下它新支持的一些有趣功能特性。
写这篇文章的目的也仅仅是对新技术的一种了解和探索,各位也不要看完之后,就急着应用到自己的项目中去;或者看完之后,就开始纠结各种浏览器的兼容性问题。我个人认为,在项目中使用技术要保守一点,尽量选择那些比较熟悉的技术方案,但是,学习新技术还是应该尽量激进。
CSS Scroll Snap
CSS Scroll Snap 用来创建平滑的滚动体验,并且还可以控制元素每次滚动操作之后的停止位置。这个新特性非常合适用在图片轮播和滚动分页的操作效果。
拿图片轮播举例,我需要给滚动的容器添加
scroll-snap-type: x mandatory;
,mandatory
的意思就是“强制的”,也就是强制里面的元素以水平方向滚动。然后给里面滚动的每一张图片添加scroll-snap-align: center;
。然后当用户滚动轮播的时候,每一张图片就能恰好顺滑的滚动到完美的位置上。即使每一张图片的尺寸都不一样或者超出了滚动容器的大小,这个功能依然能工作的很好。
查看示例:https://codepen.io/sjzcxc/pen/PdKrzv?editors=1100
查看 google 官方提供的示例:https://snap.glitch.me/carousel.html
源代码:https://glitch.com/edit/#!/snap?path=carousel.html:186:0
手机“刘海儿”区域显示
现在越来越多的手机都有那个“刘海儿”。于是浏览器添加了一些额外的外边距以处理这个区域。
默认显示效果:
viewport-fit=cover
告诉浏览器展开预留的那个“刘海儿”区域。但是你会发现有些内容会被遮挡,并且下面的导航条也会变得非常难用。那怎么才能在加上上面的元标签之后,也能防止内容不被遮挡呢?
为了实现这个效果,需要使用 css 函数:
env()
,以及四个内置的环境变量:web locks api
可以用这个 api 以异步的方式获得一个锁,然后直到你的任务完成之后,再去释放它。当其它任务占用这把锁的时候,获得这把锁的其它任务,只能是等待上一个任务释放这把锁之后,再能继续执行。这个特性非常适合用于管理公共资源的使用。
注意:这个 api 只能在 https 协议中才能获取到。
例如,当一个应用在多个 tab 页运行的时候,可以用来确保当前只有一个 tab 页在获取数据.
第一个 tab 页获得一把锁之后,开始异步的请求数据。如果另一个 tab 页也想获得相同的锁,它就必须排队。当第一个任务把锁释放之后,后面排队的任务才会被授权使用锁,并被执行。查看示例:https://codepen.io/sjzcxc/pen/GXMJzX?editors=1010
可以给
request
传递一个对象参数,用来控制锁的执行状态。model
:默认值是exclusive
,也就是独有的,排外的;shared
,可以共享自己的状态。查看在线实例:https://codepen.io/sjzcxc/pen/PdJXGZ实验发现,只要第一个任务把锁置为
shared
的状态,那么第二个任务是否需要等待上一个任务释放锁,完全是由自己决定的。signal
:它是一个AbortSignal
对象,可以用来在适当的时机中止当前任务锁,查看示例:https://codepen.io/sjzcxc/pen/EewMZm?editors=1010#ifAvailable
:默认为false
,指定为true
表示当前任务如果不能立即得到执行,就无需等待其它任务释放资源锁,按照自己的逻辑直接执行即可。如下示例所示,我们给第二个任务设置了
ifAvailable: true
,经过 3 秒钟之后,会同时看到两条 log 信息。圆锥渐变
查看示例:conic-gradient。另外,之前写过一篇关于线性渐变和放射性渐变的文章,可以点击链接查看。
属性开关切换
toggleAttribute
的第二个参数是一个布尔值。设置为true
时表示给当前元素添加属性,为false
时表示删除属性。新增两个 array 方法
flat()
flatMap()
OffscreenCanvas
以前在 worker 中是无法使用 canvas 的,因为无法在 worker 中操作 DOM 元素。现在
OffscreenCanvas
的出现,就是为了实现无需依赖于 DOM 操作的在 worker 中绘制 canvas。大家都知道,浏览器的执行时是单线程的,如果一个任务耗时过长,就会使页面出现卡顿,影响用户体验。因此将那些复杂的 canvas 绘制工作从主线程移到一个 worker 里面,不影响主线程的程序运行,可以极大提高执行效率和用户体验。
worker.js:
主文件:
关闭地址栏默认隐藏 www 字符
你在地址栏中输入
www.a.www.b.com
回车之后,它显示的是a.b.com
。这明显是有问题的,例如钓鱼网站就可能利用这个漏洞欺骗用户。今天测试发现Chrome 已经默认修复了这个问题,所以,大家只要知道有这么个开关就可以了。相关资源链接