9

我正在构建一个 Web 应用程序,它将显示事物的层次结构。层次结构将非常类似于具有文件夹和文件的文件系统,即我将拥有包含任何深度级别的文件和子文件夹的文件夹(尽管它可能永远不会超过三个级别)。

整个层次结构将显示在一个视图中。它将以树形显示,用户可以随意展开/关闭文件夹。不同的级别是缩进的,就像标准的文件系统浏览器一样。

用 HTML 和 CSS 表示它的好方法是什么?请注意,我需要帮助的不是设计/外观本身,而是如何使用 HTML 以良好的方式构建它。我应该使用列表吗?

4

5 回答 5

15

一种使用div和框架的方法span,最后用一个工作示例在下面解释。

每个文件夹包含 2 种类型的内容。Files和内Folders。所以一个基本的结构是用一个整体的容器来设计的。

整体容器

<div id="hierarchy">
    <!--folder structure goes here-->
</div>

文件夹结构

<div class="foldercontainer">
    <span class="folder fa-folder-o" data-isexpanded="true">Folder 1</span>
    <span class="file fa-file-excel-o">File 11</span>
    <span class="file fa-file-code-o">File 12</span>
    <span class="file fa-file-pdf-o">File 13</span>
</div>

文件夹结构(没有文件)

<div class="foldercontainer">
    <span class="folder fa-folder">Folder 1</span>
    <span class='noitems'>No Items</span>
</div>

foldercontainer包含span指定文件名的元素。第一个span元素包含文件夹标题,而其余元素包含文件名。该data-属性isexpanded指定指定的文件夹是展开还是折叠。

如果文件夹不包含文件,则将noitems span元素添加到结构中。

当一个文件夹包含另一个文件夹时,只需向其中添加与子文件夹相同的 html。IE,

<div class="foldercontainer">
    <span class="folder fa-folder-o" data-isexpanded="true">Folder 1</span>
    <span class="file fa-file-excel-o">File 11</span>
    <span class="file fa-file-code-o">File 12</span>
    <span class="file fa-file-pdf-o">File 13</span>

    <div class="foldercontainer">
        <span class="folder fa-folder-o" data-isexpanded="true">Folder 1-1</span>
        <span class="file fa-file-excel-o">File 1-11</span>
        <span class="file fa-file-code-o">File 1-12</span>
        <span class="file fa-file-pdf-o">File 1-13</span>
    </div>
</div>

Javascript

click事件从父#hierarchy元素委托给文件夹和文件,以处理单个事件侦听器中的单击。单击文件夹时,它会展开并且图标会更改。再次单击它会折叠并重置图标。

在展开内文件夹和折叠外文件夹时,在展开外文件夹时,根据设计,内文件夹内容状态被保留。

请参阅这篇不错的文章,了解如何在单个侦听器中处理多个元素上的事件。

注意:可以修改代码以使用CSS 自定义变量Data 属性访问 CSS更有效,而前者在 IE 中不支持,后者在跨浏览器支持方面有其自身的缺点。所以使用风险自负。

具有各种层次结构的工作示例

