#javascript #scrolltop
#javascript #scrolltop
Вопрос:
Я анимирую divs для уменьшения, когда они начинают доходить до верхней части страницы. К сожалению, scrollTop — это число пикселей, которое не подходит для реагирования, поскольку количество пикселей будет разным для каждого устройства.
Мое решение — использовать процент окна, но я все еще учусь, и я не уверен, как это сделать. Вот где я нахожусь до сих пор-
https://codepen.io/muskaurochs/pen/NWNMOYG
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 200 || document.documentElement.scrollTop > 200) {
document.getElementById("header").style.width = "80%";
} else {
document.getElementById("header").style.width = "100%";
}
if (document.body.scrollTop > 350 || document.documentElement.scrollTop > 350) {
document.getElementById("header2").style.width = "80%";
} else {
document.getElementById("header2").style.width = "100%";
}
if (document.body.scrollTop > 600 || document.documentElement.scrollTop > 600) {
document.getElementById("header3").style.width = "80%";
} else {
document.getElementById("header3").style.width = "100%";
}
}
Ответ №1:
Вы могли бы выполнить какие-то вычисления, чтобы получить проценты, но вам не нужно этого делать. Вы должны получить верхнюю часть div, используя offsetTop
вместо добавления фиксированного значения, например
if (document.body.scrollTop > document.getElementById("header").offsetTop ||
document.documentElement.scrollTop > document.getElementById("header").offsetTop) {
Код, который у вас есть для каждого заголовка div, почти одинаков, поэтому вы можете удалить повторение, если вы сохраните все элементы div в массиве, и выполните цикл, чтобы получить offsetTop
и установить стиль, вот так:
function scrollFunction() {
for (var i = 0; i < headerdivs.length; i ) {
if (document.body.scrollTop > headerdivs[i].offsetTop || document.documentElement.scrollTop > headerdivs[i].offsetTop) {
headerdivs[i].style.width = "80%";
} else {
headerdivs[i].style.width = "100%";
}
}
}
Я использовал код из вашего codepen здесь, чтобы показать вам, как заставить его работать.
window.onscroll = function() {
scrollFunction()
};
headerdivs = [
document.getElementById("header"),
document.getElementById("header2"),
document.getElementById("header3"),
]
function scrollFunction() {
for (var i = 0; i < headerdivs.length; i ) {
if (document.body.scrollTop > headerdivs[i].offsetTop || document.documentElement.scrollTop > headerdivs[i].offsetTop) {
headerdivs[i].style.width = "80%";
} else {
headerdivs[i].style.width = "100%";
}
}
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
#header {
background-color: #f1f1f1;
color: black;
text-align: center;
font-weight: bold;
width: 100%;
transition: 1s;
display: block;
}
#header2 {
background-color: #f1f1f1;
color: black;
text-align: center;
font-weight: bold;
width: 100%;
transition: 1s;
display: block;
}
#header3 {
background-color: #f1f1f1;
color: black;
text-align: center;
font-weight: bold;
width: 100%;
transition: 1s;
display: block;
}
<div id="header"><img src="https://image.freepik.com/free-photo/wide-asphalt-road-with-buildings-horizon_1127-2192.jpg" width=100%></div>
<div id="header2"><img src="https://image.freepik.com/free-photo/wide-asphalt-road-with-buildings-horizon_1127-2192.jpg" width=100%></div>
<div id="header3"><img src="https://image.freepik.com/free-photo/wide-asphalt-road-with-buildings-horizon_1127-2192.jpg" width=100%></div>
<div style="margin-top:200px;padding:15px 15px 2500px;font-size:30px">
<p><b>This example demonstrates how to shrink a header when the user starts to scroll the page.</b></p>
<p>Scroll down this frame to see the effect!</p>
<p>Scroll to the top to remove the effect.</p>
<p>Lorem ipsum dolor dummy text sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
РЕДАКТИРОВАТЬ: Вы просили, как изменить расстояние от вершины, при котором div становится меньше. Вы можете сделать это, отрегулировав значение верхней части div. например, чтобы начать, когда верхняя часть div находится на полпути вверх по экрану:
// (position of the top of the div) - (half the screen height)
headerDiv.offsetTop - (window.innerHeight / 2);
function scrollFunction() {
for (var i = 0; i < headerdivs.length; i ) {
// adjust start point for changing the size, e.g.
// (position of the top of the div) - (half the screen height)
startChangingAt = (headerdivs[i].offsetTop) - (window.innerHeight / 2);
if (startChangingAt < 0) startChangingAt = 0;
if (document.body.scrollTop > startChangingAt ||
document.documentElement.scrollTop > startChangingAt )
headerdivs[i].style.width = "80%";
else
headerdivs[i].style.width = "100%";
}
}
Комментарии:
1. Спасибо, это кажется правильным, но я планирую иметь несколько перекрывающихся элементов разных размеров, поэтому я все еще думаю, что мне нужен процент, чтобы я мог управлять каждым подразделением независимо.
2. @Aurochs Я не понимаю, зачем вам проценты? Вам нужно получить физическое верхнее положение элемента, чтобы увидеть, находится ли он в верхней части экрана.
scrollTop
показывает, что это такое на экране любого размера.3. Не имеет значения, какой процент экрана был прокручен. Устройство работает с точными значениями пикселей.
scrollTop
всегда сообщит вам положение элемента в верхней части экрана, даже если размер окна изменяется или если оно перемещается из-за изменения размера других элементов. Это окончательное значение, которое вам нужно.4. Хорошо, я все еще пытаюсь это понять. Я буду работать с этим, спасибо!
5. Есть ли что-то еще, что мне нужно сделать? Я получаю эту ошибку — Uncaught TypeError: не удается прочитать свойство ‘offsetTop’ с нулевым значением в scrollFunction (test.html:60) в window.onscroll
Ответ №2:
Вы могли бы рассчитать расстояние от вершины каждого раздела, а также их высоту. Тогда вам придется следить за этим таким образом.
let header = document.getElementById("header");
let boundingBox = header.getBoundingClientRect();
let distanceToTop = boundingBox.top;
if (document.body.scrollTop > distanceToTop || document.documentElement.scrollTop > distanceToTop) {
document.getElementById("header").style.width = "80%";
} else {
document.getElementById("header").style.width = "100%";
}
Вы также можете поиграть с высотой вашего раздела, чтобы добавить процент видимости, который вызовет анимацию:
let header = document.getElementById("header");
let boundingBox = header.getBoundingClientRect();
let height = boundingBox.height;
let distanceToTop = boundingBox.top;
if (document.body.scrollTop > distanceToTop height * 0.5|| document.documentElement.scrollTop > distanceToTop height * 0.5) {
document.getElementById("header").style.width = "80%";
} else {
document.getElementById("header").style.width = "100%";
}
Вы также можете сделать это с помощью IntersectionObserver API, документация здесь:https://developer.mozilla.org/fr/docs/Web/API/Intersection_Observer_API