如何从JSON动态添加带递增数字的正方形Div并维持网格布局
问题解决方案
问题1:JSON数据获取失败
- 原代码中
$.getJSON是异步请求,点击按钮时可能还未完成数据加载,导致myData未定义 - 修复方案:将点击事件逻辑放在
$.getJSON的回调内,确保数据加载完成后再绑定事件;同时增加错误处理,避免请求失败导致后续逻辑崩溃
问题2:正方形Div无法维持宽高比
- 原问题原因:
- 重复定义
class属性(HTML中一个元素只能有一个class属性,多个类名需用空格分隔) - 用固定高度实现正方形,网格布局中
1fr宽度随容器变化,固定高度无法匹配宽度,导致宽高比失效
- 重复定义
- 修复方案:使用padding-top百分比法实现自适应正方形,同时修正class属性写法
修改后的完整代码
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script> <title>NewSquaresList</title> <style> /* 通用网格样式 */ .grid { margin: auto; display: grid; grid-gap: 10px; } /* 自适应正方形核心样式 */ .grid-item { background-color: #e0e0e0; position: relative; padding-top: 100%; /* 高度等于宽度,维持正方形 */ -webkit-user-select: none; -ms-user-select: none; user-select: none; } /* 正方形内的内容居中 */ .grid-item .content { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; padding: 10px; } /* 高亮样式 */ .grid-item.highlight { background-color: #ffd700; } /* 响应式布局 */ @media only screen and (max-width: 900px) { .grid { grid-template-columns: repeat(3, 1fr); width: 600px; } .grid-item .content { font-size: 40px; } } @media only screen and (min-width: 900px) { .grid { grid-template-columns: repeat(5, 1fr); width: 900px; } .grid-item .content { font-size: 45px; } } @media only screen and (min-width: 1600px) { .grid { grid-template-columns: repeat(7, 1fr); width: 1200px; } .grid-item .content { font-size: 45px; } } </style> </head> <body> <br> <div class="likes" >0</div> <br><br> <button id="1" class="book" >Chapters</button><br> <button id="btn_add" class="btn">Add a Div</button><br> <button hidden class="btn" >Increment</button> <br> <div id="header" class="text" >Chapters</div> <div id="header2" class="text" ></div> <br> <div id="grab" >X</div> <div hidden id="LocRec2" >X</div> <div hidden id="Rec" >X</div> <div id="books" class="grid" ></div> <div id="board" class="grid" style="display:none;"></div> <br><br><br> <div class="grid" id="myGrid"></div> <script> let BkValues = '{ "Books" : [' + '{ "Book":"Chapters" , "id":"1" , "BkChaps":"50" , "LocalRec":"Gen" } ]}'; const obj = JSON.parse(BkValues); var myData; // 确保JSON加载完成后再绑定点击事件 $.getJSON('https://appworx.org/storage.json', function(data) { myData = data; bindBookClickEvent(); }).fail(function() { console.error('JSON数据加载失败'); alert('数据加载失败,请稍后重试'); }); function bindBookClickEvent() { $(".book").on("click", function(){ var name = this.innerHTML; var Bkid = this.id; var num = this.id-1; document.getElementById("grab").innerHTML = Bkid ; document.getElementById("header").innerHTML = name ; document.getElementById('books').style.display = 'none'; window.location.href = "#start"; document.getElementById('board').style.display = 'block'; // 清空之前的内容,避免重复添加 $("#board").empty(); var LocRec = obj.Books[num].LocalRec; var LocRec2 = LocRec + "Rec"; document.getElementById('LocRec2').innerHTML = LocRec2; var varKey = LocRec2; // 增加数据存在性判断 if (!myData?.Books?.[varKey]) { console.error('未找到对应数据'); return; } var Rec = myData.Books[varKey]; console.log( Rec ); var Chap = obj.Books[num].BkChaps; var times = parseInt(Chap); // 转换为数字类型 for(var j = 0; j < times; j++){ var num = j +1; var string = LocRec+num ; let itemClass = 'grid-item'; if (Rec.includes(string)) { itemClass += ' highlight'; } // 修正class写法,用嵌套div实现内容居中 $("#board").append(`<div class="${itemClass}"><div class="content">${num}</div></div>`); } }); } $("#btn_add").click(function(e) { // 同样使用正方形结构 $("#board").append(`<div class="grid-item"><div class="content">0</div></div>`); }); $('.btn').click(function() { var num = parseInt($('.likes').text()); $('.likes').text(num+1); $('.grid-item .content').text(num+1); }); </script> </body> </html>
关键修改点说明
JSON数据加载处理:
- 将按钮点击事件绑定放在
$.getJSON的成功回调内,确保数据加载完成后再触发逻辑 - 添加
fail回调处理请求失败情况 - 增加数据存在性判断,避免
myData未定义或数据不存在导致报错
- 将按钮点击事件绑定放在
正方形宽高比修复:
- 删除固定高度,改用
padding-top: 100%实现自适应正方形(padding百分比基于元素宽度计算) - 用嵌套
.contentdiv实现内容居中,避免高度被内容撑开 - 修正HTML中重复
class属性的错误写法,多个类名用空格分隔 - 点击按钮生成新div时,也使用统一的正方形结构
- 删除固定高度,改用
内容的提问来源于stack exchange,提问作者MarkC
相关产品推荐
相关产品推荐