var hierarchy = document.getElementById("hierarchy");
hierarchy.addEventListener("click", function(event){
    var elem = event.target;
    if(elem.tagName.toLowerCase() == "span" && elem !== event.currentTarget)
    {
        var type = elem.classList.contains("folder") ? "folder" : "file";
        if(type=="file")
        {
            alert("File accessed");
        }
        if(type=="folder")
        {
            var isexpanded = elem.dataset.isexpanded=="true";
            if(isexpanded)
            {
                elem.classList.remove("fa-folder-o");
                elem.classList.add("fa-folder");
            }
            else
            {
                elem.classList.remove("fa-folder");
                elem.classList.add("fa-folder-o");
            }
            elem.dataset.isexpanded = !isexpanded;

            var toggleelems = [].slice.call(elem.parentElement.children);
            var classnames = "file,foldercontainer,noitems".split(",");

            toggleelems.forEach(function(element){
                if(classnames.some(function(val){return element.classList.contains(val);}))
                element.style.display = isexpanded ? "none":"block";
            });
        }
    }
});
#hierarchy
{
    font-family: FontAwesome;
    width: 300px;
}
.foldercontainer, .file, .noitems
{
    display: block;
    padding: 5px 5px 5px 50px;
}
.folder
{
    color: red;
}
.file
{
    color: green;
}
.folder, .file
{
    cursor: pointer;
}
.noitems
{
    display: none;
    pointer-events: none;
}
.folder:hover,.file:hover
{
    background: yellow;
}
.folder:before, .file:before
{
    padding-right: 10px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div id="hierarchy">
<div class="foldercontainer">
    <span class="folder fa-folder-o" data-isexpanded="true">Folder 1</span>
    <span class="file fa-file-excel-o">File 11</span>
    <span class="file fa-file-code-o">File 12</span>
    <span class="file fa-file-pdf-o">File 13</span>

    <div class="foldercontainer">
        <span class="folder fa-folder-o" data-isexpanded="true">Folder 1-1</span>
        <span class="file fa-file-excel-o">File 1-11</span>
        <span class="file fa-file-code-o">File 1-12</span>
        <span class="file fa-file-pdf-o">File 1-13</span>
    </div>

    <div class="foldercontainer">
        <span class="folder fa-folder">Folder 1-2</span>
        <span class='noitems'>No Items</span>
    </div>

    <div class="foldercontainer">
        <span class="folder fa-folder">Folder 1-3</span>
        <span class='noitems'>No Items</span>
    </div>

    <div class="foldercontainer">
        <span class="folder fa-folder">Folder 1-4</span>
        <span class='noitems'>No Items</span>
    </div>
</div>

<div class="foldercontainer">
    <span class="folder fa-folder-o" data-isexpanded="true">Folder 2</span>
    <span class="file fa-file-excel-o">File 21</span>
    <span class="file fa-file-code-o">File 22</span>
    <span class="file fa-file-pdf-o">File 23</span>

    <div class="foldercontainer">
        <span class="folder fa-folder-o" data-isexpanded="true">Folder 2-1</span>
        <span class="file fa-file-excel-o">File 2-11</span>
        <span class="file fa-file-code-o">File 2-12</span>
        <span class="file fa-file-pdf-o">File 2-13</span>

        <div class="foldercontainer">
            <span class="folder fa-folder">Folder 2-1-1</span>
            <span class='noitems'>No Items</span>
        </div>
    </div>
</div>

<div class="foldercontainer">
    <span class="folder fa-folder-o" data-isexpanded="true">Folder 3</span>
    <span class="file fa-file-excel-o">File 31</span>
    <span class="file fa-file-code-o">File 32</span>
    <span class="file fa-file-pdf-o">File 33</span>

    <div class="foldercontainer">
        <span class="folder fa-folder">Folder 3-1</span>
        <span class='noitems'>No Items</span>
    </div>
</div>
</div>

于 2018-07-31T16:03:43.393 回答
8

用 HTML 表示它的好方法是将文件列表组织为... HTML 列表 :) 例如,您可能会得到:

<ul>
     <li>Folder 1
           <ul>
               <li>SubFile 1</li>
               <li>SubFile 2</li>
               <li>SubFile 3</li>
           </ul></li>
     <li>Folder 2
           <ul>
               <li>SubFile 4</li>
               <li>SubFile 5</li>
               <li>SubFile 6</li>
           </ul></li>
     <li>Main File 1</li>
     <li>Main File 2</li>
</ul>

那么 CSS 可以很软,因为列表已经代表了一个层次结构。

于 2013-07-10T08:41:41.197 回答
1

我会避免<ul>,因为那是“无序列表”,而您的文件夹结构可能会按某种顺序排列。

