单击序列生成字符串路径

时间:2018-06-25 13:06:39

标签: javascript dynamically-generated

我基于对象结构生成嵌套的div元素。单击父级,可以切换子级。

现在,我想生成单击序列和“选定”元素的路径,并用斜杠分隔。当用户单击读取->新闻->运动时,字符串路径应为“读取/新闻/体育”。现在,当用户点击“已读->图书”时,路径应为“已读/图书”

这是我当前的版本: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>

1 个答案:

答案 0 :(得分:1)

这是一种方法。除了添加对新getParents()函数的调用之外,您现有的代码均未修改,该函数通过递归爬网DOM树以生成指向所单击节点的“路径”来进行工作:

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>