我试图使用以下
JSON数据在递归内部函数中创建以下类似的结构,运气不大,真的需要一些帮助,所以如果有人可以协助请做.先感谢您.
<ul> <li></li> <li> <a href=""></a> <div> <ul> <li> <a href=""></a> <div> ....etc </div> </li> </ul> </div> </li> </ul>
我使用的JSON数据如下:
var JSON = { menu: [ {id: '0',sub: [ {name: 'lorem ipsum 0-0',link: '0-0',sub: null},{name: 'lorem ipsum 0-1',link: '0-1',{name: 'lorem ipsum 0-2',link: '0-2',sub: null} ] },{id: '1',{id: '2',sub: [ {name: 'lorem ipsum 2-0',link: '2-0',{name: 'lorem ipsum 2-1',link: '2-1',{name: 'lorem ipsum 2-2',link: '2-2',sub: [ {name: 'lorem ipsum 2-2-0',link: '2-2-0',{name: 'lorem ipsum 2-2-1',link: '2-2-1',{name: 'lorem ipsum 2-2-2',link: '2-2-2',{name: 'lorem ipsum 2-2-3',link: '2-2-3',{name: 'lorem ipsum 2-2-4',link: '2-2-4',{name: 'lorem ipsum 2-2-5',link: '2-2-5',{name: 'lorem ipsum 2-2-6',link: '2-2-6',sub: null} ]},{name: 'lorem ipsum 2-3',link: '2-3',{name: 'lorem ipsum 2-4',link: '2-4',{name: 'lorem ipsum 2-5',link: '2-5',{id: '3',sub: null} ] }
我创建的代码(不完整,这是我需要帮助的脑筋急转弯)是:
$(function(){ $.fn.dropdown = function(settings){ var that = this; var settings = $.extend({},$.fn.dropdown.defaults,settings); var methods = { isArray: function(o){ return Object.prototype.toString.call(o) === '[object Array]'; },createDropdownCode: function(arr){ var menu = arr.menu; var html = null; var menusort = function(menu){ html = that; that.find("li").each(function(idx){ var menuList = menu[idx].sub; var baseContainer = $(this); var count = -1; var subsort = (function(){ count += 1; return function(submenu,pb){ var subblock; subblock = $("<div />").append('<ul />'); if(methods.isArray(submenu)){ for(var i=0;i<submenu.length;i++){ var l = $("<li />").append("<a href='"+ submenu[i].link +"'>"+ submenu[i].name +"</a>"); subblock.find('ul').append(l); if(pb !== undefined && i == submenu.length-1){ pb.append(subblock) } if(methods.isArray(submenu[i].sub)){ subsort(submenu[i].sub,subblock.find('ul li').eq(i)); } } } } })() subsort(menuList) }) } menusort(menu); return null; //html !== null ? html.html() : null; },init: function(){ // filter through json // create the div=>ul=>li if(settings.jsonData === undefined || settings.jsonData === null){ console.warn('No JSON Data passed') return; }else{ if(!methods.isArray(settings.jsonData.menu)){ console.warn('No JSON Data passed') return; // error,no data! } } //var html = methods.createBlock(settings.jsonData.menu[0].sub); var html = methods.createDropdownCode(settings.jsonData); //console.log(html) } } methods.init(); return that; } $.fn.dropdown.defaults = { jsonData: null } }) $('#menu').dropdown({ jsonData: JSON });
使用综合代码,感谢个人提供了足够接近的答案 – 虽然会研究其他人.
$.fn.dropdown = function(settings){ var that = this; var settings = $.extend({},settings); var methods = { createDropDownCode: function(arr){ // loop through li's of primary menu that.find("li").each(function(idx){ $(this).append( menusort(arr.menu[idx].sub) ); function menusort(data){ if(data !== null) var html = "<div><ul>"; for(item in data){ html += "<li>"; if(typeof(data[item].sub) === 'object'){ html += "<a href='" + data[item].link + "'>" + data[item].name + "</a>"; if($.isArray(data[item].sub)) html += menusort(data[item].sub); } html += "</li>" } if(data !== null) html += "</ul></div>"; return html; } }) },init: function(){ var html = methods.createDropDownCode(settings.jsonData); } } methods.init(); }
解决方法
您可以尝试我刚刚编写的这个递归函数:
function buildList(data,isSub){ var html = (isSub)?'<div>':''; // Wrap with div if true html += '<ul>'; for(item in data){ html += '<li>'; if(typeof(data[item].sub) === 'object'){ // An array will return 'object' if(isSub){ html += '<a href="' + data[item].link + '">' + data[item].name + '</a>'; } else { html += data[item].id; // Submenu found,but top level list item. } html += buildList(data[item].sub,true); // Submenu found. Calling recursively same method (and wrapping it in a div) } else { html += data[item].id // No submenu } html += '</li>'; } html += '</ul>'; html += (isSub)?'</div>':''; return html; }
它返回菜单的html,所以使用它:var html = buildList(JSON.menu,false);
我相信它更快,因为它是纯JavaScript,并且它不会为每次迭代创建文本节点或DOM元素.只需在完成后调用.innerHTML或$(‘…’).html(),而不是立即为每个菜单添加HTML.
JSFiddled:http://jsfiddle.net/remibreton/csQL8/