首页 > 解决方案 > 在交互式流程图/树形图中隐藏未选择的选项

问题描述

我正在寻找一些我试图从另一个网站改编的 Javascript 代码的帮助,但我无法让它做我想做的事情。

我想完全使用 HTML 代码中的 CSS 和 javascript 来完成这项工作。我是一个完整的 javascript 初学者。

在下面的 HTML 代码中,您可以单击一个复选框,它会显示下一级选项。

但是,我想要发生的是,例如,选择“选项 1”,然后隐藏“选项 2”和“选项 3”。目前,它们仍在视图中,可以点击。

And then when, say, Option 1.2 is picked, then the other two options of 'Option 1.1' and 'Option 1.3' are hidden.

本质上,我希望用户能够向下导航一棵树,但一次只能导航一个分支,并且在他们做出选择后,同一级别中未选择的选项会消失。

当然,反之亦然,如果他们清除更高级别的选项,则完整菜单会在该级别重新显示。

我尝试了多种不同的编码,但它们要么隐藏所有内容,要么使所有复选框无响应!我缺乏 javascript 语法知识,但我认为解决方案包括将同一级别的未勾选框转换为“隐藏”类,同时将勾选的框保留为“隐藏”类并显示积极的'

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    ul,
    #myUL {
      list-style-type: none;
    }
    
    #myUL {
      margin: 0;
      padding: 0;
    }
    
    .box {
      cursor: pointer;
      -webkit-user-select: none;
      /* Safari 3.1+ */
      -moz-user-select: none;
      /* Firefox 2+ */
      -ms-user-select: none;
      /* IE 10+ */
      user-select: none;
    }
    
    .box::before {
      content: "\2610";
      color: black;
      display: inline-block;
      margin-right: 6px;
    }
    
    .check-box::before {
      content: "\2611";
      color: dodgerblue;
    }
    
    .nested {
      display: none;
    }
    
    .active {
      display: block;
    }
    
    .hide {
      display: none;
    }
  </style>
</head>

<body>

  <h2>Interactive Decision Tree</h2>

  <ul id="myUL">
    <li><span class="box">Option 1</span>
      <ul class="nested">
        <li><span class="box">Option 1.1</span>
          <ul class="nested">
            <li><span class="box">Option 1.1.1</span></li>
            <li><span class="box">Option 1.1.2</span></li>
            <li><span class="box">Option 1.1.3</span></li>
          </ul>
        </li>
        <li><span class="box">Option 1.2</span>
          <ul class="nested">
            <li><span class="box">Option 1.2.1</span></li>
            <li><span class="box">Option 1.2.2</span></li>
            <li><span class="box">Option 1.2.3</span></li>
          </ul>
        </li>
        <li><span class="box">Option 1.3</span>
          <ul class="nested">
            <li><span class="box">Option 1.3.1</span></li>
            <li><span class="box">Option 1.3.2</span></li>
            <li><span class="box">Option 1.3.3</span></li>
          </ul>
        </li>
      </ul>

      <li><span class="box">Option 2</span>
        <ul class="nested">
          <li><span class="box">Option 2.1</span>
            <ul class="nested">
              <li><span class="box">Option 2.1.1</span></li>
              <li><span class="box">Option 2.1.2</span></li>
              <li><span class="box">Option 2.1.3</span></li>
            </ul>
          </li>
          <li><span class="box">Option 2.2</span>
            <ul class="nested">
              <li><span class="box">Option 2.2.1</span></li>
              <li><span class="box">Option 2.2.2</span></li>
              <li><span class="box">Option 2.2.3</span></li>
            </ul>
          </li>
          <li><span class="box">Option 2.3</span>
            <ul class="nested">
              <li><span class="box">Option 2.3.1</span></li>
              <li><span class="box">Option 2.3.2</span></li>
              <li><span class="box">Option 2.3.3</span></li>
            </ul>
          </li>
        </ul>

        <li><span class="box">Option 3</span>
          <ul class="nested">
            <li><span class="box">Option 3.1</span>
              <ul class="nested">
                <li><span class="box">Option 3.1.1</span></li>
                <li><span class="box">Option 3.1.2</span></li>
                <li><span class="box">Option 3.1.3</span></li>
              </ul>
            </li>
            <li><span class="box">Option 3.2</span>
              <ul class="nested">
                <li><span class="box">Option 3.2.1</span></li>
                <li><span class="box">Option 3.2.2</span></li>
                <li><span class="box">Option 3.2.3</span></li>
              </ul>
            </li>
            <li><span class="box">Option 3.3</span>
              <ul class="nested">
                <li><span class="box">Option 3.3.1</span></li>
                <li><span class="box">Option 3.3.2</span></li>
                <li><span class="box">Option 3.3.3</span></li>
              </ul>
            </li>
          </ul>
        </li>
  </ul>


  <script>
    var toggler = document.getElementsByClassName("box");
    var i;

    for (i = 0; i < toggler.length; i++) {
      toggler[i].addEventListener("click", function() {
        this.parentElement.querySelector(".nested").classList.toggle("active");
        this.classList.toggle("check-box");
      });
    }
  </script>

</body>

</html>

感谢您为使其按预期工作所需的补充。

标签: javascriptcssinteractiveflowchart

解决方案


