Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML/CSS:what';嵌套元素树的布局比嵌套表更好吗?_Javascript_Jquery_Html_Css_Cross Browser - Fatal编程技术网

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上升到下一级(有电、无电)
  • 如果用户选择通电,则打开下一级(两轮、四轮)
  • 如果用户随后取消选中“已通电”,则该级别将消失
现在,通过onclick在block和none之间切换displaycss属性,这相对容易设置

该页面上当前的结构如下:

<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");
});