我试图使用以下
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/