起因
先容我讲一个故事:
我呢,三妻四妾,有大老婆,还有二老婆,三老婆
今晚,我如往常,慢慢爬上大老婆的床,然后我们进行激烈地交流
可是,过了一会,我觉得一个成熟的男人,应该雨露均沾,不能太自私。
我去了二老婆的房门,此刻大老婆眼睁睁地看着我离开,只能等我再回来。
二老婆那玩到一半,又跑去了三老婆…
有次我甚至没玩尽兴,从家里出去,去了隔壁家
上面这个故事,听起来可能挺不道德,但你把这个故事中的女人,换成网站,这样看起来就比较正常了:
我打开浏览器,我并不会只访问一个网站,会访问知乎,百度的网站,京东的网站
今晚,我如往常一样,访问了知乎,愉快地观看大佬写的文章
可是,过了一会,我有点小问题想百度一下,我便新开了一个标签页,打开了百度的网站,此刻逼乎并没有关闭,还在那挂着
过了几分钟被百度的广告刺激,又打开了京东
有次甚至离开的浏览器,把浏览器挂在了后台,打开腾讯会议
我倒是爽了,可是网站就很难受了,我不把网站直接关闭,就把它挂在那,它得一直等我。
就像前段时间的一个电影《隐入尘烟》,里面有个剧情:男主出了村子,女主在村口等到深夜才等到。天气很冷,所以女主第一时间给男主递上温水瓶,男主一喝,差点被烫到,吓了一跳。
原来,女主等了很久,在等的时候,反复再给水加温,这样男主无论在什么时候回来,第一时间都能喝到热水。
网站也是这样,在等待用户重新回来的期间,JS代码并不会停止,这有时候会造成性能浪费。
这就好比:
女神一天就把我吊着,也不删,偶尔又搭理我一下,可是我就是忍不住频繁刷新微信,看看有没有她的消息,这该怎么办啊?
我很被动!
不能惯着!
女神喜欢吊我?原因是我太单纯了,我时刻都把女神放到心上,放到了第一位置。
有句话说得好,得不到回应的热情要懂得适可而止。
女神不把我当回事,那我干嘛把她当回事?
所以女神来找我玩,我就立马穿得帅帅气气;女神一走,我就不管了,该邋遢就邋遢,怎么简单怎么来。
我完全没必要每天都穿得西装革履,精心打扮,时刻等待女神下一次再找我约会。
找我?我就穿得像人样,不找就怎么简单怎么来。
这个生活中的逻辑,类比到前端也是差不多的,用户正在浏览我的网站,我的网站就好好表现;用户一离开,去看别人了,我就把某些吃性能,或者会对我服务器造成压力的功能给关闭;他来我就开,不来我就关。
怎么才能做到?
方法一:
使用这个属性进行判断:document.hidden
当用户正在浏览的时候,document.hidden会等于false,用户一离开,值就变为true
变true的情况有这些:
- 页面最小化
- 浏览器在后台运行
- 切换tab栏到其他页面
方法二:
利用,window.onblur & window.onfocus
这两个事件进行监听
onfocus触发的场景有这些:
- onblur状态下用户存在页面操作
- focus状态下tab页切换出去,又切换回来;
- focus状态下浏览器挂后台,又把浏览器切回来
onblur触发的场景有这些:
- 页面最小化
- 浏览器切换tab页面
- 页面中的任何弹窗,alert这种
- 把浏览器挂后台了
- 点击了非内容区域的可操作按钮(比如你点击了地址栏,点击了收藏按钮等等)
- 打开了浏览器开发控制台F12
- 操作了浏览器开发控制台F12
值得注意的是:这两个事件不会一直只触发一个事件,就像坐跷跷板一样,只会一上一下,交替触发
比如:你现在是focus状态,然后你疯狂点击网页内容,这并不会疯狂触发focus事件
总结
你如果只想简单判断用户是不是正在浏览我的网站,也就是用户的眼睛,能不能看到我网站的内容。这个时候,你采用第一种方法,是最有效的,他不会像第二个方法一样,细节这么多。
而第二种方法,在某些情况下,用户眼睛明明能看见网页内容,但就是会触发blur事件。这这这,这当然没错,存在即合理,在某些场景下,可能就是刚需。
- 第一种方法:你有没有看我?
- 第二种方法:你有没有认真地看我?
你第一次看这篇文章,如果感觉实在没耐心看,或者不好理解,你可以先复制我下面的代码,然后一边自己测试,一边看我提到的关键点。
第一种方法的测试代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>心月云——</title> </head> <body> <h1></h1> <button onclick="win()">点击</button> <script> let tag = document.querySelector('h1'); let flag = null; setInterval(_ => { if (document.hidden) { print_f12(document.hidden); tag.innerText = '你没有看我'; } else { print_f12(document.hidden); tag.innerText = '你正在看我'; } }, 100); //防止控制台一直打印 function print_f12(ee) { if (ee != flag) { if (ee) { console.log('---------分隔符'); console.log('你没有看我'); console.log('---------分隔符'); } else { console.log('+++++++++分隔符'); console.log('你正在看我'); console.log('+++++++++分隔符'); } flag = ee; } } function win() { alert('这是一个弹窗'); } </script> </body> </html>
第二种方法的测试代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>心月云——</title> </head> <body> <h1></h1> <button onclick="win()">点击</button> <script> let tag = document.querySelector('h1'); window.onfocus = _ => { console.log('+++++++++分隔符'); console.log('你正在看我'); console.log('+++++++++分隔符'); tag.innerText = '你正在看我'; } window.onblur = _ => { console.log('---------分隔符'); console.log('你没有看我'); console.log('---------分隔符'); tag.innerText = '你没有看我'; } function win(){ alert('这是一个弹窗'); } </script> </body> </html>
你是一个男人,但你老婆喜欢出轨,
如果你用了第一种方法,则表示为:
你只关心你老婆是否在家,在家就行了
而第二个方法,表示为:
除了在家外,还必须一直和我互动,只要没和我互动了,我就会觉得她出轨了
暂无评论内容