大家好,我是 ConardLi。
就在刚刚结束的 WWDC24
(苹果全球开发者大会)上,带来了诸多亮眼的新功能。
作为 Web 开发者我们最关注的当然就是 WebKit
的更新了,新版本的 WebKit
总计共带来了 48
项新的 Web
平台功能,以及 18
项弃用功能和 174
项错误修复。
下面我们来一起学习下一些我觉得值得关注的内容吧。
WebKit
加入了对 View Transitions
API 的支持。它提供了一个体验非常好的浏览器 API
,可以用来将元素从一个状态动画过渡到另一个状态。基于 CSS View Transitions Module Level 1
规范,引入了一些新的 CSS
属性和伪元素,一起构成了定义过渡动画的规则,并且提供一个新的浏览器 API
来启动过渡动画,并响应不同的过渡状态的变化。
它的工作方式是通过捕获页面的当前的(旧)状态,然后将其动画过渡到新的状态。默认情况下,浏览器会应用一个在状态间的交叉淡入淡出效果。
使用 document.startViewTransition()
方法来启动捕获过程。你可以传递一个回调函数作为第一个参数,来在旧的和新的捕获之间进行 DOM
状态的变化。这个方法会返回一个 ViewTransition
对象,其中包含的 promise
可以用来跟踪视图转换的开始或结束。
const tabLinks = [...document.querySelectorAll('.tabbed-views-demo a')];
const tabPages = [...document.querySelectorAll('.tabbed-views-demo .tab-page')];
tabLinks.forEach(tab => {
function switchTab () {
tabPages.forEach(element => element.classList.add('hidden'));
tabLinks.forEach(element => element.classList.remove('current'));
let pageid = document.location.href.split('#')[1];
tab.classList.add('current');
document.getElementById(pageid).classList.remove('hidden');
}
tab.addEventListener('click', (e) => {
// Feature detect view transitions
if (document.startViewTransition)
document.startViewTransition(switchTab);
else switchTab();
});
if (document.location.href.split('#')[1])
switchTab();
});
一旦状态被捕获,就会构建一个可以用 CSS
进行定位的伪元素树,你可以通过改变这个 CSS
动画来修改过渡效果。动画从旧的页面状态过渡到新的页面状态可以通过 ::view-transition-new(*)
和 ::view-transition-old(*)
选择器来进行修改。另外,你还可以通过为指定元素设置 CSS
的 view-transition-name
属性名称,要求浏览器独立跟踪元素状态的改变。然后,你可以使用伪元素来为其定制动画。
.page-view {
view-transition-name: page-view;
}
::view-transition-old(page-view) {
animation: 500ms ease-in-out transition-out-animation;
}
::view-transition-new(page-view) {
animation: 500ms ease-in-out transition-in-animation;
}
WebKit
增加了对样式查询(Style Queries
)的支持,可以在测试 CSS
自定义属性时使用。样式查询的用法和我们使用 Sass mixins
很相似,都是用来定义一组可重复使用的样式,并将其作为一个整体进行应用。
在以下示例中,如果 --background
自定义属性被设置为黑色,则使标题和段落文本的颜色变为白色。
@container style(--background: black) {
h2, h3, p {
color: white;
}
}
别忘了注意
HTML
结构。默认情况下,样式查询引用的是父元素上的样式,我们可以通过使用容器查询 (Container Query names
) 创建不同的引用。
在 Safari 9.0
中发布的背景滤镜(backdrop filter
)为我们提供了一种方式,可以对特定元素后的内容应用图像效果。例如,你可以将 backdrop-filter
应用到标题上,那么标题后的所有内容都将变得模糊,或者饱和度降低,或者对比度增加。你可以使用来自 SVG 的任何滤镜函数,例如 blur()
、brightness()
、contrast()
、drop-shadow()
、grayscale()
、hue-rotate()
、invert()
、opacity()
、saturate()
和 sepia()
。
多年以来,背景滤镜只能在 Safari
中运行。当你在属性名称前添加 -webkit-backdrop-filter
前缀时,它才可以使用。
现在,开始于 Safari 18 beta
,我们不再需要该前缀了。
现在它在各大浏览器的兼容性都很好。
WebKit 增加了对 content-visibility
的支持,这个属性用来控制元素是否以有利于性能优化的方式渲染内容。它能让你向浏览器明确表达,页面的某些部分可能最初不在屏幕上,建议先忽略它们,从而不参与首屏的布局和渲染,这样可能会使页面加载更快。
想要详细了解这个属性可以看:只需一行CSS代码,让长列表网页的渲染性能提升几倍以上!
在 Apple Vision Pro
上,我们可以享受到的一种体验非常好的浏览空间照片和全景照片的功能。当你在 visionOS
中打开 Photos
应用时,你会看到一组你的照片的集合。点击一张图片,它就会在你面前的一个浮动框架中单独出现,而其他部分的应用则会消失。
这是一种非常好的,全方位的沉浸式体验。
现在在 visionOS 2 beta
的 Safari 18
中,我们可以使用全屏 API
在网页上实现同样的体验。你可以在网页中嵌入照片,并提供点击功能。当前 Safari
窗口消失时,照片会弹出一个浮动的框架。然后,当用户点击 visionOS
提供的空间图片或全景 UI
时,照片会进一步扩展,创造出一个全方位的沉浸式体验。
首先,我们可以使用简单的 HTML
将扁平化的全景照片嵌入网页中。
<img src="panorama.jpeg" class="go-fullscreen" alt="[description]">
然后,我们将在点击时使用 Javascript
触发 .requestFullscreen()
:
document.querySelectorAll('.go-fullscreen').forEach(element => {
element.addEventListener('click', async () => {
await element.requestFullscreen();
});
});
当然,你可以为用户点击创建你自己的 UI,而不是让整个照片成为点击目标。
空间图像的运行方式完全相同,我们可以使用 picture
元素来实现。
<picture>
<source srcset="spatial.heic" type="image/heic">
<source srcset="fallback.avif" type="image/avif">
<img src="fallback.jpg" class="go-fullscreen" alt="[description]" >
</picture>
这种技术还将导致任何支持全屏 API
的浏览器使图像进入全屏状态。
想要详细了解,可以看看《Optimize for the spatial web》 这个主题。
Safari 18 forvisionOS 2 beta
增加了对沉浸式 WebXR
的支持。现在,我们可以创建完全身临其境的体验,并通过 Apple Vision Pro
在网络上向人们提供这些体验。VisionOS 2 Beta
上的 Safari
支持沉浸式 VR
会话。WebXR
场景使用由 WebGL
驱动的硬件加速图形来显示。
如果我们想制作用户手部的 3D
模型动画,VisionOS 2 Beta
版的 Safari
还支持 WebXR
手部跟踪。为了确保隐私,将在 WebXR
会话开始时向用户请求允许进行手部跟踪的许可。
《Build immersive web experiences with WebXR
》专题详细介绍了这个话题。
WebKit
添加了对新的 URL.parse()
方法的支持,这是一种解析 URL
的方法,当解析失败时,它会返回 null
而不是异常。
// Before
let url = null;
try {
url = new URL(input, base);
} catch(e) { }
// Now
const url = URL.parse(input, base);
新版的 WebKit
会通过升级混合内容设置中的被动子资源请求,为所有图像、视频和音频添加了对安全 HTTPS
的支持。这意味着,如果某个网站的某些文件使用 HTTPS
提供,而另一些文件使用 HTTP
提供(称为“混合内容”),则所有图像和媒体现在都将自动升级到 HTTPS
,以符合《Mixed Content Level 2
》规范的要求。
不过这项能力在 Chrome
中早就提供了,可以看下我之前的文章:Chrome 81 正式发布 !消灭混合内容最后一步~
RegExp
中添加了对 Unicode 15.1.0
字符的支持。Unicode 15.1
增加了 627
个字符,使字符总数达到 149,813
个。现在,这些新字符都可以在正则表达式中使用了。
另外还通过 RegExp.prototype[Symbol.matchAll]
添加了对 v
标志的支持。提供更强大的方法来匹配 Unicode
字符,如 ECMAScript 2024
标准中所指定的那样。
例如,我们现在可以指定仅匹配拉丁字符,同时避免匹配西里尔字母字符。
const regex = /\p{sc=Latin}/v;
console.log(regex.test('A')); // true, 'A' is a Latin script character
console.log(regex.test('А')); // false, 'А' is a Cyrillic script character
或者分割与表情符号匹配的字符串。
"a 🥰 b 🥰".split(/[\p{Emoji}--\p{ASCII}]/v)// ["a ", " b ", ""]
以上只节选了一些我觉得比较值得关注的更新,想要了解全部更新内容可以看:https://webkit.org/blog/15443/news-from-wwdc24-webkit-in-safari-18-beta/