需求

我在做一个体验

当用户 submit enquiry 后会 window.open 开启 WhatsApp。而当用户关闭 WhatsApp 回来网站后,会 show 一个 feedback message。

实现思路

关键就在如何感知到,用户从 WhatsApp 切换回到了网站。

参考: Detect When Users Switch Tabs using JavaScript

监听 visibilitychange,然后通过 document.visibilityState 得知是 hidden or visible。

hidden 表示 leave tab,visible 表示 back to tab。

Android 鬼

本来是很简单的东西,但不知道是不是我手机的问题。Android 在开启 WhatsApp 的时候会触发 2 次。

Windows:open WhatsApp > hidden > close WhatsApp > visible

Android:open WhatsApp > hidden > visible > hidden > close WhatsApp > visible

显然 Windows 是正常的,Android 跑了多一次。

Workaround 就是尽可能判断出 Android 的情况,不要被它搞乱。我没有太认真去思考 right way,我觉得多半是一个 bug 来的,所以暂时解决就好了。

参考代码注释理解吧

const beforeWindowOpenTime = performance.now();
window.open(generateWhatsAppLink(whatsAppNumberBS.value, message), '_blank'); // note 解忧:
// 这里有一个 user back from WhatsApp 后 show submitted feedback 的体验。
// 它比较复杂,因为手机有 bug,
// 正常情况下 visibilitychange 会 dispatch when user leave/enter tab,离开 state = hidden,回来 state = visible。
// so when window open WhatsApp, dispatch lever tab 咯, when user close WhatsApp, dispatch enter tab 咯.
// 但是我的 android 有鬼。
// when window open WhatsApp,它会先 leave + enter 1 次, 紧接着又 leave 1 次, 直到 user back
// 所以下面代码需要顾虑它第一轮假的 leave + enter
const [visible$, hidden$] = partition(
fromEvent(window, 'visibilitychange').pipe(share()),
() => document.visibilityState === 'visible',
); // 监听第一次 visible
visible$.pipe(take(1)).subscribe(() => {
const now = performance.now();
// 如果第一次 visible 超过 1 秒
if (now - beforeWindowOpenTime >= 1000) {
// 直接 show feedback,因为 android 鬼是很快的,绝对不会超过 1 秒
showSubmittedFeedback();
return;
} // 如果小于 1 秒,那可能是 android 鬼,或者 user 真的很快就 close WhatsApp
// 我们尝试监听 hidden,如果是 android 鬼,那么 2 秒内会触发 hidden
// 如果 2 秒后没有 hidden 那判定是 user close 很快。
hidden$.pipe(take(1), timeout({ first: 2000 })).subscribe({
next() {
// android 鬼的话,等待下一次的 visible 表示 user close
visible$.pipe(take(1)).subscribe(() => showSubmittedFeedback());
},
error() {
// user close 的话,直接 show feedback
showSubmittedFeedback();
},
}); function showSubmittedFeedback() {
setTimeout(() => {
submitFeedbackReCaptchaContainer.submitFeedbackReCaptchaContainerController.showSubmittedFeedback();
}, 1000);
}
});

