HTML5中的data-*属性
我们往往会根据需要在HTML标记上添加自定义的属性来存储和操作数据,我们自定义的属性名字也千奇百怪,五花八门。我们可以通过原生的
getAttribute()或jQuery中的.attr()来获取我们自定义的属性。但是前端技术在向着规范化前进。HTML5标准规定,自定义的属性都已data—*开头,这样就区分开了固有属性和自定义属性。HTML代码如下:
<div id="testDiv" data-cname="张三" data-e-name="zhangsan" data-myName="my name is zs.">测试在元素上存储一个key-value</div>
$(document).ready(function(){
var el = document.getElementById("testDiv");
console.log(el.dataset.cname);//=>张三
el.dataset.cname = "ZS";//设置值为"ZS"
console.log(el.dataset.cname);//=>"ZS"
console.log("jQuery data:", $("#testDiv").data("eName") );
$("#testDiv").data("eName", "abcefg");
console.log("jQuery data:", $("#testDiv").data("eName") );
console.log("遍历testDiv上的自有属性");
$.each(el.dataset, function(key, value){
console.log(key+":"+value);
});
//遍历testDiv上的自有属性
//cname:ZS
//eName:zhangsan
//myname:my name is zs.
<span style="white-space:pre"> </span>
});
在获取自定义属性的值时,使用dataset属性,然后通过自定义属性(这时去掉data-前缀)的名称去获取值。dataset是JS5规范中新增加的属性,用于和data-*配合使用。
通过each打印的结果,我们需要注意:
1,如果data-后面包含了“-”,例如 date-e-name,"-"会去掉,并转换成为骆驼峰式的命名 eName。这是因为JSON Object 的key不能包含”-“。
2,如果data-后面的单词有大写,例如 myName,将会转存成小写 myname。这里就不理解为什么会转换成小写了,JSON Object的key是区分大小写的。求高人指定??
3,如果你想删除一个data-*属性,请使用 delete dataset.cname或者dataset.cname=null;
data-*属性看起来很好,但是不幸的是只有在Chrome 8+ Firefox(Gecko) 6.0+ Internet Explorer 11+ Opera 11.10+ Safari 6+的浏览器中实现了此标准。如果你的脚步需要兼容各主流浏览器的不同版本建议还是使用原生的getAttribute()或jQuery中的.attr()。
jQuery中的.data()
jQuery中的.data()方法作用:在jQuery对象对应的DOM元素上获取或存放key-value对。我们可以通过html5的data-*属性在元素上存取数据,在jQuery也可以通过data()来实现。data()方法有多个重载,传递一个参数是获取value值,传递两个参数是存储或覆盖已存在的值,传递一个JSON Object是在元素上存储或覆盖已存在的多个key-value对。如果通过data() 在元素上存储key-value,value可以是一个对象,而不是像data-*只能存储一个字符串的value。下面给出一个综合示例:
<script id="jquery_183" type="text/javascript" class="library" src="//cdn.bootcss.com/jquery/2.2.0/jquery.js"></script>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="testDiv" data-cname="张三" data-e-name="zhangsan" data-myName="my name is zs.">
测试在元素上存储一个key-value
</div>
</body>
</html>
$(function(){
function printVlaue(){
//通过data()在testDiv元素上存储 {ename:zhangsan} 健/值对。
$("#testDiv").data("ename", "zhangsan");
//修改data()通过 data-* 属性存储的值
$("#testDiv").data("cname", "我是张三");
console.log( "获取通过data()存储在testDiv元素上的ename值:", $("#testDiv").data("ename") );
console.log( "获取通过 data-* 存储在testDiv元素上的cname值:", $("#testDiv").data("cname") );
//$("#testDiv").jQueryremoveAttr("data-"+"abc");
console.log( "获取ename值:", $("#testDiv").data("ename") );
console.log( "获取cname值:", $("#testDiv").data("cname") )
console.log("删除testDiv元素上 ename 和 cname 键/值对。");
$("#testDiv").removeData("ename");
$("#testDiv").removeData("cname");
console.log("输出 eanem 和 canme 对应的值,看是否已经删除");
console.log( $("#testDiv").data("ename") );
console.log( $("#testDiv").data("cname") );
};
$("<button>获取值</button>").appendTo("body").bind("click", printVlaue);;
console.log("debug use.");;
});
/*
获取通过data()存储在testDiv元素上的ename值: zhangsan
获取通过 data-* 存储在testDiv元素上的cname值: 我是张三
获取ename值: zhangsan
获取cname值: 我是张三
删除testDiv元素上 ename 和 cname 键/值对。
输出 eanem 和 canme 对应的值,看是否已经删除
undefined
张三
*/
从上例中我们可以看出,.data()可以获取通过data-*属性存储的值。但是通过.data()修改data-*属性的值不会显示在HTML标记中,我们只是通过.data()在元素存储了一个新值。.removeData()也不能删除通过data-*存储的数据。由于jQuery是一个通用的JS框架,最浏览器兼容性做的非常好,大多数情况,我们应该通过.data()在元素上存取数据(有一个好处是可以存储一个对象)。如果我们必须通过data-*来存取和修改数据,建议使用JS5的dataset属性,这个属性的兼容问题,我们可以通过写jQuery插件来解决。这是我的插件代码,如下:
<script id="jquery_183" type="text/javascript" class="library"
src="//cdn.bootcss.com/jquery/2.2.0/jquery.js"></script>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="testDiv" data-cname="张三" data-e-nAme="zhangsan" data-myName="my name is zs.">
测试在元素上存储一个key-value
</div>
</body>
</html>
$(document).ready(function(){
function printValue(){
var $testDiv = $("#testDiv").udDataAttr();
console.log("udDataAttr get()=>", $testDiv.get("cname") );
$testDiv.set("cname", "set 张三");
console.log("udDataAttr get()=>", $testDiv.get("cname") );
console.log("打印所有已data-*开头的属性和值=>", $testDiv.dataset());
console.log("udDataAttr get e-name=>", $testDiv.get("e-name") );
//var el = document.getElementById("testDiv");
//console.log("el.dataset.eName=>", el.dataset.eName);
};
$("<button>获取值</button>").appendTo("body").bind("click", printValue);
console.log("debug use.");
});
(function($, window){
//user-defined Attribute
var plugName = "udDataAttr";
$.fn[plugName] = function(){
var $self = $(this),
obj = ($self.length && $self[0].dataset) || null;
return {
get: function(name){
return obj===null? $self.attr("data-"+name) : obj[ this._format(name) ];
}
,set: function(name, value){
if(obj === null){
$self.attr("data-"+name, value);
}else{
obj[ this._format(name) ] = value;
}
return $self;
}
,dataset: function(){
var newObj = {};
if(obj === null){
$.each(obj, function(key, value){
newObj[key] = value;
});
}else{
newObj = $self.data(); //获取所有以data-*开头的属性
}
return newObj;
}
/*
* 将name转换成dataset可识别的格式。
* 例如:e-name 转换成 eName
* 总感觉 _format()的实现不是最优的,求高手给出实现
*/
,_format: function(name){
console.log("_format old name=>",name);
name = name.toLowerCase();
if(name.indexOf('-')>-1){
var array = name.split('-');
for(var i=1,len=array.length; i<len; i++){
var v = array[i];
array[i] = v.substr(0,1).toUpperCase() + v.substr(1,v.length);
name=array.join("");
}
}
console.log("_format() new name=>",name);
return name;
}
};
};
}(jQuery, window));