向jquery中增加data-*属性时,data()方法和attr()的区别

本文探讨了jQuery中data()方法与attr()方法在数据存储上的区别:data()用于存储在jQuery对象内部,而attr()写入DOM元素。两者不互通,理解这二者的不同有助于前端开发者高效操作DOM。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是写法的不同

element.data('val','1')

element.attr('data-val','1')

其次是储存的方式不同
使用data()方法,值会储存在jquery对象中。
attr()方法会储存在dom中。

<li data-val="1">苹果</li>    //attr()

<li>苹果</li>      //data(),看不见

//两种方法并不互通。
<think>我们正在讨论jQuery中如何通过HTMLdata-*属性存储检索多个值。根据HTML标准,data-*属性只能存储字符串。但在jQuery中,我们可以利用其.data()方法智能地处理数据,包括对象数组。步骤:1.存储多个值:我们可以将一个对象或数组存储在单个data-*属性中,但需要将其序列化为JSON字符串。2.读取数据:使用jQuery的.data()方法可以自动将JSON字符串解析为JavaScript对象,而使用.attr()方法则只能得到字符串。示例:假设我们有一个div,需要存储多个数据:id, name,scores(数组)我们可以这样设置属性:<divid="myDiv" data-info='{"id":123, "name":"John","scores":[90,85,95]}'></div>注意:属性值用单引号,内部JSON字符串用双引号(符合JSON标准)。在jQuery中://读取数据varinfo =$('#myDiv').data('info');//info将是一个对象:{id:123,name:"John",scores:[90,85,95]}但是,如果我们使用.attr()方法:varinfoStr= $('#myDiv').attr('data-info');//得到的是字符串:'{"id":123,"name":"John", "scores":[90,85,95]}'因此,推荐使用.data()方法来读取,因为它会自动转换。另外,jQuery的.data()方法还可以通过代码设置数据,而不一定要写在HTML属性中:$('#myDiv').data('info', {id:123,name:"John",scores:[90,85,95]});这样设置的数据不会反映在HTML属性上,而是存储在jQuery内部对象中。在循环中绑定多个数据:假设我们有一个数组items,每个元素是一个对象,我们想为每个生成的元素设置多个数据。方法一:在HTML中设置data-*属性(循环生成HTML字符串)varhtml= '';items.forEach(function(item){html +='<divclass="item"data-item=\'' +JSON.stringify(item)+ '\'></div>';});$('body').append(html);然后,在事件处理中,我们可以这样获取:$('.item').click(function() {varitemData= $(this).data('item');//自动转换为对象console.log(itemData.id);});方法二:使用jQuery的.data()方法在创建元素后设置(避免在HTML字符串中处理JSON)items.forEach(function(item){$('<div class="item">').appendTo('body').data('item',item);});注意:方法二中,数据不会出现在HTML属性中,而是存储在jQuery内部。这样更安全(避免XSS),但如果你需要服务端渲染或SEO,可能需要方法一。关于XSS安全提示:当使用JSON.stringify()并直接插入到HTML属性,要确保字符串中不包含单引号(因为我们用单引号包裹属性值),或者进行转义。例如,如果item中的某个字符串包含单引号,可能会破坏HTML结构。因此,我们可以:var escapedJson= JSON.stringify(item).replace(/'/g,"'");或者,使用双引号包裹属性值,并转义双引号。但是,更安全的做法是避免在HTML中嵌入JSON,而使用方法二。总结:-使用jQuery的.data()方法可以方便地存储读取复杂数据(对象、数组等)。-在循环中,可以选择在生成HTML字符串序列化数据到data-*属性,或者生成元素后用.data()方法设置。-注意XSS安全问题,尽量避免在HTML中嵌入不受信任的数据。现在,我们根据用户提供的引用(jQuery代码示例)来结合说明:用户提供的代码是:$("button").click(function (){$("div").each(function(index, domEle){// domEle ==this$(domEle).css("backgroundColor", "yellow");if($(this).is("#stop")){$("span").text("Stopped atdiv index#"+ index);return false;}});});假设我们想在每个div上存储多个数据,并在点击按钮使用。修改后的例子:HTML:<div class="item" data-item='{"id":1, "name":"Alice"}'>Alice</div><divclass="item"data-item='{"id":2,"name":"Bob"}'>Bob</div><div id="stop" class="item" data-item='{"id":3, "name":"Stop"}'>Stop</div>jQuery:$("button").click(function (){$("div.item").each(function (index,domEle) {var$this= $(domEle);$this.css("backgroundColor", "yellow");//获取存储的数据varitemData= $this.data('item');console.log(itemData.name);//输出名字if($this.is("#stop")){$("span").text("Stopped atdiv index#"+ index+ ",name:" +itemData.name);returnfalse;}});});这样,我们就利用了data-*属性存储了多个值,并通过jQuery.data()方法获取。注意事项:在jQuery1.4.3以上,.data()方法会自动解析JSON。如果JSON格式错误,则会返回字符串。相关问题:1.如何防止在data-*属性中存储JSON字符串的XSS攻击?2.使用jQuery的.data()方法存储数据与HTML5的dataset属性有何区别?3.在循环处理大量元素,使用.data()方法直接读取属性哪种性能更好?</think>### jQuery 中通过 `data-*` 属性存储访问多值数据 #### 1. **`data-*` 属性的字符串本质** - 所有 HTML 属性(包括 `data-*`)**只能存储字符串值**,这是 HTML 标准限制[^1]。 - jQuery 的 `.data()` 方法会自动处理类型转换: ```javascript // HTML: <div id="user" data-user='{"id":101,"name":"Alice"}'></div> const userData = $('#user').data('user'); console.log(typeof userData); // "object"(自动转为对象) ``` #### 2. **存储多个值的两种方法** ##### 方法 1:JSON 序列化(推荐) ```html <!-- 单引号包裹JSON,避免冲突 --> <div class="item" data-item='{"id":101, "name":"Alice", "scores":[90,85,95]}'> User </div> ``` **jQuery 读取:** ```javascript $(".item").click(function() { const itemData = $(this).data('item'); // 自动解析为对象 console.log(itemData.scores[0]); // 90 }); ``` ##### 方法 2:拆分多个属性 ```html <div class="product" data-product-id="P123" data-product-price="49.99" data-product-tags="electronics,gadget"> Product </div> ``` **jQuery 读取:** ```javascript $(".product").click(function() { const $el = $(this); const tags = $el.data('product-tags').split(','); // 转为数组 console.log({ id: $el.data('product-id'), price: parseFloat($el.data('product-price')), tags: tags }); }); ``` #### 3. **循环中动态绑定数据** 结合 jQuery 的 `.each()` `.data()`: ```javascript const users = [ {id: 101, name: "Alice", roles: ["admin", "editor"]}, {id: 102, name: "Bob", roles: ["viewer"]} ]; // 动态创建元素并绑定数据 $.each(users, function(index, user) { const $userDiv = $('<div class="user">') .text(user.name) .data('user', user) // 存储完整对象 .appendTo('#container'); // 可选:设置可见属性 $userDiv.attr('data-user-id', user.id); }); ``` #### 4. **数据读写操作对比** | 操作 | 代码示例 | 特点 | |---------------------|----------------------------------|--------------------------| | **写入数据** | `$(el).data('key', value)` | 支持任意JS类型 | | **读取数据** | `$(el).data('key')` | 自动类型转换 | | **读取HTML属性** | `$(el).attr('data-key')` | 始终返回字符串 | | **批量设置** | `$(el).data({key1:val1, key2:val2})` | 一次设置多个值 | #### 5. **循环处理示例(基于引用[1])** ```javascript $("button").click(function() { $("div.item").each(function(index, domEle) { const $ele = $(domEle); const itemData = $ele.data('item'); $ele.css("background", index % 2 ? "#eee" : "#fff"); if ($ele.is("#stop")) { $("#log").text( `Stopped at: ID=${itemData.id}, Name=${itemData.name}` ); return false; // 中断循环 } }); }); ``` #### 6. **最佳实践与注意事项** 1. **数据类型转换**: ```javascript // 字符串转数字 const price = parseFloat($ele.data('price')); // 字符串转数组 const tags = $ele.data('tags').split(','); // 布尔值处理 const isActive = $ele.data('active') === 'true'; ``` 2. **性能优化**- 避免在循环内重复解析 JSON:在数据初始化完成解析 - 使用 `.data()` 而非 `.attr()` 读取复杂数据 3. **XSS 防护**: ```javascript // 不安全:直接插入未过滤数据 $div.attr('data-raw', userInput); // 安全做法:序列化前转义 const safeData = { content: $('<div>').text(userInput).html() }; $div.data('safe', safeData); ``` --- ### 相关问题 1. **如何防止通过 `data-*` 属性导致的 XSS 攻击?** 2. **使用 `$.data()` 与原生 `dataset` 属性有何性能差异?** 3. **在动态加载内容,如何确保 `data-*` 绑定数据不丢失?** 4. **jQuery 的 `.data()` 方法在存储函数类型有什么限制?** 5. **如何实现 `data-*` 属性的响应式更新(类似 Vue 的绑定机制)?** [^1]: HTML 标准要求所有属性值必须是字符串,详见 [MDN data-* 文档](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值