我正在构建一个 Web 应用程序,它将显示事物的层次结构。层次结构将非常类似于具有文件夹和文件的文件系统,即我将拥有包含任何深度级别的文件和子文件夹的文件夹(尽管它可能永远不会超过三个级别)。
整个层次结构将显示在一个视图中。它将以树形显示,用户可以随意展开/关闭文件夹。不同的级别是缩进的,就像标准的文件系统浏览器一样。
用 HTML 和 CSS 表示它的好方法是什么?请注意,我需要帮助的不是设计/外观本身,而是如何使用 HTML 以良好的方式构建它。我应该使用列表吗?
一种使用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>
用 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 可以很软,因为列表已经代表了一个层次结构。
我会避免<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>
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>
我会用一张桌子。不同的列代表更深层次的缩进。