好吧,我只是个标题党,ie6 下根本无法使用跟 h5 沾边的 localStorage。今天要向大家介绍的是 ie 特有的 userData 的存储方式,并且对它进行封装,使得不支持 localStorage 的浏览器能像使用 localStorage 一样使用 userData。

userData


在 IE5.0 中,微软通过一个自定义行为引入了持久化用户数据的概念。用户数据允许每个文档最多 128KB 数据,每个域名最多 1MB 数据。要使用持久化用户数据,首先必须如下所示,使用 CSS 在某个元素上指定 userData 行为:

<div style='behavior:url(#default#userData)' id='dataStore'></div>

一旦元素使用了 userData 行为,那么就可以使用 setAttribute() 方法在上面保存数据了。为了将数据提交到浏览器缓存中,还必须调用 save() 方法并告诉它要保存到的数据空间的名字(任意取):

var dataStore = document.getElementById('dataStore');
dataStore.setAttribute('name', 'zichi');
dataStore.save('personInfo');

下次页面载入之后,可以使用 load() 方法指定同样的数据空间名称来获取数据:

var dataStore = document.getElementById('dataStore');
dataStore.load('personInfo');
alert(dataStore.getAttribute('name'));

对 load() 的调用获取了 personInfo 数据空间的所有信息,并且使数据可以通过元素访问。只有在载入确切完成之后数据才能使用。如果 getAttribute() 调用了不存在的名称或者是尚未载入的名称,则返回 null。

我们可以通过 removeAttribute() 方法删除某元素数据,删除之后用 save() 来提交更改:

dataStore.removeAttribute('name');
dataStore.save('personInfo');

与 localStorage 不同的是,userData 有个 expires 属性,顾名思义能设置过期时间。

var dataStore = document.getElementById('dataStore');
dataStore.setAttribute('name', 'zichi');

var expires = new Date();
expires.setSeconds(expires.getSeconds() + 1);  // 设置为 1 秒后过期
dataStore.expires = expires.toUTCString();
dataStore.save('personInfo');

// 2 秒后查看结果
setTimeout(function() {
  var dataStore = document.getElementById('dataStore');
  dataStore.load('personInfo');  // 如果不 load 会 alert 'zichi'
  alert(dataStore.getAttribute('name'));  // null
}, 2000);

userData 封装


一般的客户端存储,如果支持 localStorage 的话会优先使用 localStorage,碰到一些低版本的 ie 则会使用 userData,需要根据浏览器进行判断选择,如果能把 userData 的 api 封装成 localStorage 的 api 就方便多了。

localStorage 一般使用较多的 api 有 setItem()、getItem()、romoveItem() 以及 clear()。我们把 userData 的使用方式也封装成这些 api。主要思路是把 key-value 键值对都绑在 body 标签中,每个键值对采用一个数据空间存储,数据空间的名字也用 key 值。另外为了照顾 clear() api,还需要把每个 key 值的信息存到另外一个元素标签中,这里用了 html 标签进行存储。(因为用了 body 和 html 标签做宿主,所以以下的 js 需引入在 body 元素后,千万不能引入在 head 中)

!window.localStorage && function() {
  window.localStorage = {};
  var prefix = 'data-userdata'
    , body = document.body
    , html = document.documentElement
    , mark = function(key, isRomove) {  // key 值字符串
    try {
      html.load(prefix);
      var tmp = html.getAttribute(prefix);
      tmp = !tmp ? '' : tmp;
    } catch(e) {
      tmp = '';
    }

    var reg = tmp.indexOf(key) === 0 ? new RegExp('\\b' + key + '\\b,?', 'i') : new RegExp(',?\\b' + key + '\\b', 'i')
      , hasKey = reg.test(tmp) ? true : falocalStoragee;

    tmp = isRomove ? tmp.replace(reg, '') : hasKey ? tmp : tmp === '' ? key : tmp.split(',').concat(key).join(',');
    html.setAttribute(prefix, tmp);
    html.save(prefix);
  };

  body.addBehavior('#default#userData');
  html.addBehavior('#default#userData');

  // getItem()
  localStorage.getItem = function(key) {
    try {
      body.load(key);
      return body.getAttribute(key);
    } catch(e) {
      return null;
    }
  };

  // setItem()
  localStorage.setItem = function(key, value) {
    body.setAttribute(key, value);
    body.save(key);
    mark(key, false);
  };

  // removeItem
  localStorage.removeItem = function(key) {
    body.removeAttribute(key);
    body.save(key);
    mark(key, true);
  };

  // clear()
  localStorage.clear = function() {
    try {
      html.load(prefix);
      var attrs = html.getAttribute(prefix).split(',')
        , len = attrs.length;

      for (var i = 0; i < len; i++) {
        body.removeAttribute(attrs[i]);
        body.save(attrs[i]);
      }

      html.setAttribute(prefix, '');
      html.save(prefix);
    } catch(e) {

    }
  };
}();

