Добрый день! Подскажите, пожалуйста, реализацию, при которой бы при уменьшении экрана ссылки, которые не помещаются в одну строку, автоматически складывались бы в выпадающее меню. Благодарю за помощь!
.header-item {
padding: 7px 0;
}
.hi {
display: inline-block;
}
.hi:after {
content: '|';
margin: 0 17px 0;
display: inline-block;
color: #ccc;
vertical-align: middle;
}
Уточняю вопрос: при уменьшении экрана необходимо, чтобы не все сразу ссылки помещались в выпадающее меню, а поочередно, по мере их выхода за пределы видимости экрана. спасибо!
Ответ
Первым делом напишем необходимый CSS: добавим всем элементам white-space: nowrap, чтобы они не переносились на следующую строку; скроем меню по правилам доступности — это нам также потребуется в дальнейшем при расчетах ширины скрытых элементов.
При нажатии на кнопку будем отображать и скрывать меню с элементами, которые не поместились в список.
Функция getInvisible() возвращает нам массив элементов, которые не помещаются в ширину списка. Основа всех расчетов — метод .getBoundingClientRect()
Функция moveForward() переносит все не помещающиеся элементы в выпадающее меню.
Функция moveBackward() переносит элементы из выпадающего меню обратно — это нам потребуется при ресайзе окна.
Функция debounce() нужна для оптимизации вызова функции при ресайзе.
Добавляем слушателя на событие ресайза и вызываем функцию restart(), которая вызывает moveBackward() и moveForward(). Таким образом, при ресайзе все элементы возвращаются обратно в строку, а затем те, которые не помещаются отправляются обратно в выпадающий список.
UPD. добавил также подсчет количества скрытых элементов и скрытие кнопки, когда все элементы меню видны.
let button = document.getElementById('menu-toggler');
button.addEventListener('click', function() {
document.querySelector('.menu').classList.toggle('menu--open');
});
window.addEventListener('resize', debounce(restart, 250));
moveForward();
function moveForward() {
let listElements = Array.from(document.querySelectorAll('#list .li')),
invisibleElements = getInvisible(listElements),
menuList = document.getElementById('menu-list');
invisibleElements.forEach(function(item) {
menuList.appendChild(item);
});
if(!invisibleElements.length) {
button.setAttribute('hidden', true);
} else {
button.removeAttribute('hidden');
}
button.innerHTML = invisibleElements.length;
}
function moveBackward() {
let menuListElements = Array.from(document.querySelectorAll('#menu-list .li')),
list = document.getElementById('list');
menuListElements.forEach(function(item) {
list.appendChild(item);
});
}
function restart() {
moveBackward();
moveForward();
}
function getInvisible(listElements) {
let list = document.getElementById('list');
let invisible = listElements.filter(function(item) {
if (item.getBoundingClientRect().left + item.getBoundingClientRect().width > list.clientWidth) {
return item;
}
});
return invisible;
}
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
#menu-toggler {
position: absolute;
right: 8px;
top: 8px;
width: 35px;
height: 35px;
}
#list {
width: calc(100% - 100px);
padding: 0;
margin: 0;
white-space: nowrap;
border: 1px solid #000;
font-size: 0;
overflow: hidden;
}
#menu-list {
margin: 0;
padding: 0;
}
.li {
display: inline-block;
padding: 5px 10px;
font-size: 16px;
}
.menu {
border: 1px solid;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
right: 8px;
top: 50px;
}
.menu--open {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
width: 150px;
}
- element #1
- element #2
- element #3
- element #4
- element #5
- element #6
- element #7
- element #8
- element #9
- element #10
- element #11
- element #12
- element #13
- element #14
- element #15
- element #16
- element #17
- element #18
- element #19
- element #20
Комментариев нет:
Отправить комментарий