我要突出显示我的无序列表“ g1”中的每个列表项。 该列表有几个子列表。我想按“向下箭头”和“向上箭头”以突出显示下一项。我能够遍历外部列表,但是有了子列表,我的解决方案变得超级混乱。有没有比使用纯JavaScript更好的方法了?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Family Tree</title>
</head>
<body id='main'>
<nav>
<h1 id=pos></h1>
</nav>
<ul id='g1' class="special">
<ul id='generation2'>
<li>John Williams</li>
<li>Filippa Williams</li>
<ul id='generation3'>
<li>Juan James</li>
<li>Catarina James</li>
<li>Aoifa James</li>
</ul>
<li>Juan Williams</li>
</ul>
<li>Mark Williams</li>
<li>Christina Johnson</li>
<li>Christina Johnson</li>
<li>Christina Johnson</li>
<li>Juan Williams</li>
<li>Juan Williams</li>
<ul id='generation2'>
<li>John Williams</li>
<li>Filippa Williams</li>
</ul>
</ul>
</body>
</html>
document.onkeydown = function (e) {
switch (e.keyCode) {
case 37:
alert('left');
break;
case 38:
up()
break;
case 39:
alert('right');
break;
case 40:
down();
break;
}
};
var pos = -1;
var posSub = -1;
var posSubSub = 0;
var pointer;
function down() {
var childrensChildren;
var childrensGrandchildren;
var gen1 = document.getElementById('g1');
var gen1children = gen1.children;
if (pos === -1) {
gen1children[0].style.backgroundColor = 'yellow';
pos++;
document.getElementById('pos').innerHTML = pos;
return null;
}
if (pos == gen1children.length - 1) {
gen1children[gen1children.length - 1].style.backgroundColor = 'white';
gen1children[0].style.backgroundColor = 'yellow';
pos = 0;
document.getElementById('pos').innerHTML = pos;
return null;
}
if (gen1children[pos].firstElementChild) {
var childrensChildren = gen1children[pos].children;
if (childrensChildren.firstChild) {
childrensGrandchildren = childrensChildren[posSub].children;
childrensGrandchildren[posSubSub].style.backgroundColor = 'yellow';
childrensGrandchildren[childrensGrandchildren.length - 1].style.backgroundColor = 'white';
posSubSub++;
} else {
if (posSub === -1) {
childrensChildren[0].style.backgroundColor = 'yellow';
posSub++;
return null;
}
if (posSub == childrensChildren.length - 1) {
childrensChildren[childrensChildren.length - 1].style.backgroundColor = 'white';
childrensChildren[0].style.backgroundColor = 'yellow';
return null;
} else {
posSub += 1;
childrensChildren[posSub - 1].style.backgroundColor = 'white';
childrensChildren[posSub].style.backgroundColor = 'yellow';
return null;
}
}
}
gen1children[pos].style.backgroundColor = 'white';
gen1children[pos + 1].style.backgroundColor = 'yellow';
pos += 1;
document.getElementById('pos').innerHTML = pos;
return null;
}
function up() {
var gen1 = document.getElementById('g1');
var gen1children = gen1.children;
if (pos === -1) {
gen1children[0].style.backgroundColor = 'yellow';
pos++;
document.getElementById('pos').innerHTML = pos;
return null;
}
if (pos == 0) {
gen1children[gen1children.length - 1].style.backgroundColor = 'yellow';
gen1children[0].style.backgroundColor = 'white';
pos = gen1children.length - 1;
document.getElementById('pos').innerHTML = pos;
return null;
}
gen1children[pos].style.backgroundColor = 'white';
gen1children[pos - 1].style.backgroundColor = 'yellow';
pos -= 1;
document.getElementById('pos').innerHTML = pos;
return null;
}
答案 0 :(得分:1)
您可以在分层DOM树中快速创建所有li
项的平面列表,并使用箭头键直观地遍历该列表:
// Flat list of all `li` elements (in expected order)
let allLiElems = Array.from(document.getElementById('g1').getElementsByTagName('li'));
let liInd = null;
let highlightAtInd = ind => {
// Remove highlight from previous node
if (liInd !== null) allLiElems[liInd].classList.remove('highlight');
// Apply highlight to next node
liInd = ind;
allLiElems[liInd].classList.add('highlight');
};
window.addEventListener('keydown', evt => {
if (![ 38, 40 ].includes(evt.keyCode)) return;
// Get the new index; ensure it doesn't over/underflow
let newInd = liInd + ((evt.keyCode === 38) ? -1 : +1);
if (newInd < 0) newInd = allLiElems.length - 1;
if (newInd >= allLiElems.length) newInd = 0;
highlightAtInd(newInd);
evt.preventDefault();
});
// Initially highlight the 1st node
highlightAtInd(0);
* { overflow: hidden !important; }
#g1 { font-size: 11px; /* I want this to fit in the preview box */ }
.highlight {
background-color: rgba(255, 0, 0, 0.3);
}
<ul id='g1' class="special">
<ul id='generation2'>
<li>John Williams</li>
<li>Filippa Williams</li>
<ul id='generation3'>
<li>Juan James</li>
<li>Catarina James</li>
<li>Aoifa James</li>
</ul>
<li>Juan Williams</li>
</ul>
<li>Mark Williams</li>
<li>Christina Johnson</li>
<li>Christina Johnson</li>
<li>Christina Johnson</li>
<li>Juan Williams</li>
<li>Juan Williams</li>
<ul id='generation2'>
<li>John Williams</li>
<li>Filippa Williams</li>
</ul>
</ul>
在尝试执行关键事件之前,请确保已聚焦窗口!
答案 1 :(得分:0)
您可以为所有菜单项创建一个类,然后在CSS https://www.w3schools.com/howto/howto_custom_select.asp中设置“ select”属性