JavaScript

前端奇技淫巧之保持悬浮状态

先感慨一句, 一入前端深似海, 都是泪

经常要调前端样式, 有一些元素是只在鼠标悬停状态下才能显示, 那么, 怎么看和调试这些元素呢?

在 Chrome 等开发者工具里, 可以在 Element 那个选项卡右边的 Style 选项卡里点那个大头针图标, 将元素强制维持在 :hover 状态. 也可以在 Elements 左边的元素节点上点右键选状态

但这只是 CSS 上的搞法, 如果某个元素是 Javascript 悬浮事件弄出来的呢? 加 :hover 完全木用啊. 这时候可以用更奇葩的搞法: 暂停 Javascript 执行. 就是在开发者工具的 Sources 那个选项卡里, 调试 JS 那个地方有个暂停按钮, 按一下就好了

围观群众: 你特么一定是在逗我, 明明是鼠标悬停才能触发的事件, 鼠标一移开去点暂停键那不就没了悬停状态了么

当然了… 这时候是没法腾出手来按那个按钮的, 但是我们有快捷键啊, OS X 下是 F8Cmd + \, 剩下的就不用过多解释了

为什么通过前端 .js 记用户日志会丢数据

在这个数据驱动的时代, 做什么事情没有数据光凭感觉是不可能了, 今年夏天开始接手新鲜事的策略, 先推日志的丰富化和标准化, 关于点击日志, 解决方法无外乎这么三种:

1. 在点击 url 串上带上丰富信息, 然后在后续处理的前端 (比如 nginx 或 apache) 上打印请求日志, 把请求日志汇总过滤得到想要的
2. 做点击跳转, 用户点击后先跳到自己服务器上, 然后由自己的服务器做重定向, 并记录这一次请求
3. 前端 JavaScript 监控用户鼠标行为, 并及时上报到服务器

这三种方法也分别有各自的优缺点, 当时分析的是

1. 这个必须要保证点击后还是跳到自己的服务器上, 否则跳出去的点击无法跟踪. 不太可能丢日志, 只是过滤会多道工序. 目测 Facebook 曾经是这样干的
2. 绝对完整的记录. 不过需要新增服务器响应跳转请求, 并且如果跳转服务挂了会让用户压根到不了 url 指向的地方. 目前所有的广告服务都是这样 (而且点击串加密), Google 的网页搜索很早就是这样, 百度跟 360 干上后也换成了这种. 根据度厂员工在新浪微博上跟别人的讨论, 即使是百度网页搜索那么大的量, 算上灾备最多 50 台跳转服务器可以搞定 (根据公开资料, 百度每天网页搜索量在十亿这个量级, 按搜索引擎页面点击率 30% 算, 每天至少三亿次点击跳转请求)
3. 可记录的东西非常多, 不仅仅是点击, 而且还有一些页面上的其他 js 行为 (如悬浮, js 展开元素等), 但是会丢 15%~20% 的数据. 跟 360 干架前百度的网页搜索用的这种方式, 刚看了下 FB 也是这种了

其他的优缺点都比较容易明白, 但是 js 模式会丢 15%~20% 的数据这个非常难理解, 之前我只听到 20% 这个比例, 但是没人告诉我为什么, 昨天跟死猫君说日志的时候他也提到他们那边用 js 记的日志也有 15% 的丢失率, 但是他也只是听说这个比例而不明白原理.

今天跟前端同学讨论, 终于搞懂了为什么是这样. 后端的思维是每发生一次事件就打一条日志, 所以极难发生日志丢失的问题. 而前端不能每发生一次事件就向服务器发请求打一次日志, 这样会带来很大的网络开销并拖慢用户的浏览器, 所以前端都是把要纪录的行为在用户端先缓存, 等积累够若干条或过了若干秒后才向服务器汇总上报, 如果在这个上报条件触发前浏览器崩溃掉, 那日志就没了, 或者用户关掉浏览器也会丢掉这部分数据 (据说有一些方式可以响应关闭事件并上报日志, 但具体方式不了解, 另外前端同学反馈 IE6 下丢数据现象更严重). 所以丢数据这事其实是用户流畅度体验和数据完备性的一个平衡, 如果让用户卡一点那丢失比例就低一点. 另外接 js 汇报日志的服务器压力也是一个要考虑的点, 因为如果真用 js 汇报, 那一定就不止点击这点数据了, 鼠标滚轮, 悬停等事件显然是能有都有, 服务器不一定扛的过来.