首页 > 其他分享 >JS的for循环动态渲染html只有最后一个元素生效?

JS的for循环动态渲染html只有最后一个元素生效?

时间:2023-04-16 11:01:00浏览次数:50  
标签:myListTwo 渲染 元素 li html let listItem JS

背景:

我想在html3个ul中动态生成5个子元素li

目标效果:

image.png

废话少说,代码直接梭起来~

1. 先写html结构

<section class="list-box">
    <ul id="myList"></ul>
    <ul id="myListOne"></ul>
    <ul id="myListTwo"></ul>
</section>

2. 动态渲染子元素li

不就是写个for循环呗,并且我还加了class属性item

for (var i = 1; i <= 5; i++) {
        var listItem = document.createElement("li");
        listItem.setAttribute('class', 'item')
        document.getElementById("myList").appendChild(listItem);
        document.getElementById("myListOne").appendChild(listItem);
        document.getElementById("myListTwo").appendChild(listItem);
    }

3. 失败,没达到预期效果

心想这个简单,很自信的打开浏览器查阅效果

哦豁?怎么回事?只有一列?

image.png

不应该呢,赶紧F12打开控制台查看

image.png

两个问号

  1. myListmyListOne 怎么没有渲染出子元素li呢?
  2. 为什么只有myListTwo渲染出来子元素?

返回查看代码

难道是 var定义变量的问题么?

好,修改成let

还是一样只有一列,有点迷了~

4. 查阅资料

查阅资料中......

嘿!好家伙 还真的找到了,开心!

MDN官方文档 API:appendChild
MDN官方文档 API:cloneNode

image.png

5. 分析原因

在每次迭代时,listItem都会被添加到myListmyListOnemyListTwo中。但是,由于 DOM (文档对象模型) 的规则限制,一个 DOM 元素节点在同一时刻只能存在于 DOM 树的一个位置。 也就是说,在每次循环迭代时,都需要创建新的li元素节点,而不是重复使用同一个listItem。因此,当listItem被添加到myListTwo之后,它就从myListmyListOne中被移除了,因为它已经成为了myListTwo的子元素。

6. 解决问题

两个解决办法:
(1). 用Node.cloneNode()api进行克隆一份副本,每个节点进行单独appendChild()

    for (let i = 1; i <= 5; i++) {
        let listItem = document.createElement("li");
        listItem.setAttribute('class', 'item')
        document.getElementById("myList").appendChild(listItem);
        
        let listItemOne = listItem.cloneNode(true); //true 深度克隆 li下面所有子节点
        listItemOne.setAttribute('class', 'item')
        document.getElementById("myListOne").appendChild(listItemOne);

        let listItemTwo = listItem.cloneNode(true);
        listItemTwo.setAttribute('class', 'item')
        document.getElementById("myListTwo").appendChild(listItemTwo);
    }

(2). 可以通过将listItem = document.createElement("li"),每个节点进行单独appendChild()

    for (let i = 1; i <= 5; i++) {
        let listItem = document.createElement("li");
        listItem.setAttribute('class', 'item')
        document.getElementById("myList").appendChild(listItem);


        let listItemOne = document.createElement("li");
        listItemOne.setAttribute('class', 'item')
        document.getElementById("myListOne").appendChild(listItemOne);

        let listItemTwo = document.createElement("li");
        listItemTwo.setAttribute('class', 'item')
        document.getElementById("myListTwo").appendChild(listItemTwo);
    }

查看效果,成功解决

image.png

7. 优化代码

上面两种解决办法都存在相同的代码,抽离出来

    // 定义一个创建并设置属性的函数
    function createListItem(className) {
        let listItem = document.createElement("li");
        listItem.setAttribute('class', className);
        return listItem;
    }

    // 在循环中调用函数创建并添加 <li> 元素
    for (let i = 1; i <= 5; i++) {
        let listItem = createListItem('item');
        document.getElementById("myList").appendChild(listItem);

        let listItemOne = createListItem('item');
        document.getElementById("myListOne").appendChild(listItemOne);

        let listItemTwo = createListItem('item');
        document.getElementById("myListTwo").appendChild(listItemTwo);
    }

