使用jQuery操作data-attr的注意事项

今天又一次掉进这个坑里面。

data-attr是HTML5里面的一个新属性(其实这东西都好多年了),方便CSS\JS去读取DOM上面的属性值。

jQuery在很久之前,就封装了一个 $.fn.data() 的方法,而该方法是将数据存放在DOM内部的一个数据对象中。

在data-attr来了之后, $.fn.data() 也支持用来读取DOM上面的data-attr,但是,它会缓存这个结果到DOM内部的数据对象,他会缓存,缓存,缓存。

后续对这个key的所有读写操作,其实都是操作的这个数据缓存,而DOM上面的data-attr并不会发生任何变化。

The data- attributes are pulled in the first time the data property is accessed and then are no longer accessed or mutated (all data values are then stored internally in jQuery).

如果你有一些样式,是希望同步这个data-attr的状态的,用 $.fn.data() 来操作就会发生一些奇怪的事情(之前一次没细看jQuery这块的实现,只是发现出来的效果怪怪的),建议改用 $.fn.attr() 方法或者JS原生方法。

附:

为了和 $.data() 做区分,我这里用 $.fn.attr() 和 $.fn.data() 这种jQuery原型链上的方法来表示 $(selector).data()

Generator异步隐藏测试

直接贴代码

贴个结果

嗯,结果有点超乎我的意料,我以为Generator函数这么特别,会卡住流程。

这样有没有Generator感觉都是一样的,只不过把异步的包在一个函数里面,对外没有暴露出来而已

嗯,一次失败的研究,继续找找其他应用场景。

微信WebView会话时长

主要想测试下微信里面的会话cookie的实际作用时间是多久。

一般浏览器的会话cookie,是当浏览器退出后,会话cookie即失效。

猜想微信的会话cookie,应该是退出网页后失效。

但实际测试结果,却并非如此,微信会一直保留这个会话cookie,直到微信进程退出。

从WebView返回微信主界面 cookie不失效
返回手机系统主界面 cookie不失效
后台关闭微信进程 cookie失效
微信切换账号 cookie失效

测试设备:

  • iOS9 – 微信6.3.6
  • Android 4.4.2 – 微信6.3.5

当然,估计还和手机内存有关,内存小的机型,这部分临时存储就会被系统释放掉。

附:测试地址

家家都有本难念的经

常年不在妈的身边,表弟替我承担了很多本该我来承担的压力和孝心,这个假期,我来接力

人生最难熬的不是亲人的离去,而是好好的人在眼前,但病情却被医生判了死刑,未来注定是反反复复,看不到希望

深入Sever-Sent Events

Server-Sent Events(SSE)实现了服务器向浏览器单向推送消息的能力,前面文章有提到过,今天这里来详细讲解下。

SSE是什么

SSE设计了两个新东西

  • EventSource接口
  • “事件流”数据格式

EventSource接口详解

整个SSE在浏览器端的API,就如上5个,非常简单,但是为我们实现了大量的细节功能。

例如连接意外断开后,浏览器会自动重连,并发送上一次的消息ID,便于服务端重传丢失的消息和恢复数据流。

“事件流”协议

下面是一个SSE事件流的HTTP报文

里面有几个关键点:

  • 请求头
    • 带上Accept: text/event-stream
  • 响应头
    • 带上Content-type: text/events-stream
    • 带上Transfer-Encoding: chunked
  • 响应内容
    • retry 连接意外断开后,浏览器重新发起连接的时间间隔
    • data 消息的有效载荷,可以是普通字符串类型,或者是JSON对象
    • event 事件类型
    • id 可以用来标记消息序号,便于重连后能恢复数据流,重连时会带上Last-Event-ID来帮助恢复事件流
    • \n\n 用来分割每条消息边界

SSE额外注意事项

SSE所定义的“事件流”格式,让不支持的SSE的浏览器,可以通过XHR模拟来优雅降级。

SSE的数据为UTF-8数据,不支持二进制流,但是支持使用服务端的Gzip进行体积压缩。

SSE的“事件流”格式,已经定义了id作为消息序号,不需要业务在消息的内容中再次定义。

SSE使用场景

例如各种Dashboard的实时采集量反馈

例如实时投票结果等

JS常用库解密-FastClick

众所周知,移动端在处理点击事件的时候,会有300毫秒的延迟。恰恰是这300毫秒的延迟,会让人有一种卡顿的体验。

这300毫秒的原因,在于早期浏览器的实现中,浏览器不知道用户触摸后,到底想做什么,所以故意等待300毫秒,再触发click事件。

既然我们已经知道了原因了,怎么解决呢?

方案1-粗暴治标法

因为浏览器对click事件的处理,有300ms的延迟,而touchstart几乎是立即执行的,估将所有click事件的监听,改为touchstart事件的监听,即可消除这300ms的延迟。

但这样副作用也很大,移动端的交互体验全靠触摸,touchstart将会干扰其他交互行为的处理,例如滚动、拖拽等。

方案2-模拟修复法

既然浏览器有这300ms的延迟,那么我们来代替浏览器判断,手动触发click事件,这也是fastClick的解决方案。

fastClick的核心代码

这里可以看到,FastClick在touchEnd的时候,在符合条件的情况下,主动触发了click事件,这样避免了浏览器默认的300毫秒等待判断。为了防止原生的click被触发,这里还通过event.preventDefault()屏蔽了原生的click事件。

我们来看看他是怎么模拟click事件的

我们在网上搜索fastClick,大部分都在说他解决了zepto的点击穿透问题,他是怎么解决的呢?就是上面最后一句,他模拟的click事件是在touchEnd获取的真实元素上触发的,而不是通过坐标计算出来的元素。

最后,原理虽简单,但还是建议大家直接用FastClick而不是自己再实现一个。因为,你看他源码里面的注释,有很多特殊情况的补丁的,自己实现一个精简版难免会漏这漏那。

手札《nginx – A Practical Guide to High Performance》

今晚无意发现Nginx官方出了一本Guide to Hight Performance的书,翻了一下,有一些蛮有意思的点。

Virtualhosts 虚拟主机

这段配置,支持用一个server块来配置所有虚拟主机的作用。

只要有域名绑定到该主机上,Nginx就会查找该域名对于的root目录。

跑多个虚拟主机的话很方便,一次定义即可,每次添加新的虚拟主机,只要开目录,配置DNS指向即可,省去了服务器端的解析配置工作。