用户可以从例如1000个项目中 Select 一个项目.要访问某个项目,请首先从60个项目的列表中进行 Select .则为该项目创建动态列表.您可以 Select 一个子项.在某些情况下,这就足够了.在其他情况下,用户可以从另一个动态列表中进行 Select .

2级和3级项目都很短,例如数字、字母或大小.

Boostrap可用,因此可以使用.

我如何才能创建这样一个直观、简单、在手机上可用的多层次搜索?

Solution 1可能是Bootstrap多级下拉菜单.当您第一次 Select 项目50时,第二个菜单可能不容易访问.您可以在下面找到一些代码.

enter image description here

Solution 2类似于解决方案1,但每个菜单的可见行数是有限的.这个不起作用,因为水平滚动(目前)不起作用.

<ul class="dropdown-menu menu-scroll">
  <li><a class="dropdown-item" href="#"> Dropdown item 1 </a></li>
  <li><a class="dropdown-item" href="#"> Dropdown item 1a </a></li>
  <li><a class="dropdown-item" href="#"> Dropdown item 1b </a></li>
  ..... many rows
  <li><a class="dropdown-item" href="#"> Dropdown item 10 &raquo; </a>
     <ul class="submenu dropdown-menu">
      <li><a class="dropdown-item" href="#">Submenu item 1</a></li>
      <li><a class="dropdown-item" href="#">Submenu item 2</a></li>
      <li><a class="dropdown-item" href="#">Submenu item 3 &raquo; </a>
        <ul class="submenu dropdown-menu">
          <li><a class="dropdown-item" href="#">Multi level 1</a></li>
          <li><a class="dropdown-item" href="#">Multi level 2</a></li>
      </ul>
      </li>
      <li><a class="dropdown-item" href="#">Submenu item 4</a></li>
      <li><a class="dropdown-item" href="#">Submenu item 5</a></li>
   </ul>
  </li>
</ul>

样式表包含:

.menu-scroll {
    overflow-y: scroll;
    max-height: 200px;
}

Solution 2-B:将新的第2级项目动态添加到选定的第1级以下不是一个好主意.这可能会阻止清晰地查看级别1 Select .即使 Select 了3级项目,所选的1级和2级项目也应该是可见的.

Solution 3可能会有一个下拉列表.所选内容会动态填充第二个下拉列表.当 Select 一个项目时,可能会触发第三个下拉列表的填充.可能是一种解决方案.有没有人举个例子?我还没能找到一个好的解决方案.

Solution 4可能是1级物品的下拉列表. Select 一个项目可以将第二个级别显示为一系列小按钮.在这种情况下,是数字或字母. Select 这样的按钮可能会显示下面的一组新按钮.

enter image description here

Solution 5是一个增强的搜索框.这不是一个很好的解决方案.

你能给我一些解开这个谜题的提示吗? bootstrap 程序可用.

下面给出了多级菜单的一个示例:

<ul>    
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">  Treeview menu  </a>
      <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#"> Dropdown item 1 </a></li>
      <li><a class="dropdown-item" href="#"> Dropdown item 2 &raquo; </a>
         <ul class="submenu dropdown-menu">
          <li><a class="dropdown-item" href="#">Submenu item 1</a></li>
          <li><a class="dropdown-item" href="#">Submenu item 3 &raquo; </a>
            <ul class="submenu dropdown-menu">
              <li><a class="dropdown-item" href="#">Multi level 1</a></li>
              <li><a class="dropdown-item" href="#">Multi level 2</a></li>
          </ul>
          </li>
          <li><a class="dropdown-item" href="#">Submenu item 4</a></li>
       </ul>
      </li>
      <li><a class="dropdown-item" href="#"> Dropdown item 3 </a></li>
      </ul>
  </li>
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">  More items  </a>
      <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#"> Dropdown item 1 </a></li>
      <li><a class="dropdown-item" href="#"> Dropdown item 2 &raquo; </a>
         <ul class="submenu dropdown-menu">
          <li><a class="dropdown-item" href="#">Submenu item 1</a></li>
       </ul>
      </li>
      <li><a class="dropdown-item" href="#"> Dropdown item 3 &raquo; </a>
         <ul class="submenu dropdown-menu">
          <li><a class="dropdown-item" href="#">Another submenu 1</a></li>
       </ul>
      </li>
      <li><a class="dropdown-item" href="#"> Dropdown item 5 </a></li>
    </ul>
  </li>
