如何点击时为属性追加新值(逗号分隔)而非覆盖原有值?
问题描述
点击li.ui-menu-item元素时,我会从它的子元素中读取数据,然后将数据设置到.field--name-field-pms-colors元素的自定义属性中。当前使用的代码如下:
$("li.ui-menu-item").click(function() { const $viewsFieldPmsColorData = $(this).find(".views-field-pms-color-data"); const $viewsFieldNameContent = $(this).find(".views-field-name .field-content").text(); const imageSrc = $viewsFieldPmsColorData.data("src"); const hex = $viewsFieldPmsColorData.data("hex"); const additionalColorData = { [$viewsFieldNameContent]: { 'name': $viewsFieldNameContent, 'hex': hex, 'src': imageSrc } }; const additionalColorDataString = JSON.stringify(additionalColorData).replace(/"/g, '"'); $(".field--name-field-pms-colors").attr('data-custom-attribute', additionalColorDataString); });
现在的问题是每次后续点击都会覆盖属性值,需求改为:每次点击时将新的颜色数据追加到属性中,最终形成包含多个颜色信息的完整JSON对象。
当前现象
- 首次点击某
<li>后,属性内容为:
<div class="field--name-field-pms-colors" data-custom-attribute="{&quot;1925c&quot;:{&quot;name&quot;:&quot;1925c&quot;,&quot;hex&quot;:&quot;#FE464C&quot;,&quot;src&quot;:&quot;&quot;}}"></div>
- 第二次点击另一个
<li>后,属性内容会被完全覆盖:
<div class="field--name-field-pms-colors" data-custom-attribute="{"425c":{"name":"425c","hex":"#57586E","src":""}}"></div>
预期效果
点击两个不同<li>后,属性应合并所有点击的颜色数据:
<div class="field--name-field-pms-colors" data-custom-attribute="{"425c":{"name":"425c","hex":"#57586E","src":""},"116c":{"name":"116c","hex":"#FCCA11","src":""}}"></div>
解决方案
要实现追加而非覆盖,核心逻辑是先读取属性中已有的数据,合并新数据后再重新设置属性,具体修改如下:
$("li.ui-menu-item").click(function() { // 获取目标元素 const targetEl = $(".field--name-field-pms-colors"); // 读取现有属性值,为空时默认用空对象的JSON字符串 const existingDataStr = targetEl.attr('data-custom-attribute') || '{}'; // 解析现有数据为JS对象(处理HTML实体转义) let existingData; try { // 先把转义的"转回普通引号,再解析JSON const decodedStr = existingDataStr.replace(/"/g, '"'); existingData = JSON.parse(decodedStr); } catch (e) { // 解析失败时重置为空对象,避免报错 existingData = {}; } // 读取当前点击项的颜色数据 const $viewsFieldPmsColorData = $(this).find(".views-field-pms-color-data"); const colorName = $(this).find(".views-field-name .field-content").text(); const imageSrc = $viewsFieldPmsColorData.data("src"); const hex = $viewsFieldPmsColorData.data("hex"); // 合并新数据到现有对象(重复点击同一项会覆盖旧数据) existingData[colorName] = { 'name': colorName, 'hex': hex, 'src': imageSrc }; // 重新序列化为JSON并转义引号,设置回属性 const updatedDataStr = JSON.stringify(existingData).replace(/"/g, '"'); targetEl.attr('data-custom-attribute', updatedDataStr); });
关键说明
- 处理初始状态:当属性为空时,默认使用空对象
{},保证首次点击能正常创建数据结构; - 实体转义处理:读取属性时必须把
"转回普通引号,才能正确解析JSON; - 异常容错:增加解析失败的捕获逻辑,避免因属性格式错误导致代码崩溃;
- 重复点击处理:如果重复点击同一个
<li>,新数据会覆盖旧数据,符合常规交互逻辑。
内容的提问来源于stack exchange,提问作者nathan111777
相关产品推荐
相关产品推荐

