如何使用JS/jQuery添加HTML起始标签实现子菜单元素分栏包裹
问题描述
我有一个固定的WordPress子菜单列表,结构如下:
<ul class="sub-menu" style="display:flex"> <li class="open1col"><a>Treatment Trials</a></li> <li class=""><a>Alzheimer’s</a></li> <li class="close1col open2col"><a href="">Asthma</a></li> <li class=""><a>COVID-19 Treatment</a></li> <li class="close2col"><a>COPD</a></li> </ul>
需求是将前3个、最后2个<li>元素分别包裹到2个<div class="sub-menu-col">元素中,实现两列并排展示效果。
补充说明:菜单内容无法直接编辑,仅能为li标签添加类名。
我最初尝试用如下jQuery代码实现需求:
var open1col='<div class="sub-menu-col">'; var close1col='</div><div class="sub-menu-col">'; var close2col='</div>'; $(".sub-menu li:first-child").before(open1col); $(".sub-menu li:nth-child(3)").before(close1col); $("sub-menu li:last-child").after(close2col);
但代码执行时,插入的div起始标签会被浏览器立即自动闭合,导致目标3个<li>元素落在div容器外部,无法实现包裹效果。
问题原因
你无法通过DOM操作单独插入HTML起始标签或者闭合标签。浏览器解析页面时会构建完整的DOM节点树,所有DOM插入操作操作的都是完整的元素节点,不是原始HTML字符串片段。当你调用before()/after()方法传入半个div标签时,浏览器会自动补全缺失的闭合标签,最终生成独立的空div节点,自然无法实现包裹li的效果。
另外原有代码最后一个选择器存在书写错误,缺少类名前缀.,正确写法应为.sub-menu。
实现方案
不要尝试拆分标签插入,直接使用jQuery提供的分组包裹方法即可,两种常用实现方式可按需选择:
方式1:利用已添加的边界类名匹配分组
你已经给分组边界的li加了open1col/close1col/close2col类,可以直接用nextUntil()配合wrapAll()实现包裹:
// 包裹第一列:从.open1col开始,到.close1col结束(包含边界节点本身) $('.sub-menu li.open1col').nextUntil('.close1col').addBack().add('.close1col').wrapAll('<div class="sub-menu-col"></div>'); // 包裹第二列:从.open2col开始,到.close2col结束(包含边界节点本身) $('.sub-menu li.open2col').nextUntil('.close2col').addBack().add('.close2col').wrapAll('<div class="sub-menu-col"></div>');
方式2:按位置切片分组(无需额外添加类名)
如果不需要依赖自定义类,直接按照前3个、后2个的规则切片包裹即可:
const $menuItems = $('.sub-menu li'); // 前3个元素包为第一列 $menuItems.slice(0,3).wrapAll('<div class="sub-menu-col"></div>'); // 剩余元素包为第二列 $menuItems.slice(3).wrapAll('<div class="sub-menu-col"></div>');
代码执行后最终生成的DOM结构如下,后续只需要给.sub-menu-col添加对应宽度、布局样式即可实现两列并排效果:
<ul class="sub-menu" style="display:flex"> <div class="sub-menu-col"> <li class="open1col"><a>Treatment Trials</a></li> <li class=""><a>Alzheimer’s</a></li> <li class="close1col open2col"><a href="">Asthma</a></li> </div> <div class="sub-menu-col"> <li class=""><a>COVID-19 Treatment</a></li> <li class="close2col"><a>COPD</a></li> </div> </ul>
内容的提问来源于stack exchange,提问作者Attila Zoltán Kedei
相关产品推荐
相关产品推荐

