如何精简重复创建DOM的JavaScript代码?实现整洁写法
优化方案:数据驱动+函数封装
你这段代码的核心问题是把重复的饼图组件创建逻辑硬写了四次,通过数据与逻辑分离+函数封装可以彻底简化代码,同时让后续维护更轻松。
具体优化步骤
1. 抽离可变数据
把每个饼图的名称、百分比单独存成数组,后续新增/修改技能只需要改这个数组,不用碰DOM操作逻辑:
const skillData = [ { name: "HTML", percentage: "%99" }, { name: "CSS", percentage: "%99" }, { name: "BOOTSTRAP", percentage: "%80" }, { name: "JAVASCRIPT", percentage: "%75" } ];
2. 封装单个饼图的创建逻辑
写一个专门生成饼图组件的函数,接收单个技能数据作为参数,内部完成所有元素创建、类名添加和节点组装:
function createPieChart(skill) { // 创建所有需要的DOM元素 const pie = document.createElement("div"); const rightDiv = document.createElement("div"); const leftDiv = document.createElement("div"); const percentDiv = document.createElement("div"); const numberDiv = document.createElement("div"); const nameDiv = document.createElement("div"); // 统一添加类名 pie.classList.add("pie1"); rightDiv.classList.add("slice-right1"); leftDiv.classList.add("slice-left1"); percentDiv.classList.add("percent1"); numberDiv.classList.add("number1"); nameDiv.classList.add("name1"); // 填充技能数据 nameDiv.innerHTML = skill.name; numberDiv.innerHTML = skill.percentage; // 组装节点结构 percentDiv.append(numberDiv, nameDiv); pie.append(rightDiv, leftDiv, percentDiv); return pie; }
3. 简化showSkills函数
原来的四次重复代码直接替换成循环调用封装函数,批量生成所有饼图:
function showSkills() { arrow.removeEventListener("click", showSkills); deleteSkills.style.display = "inline-block"; // 循环生成饼图并添加到容器 skillData.forEach(skill => { callAllPie.appendChild(createPieChart(skill)); }); }
4. 简化deleteInfos函数
原函数的循环删除逻辑可以用更简洁的方式实现,同时避免重复查询DOM:
function deleteInfos() { // 直接清空容器内容 callAllPie.innerHTML = ""; deleteSkills.style.display = "none"; arrow.addEventListener("click", showSkills); }
完整优化后代码
const arrow = document.querySelector("#arrow"); const callAllPie = document.querySelector(".allPie"); const deleteSkills = document.querySelector("#exit"); // 抽离技能数据 const skillData = [ { name: "HTML", percentage: "%99" }, { name: "CSS", percentage: "%99" }, { name: "BOOTSTRAP", percentage: "%80" }, { name: "JAVASCRIPT", percentage: "%75" } ]; eventList(); function eventList() { arrow.addEventListener("click", showSkills); deleteSkills.addEventListener("click", deleteInfos); } function deleteInfos() { callAllPie.innerHTML = ""; deleteSkills.style.display = "none"; arrow.addEventListener("click", showSkills); } // 封装饼图创建函数 function createPieChart(skill) { const pie = document.createElement("div"); const rightDiv = document.createElement("div"); const leftDiv = document.createElement("div"); const percentDiv = document.createElement("div"); const numberDiv = document.createElement("div"); const nameDiv = document.createElement("div"); pie.classList.add("pie1"); rightDiv.classList.add("slice-right1"); leftDiv.classList.add("slice-left1"); percentDiv.classList.add("percent1"); numberDiv.classList.add("number1"); nameDiv.classList.add("name1"); nameDiv.innerHTML = skill.name; numberDiv.innerHTML = skill.percentage; percentDiv.append(numberDiv, nameDiv); pie.append(rightDiv, leftDiv, percentDiv); return pie; } function showSkills() { arrow.removeEventListener("click", showSkills); deleteSkills.style.display = "inline-block"; skillData.forEach(skill => { callAllPie.appendChild(createPieChart(skill)); }); }
额外优化细节
- 用
element.style.display替代setAttribute("style", ...),更符合DOM操作规范 - 用
append()替代多次appendChild(),可以一次性添加多个节点 - 复用提前获取的
deleteSkills变量,避免重复查询DOM元素
内容的提问来源于stack exchange,提问作者hseyinyrekli
相关产品推荐
相关产品推荐

