如何使用材料设计 mdc-list 制作嵌套列表

问题描述

我想制作嵌套列表,使其类似于树文件夹结构

这是我对我的清单的期待

I want any number of nested list

这是我尝试过但不起作用的方法

    <link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
    
    
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    
       <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
       
       
      <ul class="mdc-list" style="margin-left: 17px;padding: 0;margin-top: -7px;">
                <li class="mdc-list-item" tabindex="0">
                    <span class="material-icons"> arrow_right </span>
                    <span class="mdc-list-item__ripple"></span><span class="material-icons folder-base-color"> folder </span>
                    
                    <span class="mdc-list-item__text">json-dumps</span>
                </li>
                    
                  <li class="mdc-list-item" tabindex="0">
                    <span class="material-icons"> arrow_right </span>
                    <span class="mdc-list-item__ripple"></span><span class="material-icons folder-base-color"> folder </span>
                    
                    <span class="mdc-list-item__text">test</span>


                    <ul class="mdc-list" style="margin-left: 17px;padding: 0;margin-top: -7px;">
                      <li class="mdc-list-item" tabindex="0">
                          <span class="material-icons"> arrow_right </span>
                          <span class="mdc-list-item__ripple"></span><span class="material-icons folder-base-color"> folder </span>
                          
                          <span class="mdc-list-item__text">nested test</span>
                      </li>
                          
                          <li class="mdc-list-item" tabindex="0">
                          <span class="material-icons"> arrow_right </span>
                          <span class="mdc-list-item__ripple"></span><span class="material-icons folder-base-color"> folder </span>
                          
                          <span class="mdc-list-item__text">nested test 2</span>
                      </li>
                    </ul>

                </li>
           </ul>

解决方法

编辑:我已更新代码沙箱链接以使用 ul 和 li

看看这是否适合您https://codesandbox.io/s/stupefied-swirles-219nc?file=/index.html

正如您所要求的,它在没有 JS 的情况下也为您提供了功能。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <style>
      .app-nested-nav__section-content {
        margin-left: 2em;
      }
    </style>
  </head>
  <body>
    <link
      href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css"
      rel="stylesheet"
    />

    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
    />

    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>

    <details class="app-nested-nav__section" open>
      <summary class="app-nested-nav__section-header mdc-list-item">
        <span class="mdc-list-item__ripple"></span
        ><span class="material-icons folder-base-color"> folder </span>

        <span class="mdc-list-item__text">json-dumps</span></summary
      >
      <details class="app-nested-nav__section-content">
        <summary class="app-nested-nav__section-header mdc-list-item">
          <span class="mdc-list-item__ripple"></span
          ><span class="material-icons folder-base-color"> folder </span>

          <span class="mdc-list-item__text">json-dumps</span></summary
        >
        <div class="app-nested-nav__section-content">
          <summary class="app-nested-nav__section-header mdc-list-item">
            <span class="mdc-list-item__ripple"></span
            ><span class="material-icons folder-base-color"> folder </span>

            <span class="mdc-list-item__text">json-dumps</span></summary
          >
          <summary class="app-nested-nav__section-header mdc-list-item">
            <span class="mdc-list-item__ripple"></span
            ><span class="material-icons folder-base-color"> folder </span>

            <span class="mdc-list-item__text">json-dumps</span></summary
          >
          <summary class="app-nested-nav__section-header mdc-list-item">
            <span class="mdc-list-item__ripple"></span
            ><span class="material-icons folder-base-color"> folder </span>

            <span class="mdc-list-item__text">json-dumps</span></summary
          >
        </div>
      </details>
      <summary class="app-nested-nav__section-content mdc-list-item">
        <span class="mdc-list-item__ripple"></span
        ><span class="material-icons folder-base-color"> folder </span>

        <span class="mdc-list-item__text">json-dumps</span></summary
      >
    </details>
  </body>
</html>

灵感来自https://codepen.io/rustemgareev/pen/GOBado

,

您可以尝试以下示例。所有元素都是基于 JSON 中提供的元素、递归函数 buildTree<template> 元素创建的。 JSON 的架构非常简单(title,iconClass,children)。我想你会发现它很简单。

const buildTree = (tree,ancestor = null) => {
  let ulMDCList = document.querySelector('.mdc-list');
  tree.forEach((item,index) => {
    let liTemplate = document.getElementById('list-item').content.cloneNode(true);
    let liMDCItem = liTemplate.querySelector('.mdc-list-item');    
    
    if(ancestor !== null) {
      liMDCItem.dataset.childOf = ancestor.id;
      liMDCItem.classList.add('child','hidden'); 
      liMDCItem.id = ancestor.id + liMDCItem.dataset.id + index;
      liMDCItem.dataset.z = parseInt(ancestor.dataset.z) + 1;
    } else {
      liMDCItem.id = liMDCItem.dataset.id + index;
      liMDCItem.dataset.z = 0;
    }
    let arrow = liTemplate.querySelector('span[data-id="arrow"]');
    let icon = liTemplate.querySelector('span[data-id="icon"]');
    let title = liTemplate.querySelector('span[data-id="title"]');    
    if(item.iconClass.length > 0) {  
      icon.innerHTML = item.iconClass;
    }
    title.innerHTML = item.title;
    ulMDCList.append(liTemplate);
    if(hasChildren(item.children)) {
      buildTree(item.children,liMDCItem);
      liMDCItem.addEventListener('click',(e) => {
        if(arrow.innerHTML == 'arrow_drop_down') {
          arrow.innerHTML = 'arrow_right';
        } else {
          arrow.innerHTML = 'arrow_drop_down';
        }
        ulMDCList.querySelectorAll(`[data-child-of=\"${liMDCItem.id}\"]`).forEach((item) => { item.classList.toggle('hidden') });
      });     
    } else {
      arrow.innerHTML = '';
    }
  });
}
const hasChildren = (children) => {
  return (typeof children !== 'undefined' && Array.isArray(children) && children.length > 0);
}
const menuData = '[{"title": "json","iconClass": "folder","children": [{"title": "1st-child","children": [{"title": "Another image","iconClass": "image","children": []},{"title": "Another folder","children": [{"title": "And another image","children": []}]}]},{"title": "My image","children": []}]},{"title": "A solo image","children": []}]';
mdc.autoInit();
buildTree(JSON.parse(menuData));
.mdc-list-item.hidden {
 display: none;
}
[data-z="1"] {
  margin-left: 5%;
}
[data-z="2"] {
  margin-left: 10%;
}
[data-z="3"] {
  margin-left: 15%;
}

[data-id="icon"] {
  padding-right: 0.5rem;
  width: 1.25rem;
}
[data-id="arrow"] {
  width: 1.25rem;
}
.material-icons.image {
  content: 'image';
}
<link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
<ul class="mdc-list" aria-role="list" aria-orientation="vertical">
</ul>

<template id="list-item">
  <li class="mdc-list-item" tabindex="0" data-id="listitem">
    <span class="material-icons" data-id="arrow"> arrow_right </span>
    <span class="mdc-list-item__ripple"></span>
    <span class="material-icons" data-id="icon"> folder </span>
    <span class="mdc-list-item__text" data-id="title"></span>
  </li>
</template>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...