iOS17 Safari PWA中window.matchMedia暗黑模式监听失效问题
iOS17 PWA中prefers-color-scheme事件监听器不触发的问题及解决办法
这是iOS17上PWA的一个已知bug,不少开发者都碰到过相同问题:当Web应用以PWA形式安装到iPhone主屏后,通过window.matchMedia("(prefers-color-scheme: dark)")添加的change事件监听器,在切换系统暗黑/亮色模式时不会触发,但iOS16下正常,浏览器内运行也没问题。
你提供的代码逻辑本身没问题,但受限于iOS17的这个bug,在PWA模式下无法触发事件:
useEffect(() => { function handleColorSchemeChange(event) { // this listener won't trigger when the web app is installed as PWA on the iPhone's home screen const newColorScheme = event.matches ? "dark" : "light"; setCurrentDarkMode(newColorScheme); } window .matchMedia("(prefers-color-scheme: dark)") .addEventListener("change", handleColorSchemeChange); return () => { window .matchMedia("(prefers-color-scheme: dark)") .removeEventListener("change", handleColorSchemeChange); }; }, []);
临时解决办法
可以通过监听应用的可见性变化事件,在应用从后台回到前台时主动检查当前的配色方案,弥补change事件不触发的问题:
useEffect(() => { // 主动检查当前配色方案 function checkCurrentColorScheme() { const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; setCurrentDarkMode(isDarkMode ? "dark" : "light"); } function handleColorSchemeChange(event) { const newColorScheme = event.matches ? "dark" : "light"; setCurrentDarkMode(newColorScheme); } const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); mediaQuery.addEventListener("change", handleColorSchemeChange); // 监听应用可见性变化,回到前台时主动检查 function handleVisibilityChange() { if (!document.hidden) { checkCurrentColorScheme(); } } document.addEventListener("visibilitychange", handleVisibilityChange); // 组件卸载时清理监听器 return () => { mediaQuery.removeEventListener("change", handleColorSchemeChange); document.removeEventListener("visibilitychange", handleVisibilityChange); }; }, []);
这个办法的核心是:iOS17的PWA在系统配色切换后,不会主动触发change事件,但当应用重新被激活(从后台切回)时,我们可以主动查询当前的配色状态,更新应用的主题设置。
目前这个bug已经在苹果的开发者反馈系统中有相关报告,暂时只能用这类临时方案规避,等待苹果后续系统更新修复。
内容的提问来源于stack exchange,提问作者Dinislam Maushov
相关产品推荐
相关产品推荐

