前言
今天看阮一峰老师的微博,看到一个有趣的代码,用CSS部署点击监测代码,完全不依赖js,而且用户禁用js都无法关掉这个监测。
代码
CSS的核心是:active:after
和content: url()
。
<style type="text/css">
.track-xx:active:after {
content: url(track.php?xxxx=ooooo);
}
</style>
<a class="track-xx" href="http://www.baidu.com">111</a>
<a class="track-xx">111</a>
使用效果
可以先打开浏览器控制台的Network,观察请求。
你会发现,鼠标无论是点击代码里的哪个a标签,都会发出一个向track.php?xxxx=ooooo
的请求。虽然有这个请求,但是并没有打开这个页面。
机理
先说:active
这个很简单,就是a标签被点击的那一瞬间,鼠标按下去触发的状态。没有点击的前提下,永远不会触发这个状态。
然后说:after
和content: url()
的配合
:after
的作用是在元素之后新增内容,通常与content
配合使用。content
的值,可以是文本,也可以是url值。如果是url值,就需要用url()
包起来,浏览器将认为你是想把这个url当做图片来呈现。浏览器对这个URL的请求头里面是:
Accept:image/webp,image/apng,image/*,*/*;q=0.8
如果这个url真的是一个图片,那么就会在后面呈现出来,比如下图里的2个小图标,都是content生成的。
但是,如果url并不是图片地址,而是一个其他类型的网址,比如track.php?xxxx=ooooo
,会发生什么?浏览器不管那么多,照样当做图片来请求,然后把所谓的图片放到a标签的后面。既然咱们这个只是监控代码,当然不会返回图片,所以a标签后面什么也不会有。然而,我们请求了一次track.php?xxxx=ooooo
的目的就达到了。
补充
这个方案还有一个小优点,就是不会重复触发。你可以多点击几次<a class="track-xx">111</a>
,你会发现,track.php?xxxx=ooooo
总共只会请求一次,多次点击不会多次触发。因为这是浏览器对content
的特殊处理,会缓存这个URL。这样导致统计起来更为精确。