#javascript #html #dom
#javascript #HTML #dom
Вопрос:
У меня есть веб-страница с двумя разделениями высоты 100%, подобными этому…
<style>
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
</style>
...
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
Теперь я хочу «выбрать» тот, который в данный момент прокручивается. Это означает, что верхняя часть элемента достигла верхней части браузера, а нижняя — нет. Вот где я запутался, это JS…
<script type="module">
const body = document.getElementsByTagName("body")[0];
const handleScroll = function(info){
const items = body.getElementsByClassName("scroll-item");
for(let i = 0; i < length; i ){
const item = items[i];
// TODO How do I tell if it is there
}
}
body.addEventListener("wheel",handleScroll);
</script>
Я пытался использовать ограничивающую рамку, но не могу понять, как заставить ее работать правильно.
Как я могу определить, когда верхняя или нижняя часть элемента достигает верхней части браузера (учитывая возможное смещение для панели навигации)?
Ответ №1:
Вы можете использовать getBoundingClientRect() . Это дает вам объект DOMRect, содержащий размер и координаты элемента.
Для расширенного использования см. IntersectionObserver, который определяет видимость элементов внутри области просмотра.
Комментарии:
1. Это работает хорошо, пока нет заголовка. Но у меня есть заголовок, я открою еще один вопрос, поскольку он немного расширяет тему, но пример того, что я имею в виду, см. Ниже. И спасибо!
Ответ №2:
Используйте оболочку для получения текущей позиции и прослушивания события прокрутки, кроме того, лучше прослушивать прокрутку вместо события колеса.
// Use the wrapper to get and listen scroll
const wrapper = document.querySelector('#wrapper')
const handleScroll = function(event) {
const top = wrapper.scrollTop;
document.querySelectorAll('.scroll-item').forEach((item, index) => {
// Calculate item bottom position
const bottom = item.offsetTop item.offsetHeight;
// Is the scroll between item top and bottom?
if(top >= item.offsetTop amp;amp; top < bottom) {
console.log(`Item ${index} is active`);
}
});
}
// scroll event is more accurate than wheel
wrapper.addEventListener("scroll", handleScroll);
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
Комментарии:
1. Я попробовал это, и это сработало с моим упрощенным примером. В реальном мире моей оболочкой является height: calc(100% — 64px); и там у нас заголовок 64px. Когда я пытаюсь сделать это так, как этот item.offsetHeight всегда равен 0. Есть идеи, почему это может быть? Доступен этот новый пример github.com/jrgleason/rollup-demo/blob/SCROLL_WORK/modules/esm /…
2. Таким образом, он работает с github.com/jrgleason/rollup-demo/blob/SCROLL_WORK/modules/esm /… но не github.com/jrgleason/rollup-demo/blob/SCROLL_WORK/modules/esm/… Я открою второй вопрос
3. Также прокрутка не работает для macbook с прокруткой пальцем AFAIK