</ul>

Select Level 1后,该标高应可见.然后,将显示级别2项目.在 Select Level 2项目时,可见提示显示该 Select 并显示第三个级别.因此,在 Select 新的级别项目时,之前 Select 的项目应该突出显示.

推荐答案

我相信你可以让它充满活力:

function generateDropdown(data) {
    let template = ``;
    for (let key in data) {
        if (typeof(data[key]) === "object") {
            template += `<li onclick="select(this); event.stopPropagation();">${key}: ${generateDropdown(data[key])}</li>`;
        } else {
            template += `<li onclick="select(this); event.stopPropagation();">${key}: ${data[key]}</li>`;
        }
    }
    return `<ul>${template}</ul>`;
}

function select(what) {
    if (what.classList.contains("selected")) {
        what.classList.remove("selected");
        while (!what.classList.contains("multiselect-dropdown")) {
            what = what.parentNode;
            if (what.classList.contains("opened")) {
                what.classList.remove("opened");
                what.classList.add("selected");
                return;
            }
        }
        return;
    } else if (what.classList.contains("opened")) {
       for (let subitem of what.querySelectorAll(".selected, .opened")) {
           if (subitem.classList.contains("selected")) subitem.classList.remove("selected");
           if (subitem.classList.contains("opened")) subitem.classList.remove("opened");
       }
       what.classList.remove("opened");
        while (!what.classList.contains("multiselect-dropdown")) {
            what = what.parentNode;
            if (what.classList.contains("opened")) {
                what.classList.remove("opened");
                what.classList.add("selected");
                return;
            }
        }
        return;
    }
    let root = what;
    while (!root.classList.contains("multiselect-dropdown")) root = root.parentNode;
    let selected = root.querySelectorAll(".selected");
    for (let s of selected) s.classList.remove("selected");
    let opened = root.querySelectorAll(".opened");
    for (let o of opened) o.classList.remove("opened");
    what.classList.add("selected");
    root = what.parentNode;
    while (!root.classList.contains("multiselect-dropdown")) {
        if (root.tagName.toLowerCase() === "li") root.classList.add("opened");
        root = root.parentNode;
    }
}

let context = document.getElementById('container');

context.innerHTML = generateDropdown({
    a: 1,
    b: 2,
    c: 3,
    d: {
        da: 4,
        db: 5,
        dc: 6,
        dd: 7
    },
    e: {
        ea: 8,
        eb: 9,
        ec: {
            eca: 10,
            ecb: 11,
            ecc: 12
        },
        ed: 13
    },
    f: 14
}, context);
.selected {
    background-color: gray;
}

.opened {
    background-color: lightgray;
}

.selected * {
    background-color: white;
}

.multiselect-dropdown li:not(.selected):not(.opened) * {
    display: none;
}
<div id="container" class="multiselect-dropdown">
</div>

解释:

  • GenerateDropdown生成递归的ul-li struct (您可以将此 struct 更改为您喜欢的 struct )
  • Select 负责 Select 和取消 Select 项目
    • Select 非复合元素即可将其选中
    • Select 未 Select 的复合元素
      • Select 它
      • 打开它
    • Select 选定的复合元素
      • 取消选中
      • Select 其最近打开的子项(如果存在)

Html相关问答推荐

在浮动元素旁边垂直居中

Angular 分量被循环

使用无限数量的元素创建特定的CSS网格

在一行中对齐文本和图标

使用响应迅速的网格系统,将两列保持在同一行,同时允许更多列用于更大的屏幕

SCSS动画错误:心脏在页面刷新时启动动画,原因是:Checked和:Not(:Checked) Select 器

是否可以只使用css而不使用像&;nbsp;这样的HTML符号来实现断字而不换行空格?

为什么字体大小而不是 colored颜色 属性适用于元素?

如何使用css在响应图像后面添加形状?

仅 Select 悬停的级别,而不 Select 其父级或子级

这两个CSS中的网格居中对齐内部盒子有什么区别?

如何只为 Navbar 中的一个元素提供动画,其余元素没有使用 css 的动画

使用图像自定义 CSS 网格边框

高度大于页面高度和页面大于覆盖的 CSS 覆盖

在 jinja 模板内的 html 表中嵌套 For 循环

shinydashboard 标题中的位置标题

动态使用时波浪号不转换为绝对路径

那里有一个类似于 ?

所有幻灯片上的 Quarto RevealJS 标题

悬停时倾斜效果错误