演示效果
不多说,直接代码。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>微信自定义菜单</title> 6 <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> 7 </head> 8 <body> 9 <style> 10 td {padding:5px;} 11 button {padding:5px;} 12 .btnAddLv1Menu, .btnAddLv2Menu{width:100px;} 13 input,select {padding:5px; width:100px;} 14 .lv1Menu{border-color:blue;} 15 </style> 16 17 <div class="tableform"> 18 <form id=\'menuForm\' action="http://www.baidu.com" method="post"> 19 <div class="tableform"> 20 <table width="100%" border="1" cellspacing="0" cellpadding="0" style="border:1px solid #ccc"> 21 <tr> 22 <td width="12%"><button type="button" class="btnAddLv1Menu">添加一级菜单</button></td> 23 <td width="20%">菜单名称</td> 24 <td width="20%">菜单类型</td> 25 <td width="20%">菜单值</td> 26 </tr> 27 <!-- 数据显示区域 --> 28 </table> 29 </div> 30 <div class="table-action"> 31 <button>保存</button> 32 </div> 33 </form> 34 </div> 35 <!-- 一级菜单模板 --> 36 <table id="lv1Menu_tpl" style="display: none"> 37 <tr class="lv1Menu"> 38 <td> 39 <button type="button" class="btnAddLv2Menu">添加二级菜单</button> 40 <button type="button" class="btnRemoveMenu">删除</button> 41 </td> 42 <td> 43 <input type=\'text\' name=\'name\' class="x-input" > 44 </td> 45 <td> 46 <select name="type" class="x-input"> 47 <option value="">一级菜单</option> 48 <option value="click">Key</option> 49 <option value="view">链接</option> 50 </select> 51 </td> 52 <td> 53 <input type=\'text\' name=\'key\' class="x-input hide" > 54 </td> 55 </tr> 56 </table> 57 <!-- 二级菜单模板 --> 58 <table id="lv2Menu_tpl" style="display: none"> 59 <tr class="lv2Menu"> 60 <td> 61 <button type="button" class="btnRemoveMenu" style="margin-left: 108px;">删除</button> 62 </td> 63 <td> 64 —— <input type=\'text\' name=\'name\' class="x-input"> 65 </td> 66 <td> 67 <select name="type" class="x-input"> 68 <option value="click" seleted>Key</option> 69 <option value="view">链接</option> 70 </select> 71 </td> 72 <td> 73 <input type=\'text\' name=\'key\' class="x-input" > 74 </td> 75 </tr> 76 </table> 77 <script> 78 var menus = [ 79 { 80 \'name\' : \'必看福利\', 81 \'sub_button\' : [ 82 {\'name\':\'每日签到\', \'type\':\'view\', \'url\':\'http://www.bbc.cn/dispather.html?act=qiandao\'}, 83 {\'name\':\'超级拼团\', \'type\':\'view\', \'url\':\'http://www.bbc.cn/dispather.html?act=pintuan\'}, 84 {\'name\':\'下载领红包\', \'type\':\'view\', \'url\':\'http://www.bbc.cn/dispather.html?act=download\'}, 85 ], 86 }, 87 { 88 \'name\' : \'爱理巴巴\', 89 \'type\' : \'view\', 90 \'url\' : \'http://www.bbc.cn/dispather.html?act=site\', 91 }, 92 { 93 \'name\' : \'我的服务\', 94 \'sub_button\' : [ 95 {\'name\':\'在线客服\', \'type\':\'click\', \'key\':\'kefu\'}, 96 {\'name\':\'我的返利\', \'type\':\'click\', \'key\':\'fanli\'}, 97 {\'name\':\'商务合作\', \'type\':\'view\', \'url\':\'http://www.bbc.cn/dispather.html?act=hezuo\'}, 98 ], 99 }, 100 ]; 101 render(menus); 102 $(function(){ 103 //添加一级菜单 104 $("#menuForm").on("click", ".btnAddLv1Menu", function(){ 105 if(menus.length >= 3){ 106 alert("最多只能添加3个一级菜单"); 107 return; 108 } 109 //数据变化 110 var menu = {\'name\':\'\', \'sub_button\':[]}; 111 menus.push(menu); 112 //样式变化 113 render(menus); 114 }); 115 //添加二级菜单 116 $("#menuForm").on("click", ".btnAddLv2Menu", function(){ 117 var lv1Menu = $(this).parents(".lv1Menu"); 118 var lv2Menus = lv1Menu.nextUntil(".lv1Menu"); 119 if(lv2Menus.length >= 5){ 120 alert("最多只能添加5个二级菜单"); 121 return; 122 } 123 //数据变化 124 var lv1MenuIndex = $("#menuForm .lv1Menu").index(lv1Menu); 125 var menu = {\'name\':\'\', \'type\':\'key\', \'key\':\'\'}; 126 menus[lv1MenuIndex][\'sub_button\'].push(menu); 127 128 //样式 129 render(menus); 130 }); 131 //删除菜单 132 $("#menuForm").on("click", ".btnRemoveMenu", function(){ 133 var tr = $(this).parents("tr"); 134 if(tr.hasClass("lv1Menu")){ 135 var lv1MenuIndex = $("#menuForm .lv1Menu").index(tr); 136 menus.splice(lv1MenuIndex, 1); 137 }else if(tr.hasClass("lv2Menu")){ 138 var lv1MenuIndex = tr.prevAll(".lv1Menu").length -1; 139 var lv2MenuIndex = tr.prevUntil(".lv1Menu").length; 140 menus[lv1MenuIndex][\'sub_button\'].splice(lv2MenuIndex, 1); 141 } 142 render(menus); 143 }); 144 //失去焦点 145 $("#menuForm").on("blur", "input", function(){ 146 var name = $(this).attr(\'name\'); 147 var tr = $(this).parents("tr"); 148 if(tr.hasClass("lv1Menu")){ 149 var lv1MenuIndex = $("#menuForm .lv1Menu").index(tr); 150 menus[lv1MenuIndex][name] = $(this).val(); 151 }else if(tr.hasClass("lv2Menu")){ 152 var lv1MenuIndex = tr.prevAll(".lv1Menu").length -1; 153 var lv2MenuIndex = tr.prevUntil(".lv1Menu").length; 154 menus[lv1MenuIndex][\'sub_button\'][lv2MenuIndex][name] = $(this).val(); 155 } 156 }); 157 //下拉列表 158 $("#menuForm").on("change", "select", function(){ 159 var tr = $(this).parents("tr"); 160 var name = $(this).attr(\'name\'); 161 var value = $(this).val(); 162 if(tr.hasClass("lv1Menu")){ 163 var lv1MenuIndex = $("#menuForm .lv1Menu").index(tr); 164 if(value){ 165 menus[lv1MenuIndex][name] = value; 166 if(value == \'click\'){ 167 menus[lv1MenuIndex][\'key\'] = \'\'; 168 }else if(value == \'view\'){ 169 menus[lv1MenuIndex][\'url\'] = \'\'; 170 } 171 delete menus[lv1MenuIndex][\'sub_button\']; 172 }else{ 173 delete menus[lv1MenuIndex][\'key\']; 174 delete menus[lv1MenuIndex][\'url\']; 175 delete menus[lv1MenuIndex][\'type\']; 176 menus[lv1MenuIndex][\'sub_button\'] = new Array(); 177 } 178 }else if(tr.hasClass("lv2Menu")){ 179 var lv1MenuIndex = tr.prevAll(".lv1Menu").length -1; 180 var lv2MenuIndex = tr.prevUntil(".lv1Menu").length; 181 menus[lv1MenuIndex][\'sub_button\'][lv2MenuIndex][name] = $(this).val(); 182 } 183 render(menus); 184 }); 185 $("#menuForm").on("submit", function(){ 186 console.log(menus); 187 return false; 188 }); 189 }); 190 191 192 //tr渲染 193 function trRender(parentEle, menu, prevEle){ 194 if(!parentEle){ 195 if(!prevEle){ 196 parentEle = $("#lv1Menu_tpl .lv1Menu").clone(true); 197 var tbody = $("#menuForm table tbody"); 198 tbody.append(parentEle); 199 }else { 200 parentEle = $("#lv2Menu_tpl .lv2Menu").clone(true); 201 prevEle.after(parentEle); 202 } 203 } 204 parentEle = $(parentEle); 205 parentEle.find("input[name=\'name\']").val(menu[\'name\']); 206 if(menu[\'type\']){ 207 parentEle.find(".btnAddLv2Menu").hide(); 208 parentEle.find(".btnRemoveMenu").css(\'margin-left\', \'108px\'); 209 parentEle.find("select[name=\'type\']").val(menu[\'type\']); 210 }else{ 211 parentEle.find(".btnRemoveMenu").css(\'margin-left\', \'0\'); 212 parentEle.find(".btnAddLv2Menu").show(); 213 } 214 if(menu[\'key\'] != undefined){ 215 parentEle.find("input[name=\'url\']").attr(\'name\', \'key\'); 216 parentEle.find("input[name=\'key\']").val(menu[\'key\']).show(); 217 }else if(menu[\'url\'] != undefined){ 218 parentEle.find("input[name=\'key\']").attr(\'name\', \'url\'); 219 parentEle.find("input[name=\'url\']").val(menu[\'url\']).show(); 220 }else{ 221 parentEle.find("input[name=\'key\']").hide(); 222 parentEle.find("input[name=\'url\']").hide(); 223 } 224 return parentEle; 225 } 226 //菜单渲染 227 function render(menus){ 228 var parentEle = $("#menuForm"); 229 var lv1Menus = parentEle.find(".lv1Menu"); 230 for(var i=0; i<menus.length; i++){ 231 var lv1Menu = trRender(lv1Menus[i], menus[i], null); 232 if(menus[i][\'sub_button\'] && menus[i][\'sub_button\'].length > 0){ 233 var sub_menus = menus[i][\'sub_button\']; 234 for(var j=0; j<sub_menus.length; j++){ 235 var lv2Menus = lv1Menu.nextUntil(".lv1Menu"); 236 trRender(lv2Menus[j], sub_menus[j], lv2Menus.length>0?lv2Menus.last():lv1Menu); 237 } 238 //tr行数大于记录数时 239 if(lv2Menus.length > menus[i][\'sub_button\'].length){ 240 for(var j=menus[i][\'sub_button\'].length; j<lv2Menus.length; j++){ 241 lv2Menus[j].remove(); 242 } 243 } 244 245 }else{ 246 lv1Menu.nextAll(".lv2Menu").remove(); 247 } 248 } 249 250 //tr行数大于记录数时 251 lv1Menus = parentEle.find(".lv1Menu"); 252 if(lv1Menus.length > menus.length){ 253 for(var i=menus.length; i<lv1Menus.length; i++){ 254 var lv2Menus = $(lv1Menus[i]).nextUntil(".lv1Menu"); 255 lv2Menus.remove(); 256 $(lv1Menus[i]).remove(); 257 } 258 } 259 } 260 </script> 261 </body> 262 </html>