分别针对多级<div>的setAttribute

时间:2019-01-19 15:20:24

标签: javascript html

我想要一个专业的代码,用于在<li>标签和setAttribute数据级别内为每个级别<div>动态地自动循环。例如,如果我们有10个以上级别的设备可以正常工作。

我遵循以下代码:

var subMenuLevelOne = document.querySelectorAll('.nav-menu > ul > li > div');
var subMenuLevelTwo = document.querySelectorAll('.nav-menu > ul > li > div > ul > li > div');
var subMenuLevelThree = document.querySelectorAll('.nav-menu > ul > li > div > ul > li > div > ul > li > div');
var subMenuLevelFour = document.querySelectorAll('.nav-menu > ul > li > div > ul > li > div > ul > li > div > ul > li > div');
var navMenu = document.querySelector('.nav-menu');
for(var i=0;i<subMenuLevelOne.length;i++) {
	subMenuLevelOne[i].setAttribute("data-level", 1);
}
for(var i=0;i<subMenuLevelTwo.length;i++) {
	subMenuLevelTwo[i].setAttribute("data-level", 2);
}
for(var i=0;i<subMenuLevelThree.length;i++) {
	subMenuLevelThree[i].setAttribute("data-level", 3);
}
for(var i=0;i<subMenuLevelFour.length;i++) {
	subMenuLevelFour[i].setAttribute("data-level", 4);
}

console.log(subMenuLevelOne);
console.log(subMenuLevelTwo);
console.log(subMenuLevelThree);
console.log(subMenuLevelFour);
<div class="nav-menu">
		<ul>
			<li><a href="#">menu 1</a>
			<div class="sub-menu">
				<ul>
				<li><a href="#">menu 1-1</a>
				<div class="sub-menu">
				<ul>
					<li><a href="#">menu 1-1-1</a>
					<div class="sub-menu">
					<ul>
						<li><a href="#">menu 1-1-1-1</a>
						<div class="sub-menu">
						<ul>
							<li><a href="#">menu 1-1-1-1-1</a></li>
							<li><a href="#">menu 1-1-1-1-2</a></li>
							<li><a href="#">menu 1-1-1-1-3</a></li>
							</ul>
							</div>
						</li>
						<li><a href="#">menu 1-1-1-2</a></li>
						<li><a href="#">menu 1-1-1-3</a></li>
						</ul>
						</div>
					</li>
					<li><a href="#">menu 1-1-2</a></li>
					<li><a href="#">menu 1-1-3</a></li>
					</ul>
					</div>
				</li>
				<li><a href="#">menu 1-2</a></li>
				<li><a href="#">menu 1-3</a></li>
				<li><a href="#">menu 1-4</a></li>
				<li><a href="#">menu 1-5</a></li>
				</ul>
				</div>
			</li>
				
			<li><a href="#">menu 2</a>
			<div class="sub-menu">
				<ul>
				<li><a href="#">menu 2-1</a></li>
				<li><a href="#">menu 2-2</a></li>
				<li><a href="#">menu 2-3</a>
					<div class="sub-menu">
					<ul>
						<li><a href="#">menu 2-3-1</a></li>
						<li><a href="#">menu 2-3-2</a></li>
						<li><a href="#">menu 2-3-3</a></li>
						</ul>
					</div>
					</li>
				</ul>
				</div>
			</li>
			<li><a href="#">menu 3</a></li>
			<li><a href="#">menu 4</a></li>
			<li><a href="#">menu 5</a></li>
			</ul>
		</div>

1 个答案:

答案 0 :(得分:0)

这是一种方法:

function level(parent, element, tagName) {
    return (!element.parentNode || element.parentNode === parent) ? 0 :
      (element.tagName === tagName ? 1 : 0) + level(parent, element.parentNode, tagName);
}

const menuParent = document.querySelector('div.nav-menu');

menuParent.querySelectorAll('div').forEach(div => {
    div.setAttribute("data-level", level(menuParent, div, "DIV"));
});

我建议您汇总自己的版本;这不是高雅的巅峰之作(但很简洁)。

读者摘要版本

我将其重写为一个更易于理解的版本。希望这可以帮助您前进!

/* Note that this is a recursive function */
function level(parent, element, tagName) {

  /* We are at top level element, return 0 */
  if (!element.parentNode) {
    return 0;
  }

  /* We have reaced the predestined parent, return 0 */
  if (element.parentNode === parent) {
    return 0;
  }

  /* If this element matches the tag name, return 1 + results for all the parents */
  if (element.tagName === tagName) {
    return 1 + level(parent, element.parentNode, tagName);
  }

  /* Otherwise, just return results for all the parents */
  return level(parent, element.parentNode, tagName);
}

/* Find the root element for the menu tree */
const menuParent = document.querySelector('div.nav-menu');

/* Enumerate every <div> under the root element (at *every* level) */
const eachDivUnderParent = menuParent.querySelectorAll('div');

/* Iterate each <div> under <div class="nav-menu"> */
eachDivUnderParent.forEach(divElement => {
  /* Calculate the level at that element */
  const divLevel = level(menuParent, divElement, "DIV");
  /* Set the calculated value as `data-level` attribute */
  divElement.setAttribute("data-level", divLevel);
});