【问题标题】:generate Jquery Multilevel menu list with ul li使用 ul li 生成 Jquery 多级菜单列表
【发布时间】:2013-04-06 13:15:35
【问题描述】:
...images
......|vertical
......|horizontal
...Jquery
......|UI
......|include
...quickfox

要处理的数组: 我有像上面一样的文件夹结构。它存储在数组目录中。见下文

var dirs = [ 
        "images",
        "images/vertical",
        "images/horizontal",
        "Jquery",
        "Jquery/UI",
        "Jquery/include",
        "quickfox"
        ];

目标:我怎样才能使嵌套的ul li如下。

<ul id="categorymenu">
    <li>images </li>
    <ul>
        <li>vertical</li>
        <li>horizontal</li>
    </ul>
    <li>Jquery</li>
    <ul>
        <li>UI</li>
        <li>include</li>
    </ul>
    <li>quickfox</li>
</ul>

更新:XML 结构

<directory name="images">
   <file path="BBB.gif" width="500" height="282">BBB.gif</file>
   <file path="AAA.jpg" width="964" height="525">AAA.jpg</file>
   <directory name="images/vertical">
      <file path="CCC.jpg" width="964" height="525">CCC.jpg</file>
   </directory>
   <directory name="images/horizontal">
      <file path="DDD.jpg" width="964" height="525">DDD.jpg</file>      
   </directory>
</directory>

这是我从 xml 制作数组的地方 ..

$(document).ready(function () {
    //------ READ XML -----------
    $.ajax({
        type: "GET",
        url: "___deck.xml",
        dataType: "xml",
        success: function (data) {
            my_xml = data;
            xmlDirParser(my_xml);
        }
    });
    //------ Get Files on List Change  -----------
    $("#dirlist").change(function () {
        var folder = $(this).find('option:selected').text();
        xmlFileParser(folder, my_xml);
    });
});

function xmlDirParser(my_xml) {
    $(my_xml).find('directory').each(function () {
        var dirname = $(this).attr('name');
        // $('#dirlist').append('<option value="1">'+dirname+'</option>');
        //This is where I get dirs array
    });
}

【问题讨论】:

    标签: jquery html-lists multi-level


    【解决方案1】:

    你的数组结构对创建元素没有用,你可以基于数组创建一个对象并使用这个对象。

    var o = {}; 
    
    // Creating an object based on the array elements
    $.each(dirs, function (_, value) {
        if (value.indexOf('/') === -1) {
            o[value] = [];
        } else {
            var arr = value.split('/');
            o[arr[0]].push(arr[1]);
        }
    });
    
    // Creating elements
    
    var html = '<ul id="categorymenu">';
    for (key in o) {
        html += '<li>' + key + '</li>';
        if (o[key].length) {
            html += '<ul><li>' + o[key].join('</li><li>') + '</li></ul>';
        }
    }
    html += '</ul>';
    

    http://jsfiddle.net/5DuDp/

    更新

    我没有注意到预期的标记无效,ul 元素应该只有 li 子元素,您应该将后代 ul 元素添加到 li 元素:

    for (key in o) {
        html += '<li>' + key ;
        if (o[key].length) {
            html += '<ul><li>' + o[key].join('</li><li>') + '</li></ul>';
        }
        html += '</li>';
    }
    html += '</ul>';
    

    http://jsfiddle.net/642pr/

    【讨论】:

    • 您的代码运行良好,但 function (_, value) 中的 _ 是什么?
    • @Bingo 这是索引,_ 是 JavaScript 中的有效标识符,可以认为是 iindex
    【解决方案2】:

    原始答案

    如果您将数据结构更改为多维数组/对象,则可以使用递归函数循环遍历无限嵌套级别,如下所示:

    var dirs = [{
        name: "images",
        subdir: [{
            name: "vertical"
        }, {
            name: "horizontal"
        }]
    }, {
        name: "Jquery",
        subdir: [{
            name: "UI", subdir: [{name:'Nested 1',subdir: [{name:'Nested 2',subdir: [{name:'Nested 3'}]}]}]
        }, {
            name: "include"
        }]
    }, {
        name: "quickfox"
    }];
    
    function createList( array){
        var html='<ul>';
        $.each( array, function(k, item){
            html+='<li>'+item.name;
            if( item.subdir){
                html+=createList(item.subdir);
            }
            html+='</li>';
        });
         html+='</ul>';
        return html;
    }
    
    
    $('body').html( createList( dirs))
    

    演示:http://jsfiddle.net/AA6yb/1

    修订答案

    基于xml已经嵌套的更新信息,问题是如何解析xml而不是平面数组。

    以下递归循环遍历xml中所有children的目录。通过使用find(),您创建了一个平面数组,因为find() 查找所有后代

    function createList($xml) {
        var html = '';
    
        $xml.children('directory').each(function () {
            var $dir = $(this);
            var name= $dir.attr('name');
            html += '<li class="dir">' + parseName($dir.attr('name'));
            if ($dir.children().length) {
                html += '<ul>';
                $dir.children('file').each(function () {
                    html += '<li class="file">' + $(this).attr('path') + '</li>';
                });
                /* recursively loop through children directories of this directory*/
                if( $dir.children('directory').length){
                    html+=createList($dir);
                }
                html += '</ul>';
            }
        });
        html += '</li>';
        return html;
    }
    function parseName( name){
        if( name.indexOf('/')>-1){
            return name.split('/').pop();
        }else{
            return name;
        }
    }
    
    $('#directory_list').html(createList($(xmlData)))
    

    HTML

    <ul id="directory_list"></ul>
    

    演示:http://jsfiddle.net/AA6yb/2/

    【讨论】:

    • 谢谢@charlietfl。 1-如何将有问题的 var dirs 转换为 multil dim 数组。因为这些条目来自 xml。 2-我们如何在这段代码中添加缩进来美化。
    • 您是在服务器上还是在 javascript AJAX 请求中解析 xml?如果是javascript;提供xml样本
    • 我添加了相关的 xml 和 javascript。
    • 通过显示平面数组使问题变得更加困难。您的 xml 已经嵌套,无需转换为平面数组。问题是您使用 find('directory) 而不是 children('directory') 忽略 xml 嵌套,然后递归循环遍历该目录的子项(如果存在)
    • 你能建议更正的代码吗?与孩子('目录)
    【解决方案3】:

    如果你必须有这个数据结构,你可以使用这个:

    $(function () {
        var dirs = [
            "images",
            "images/vertical",
            "images/horizontal",
            "Jquery",
            "Jquery/UI",
            "Jquery/include",
            "quickfox"];
    
        var rootList = $("<ul id='categorymenu'>").appendTo("body");
        var elements = {};
    
        $.each(dirs, function () {
            var parent = elements[this.substr(0, this.lastIndexOf("/"))];
            var list = parent ? parent.next("ul") : rootList;
            var textMenu= parent ? this.split("/")[1] : this;
            if (!list.length) {
                list = $("<ul>").insertAfter(parent);
            }
            var item = $("<li>").appendTo(list);
            $("<a>").text(textMenu).appendTo(item);
            elements[this] = item;
        });
    });
    

    这是一个小提琴:http://jsfiddle.net/K8SZk/3/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多