前端问题一:使用innerHTML向DOM元素中追加问题

本文详细介绍了在JavaScript中使用innerHTML动态添加DOM元素时遇到的Echarts图表重绘问题,分析了问题原因在于innerHTML的使用导致的DOM重绘,提出了两种解决方案:一是分步创建和初始化DOM及图表;二是使用appendChild避免重绘。文章旨在分享解决问题的思路和方法。
摘要由CSDN通过智能技术生成

Header: 首创不易,还请大家不吝指导赐教,Code is never die!

ps:本着让更多人不止解决问题,更能够学到一点点方法的目的,内容有点赘述,还请耐心。

今天在修改项目时,偶然碰到了innerHTML部分知识的使用。
直击问题:
根据后台返回数据的个数循环动态添加dom元素,并且对dom元素进行相应的操作(例如:添加、编辑dom元素等)

for (let i = 0; i < This.dataList.length; i++) {
    // 此处为每个div添加一个id(为简洁直接以i作为id)
	dom.innerHTML += `<div id=${i} style="width:200px;height:200px;"></div>`;
	let domItem = document.getElementById(i);
	// 此处以添加一个echarts图表为例;
	domItem.myChart = echarts.init(domItem);
	......
}

问题阐述:
这是一段很常规的代码,但是当真正渲染时会发现,当有两个(及以上)的数量时,最终只会展现最后一个可视化部分,而前面的部分dom元素也存在,但就是无法显示出来。

初步想法:
① 一开始更多的想的是可视化的数据出现了问题,用过echarts的朋友都知道,数据不准确会导致这种情况。在反复各种打印控制台log各种数据后发现,各类数据都一一打印出来。所以,数据部分导致的设想Pass掉了。
② 考虑的是初始化echarts时,也就是上面代码中的domItem,因为每次循环使用同一个变量,后面的可能会把前面的覆盖,导致前面可视化图形展示不出来。后面通过对象赋予不同变量domItem[i] 然而发现,并没有什么作用,原因猜测是当前面的可视化初始化–>完成,已经完成了本轮图形化的构建,当第二次循环使用的话相当于用了一个“新”的变量,所以这个不是主要原因。所以,也Pass掉了。

最终原因:
后面瞪着代码看,然后瞪着代码看,然后再瞪着代码看,最终跟着循环走了第一圈,发现当第一次可视化完成之后,来到第二次可视化,关键来了!dom.innerHTML +=......其实也就是dom.innerHTML = dom.innerHTML +...... 这个过程,相当于前面我第一次完成的echarts构建,在这里就是dom.innerHTML + +号前面的部分,又重新绘制了一遍,那么问题就浮出了水面,会导致已经可视化完成的第一个图表,再进行第二轮可视化时发生了 重绘 整个dom元素,所以前面已然完成的可视化,又将被“打回原形”,变成了一个空壳子,而第二次的可视化正常,以此类推…所以最终只会显示最后一个可视化(真实创建并渲染完成显示)

解决办法:
① 针对上述这种需要进行操作的类型,既然会发生重绘,那我何不将计就计,等你各种重绘完成之后,我再去给你每个盒子进行操作呢。这就好比于下课的时候大家都在吵闹,你去制止A同学,A不说话了,当你再去制止B,会发现A继续和大家吵闹,而B不说了,往复循环,最后发现让他们吵闹去吧,一上课大家就立马安静了。这里的上课就类比于重绘完成,一切就绪,就可以一个一个的去批评啦,哈哈哈…例子稍微一点点牵强,不过意思到了。
代码也非常简单

//孩子创建过程,随便重绘
for (let i = 0; i < This.dataList.length; i++) {
	dom.innerHTML += `<div id=${i} style="width:200px;height:200px;"></div>`;
}
// 创建完成了,不会再重绘了..后续操作
for (let i = 0; i < This.dataList.length; i++) {
	let domItem = document.getElementById(i);
	// 此处以添加一个echarts图表为例;
	domItem.myChart = echarts.init(domItem);
	......
}

②当你需要循环添加的dom元素内容单一、固定格式的元素时,也可以选择appendChild来解决重绘问题。具体见代码

// 给body添加dom元素
var dom=document.createElement('h1');
dom.className='test';
dom.innerHTML='Hello,Rain';
document.body.appendChild(dom);

这样也避免了重绘问题。

Ending…
好啦,首创怀着激动的心啰里啰唆竟然码了2k,问题不是特别难理解,主要的是想要给大家分享拿到问题的整个流程和想法,如有个别地方表述不当或您有疑问,咱们讨论区相互学习哦,还望各位支持一下哦~

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rainux.

生活最美——开心最大

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值