前端开发 大前端 W3Cbest

一个专注 WEB 开发的技术博客

0%

javascript 实现可伸缩性导航

上篇文章写的是利用CSS3 选择器:target制作一个可伸缩的导航菜单,可以在兼容这个选择器的基础可以使用,但是如果在低版本浏览器就可能使用不了了,这篇文章是通过JavaScript实现可伸缩性导航,我们看下面代码:

CSS代码:

.tabs {
position: relative;
}
.tabs:not(.jsfied) {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.tabs .hidden {
display: none;
}
.tabs a,
.tabs button {
width: 100%;
height: 100%;
display: block;
font-size: 1em;
line-height: 1.2;
text-align: center;
color: #FAF3DD;
background-color: transparent;
}
.tabs .primary {
display: flex;
}
.tabs .primary > li {
flex-grow: 1;
background-color: #5a5a5a;
}
.tabs .primary > li + li {
border-left: 1px solid #414141;
}
.tabs .primary > li > a,
.tabs .primary > li > button {
white-space: nowrap;
padding: 1em 0.6em;
box-shadow: inset 0 -0.2em 0 #414141;
}
.tabs .primary > li > a:hover,
.tabs .primary > li > button:hover {
background-color: #414141;
}
.tabs .primary > li > a:active,
.tabs .primary > li > button:active {
background-color: #4a4a4a;
}
.tabs .primary .more {
background-color: #414141;
}
.tabs .primary .more > button span {
display: inline-block;
transition: -webkit-transform 0.2s;
transition: transform 0.2s;
transition: transform 0.2s, -webkit-transform 0.2s;
}
.tabs.show-secondary .primary .more > button span {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
.tabs .secondary {
max-width: 100%;
min-width: 10em;
display: none;
position: absolute;
top: 100%;
right: 0;
box-shadow: 0 0.3em 0.5em rgba(0, 0, 0, 0.3);
-webkit-animation: nav-secondary 0.2s;
animation: nav-secondary 0.2s;
}
.tabs .secondary li {
border-top: 1px solid #353535;
background-color: #414141;
}
.tabs .secondary a,
.tabs .secondary button {
padding: 0.6em;
}
.tabs .secondary a:hover,
.tabs .secondary button:hover {
background-color: #4a4a4a;
}
.tabs .secondary a:active,
.tabs .secondary button:active {
background-color: #353535;
}
.tabs.show-secondary .secondary {
display: block;
}

@-webkit-keyframes nav-secondary {
0% {
opacity: 0;
-webkit-transform: translateY(-1em);
transform: translateY(-1em);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}

@keyframes nav-secondary {
0% {
opacity: 0;
-webkit-transform: translateY(-1em);
transform: translateY(-1em);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}

JS:

const container = document.querySelector(‘.tabs’)
const primary = container.querySelector(‘.primary’)
const primaryItems = container.querySelectorAll(‘.primary > li:not(.more)’)
container.classList.add(‘jsfied’)

primary.insertAdjacentHTML(‘beforeend’, `

    • ${primary.innerHTML}
  • \`) const secondary = container.querySelector('.secondary') const secondaryItems = secondary.querySelectorAll('li') const allItems = container.querySelectorAll('li') const moreLi = primary.querySelector('.more') const moreBtn = moreLi.querySelector('button') moreBtn.addEventListener('click', (e) => { e.preventDefault() container.classList.toggle('show-secondary') moreBtn.setAttribute('aria-expanded', container.classList.contains('show-secondary')) })

    // 调整选项卡

    const doAdapt = () => {
    // 显示所有项目
    allItems.forEach((item) => {
    item.classList.remove(‘hidden’)
    })

    // 隐藏已经超过导航的其他项目
    let stopWidth = moreBtn.offsetWidth
    let hiddenItems = []
    const primaryWidth = primary.offsetWidth
    primaryItems.forEach((item, i) => {
    if(primaryWidth >= stopWidth + item.offsetWidth) {
    stopWidth += item.offsetWidth
    } else {
    item.classList.add(‘hidden’)
    hiddenItems.push(i)
    }
    })

    // 切换更多按钮
    if(!hiddenItems.length) {
    moreLi.classList.add(‘hidden’)
    container.classList.remove(‘show-secondary’)
    moreBtn.setAttribute(‘aria-expanded’, false)
    }
    else {
    secondaryItems.forEach((item, i) => {
    if(!hiddenItems.includes(i)) {
    item.classList.add(‘hidden’)
    }
    })
    }
    }

    doAdapt()
    window.addEventListener(‘resize’, doAdapt)

    document.addEventListener(‘click’, (e) => {
    let el = e.target
    while(el) {
    if(el === secondary el === moreBtn) {
    return;
    }
    el = el.parentNode
    }
    container.classList.remove(‘show-secondary’)
    moreBtn.setAttribute(‘aria-expanded’, false)
    })

    坚持技术创作分享,您的支持将鼓励我继续创作!