HTML5 Storage APIs

因为太久没用这些东西,之前被人问起时只能勉强答出两个,并且连事件也不记得,只好把常用的列出来强化记忆了。

localStoragesessionStorage 的 APIs 在行为表现上是一致的,以下以 localStorage 为例,而 globalStorage 因为不是标准,所以略过。

函数和属性:

setItem(key, value)

valuekey 为名存入 localStorage

keyvalue 理论上可接受任何类型,但实际会通过 String(value) 转换为字符串,所以需慎用,比如 Object 会转换成 '[object Object]'null 会转换成 'null'

localStorage.setItem('hello', 'Chris')
localStorage.key(0) + ' ' + localStorage.getItem('hello') // 'hello Chris'

localStorage.clear()
var obj = { str: 'an object' }
localStorage.setItem(obj, { posts: [{}, {}] })
localStorage.key(0) // '[object Object]'
localStorage.getItem(obj) // '[object Object]'
var otherObj = { str: 'another object' }
localStorage.setItem(otherObj, true)
localStorage.getItem(obj) // 'true'

localStorage.clear()
localStorage.setItem(null, null)
localStorage.getItem(null) // 'null'

getItem(key)

要注意 String() 的问题。

key 不存在,getItem() 会返回 null,如果在 setItem() 时并没有进行严格验证的话,建议同时判断是否为 'null' 来确定是否存在。

访问 key/value 的其他方法

localStorage 可以像数组一样操作,而 key 也会作为普通对象的属性一样被访问。

localStorage['hello'] = 'world'
localStorage.hello // 'world'
localStorage.hello = 'Chris'
localStorage['hello'] // 'Chris'

removeItem()clear()

一个删除单个,一个删除全部,不返回任何值,key 不存在时也不会报错。

key(keyID)

返回指定 ID 的 key 名字。

keyID 只接受整数,因为会通过 Math.floor(keyID) 来转换,所以支持非整数,如 '1.1''1a'true 等等,只是结果为 NaN 时取 0;若不存在,返回 null

已知问题:

  • Chrome v25 和 Firefox v19 的行为不一样:Chrome 会将 keys 按照字符串大小进行正排序,而 Firefox 则几乎是乱序,不可预测 key 的位置。
localStorage.setItem('google', 'what the hell?')
localStorage.setItem('miscrosoft', 'not bad')
localStorage.setItem('apple', 'great')

localStorage.key(0) // Chrome: apple
localStorage.key(1) // Chrome: google

length

返回 key 的总数。

事件

目前只支持一个事件:storage

if (window.addEventListener) {
  window.addEventListener("storage", handle_storage, false);
} else {
  window.attachEvent("onstorage", handle_storage);
};

这段代码我偷懒从 Dive Into HTML5 搬过来的,专有的事件属性如下:

  • key:不解释
  • oldValue:旧值
  • newValue:新值
  • url:页面的 URL

url 有点特殊,原来是叫 uri 的,所以要兼容某些浏览器的话,最好两个都判断,较新的标准浏览器应该没有这个问题。

此事件不可终止,并且只有在 setItem()removeItem()clear() 确实影响了值才会触发:

localStorage.setItem('hello', 'world') // will fire
localStorage.clear() // will fire
localStorage.clear() // will not fire

另外,对触发页面的要求也很特别:会触发事件的页面并不是执行修改操作的页面,而是已打开的、共享同一个储存区的其他页面

最后,事件绑定只能绑定在 window 上。

以上仅在 Chrome v25 和 Firefox v19 上测试过。