溜了~
继续写BUG~

标签:myListTwo,渲染,元素,li,html,let,listItem,JS
From: https://www.cnblogs.com/zy-mg/p/17322663.html

相关文章

  • js动态查询指定class名的所有元素,querySelectorAll()和querySelectorAll()的区别
    "document.querySelectorAll()"方法返回的是一个静态的NodeList(节点列表),即它只能在页面刚加载时获取到一次,之后即使有新的元素符合选择器,它也不会再重新获取。如果你想动态地获取到新增的元素,可以使用"document.getElementsByClassName()"或"document.getElementsByTagName()"......
  • js 异步任务执行顺序问题
    js是单线程的(非阻塞的),实现方法就是事件循环;分同步任务和异步任务;newPromise((resolve,reject)=>{resolve(1)console.log('log1')}).then(()=>{console.log('log2')})console.log('log3')setTimeout(()=>......
  • Vue3中(vite.config.js)配置打包的时候去除console.log
    参考:https://www.cnblogs.com/lovewhatIlove/p/16476165.html安装tersernpmadd-Dterservite中配置import{defineConfig}from"vite";importvuefrom"@vitejs/plugin-vue";importvueJsxfrom"@vitejs/plugin-vue-jsx";importvisua......
  • js方法实现 10+ 100+ 1000+ 10000+
    将数字类型优化12=>10+120=>100+1200=>1000+10以内不管调用后赋值进行数字化item.read_num=Number(util.picture(item.read_num))直接cv代码数字优化自己调用定义函数**//浏览量优化functionpicture(num){if(num<10){returnnum;}va......
  • OSG 使用整理(2):设置渲染状态
    二、场景管理2.1遍历场景图场景图遍历类型有以下几种:(1)    事件遍历:在遍历节点时,处理鼠标和键盘输入。(2)    更新遍历:用于修改场景图,添加节点,设置节点属性,执行回调。(3)    裁剪遍历:根据节点是否位于一个视口内来筛选节点,裁剪掉不可见和不可用的......
  • HTML+css
    因为测试需要用到css的内容,所以开始系统学习css和js技术css有id选择器,类选择器,可以组合,也可以单独分布首先是基本的选择器h1{color:rebeccapurple;}/*类样式class=*/.f20{font-size:18px;}/*id样式id=,notcopy*/#p4{font-size:30px;......
  • AntDesign中a-tab的forcerender属性强制DOM渲染
    <a-tabsv-model:activeKey="activeKey"@change="clickTag"><a-tab-panekey="1"tab="警情"v-if="tab01Visible":forceRender="true"><AssociatedElementsInformingDetail......
  • django渲染模版时比实际少了8小时?
    这是因为django的时间是UTC时间.我们通过改配置文件将其改成本地时间修改配置文件#将时间从UTC转化成当前时间TIME_ZONE='Asia/Shanghai'#USE_TZ=Truehtml页面上面渲染<td>{{foo.create_datetime|date:"Y-m-dH:i:s"}}</td>......
  • js 数组、对象转json 以及json转 数组、对象
    1、JS对象转JSON方式:JSON.stringify(obj)varjson={"name":"iphone","price":666};//创建对象;varjsonStr=JSON.stringify(json);//转为JSON字符串console.log(jsonStr);2、JS数组转JSON//数组转json串vararr=[1,2,3,{a:1}];JSON.st......
  • unity中实现地球与大气层的特效渲染(非物理向)
        在很多太空科幻类的电影、游戏中、我们常常看到在太空中的星球的场景,在这些场景中我们可以看到真实的行星地表光影效果和云层、以及非常炫酷的大气层效果。在unity中我们也可以创建类似的效果。本文我将介绍如何在unityshader中编写地球特效渲染。 上图是最终的......