所以,我为自己的问题编写了一个解决方案。我意识到我发布的示例的功能不足以勾选复选框并显示无论您在选择列表上还是下的项目。因此,它需要一种不同的方法,如下所述。这对我有用,而且我完全理解它,因为我写了这一切,改编了来自其他各种来源的代码。希望这对将来的其他人有所帮助。

<!DOCTYPE html>
<html>

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        ul,
        #myUL {
            list-style-type: none;
        }

        #myUL {
            margin: 0;
            padding: 0;
        }

        .box hide {
            cursor: pointer;
            -webkit-user-select: none;
            /* Safari 3.1+ */
            -moz-user-select: none;
            /* Firefox 2+ */
            -ms-user-select: none;
            /* IE 10+ */
            user-select: none;
        }

        .box::before {
            content: "\2610";
            color: black;
            display: inline-block;
            margin-right: 6px;
        }

        .check-box::before {
            content: "\2611";
            color: dodgerblue;
        }

        .hide {
            display: none;
        }

        .show {
            display: block;
        }

    </style>
</head>

<body>

    <h2>Interactive Decision Tree</h2>
    <p id="O" class="box">Start</p>
    <p id="O1" class="box hide">Option O1</p>
    <p id="O11" class="box hide">Option O11</p>
    <p id="O111" class="box hide">Option O111</p>
    <p id="O112" class="box hide">Option O112</p>
    <p id="O113" class="box hide">Option O113</p>
    <p id="O12" class="box hide">Option O12</p>
    <p id="O121" class="box hide">Option O121</p>
    <p id="O122" class="box hide">Option O122</p>
    <p id="O123" class="box hide">Option O123</p>
    <p id="O13" class="box hide">Option O13</p>
    <p id="O131" class="box hide">Option O131</p>
    <p id="O132" class="box hide">Option O132</p>
    <p id="O133" class="box hide">Option O133</p>
    <p id="O2" class="box hide">Option O2</p>
    <p id="O21" class="box hide">Option O21</p>
    <p id="O211" class="box hide">Option O211</p>
    <p id="O212" class="box hide">Option O212</p>
    <p id="O213" class="box hide">Option O213</p>
    <p id="O22" class="box hide">Option O22</p>
    <p id="O221" class="box hide">Option O221</p>
    <p id="O222" class="box hide">Option O222</p>
    <p id="O223" class="box hide">Option O223</p>
    <p id="O23" class="box hide">Option O23</p>
    <p id="O231" class="box hide">Option O231</p>
    <p id="O232" class="box hide">Option O232</p>
    <p id="O233" class="box hide">Option O233</p>
    <p id="O3" class="box hide">Option O3</p>
    <p id="O31" class="box hide">Option O31</p>
    <p id="O311" class="box hide">Option O311</p>
    <p id="O312" class="box hide">Option O312</p>
    <p id="O313" class="box hide">Option O313</p>
    <p id="O32" class="box hide">Option O32</p>
    <p id="O321" class="box hide">Option O321</p>
    <p id="O322" class="box hide">Option O322</p>
    <p id="O323" class="box hide">Option O323</p>
    <p id="O33" class="box hide">Option O33</p>
    <p id="O331" class="box hide">Option O331</p>
    <p id="O332" class="box hide">Option O332</p>
    <p id="O333" class="box hide">Option O333</p>


    <script>
        function getElementsStartWithId(id) {
            var children = document.body.getElementsByTagName('*');
            var elements = [],
                child;
            for (var i = 0, length = children.length; i < length; i++) {
                child = children[i];
                if (child.id.substr(0, id.length) == id)
                    elements.push(child);
            };
            return elements;
        }

        function getNextLayerDown(id) {
            var children = document.body.getElementsByTagName('*');
            var elements = [],
                child;
            for (var i = 0, length = children.length; i < length; i++) {
                child = children[i];
                if (child.id.substring(0, child.id.length - 1) == id)
                    elements.push(child);
            };
            return elements;
        }

        function getAllPreviousLayers(id) {
            var children = document.body.getElementsByTagName('*');
            var elements = [],
                child;
            var newId = id
            do {
                for (var i = 0, length = children.length; i < length; i++) {
                    child = children[i];
                    if (child.id == newId)
                        elements.push(child);
                };
                var newId = newId.substring(0, newId.length - 1);
            }
            while (newId.length > 0);
            return elements;
        }

        function updateShowItems(itemId) {
            // hide all previous shown items
            for (i = 0; i < showItems.length; i++) {
                showItems[i].classList.remove("show");
                showItems[i].classList.remove("check-box");
            };
            var checkedItems = getAllPreviousLayers(itemId)
            // add check-box to all layers picked already
            for (i = 0; i < checkedItems.length; i++) {
                checkedItems[i].classList.add("check-box");
            };
            // update show items list with latest click
            showItems = getAllPreviousLayers(itemId).concat(getNextLayerDown(itemId));
            // show all items now required
            for (i = 0; i < showItems.length; i++) {
                showItems[i].classList.add("show");
            };
        }


        // set each ID to be a trigger point
        var allItems = getElementsStartWithId("O");
        var showItems = getNextLayerDown("O");
        console.log(showItems);
        var i;
        for (i = 0; i < allItems.length; i++) {
            allItems[i].addEventListener("click", function() {
                updateShowItems(this.id);
            });
        };

    </script>

</body>

</html>


推荐阅读