Skip to content

Commit

Permalink
feat: new post (#32)
Browse files Browse the repository at this point in the history
Co-authored-by: Yi Zhou <yizhou1@WKMZT333F147.global.publicisgroupe.net>
  • Loading branch information
Zhou Yi and Yi Zhou authored Dec 6, 2023
1 parent e7cf865 commit 81847a3
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions _posts/2023-12-6.webview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: WebView的世界
date: 2023-12-06
slug: about-web-view
description: 可能长期更新,在做WebView时遇到的一些常见问题。
---

当H5遇上WebView,我们会遇到哪些常见的需求/问题?

1. 颜色适应
2. APP调起
3. 数据通信
4. 兼容性

## 颜色适应

可以细分为两种情形:

1. APP内的同一处页面需要支持不同颜色展示,常见于APP支持设置亮色、暗色主题
2. APP内不同处用到了同一页面,但是需要该页面可支持多种主题色。常见为通用H5在多处被复用,甚至在多APP内被复用。

### 场景1:

关键词:**[prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)**

通过这个媒体查询,H5可以定制一套dark样式。

但你就不得不问了,这个媒体查询什么时候生效?WebView可以控制么?

一般在默认情况下,prefers-colors-scheme会跟随系统主题生效。

那WebView能进一步控制么?毕竟很多的App是允许用户手动设置浅色/深色模式的。

答案是可以的。建议参考这两篇指南:

- [Darken web content in WebView | Android Developers](https://developer.android.com/develop/ui/views/layout/webapps/dark-theme)
- [Supporting Dark Mode In WKWebView (useyourloaf.com)](https://useyourloaf.com/blog/supporting-dark-mode-in-wkwebview/)

上述指南还包含三个进阶知识点:

1. H5增加**meta tag `<meta name="color-scheme" content="dark light" />` 可以更好的帮助APP使用正确的颜色配置。**
2. 即使没有设置prefers-color-schema,WebView其实也支持通过算法为H5生成一套深色外观。
3. 在CSS中设置`color-scheme`可以帮助滚动条、Textarea元素等自带样式的控件应用正确的外观。

e.g. hacker news自动生成的深色外观:

![hacker news1.png](https://s2.loli.net/2023/12/06/Dj2iHASFUugO7ml.png)

![hacker news2.png](https://s2.loli.net/2023/12/06/ADZGqs3NMeu1wdn.png)

## 场景2:

场景2需要为页面做动态样式渲染,也就是说WebView需要给H5传样式参数,来得到不同的样式。

那么参数怎么传,以及H5怎么接收参数,怎么渲染呢?

其实WebView和H5之间通信是之后的话题,考虑到这里只需要WebView单向的往H5传参,最常见的想法就是:

1. URL search parameters
2. JS bridge

这些方案都行,但用它们做样式动态设置其实并不太好,因为一定会产生**肉眼可见的样式变化延迟**——参数的接收和生效都是在客户端进行的,JS后置,这个延迟一般能有几百毫秒。

更好的方案?你可能已经想到了,我个人觉得动态路由+SSR非常适合这种场景。使用动态路由就可以在服务端完成参数的接收,那么返回的HTML就是参数已经生效的版本,一切都会显得非常的丝滑。

## APP调起

唤端:

- IOS:
- URI Scheme,不推荐,理由有
- 无法实际判断唤端成功与否,一般通过页面计时来猜测是否成功,体验并不好
- 失败的时候,会提示不认得这个链接,看起来像个报错
- Universal link,目前官方最推荐的方法
- Android
- URI Scheme似乎表现尚可

## 数据通信,方法互相调用

1. JS bridge是比较常见的方案,JS需要将方法暴露到window上,然后flutter就可以调用该方法。
2. Flutter的WebView插件[InAppWebview](https://inappwebview.dev/),本身提供了handler进行数据通信

## 兼容性

当遇到兼容性问题的时候,首先我们关心的就是WebView内核版本。

### Android

安卓的WebView是一个独立的组件。因此当遇到兼容问题的时候,首先要查看它的版本。

一般可以在设置中打开开发者模式后,找到对应的信息:

![WebView version.png](https://s2.loli.net/2023/12/06/QBEgJOPjlVDYxMT.png)

顺带一提,升级系统WebView的方式:

- 大陆的安卓手机系统一般是通过升级系统版本随带更新WebView版本。
- 支持Google服务的安卓手机系统可通过Google Play单独升级系统WebView版本。

0 comments on commit 81847a3

Please sign in to comment.