When implementing scrollIntoView()
with navigation buttons (up and down), I aim to display two items at a time to signal to the user that there are more items to navigate. However, the first and last items should retain their default behavior so the user understands it is the end of the list.
You can refer to this image for clarification: https://i.stack.imgur.com/zoerG.jpg
Below is the code snippet:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
.myList{
width: 100px;
height: 100px;
margin: 5px;
overflow: scroll;
display: flex;
flex-direction: column;
background-color: gray;
list-style: none;
}
button{
width: 40px;
margin: 0 5px;
}
.myList>*{
display: block;
padding: 5px;
}
.focused{
background-color: yellow;
color: black;
}
<html>
<body>
<ul class="myList">
<li data-nav="0">Item 1</li>
<li data-nav="1">Item 2</li>
<li data-nav="2">Item 3</li>
<li data-nav="3">Item 4</li>
<li data-nav="4">Item 5</li>
<li data-nav="5">Item 6</li>
<li data-nav="6">Item 7</li>
</ul>
<button onclick="move(true)">UP</button>
<button onclick="move(false)">down</button>
<script>
let nav = document.querySelectorAll("[data-nav]");
nav.forEach(el=>{
el.classList.remove("focused");
})
nav[0].classList.add("focused");
let focusedIndex = 0;
function move(dir){
if(dir && focusedIndex > 0) focusedIndex--;
else if(!dir && focusedIndex < 6) focusedIndex++;
nav.forEach(elem =>{
elem.classList.remove("focused");
})
nav[focusedIndex].classList.add("focused");
nav[focusedIndex].scrollIntoView(true);
}
</script>
</body>
</html>