CSS & JS Effect – Do something on enter/leave window tab的更多相关文章

  1. #3使用html+css+js制作网页 番外篇 使用python flask 框架 (II)

    #3使用html+css+js制作网页 番外篇 使用python flask 框架 II第二部 0. 本系列教程 1. 登录功能准备 a.python中操控mysql b. 安装数据库 c.安装mys ...

  2. CSS & JS 制作滚动幻灯片

    ==================纯CSS方式==================== <!DOCTYPE html> <html> <head> <met ...

  3. Batsing的网页编程规范(HTML/CSS/JS/PHP)

    特别注意!!!我这里的前端编程规范不苟同于Bootstrap的前端规范. 因为我和它的目的不同,Bootstrap规范是极简主义,甚至有些没有考虑到兼容性的问题. 我的规范是自己从编程实践中总结出来的 ...

  4. 【转】Maven Jetty 插件的问题(css/js等目录死锁)的解决

    Maven Jetty 插件的问题(css/js等目录死锁,不能自动刷新)的解决:   1. 打开下面的目录:C:\Users\用户名\.m2\repository\org\eclipse\jetty ...

  5. Css Js Loader For Zencart

    Css Js Loader 描述:这个插件很早就出来了,可能知道人非常少 这个插件的功能是整合所有的网站的CSS和JS内容到一个文件里边. 因为CSS和JS文件到了一个文件,加快了程序的运行 在配合其 ...

  6. 购物车数字加减按钮HTML+CSS+JS(有需要嫌麻烦的小伙伴拿走不谢)

    之前在写详情页的时候,如下图 因为自己嫌麻烦,就去看其他网站是怎么写的,想直接拿来用,后来看来看去觉得写得很麻烦,于是最后还是决定自己写,附上HTML+CSS+JS代码,一条龙一站式贴心服务2333 ...

  7. vs合并压缩css,js插件——Bundler & Minifier

    之前做了一个大转盘的抽奖活动,因为比较火,部分用户反馈看不到页面的情况,我怀疑js加载请求过慢导致,所以今天针对之前的一个页面进行调试优化. 首先想到的是对页面的js和css进行压缩优化,百度了下vs ...

  8. 使用CSS/JS代码修改博客模板plus

    之前对CSS/JavaScript了解还不深,只是把模板的CSS胡乱修改了几个属性.最近正好也在做一个网站的前端,学习了不少东西,再来改一改~ 上次最后之所以铩羽而归,是因为从CSS里找不到那些#和. ...

  9. nginx资源定向 css js路径问题

    今天玩玩项目,学学nginx发现还不错,速度还可以,但是CSS JS确无法使用,原来Iginx配置时需要对不同类型的文件配置规则,真是很郁闷,不过想想也还是很有道理.闲暇之际,把配置贴上来.#user ...

  10. IIS7的集成模式下如何让自定义的HttpModule不处理静态文件(.html .css .js .jpeg等)请求

    今天将开发好的ASP.NET站点部署到客户的服务器上后,发现了一个非常头疼的问题,那么就是IIS7的应用程序池是集成模式的话,ASP.NET项目中自定义的HttpModule会处理静态文件(.html ...

随机推荐

  1. linux系统&自动清理日志实现脚本

    文章来源:https://blog.csdn.net/lakelise/article/details/93711932 编写清理脚本,添加到定时任务中:创建可执行文件cd /hometouch cl ...

  2. oeasy 教您玩转linux 之 010209 装酷利器 hollywood

    我们来回顾一下 上一部分我们都讲了什么? 屏幕故障风格的软件包bb 可以设置音频 这次装一个酷 下个hollywood软件包 apt show hollywood apt search hollywo ...

  3. AT_abc218_d 题解

    洛谷链接&Atcoder 本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读. 题目简述 给定一个平面内的 \(N\) 个点的坐标,求这 \(N\) 个点中选 \(4\) 个点可构成 ...

  4. c++17 using继承所有构造函数

    //使用using继承所有的构造函数 #include "tmp.h" #include <iostream> using namespace std; struct ...

  5. 滑块解锁-scratch编程作品

    程序说明: <滑块解锁>是一款基于Scratch平台制作的益智类小游戏.游戏中存在多个黄色滑块阻挡红色滑块通往出口的路径.玩家需要通过逻辑思考和精确操作,滑动黄色滑块以开辟道路,使红色滑块 ...

  6. Nuxt.js必读:轻松掌握运行时配置与 useRuntimeConfig

    title: Nuxt.js必读:轻松掌握运行时配置与 useRuntimeConfig date: 2024/7/29 updated: 2024/7/29 author: cmdragon exc ...

  7. 【Java】关于获取注解的问题发现

    同事设置了个注解,想用Spring获取的Bean来找到Class获取注解 但是发现是空的,在查看的Spring返回Bean之后,发现这个Bean对象并不是原生的实例 而是被Spring代理增强的代理对 ...

  8. 【托普斯的力场】—— ARPG游戏《艾尔登法环》中的人物:托普斯

    地址: https://youtube.com/shorts/oSIbOQ_r4fA?si=F-knFwjZ3iPXqPeS https://www.bilibili.com/video/BV1fV4 ...

  9. ZPL Viewer工具网站

    新上线的ZPL Viewer工具网站 大家好! 在工作中,我们经常需要设计和预览ZPL(Zebra Programming Language)文件.以前,我一直使用ZPL Design这类工具,但后来 ...

  10. C语言操作时间函数time.ctime,实现定时执行某个任务小例子

    时间操作函数在实际项目开发中会经常用到,最近做项目也正好用到就正好顺便整理一下. 时间概述 由上图可知: 通过系统调用函数time()可以从内核获得一个类型为time_t的1个值,该值叫calenda ...