Javascript HTML/CSS:what';嵌套元素树的布局比嵌套表更好吗?
好的,我有一组选择标准的复选框。为了便于讨论,我们将说数据如下所示:Javascript HTML/CSS:what';嵌套元素树的布局比嵌套表更好吗?,javascript,jquery,html,css,cross-browser,Javascript,Jquery,Html,Css,Cross Browser,好的,我有一组选择标准的复选框。为了便于讨论,我们将说数据如下所示: [] Vehicles [] Unpowered [] Bicycle [] Skateboard [] Powered [] Two-wheeled [] Motorcycle [] Scooter [] Four-wheeled etc []s表示复选框 忽略这个例子明显是人为造成的,其想法是: 首先,只有车辆复选框可见 如
[] Vehicles
[] Unpowered
[] Bicycle
[] Skateboard
[] Powered
[] Two-wheeled
[] Motorcycle
[] Scooter
[] Four-wheeled
etc
[]s表示复选框
忽略这个例子明显是人为造成的,其想法是:
- 首先,只有车辆复选框可见李>
- 如果用户点击车辆复选框,则opsn上升到下一级(有电、无电)李>
- 如果用户选择通电,则打开下一级(两轮、四轮)李>
- 如果用户随后取消选中“已通电”,则该级别将消失
<table>
<tr>
<td><input type="checkbox" onclick="toggle('__Vehicles');"></td>
<td>Vehicles
<table id="__Vehicles">
<tr>
<td><input type="checkbox"></td>
<td>Unpowered
etc
车辆
无动力
等
在有人问之前,我应该指出:复选框放在表格单元格中的原因是为了控制格式。由于下一个表单元格中的所有内容都将对齐,因此可以轻松有效地进行缩进
这一切都很好,但表嵌套变得相当深。我一直在想一定有比这更好的办法。它必须能够轻松地动态构建,并且对“树”的格式具有良好的跨浏览器支持
我还应该提到jQuery是可用的。我在用它做其他事情
建议
编辑:是复选框样式很重要,正如一些评论所指出的。另外,根据我得到的回复,我发布了一个解决方案,作为下面的答案(太大,无法在此添加),仅供好奇的人参考。表格用于表格数据。使用嵌套列表和CSS进行格式设置
如果您正在寻找一个完整的解决方案,下面是一个使用纯CSS(用于现代浏览器)和JavaScript(用于IE)的解决方案:
<style>
ul.tree, ul.tree ul {
position: relative;
list-style: none;
margin: 0 0 0 20px;
padding: 0;
}
ul.tree input {
position: absolute;
margin-left: -20px;
}
ul.tree ul {
display: none;
}
ul.tree input:checked ~ ul {
display: block;
}
ul.tree label:hover {
text-decoration: underline;
}
</style>
<ul class="tree">
<li>
<input type="checkbox" id="option1">
<label for="option1">Option 1</label>
<ul>
<li>
<input type="checkbox" id="option1a">
<label for="option1a">Option 1 Sub Option A</label>
</li>
<li>
<input type="checkbox" id="option1b">
<label for="option1b">Option 1 Sub Option B</label>
</li>
</ul>
</li>
<li>
<input type="checkbox" id="option2">
<label for="option2">Option 2</label>
</li>
</ul>
<!--[if lte IE 7]>
<script>
var tree = document.getElementsByTagName('ul')[0];
tree.attachEvent('onclick', function() {
var src = event.srcElement;
if(src.nodeName.toLowerCase() === 'label')
var box = document.getElementById(src.htmlFor);
else if(src.nodeName.toLowerCase() === 'input')
var box = src;
else return;
for(var current = src.nextSibling;
current && current.nodeName.toLowerCase() !== 'ul';
current = current.nextSibling);
if(current)
current.style.display = box.checked ? 'block' : 'none';
});
</script>
<![endif]-->
树,树,树{
位置:相对位置;
列表样式:无;
利润率:0.20px;
填充:0;
}
树输入{
位置:绝对位置;
左边距:-20px;
}
树{
显示:无;
}
ul.树输入:选中~ul{
显示:块;
}
树标签:悬停{
文字装饰:下划线;
}
-
选择1
-
方案1次级方案A
-
备选案文1次级备选案文B
-
选择2
假设复选框不宽,嵌套无序列表是这类事情的最佳实践
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
</ul>
</li>
</ul>
- 项目1
- 项目2
- 分项目1
- 分项目2
- 分项目3
- 项目3
- 项目4
- 分项目1
- 分项目2
- 分项目3
还有js
$(document).ready(function() {
$('li input:checkbox').click(function () {
$(this).parent().toggleClass('opened');
$(this).parent().toggleClass('closed');
});
$('li').addClass('closed');
});
再次编辑,因为Sparr需要一些更好的样式(假设复选框的样式为“checkbox”)
您可以这样做:
<ul>
<li>
<input type="checkbox" /> Option 1
<ul>
<li><input type="checkbox" /> Option 1 Sub Option A</li>
</ul>
</li>
</ul>
对于javascript,在每个复选框中附加一个事件,以确定同级UL(如果存在)是否应可见。如果选中该复选框,则显示它,否则隐藏它。创建cb时,根据级别为其提供css类
<input class="LevelXcb" type="checkbox" />
如果“left”不起作用,请尝试设置“margin left”。除了上面的建议外,我还建议您从标记中提取javascript。使用lowpro(我最喜欢的库)等库,您可以创建一个对象来处理嵌套的复选框行为,并自动应用它。这样包装您的代码使您的标记更易于维护,您的代码更易于编写、更强大、更易于维护。我知道这与问题关系不大,所以请不要投票这只是一个暗示 在这个来自davethegr8的示例中:
<ul>
<li>Vehicles <ul>
<li>Unpowered</li>
<li>Bicycle</li>
<li>Skateboard</li>
</ul></li>
<li>Powered <ul>
<li>Two-wheeled <ul>
<li>Motorcycle</li>
<li>Scooter</li>
</ul></li>
<li>Four-wheeled</li>
</ul></li>
</ul>
只是一个小建议:)虽然jQuery插件以不同的方式处理嵌套列表问题(没有复选框),但它可能适合您的需要。想看看jQuery的深层魔法吗
<ul class="tree">
<li><input type="checkbox" name="Vehicles" checked>Vehicles
<ul>
<li<input type="checkbox" name="Unpowered">Unpowered
<ul>
<li><input type="checkbox" name="Bicycle">Bicycle</li>
<li><input type="checkbox" name="Skateboard">Skateboard</li>
</ul>
</li>
<li><input type="checkbox" name="Powered" checked>Powered
<ul>
<li><input type="checkbox" name="Two-wheeled">Two-wheeled
<ul>
<li><input type="checkbox" name="Motorcycle" checked>Motorcycle</li>
<li><input type="checkbox" name="Scooter">Scooter</li>
</ul>
</li>
<li><input type="checkbox" name="Two-Wheeled">Four-wheeled</li>
</ul>
</ul>
</li>
</ul>
还有魔法:
$(function() {
$("ul.tree li:has(ul) > :checkbox").click(function() {
jQuery(this).parent().toggleClass('closed');
}).not(":checked").parent().addClass("closed");
});
当你点击复选框时,这会把整个事情变成一个工作的打开和关闭树。太棒了
感谢davethegr8、Jonathon Sampson和其他人的建议。如果复选框的宽度仍然是一个问题(在所有以前的答案之后…),您可以:
- 将所有复选框置于“固定带”框中,以便准确知道文本的起始位置(以及下一级复选框)
- 使用一些jquery计算来获得宽度,并动态设置其他元素的边距(虽然看起来有点太多了…)
显然,使用建议的嵌套列表结构。您遗漏的问题的关键点是,使用嵌套表会使复选框在父级标签下方的一个级别上对齐。需要一些更高级的样式来复制列表的这种行为,而样式是这个问题的“难点”部分。但请记住,它们后面的所有项目也必须对齐。您为它们设置了正确的css类,它们会这样做,不是吗?+1用于记住复选框(而不仅仅是发布任意嵌套的列表)-1用于缩进10px,而不是缩进复选框的宽度,是原件的关键点question@Sparr,虽然我认为这不是否决答案的好理由,但我已将其更新为20px。一旦你使用它,你就有能力自己编辑代码。Firefox使用填充和IE使用边距作为列表间距/缩进,这难道不是跨浏览器的事情吗?@Cletus,是的。这就是为什么我将边距/填充设置为0,然后在LI上使用填充进行缩进。您遗漏的问题的关键点是,使用嵌套表会使某一级别的复选框在父级别的标签下方对齐。一些爱好者
<input class="LevelXcb" type="checkbox" />
.Level0cb{left:4px;}
.Level1cb{left:16px;}
.Level2cb{left:28px;}
<ul>
<li>Vehicles <ul>
<li>Unpowered</li>
<li>Bicycle</li>
<li>Skateboard</li>
</ul></li>
<li>Powered <ul>
<li>Two-wheeled <ul>
<li>Motorcycle</li>
<li>Scooter</li>
</ul></li>
<li>Four-wheeled</li>
</ul></li>
</ul>
$("li.Two-wheeled").click(function(event){
$("div.main_wrapper ul.Moto_or_scooter:hidden").slideDown("slow");
}
<ul class="tree">
<li><input type="checkbox" name="Vehicles" checked>Vehicles
<ul>
<li<input type="checkbox" name="Unpowered">Unpowered
<ul>
<li><input type="checkbox" name="Bicycle">Bicycle</li>
<li><input type="checkbox" name="Skateboard">Skateboard</li>
</ul>
</li>
<li><input type="checkbox" name="Powered" checked>Powered
<ul>
<li><input type="checkbox" name="Two-wheeled">Two-wheeled
<ul>
<li><input type="checkbox" name="Motorcycle" checked>Motorcycle</li>
<li><input type="checkbox" name="Scooter">Scooter</li>
</ul>
</li>
<li><input type="checkbox" name="Two-Wheeled">Four-wheeled</li>
</ul>
</ul>
</li>
</ul>
ul.tree {
list-style-type: none;
margin: 0 0 0 -22px;
padding: 0;
}
ul.tree ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul.tree input {
margin-right: 6px;
}
ul.tree li {
padding: 0 0 0 22px;
margin: 1px;
}
.closed ul {
display: none;
}
$(function() {
$("ul.tree li:has(ul) > :checkbox").click(function() {
jQuery(this).parent().toggleClass('closed');
}).not(":checked").parent().addClass("closed");
});