我会使用定义列表或有序列表;

<dl>
    <dt>Folder 1
        <dl>
            <dt>Child 1</dt>
            <dt>Child 2</dt>
            <dt>Child 3</dt>
        </dl>
    </dt>
    <dt>Folder 2
        <dl>
            <dt>Child 1</dt>
            <dt>Child 2</dt>
            <dt>Child 3</dt>
        </dl>
    </dt>
</dl>

<ol>
    <li>Folder 1
        <ol>
            <li>Child 1</li>
            <li>Child 2</li>
            <li>Child 3</li>
        </ol>
    </li>
    <li>Folder 2
        <ol>
            <li>Child 1</li>
            <li>Child 2</li>
            <li>Child 3</li>
        </ol>
    </li>
</ol>
于 2013-07-10T08:45:17.600 回答
0
I have created folder hierarchy using list items. This will help for sure.

$(function() {
        setFolderHeirarchy();
    });

    function setFolderHeirarchy() {
               var labelWrapper= $('.labelWrapper');
                $(labelWrapper).each(function () {
                    if (!$(this).next('.subFolderHeirarchy')||$(this).next('.subFolderHeirarchy').length==0) {
                        $(this).find('.arrow').remove();
                    }
                    else{
                        console.log($(this).next('.subFolderHeirarchy'));
                    }
                });

     

        $('.labelWrapper').click(function() {
            if ($(this).next('.subFolderHeirarchy').length > 0) {
                $(this).parent('.folderHeirarchyList').toggleClass('active');

                if ($(this).parent('.folderHeirarchyList').hasClass('active')) {
                    $(this).find('.arrow').removeClass('glyphicon-triangle-right').addClass('glyphicon-triangle-bottom');
                } else {
                    $(this).find('.arrow').removeClass('glyphicon-triangle-bottom').addClass('glyphicon-triangle-right');
                }
            }else{
                // $(this).css('color','red');
            }

        });

    }
.mainFolderHeirarchy li {
  border: none;
  background: 0 0!important
}

.mainFolderHeirarchy li a {
  color: #000;
  text-decoration: none!important
}

.mainFolderHeirarchy li a:hover {
  text-decoration: none!important
}

.mainFolderHeirarchy .folderHeirarchyList {
  padding-top: 3px;
  padding-bottom: 3px
}

.mainFolderHeirarchy .folderHeirarchyList.active>.subFolderHeirarchy {
  display: block
}

.mainFolderHeirarchy .folderHeirarchyList .subFolderHeirarchy {
  display: none;
  padding-left: 5px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>

    <h1> Folder Heirarchy/ multi level list item</h1>
    <hr />
    <ul class="list-group mainFolderHeirarchy">
            <li class="list-group-item folderHeirarchyList">
                <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                <ul class="subFolderHeirarchy">
                    <li class="list-group-item folderHeirarchyList">
                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                        <ul class="subFolderHeirarchy">
                            <li class="list-group-item folderHeirarchyList">
                                <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                            </li>
                            <li class="list-group-item folderHeirarchyList">
                                <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                <ul class="subFolderHeirarchy">
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                    </li>
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                        <ul class="subFolderHeirarchy">
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                    </li>
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                        <ul class="subFolderHeirarchy">
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                        <ul class="subFolderHeirarchy">
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                    </li>
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                    </li>
                                </ul>
                                    </li>
                                    <li class="list-group-item folderHeirarchyList">
                                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                                    </li>
                                </ul>
                                    </li>
                                </ul>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li class="list-group-item folderHeirarchyList">
                        <a href="#" class="labelWrapper"><span class="arrow glyphicon glyphicon-triangle-right"></span><span class="listlabel">listitem</span> </a>
                    </li>
                </ul>
            </li>
        </ul>

于 2016-06-14T01:54:08.647 回答
-3

我会用一张桌子。不同的列代表更深层次的缩进。

于 2013-07-10T08:40:27.383 回答