I have three main div boxes pink, red and green.
I want to make all segments moving with arrow keys. For example: when we load the page, active box would be in segment 'pink' in the middle. And with arrow keys we can go up/down/right/left. This is implemented in code below.
But I need one more task to do, when we go to right last box in segment 'pink' on next right press we want to move to 'red' segment. There is one box so when I will press left button we will go to the 'pink' segment back. We are in segment 'pink' and press array down to last box in 'pink' segment so then after pressing down button we need to go to 'green' segment and then be able to moving around three boxes in there.
And also, if we are at 'green' segment and go to last right box and press right key then I need nothing. Also with left box in 'green' segment. Go outside from 'green' segment only with UP arrow key
Is there any appropriate ways to do that?
const boxContainer = document.getElementById('tails')
const selected = {
row: 2,
column: 2,
}
const Clamp = (num, min, max) => Math.min(Math.max(num, min), max)
const ActivateSelection = (prev) => {
const box = boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`)
box.classList.add('hover')
if (!prev) return
if (prev.row === selected.row && prev.column === selected.column) return
const prevBox = boxContainer.querySelector(`.boxGroup:nth-child(${prev.row}) .box:nth-child(${prev.column})`)
prevBox.classList.remove('hover')
}
const OnKeyDown = event => {
const maxRow = boxContainer.querySelectorAll('.boxGroup').length
const maxCol = boxContainer.querySelectorAll(`.boxGroup:nth-child(${selected.row}) .box`).length
const prevBox = { ...selected
}
switch (event.key) {
case "ArrowUp":
boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`).classList.remove('active')
selected.row = Clamp(selected.row - 1, 1, maxRow)
break;
case "ArrowDown":
boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`).classList.remove('active')
selected.row = Clamp(selected.row + 1, 1, maxRow)
break;
case "ArrowRight":
boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`).classList.remove('active')
selected.column = Clamp(selected.column + 1, 1, maxCol)
break;
case "ArrowLeft":
boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`).classList.remove('active')
selected.column = Clamp(selected.column - 1, 1, maxCol)
break;
case "Enter":
boxContainer.querySelector(`.boxGroup:nth-child(${selected.row}) .box:nth-child(${selected.column})`).classList.add('active')
break;
default:
return;
}
ActivateSelection(prevBox)
}
const GetActive = () => {
const active = {}
boxContainer.querySelectorAll('.boxGroup').forEach((el, index) => {
el.querySelectorAll('.box').forEach((el2, index2) => {
if (el2.classList.contains('hover')) {
active.row = index + 1
active.column = index2 + 1
}
})
})
if (active.row) return active
return undefined
}
ActivateSelection()
window.addEventListener('keydown', OnKeyDown)
boxContainer.querySelectorAll('.boxGroup').forEach((el, index) => {
el.querySelectorAll('.box').forEach((el2, index2) => {
el2.addEventListener('click', () => {
const prev = GetActive()
selected.row = index + 1
selected.column = index2 + 1
ActivateSelection(prev)
})
})
})
body,
html {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
div {
overflow: hidden;
}
.box {
background-color: rgb(100, 12, 120);
height: 100px;
width: 100px;
transition: transform .6s;
}
.box-navigation {
background-color: rgb(100, 12, 120);
height: 100px;
width: 100px;
transition: transform .6s;
}
.box-navigation:hover {
transform: scale(1.1);
background-color: rgb(20, 10, 3);
}
.box:hover {
transform: scale(1.1);
background-color: rgb(20, 10, 3);
}
.hover {
background-color: rgb(200, 150, 120);
transform: scale(.9);
}
.active {
background-color: rgb(200, 51, 200);
transform: scale(1.2);
}
.flex-fill {
flex: 1 1 auto;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<div class="container-fluid h-100 d-flex flex-column bg-secondary text-white">
<div class="row flex-fill">
<div class="col-lg-6 row" id="tails" style="background-color: pink;">
<div class="m-auto d-flex justify-content-around p-3 boxGroup">
<div class="box"></div>
<div class="box "></div>
<div class="box"></div>
</div>
<div class=" m-auto d-flex justify-content-around p-3 boxGroup">
<div class="box"></div>
<div class="box hover"></div>
<div class="box"></div>
</div>
<div class=" m-auto d-flex justify-content-around p-3 boxGroup">
<div class="box"></div>
<div class="box "></div>
<div class="box"></div>
</div>
</div>
<div class=" col-lg-6 d-flex justify-content-around " id="text" style="background-color: rgb(156, 51, 69);">
<div class="box m-auto"></div>
</div>
</div>
<div class="row " id="navigation" style="background-color: rgb(142, 197, 71);">
<div class=" m-auto d-flex justify-content-around p-3">
<div class="box-navigation"></div>
<div class="box-navigation"></div>
<div class="box-navigation"></div>
</div>
</div>
</div>