从点击序列中生成字符串路径

generate string path out of a click sequence

我根据对象结构生成嵌套的 div 元素。通过单击父项,您可以切换子项。

现在我想生成一个路径,用斜杠分隔,点击序列和 "selected" 元素。当用户单击阅读 -> 新闻 -> 体育时,字符串路径应为 "read/news/sport"。当用户现在点击阅读 -> 书籍时,路径现在应该是 "read/books"

这是我当前的版本:https://codepen.io/iamrbn/pen/yEqPjG

let path = "";

let object = {
  "design": {
    "inspiration": {},
    "news": {}
  },
  "read": {
    "news": {
      "sport": {}
    },
    "books": {}
  },
 "code": {}
}

let categoryContainer = document.querySelector(".categoryContainer")

function categoryTree(obj, parent, start = true) {
  for (var key in obj) {
    let div = document.createElement("div");
    div.textContent = key;
  div.classList.add("category");
    if (parent.children) parent.className += " bold";
    if (!start) div.className = "normal hide category";

    div.addEventListener('click', function(e) {
      e.stopPropagation()
  this.classList.toggle('active');
      Array.from(div.children).forEach(child => {
        child.classList.toggle('hide');
      })
    })
    categoryTree(obj[key], div, false)
    parent.appendChild(div)
  }
}


categoryTree(object, categoryContainer)
.category {
 color: black;
 display: block;
 line-height: 40px;
 background-color: RGBA(83, 86, 90, 0.2);
 margin: 8px;
}

.category .category {
 display: inline-block;
 margin: 0 8px;
 padding: 0 8px;
}

.category.hide {display: none;}
.category.normal {font-weight: normal;}
.category.bold {font-weight: bold;}
.category.active {color: red;}
<div class="categoryContainer"></div>

这是一种方法。除了添加对新 getParents() 函数的调用外,您现有的代码未被修改,该函数通过递归地向上爬行 DOM 树来为单击的节点生成 "path":

let path = "";

let object = {
  "design": {
    "inspiration": {},
    "news": {}
  },
  "read": {
    "news": {
      "sport": {}
    },
    "books": {}
  },
  "code": {}
}

let categoryContainer = document.querySelector(".categoryContainer")

function categoryTree(obj, parent, start = true) {
  for (var key in obj) {
    let div = document.createElement("div");
    div.textContent = key;
    div.classList.add("category");
    if (parent.children) parent.className += " bold";
    if (!start) div.className = "normal hide category";

    div.addEventListener('click', function(e) {
      e.stopPropagation()
      this.classList.toggle('active');
      Array.from(div.children).forEach(child => {
        child.classList.toggle('hide');
      })
      var thePath = getParents(e.target); // <--- new
      console.log(thePath)
    })
    categoryTree(obj[key], div, false)
    parent.appendChild(div)
  }
}

function getParents(node, path) {
  // Cheat a bit here: we know the textnode we want is the first child node, so we don't have to iterate through all children and check their nodeType:
  let thisName = node.childNodes[0].textContent;
  path = path ? (thisName + "/" + path) : thisName ; 
  // iterate to parent unless we're at the container:
  if (node.parentNode.className.split(/\s+/).indexOf("categoryContainer") !== -1) {
    return path;
  } else {
    return getParents(node.parentNode, path);
  }
}

categoryTree(object, categoryContainer)
.category {
  color: black;
  display: block;
  line-height: 40px;
  background-color: RGBA(83, 86, 90, 0.2);
  margin: 8px;
}

.category .category {
  display: inline-block;
  margin: 0 8px;
  padding: 0 8px;
}

.category.hide {
  display: none;
}

.category.normal {
  font-weight: normal;
}

.category.bold {
  font-weight: bold;
}

.category.active {
  color: red;
}
<div class="categoryContainer"></div>