jQuery新版本中data属性转对象后JSON.stringify顺序反转问题
jQuery升级后data属性顺序反转问题的解决
问题描述
使用jQuery获取元素data属性时,在1.10.x版本中,data()返回的对象键顺序和HTML里属性出现的顺序一致(比如data-id、data-col、data-sport依次排列),但升级到1.11.0及以后版本,键顺序完全反转,最后一个data属性排在首位。原有代码依赖键的索引位置(比如Object.keys(a)[2])来操作属性,导致升级后逻辑出错。
旧版本(1.10.2)的可正常运行代码:
JavaScript代码
$(document).ready(function(){ $(".btnOne").on('click', function(){ a = $(this).data(); b = JSON.stringify(a) var count=Object.keys(a).length; console.log("a: "+b+" -- "+Object.keys(a)); console.log("KEY: --- "+Object.keys(a)[2]); if(a[Object.keys(a)[2]]=="Golf"){ console.log("CHANGE"); a[Object.keys(a)[2]] = "Snooker"; $(this).html(a[Object.keys(a)[2]]); }; }); });
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <p class="btnOne" data-id="14" data-col="R" data-sport="Rugby">Rugby</p> <p class="btnOne" data-id="12" data-col="B" data-sport="Cricket" data-team="Somerset" >Cricket</p> <p class="btnOne" data-id="23" data-col="Y" data-sport="Golf">Golf</p>
问题原因
- jQuery 1.11.0版本调整了
data()方法的属性解析逻辑,从原来的正序遍历HTML属性改为倒序遍历,导致返回对象的键顺序反转。 - 更关键的是:JavaScript对象的键在ES6之前没有官方顺序保证,旧版本jQuery和浏览器呈现的顺序只是实现巧合,依赖
Object.keys()的索引位置访问属性本身就是不稳定的写法。
解决方案
方案1:直接通过明确键名访问(推荐)
放弃依赖键的索引位置,直接通过data('键名')或者对象属性名访问,这是最可靠的方式:
$(document).ready(function(){ $(".btnOne").on('click', function(){ var data = $(this).data(); var dataStr = JSON.stringify(data); console.log("data: "+dataStr+" -- "+Object.keys(data)); console.log("sport值: --- "+data.sport); if(data.sport === "Golf"){ console.log("CHANGE"); data.sport = "Snooker"; $(this).html(data.sport); // 如果需要同步更新DOM上的data属性,添加下面一行 // $(this).data('sport', 'Snooker'); }; }); });
方案2:按HTML属性顺序收集data属性
如果业务确实需要严格遵循HTML中data属性的出现顺序,可以直接遍历元素的attributes集合,手动筛选并构建有序的data对象:
$(document).ready(function(){ $(".btnOne").on('click', function(){ var orderedData = {}; // 按HTML属性的原始顺序遍历 $.each(this.attributes, function() { if(this.name.startsWith('data-')) { // 把data-xxx转成jQuery.data()使用的驼峰命名 var key = this.name.replace('data-', '').replace(/-([a-z])/g, function(match, letter) { return letter.toUpperCase(); }); // 用jQuery.data()获取值,自动处理类型转换(比如数字、布尔值) orderedData[key] = $(this).data(key); } }); var dataStr = JSON.stringify(orderedData); console.log("按HTML顺序的data: "+dataStr+" -- "+Object.keys(orderedData)); if(orderedData.sport === "Golf"){ console.log("CHANGE"); orderedData.sport = "Snooker"; $(this).html(orderedData.sport); $(this).data('sport', 'Snooker'); }; }); });
内容的提问来源于stack exchange,提问作者London28
相关产品推荐
相关产品推荐

