#javascript #css
Вопрос:
Я хочу создать вертикальный выбор, как на изображении ниже, кто-нибудь может мне помочь?
Я пытался сделать один, но нет, результат не тот, что я хочу, активный класс не находится посередине между стрелками при прокрутке.
const div = document.querySelectorAll("#menulist");
const atag = document.querySelectorAll("#list");
var curLen = 0;
let len = atag.length;
function activeMenu(){
debugger
if(event.wheelDelta > 0){
if(curLen > 0){
curLen --;
}
atag.forEach(ltx => ltx.classList.remove("active"));
atag[curLen].classList.add("active");
} else {
if((len - curLen) > 1){
curLen ;
}
atag.forEach(ltx => ltx.classList.remove("active"));
atag[curLen].classList.add("active");
}
}
window.addEventListener('wheel', activeMenu);
.menuBox {
margin: 0 auto;
width:100%;
margin: 23em 0 0 0;
}
.vertical-menu {
display: flex;
float:left;
height: 450px;
}
.vertical-menu:after {
display: block;
content: '';
clear: both;
}
.vertical-menu .list{
margin-top:-100px;
text-align:center;
display:inline-block;
font-size:var(--small-font-size);
overflow-y: auto;
width:100%;
/* scroll-snap-type: y mandatory; */
-ms-overflow-style: none;
}
.vertical-menu .list a.active {
background-color: #fff;
color:#000;
font-weight: bold;
font-size:var(--menulist-font-size);
}
.vertical-menu .list::-webkit-scrollbar{ display:none; }
.vertical-menu .left{
display:inline-block;
text-align:center;
font-size:50px;
widht:10%;
}
.vertical-menu .right{
display:inline-block;
text-align:center;
font-size:50px;
widht:10%;
}
.vertical-menu a {
font-family: fantasy;
background-color: #fff;
color: #bbbbbb;
display: block;
padding: 12px;
text-decoration: none;
}
.vertical-menu a:hover {
/* background-color: #fff;
color:#000;
font-weight: bold; */
}
.vertical-menu a.active {
background-color: #fff;
color:#000;
font-weight: bold;
font-size:50px;
}
.vertical-icon {
width:40%;
text-align:center;
align-items:center;
display: flex;
justify-content:center;
margin: 0 0 0 0;
}
<div class="menuBox">
<div class="vertical-menu align-self-center">
<div class="vertical-menu left"><a href="#"><</a></div>
<div id="menulist" class="vertical-menu list" style="display:inline !important;">
<a id="list" href="#" >Home</a>
<a id="list" href="#" >TPHO Receive</a>
<a id="list" href="#" >PO Completion</a>
<a id="list" href="#" >HQ Revision</a>
<a id="list" href="#" >Pre-BOM</a>
<a id="list" href="#" >CR2 BOM</a>
<a id="list" href="#" >Final BOM</a>
<a id="list" href="#" >Upper Mold</a>
<a id="list" href="#" >Bottom Mold</a>
</div>
<div class="vertical-menu right"><a href="#">></ion-icon></a></div>
</div>
</div>
на самом деле я хочу сделать этот компонент в vue, но сначала я хочу попробовать его с помощью css и js, а затем я настрою его в vue. но мои навыки css плохие.
или есть библиотека выбора, подобная представлению, которое я хочу видеть выше? похоже, так будет проще
Ответ №1:
Я отредактировал ваш код, чтобы получить тот же результат, что и на изображении выше.
- .стрелки меню и .список меню должны быть в
position: absolute
- Найдите начальную позицию в списке .menu в центре окна .menu со свойством
top: calc()
- Затем в javascript определите начальную позицию по индексу
- Поместите результат вычисления в .меню-список со стилем преобразования
const menuList = document.querySelector('.menu-list')
const atag = document.querySelectorAll(".list");
let curLen = 4; // Set index for active class
let len = atag.length;
// Add class 'active' to the 'home' when page loaded
atag[curLen].classList.add('active')
// Get the current fixed height of the list class
const heightActiveClass = atag[curLen].getBoundingClientRect().height
// Multuply current index element with fixed height
const startYPos = curLen * heightActiveClass
// Set result number in style
menuList.style.transform = `translate(-50%, -${startYPos}px)`
function activeMenu(event) {
if (event.wheelDelta > 0) {
if (curLen > 0) curLen--
setActiveLinkWithArrows(atag)
} else {
if ((len - curLen) > 1) curLen
setActiveLinkWithArrows(atag)
}
}
function setActiveLinkWithArrows(arr) {
arr.forEach((el, idx) => {
if (curLen === idx) {
el.classList.add("active")
// Multuply current index element with fixed height
const yPos = idx * heightActiveClass
// Set result number in style
menuList.style.transform = `translate(-50%, -${yPos}px)`
return
}
el.classList.remove("active")
});
}
window.addEventListener('wheel', activeMenu);
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--menubox-height: 400px;
--list-heigth: 50px;
}
body {
width: 100vw;
height: 100vh;
display: grid;
place-items: center;
color: aliceblue;
background-color: hsl(0, 0%, 100%);
position: relative;
overflow-x: hidden;
}
a {
font-family: fantasy;
text-decoration: none;
color: hsl(0, 0%, 73%);
}
.menu-box {
width: 250px;
height: var(--menubox-height);
display: flex;
justify-content: center;
position: relative;
overflow: hidden;
}
.menu-box::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
to bottom,
hsl(0 0% 100%) 0%,
hsl(0 0% 0% / 0) 50%,
hsl(0 0% 100%) 100%
);
z-index: 10;
pointer-events: none;
}
.menu-list {
width: 80%;
display: flex;
flex-flow: column;
text-align: center;
font-size: 1rem;
position: absolute;
top: calc(var(--menubox-height) / 2 - var(--list-heigth) / 2);
left: 50%;
transform: translate(-50%, 0);
transition: transform 0.3s ease-in-out;
}
.list {
height: var(--list-heigth);
position: relative;
padding: 12px;
transition: all 0.3s ease-in-out;
}
.list.active {
color: hsl(0, 0%, 0%);
font-size: 1.3rem;
}
.menu-arrows {
width: 100%;
height: var(--list-heigth);
display: flex;
justify-content: space-between;
position: absolute;
top: 50%;
font-size: 3rem;
pointer-events: none;
transform: translateY(-50%);
}
.arrow-left,
.arrow-right {
pointer-events: all;
}
.arrow-left a,
.arrow-right a {
color: hsl(0, 0%, 48%);
position: relative;
top: -5px;
transition: all 0.3s ease-in-out;
}
.arrow-left:hover a,
.arrow-right:hover a {
color: hsl(0, 0%, 0%);
position: relative;
top: -5px;
}
<div class="menu-box">
<div class="menu-list">
<a class="list" href="#home">Home</a>
<a class="list" href="#">TPHO Receive</a>
<a class="list" href="#">PO Completion</a>
<a class="list" href="#">HQ Revision</a>
<a class="list" href="#">Pre-BOM</a>
<a class="list" href="#">CR2 BOM</a>
<a class="list" href="#">Final BOM</a>
<a class="list" href="#">Upper Mold</a>
<a class="list" href="#">Bottom Mold</a>
</div>
<div class="menu-arrows">
<div class="arrow-left">
<a href="#left">
<</a>
</div>
<div class="arrow-right"><a href="#right">></a></div>
</div>
</div>
Комментарии:
1. Удивительно,я не подумал о том, чтобы установить верх, спасибо за помощь