问题:
在使用jquery
时,通过data()
方法获取属性时,如果动态更新了data-*
是获取不到的;
// html
<div id="app" data-id="001" data-type="container">示例</div>
// js
let app = $("#app");
console.log("原始:",app.data("id"),app.data("type")); // 001 , container
// 动态改变
app.attr("data-id","002");
app.attr("data-type","container_02");
console.log("更新:",app.data("id"),app.data("type")); // 001 , container
// 尝试通过 attr() 进行获取,获取到了
console.log(app.attr("data-id"),app.attr("data-type")); // 002, container_02
分析: 通过查看网页源代码、实际的标签上的属性data-id
/data-type
均已改变,但是通过data()
方法获取到的仍是第一次的值。然后通过使用attr()
方法获取到了正确值。
那就说明Jquery
中的data()
不是专门用于处理html元素data-*
属性的。
Jquery .data()
说明
JQuery官网
-
描述:存储与匹配元素(DOM元素)的任意数据,返回与值匹配的数据值。
app.data("user",{name:"hello",age:"23"}); console.log(app.data("user").age); // 23 // 使用原生html元素属性获取不到值 console.log(app[0].dataset.user); // undefined // 设置 JSONString 然后通过解析获取到对象进行操作 <div data-user='{"name":"hello","age":"23"}'>示例</div> console.log(JSON.parse(app[0].dataset.user));
Jquery
的data()
方法是把属性存储在内存中的,顺便把数值、字符串作为html属性加到元素上;
原生htmldata-*
方法将值作为节点属性挂载到DOM上,所以不能放置对象,可以设置规范的JSONString
,获取到之后parse()
。 -
分析:使用规则
官网介绍说,如果值更新将不会影响DOM属性,也就不会获取到更新后的值;推荐属性attr
可以获取到
而且通过原生方式dataset
是可以去获取到的,说明是方法data()
的内部实现问题导致。console.log(app[0].dataset.id); // 002
-
解剖:分析
data()
实现
1.4.3
之前的早版本中data(obj)
会覆盖所有已设置的值;之后则是进行浅复制覆盖。(即注意对象的引用特性)data-*
会被用来初始数据,之后不会再被访问,这也是为什么更新之后不能获取到改变的值
所以在html元素上设置的标注JSONString
,Jquery
会自动解析,使用data()
拿到数据对象。做一个测试:
1. 第一种测试,先不要调用data()方法 ,更新后再获取 app.attr("data-id","002"); app.attr("data-name","app_02"); app.attr("data-type","container_02"); console.log("更新:",app.data("id"),app.data("name"),app.data("type")); // 002 app_02 container_02 2. 复制DOM结构重新添加进去 // 复制DOM结构 let node = app.clone(); app.remove(); $("body").append(node); console.log("更新:",app.data("id"),app.data("name"),app.data("type")); // 002 app_02 container_02
也就是
Jquery
键值对保存了<dom,data>
类似WeabkMap
数据结构,为了方便存储DOM
关联数据,查询提升响应速度。结论:要操作
DOM
元素的属性还是使用attr
吧。
原生DOM中的data-*
属性
data-*
是html 标签的全局属性;
- 作为
DOM
元素的属性获取 -getAttribute()
getAttribute()
获取html元素的属性,指定属性不存在则返回Null
或空字符串。let name = app[0].getAttribute("data-name"); console.log(name); // app_02
- 通过
HTMLElement.dataset
获取data-*
值,所有的属性值类型为DOMStringMap
DOM.dataset.*
获取不到时为undefined
,类似data-*-*
属性获取时驼峰式命名获取值;let main = app[0]; for(key in main.dataset){ console.log(main.dataset[key]); } // 直接访问获取某个属性 console.log(main.dataset.id);
data-*
作为html属性,既可以使用JS
操作,也可用作css
属性过滤设置样式;
::after
等伪类将html属性data-*
的值添加到元素;div[data-id="001"]{ background: red; } /*也可以将属性的data-* 使用伪类展示在元素中*/ div::after{ content:attr(data-id) }