如何在 ie6 中使用 "localStorage"的更多相关文章

  1. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  2. 如何在SpringBoot中使用JSP ?但强烈不推荐,果断改Themeleaf吧

    做WEB项目,一定都用过JSP这个大牌.Spring MVC里面也可以很方便的将JSP与一个View关联起来,使用还是非常方便的.当你从一个传统的Spring MVC项目转入一个Spring Boot ...

  3. 如何在latex 中插入EPS格式图片

    如何在latex 中插入EPS格式图片 第一步:生成.eps格式的图片 1.利用visio画图,另存为pdf格式的图片 利用Adobe Acrobat裁边,使图片大小合适 另存为.eps格式,如下图所 ...

  4. 如何正确的使用json?如何在.Net中使用json?

    什么是json json是一种轻量级的数据交换格式,由N组键值对组成的字符串,完全独立于语言的文本格式. 为什么要使用json 在很久很久以前,调用第三方API时,我们通常是采用xml进行数据交互,但 ...

  5. [原创]如何在Parcelable中使用泛型

    [原创]如何在Parcelable中使用泛型 实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示: public static cl ...

  6. 如何在springMVC 中对REST服务使用mockmvc 做测试

    如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试  spring 集成测试中对mock 的集成实在是太棒了!但 ...

  7. 如何在tomcat中如何部署java EE项目

    如何在tomcat中如何部署java EE项目 1.直接把项目复制到Tomcat安装目录的webapps目录中,这是最简单的一种Tomcat项目部署的方法,也是初学者最常用的方法.2.在tomcat安 ...

  8. 【转】我是如何在SQLServer中处理每天四亿三千万记录的

    原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ...

  9. 如何在JAVA中实现一个固定最大size的hashMap

    如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录 ...

随机推荐

  1. MySQL锁问题

    MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎 采用的是表级锁:BDB存储引擎采用的是页面锁,但也支持表级锁:InnoDB存储引擎 ...

  2. Rollback 语句 在08R2版本

    有时候为了数据完整我们会启用到事务.正常的时候一帆风顺,如果rollback 呢? 最简单的一个回滚 IF OBJECT_ID('PROC1') IS NOT NULL     DROP PROCED ...

  3. Linux服务器文件删除空间未释放的问题

    一.问题起源 在Linux系统中,通过rm删除文件将会从文件系统的目录结构上解除链接(unlink),如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件磁盘空间也一直被占用 这样就 ...

  4. spring多数据源的处理 mybatis实现跨库查询

    实现Myibatis动态sql跨数据库的处理 Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不 同于常见 ...

  5. java学习之 反射

    以前学习java只是学习了基本语法操作,各种常用方法的使用,随着慢慢学习,很多大神都觉得要想成为大神,就必须把java的反射给理解透,这样我就带着好奇的心去学习到底反射是什么玩意,所以就上网找资料学习 ...

  6. 高性能MySQL笔记 第4章 Schema与数据类型优化

    4.1 选择优化的数据类型   通用原则   更小的通常更好   前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少.   简单就好   简 ...

  7. 聚合及UML表示

     聚合聚合是一种特别类型的关联,用于描述“总体到局部”的关系. 聚合分成: 基本聚合与合成聚合   基本聚合: 基本聚合一般也简称为聚合(Aggregation).在基本的聚合关系中, 部分类(B)  ...

  8. 创建Windows Azure内部负载均衡器

    与普通的负载均衡器一样,Windows Azure内部负载均衡器也是四层的.内部负载均衡器会被分配一个内网地址,只能从虚拟网络内部访问,包括VPN和ExpressRoute. 内部负载均衡器通常被用于 ...

  9. selenium如何高亮某元素和操作隐藏的内容

    高亮元素的思路是: 1.找到要高亮的元素 2.对该元素执行js,更改style达到高亮效果. 操作隐藏的内容思路: 1.可以用Actions的moveToElement,使鼠标悬停在触发隐藏内容的元素 ...

  10. (三)策略模式-C++实现

    策略模式:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换,本模式使得算法可独立于使用它的客户而变化. 三种角色: 1.策略:一个抽象类,这个接口定义了若干个算法标识,即多个虚函数,这些个 ...