我的网站上有两个固定的标题;其中一个被另一个覆盖着-除非您一直滚动到彩色部分,否则应该剪掉顶部的颜色并在底部露出一个颜色:
let invertedNavbar = document.querySelector('.navbar--inverted'),
navbarHeight = invertedNavbar.scrollHeight,
element = document.querySelector('.color-section')
function intersectionChecker(e) {
let elementPosition = element.getBoundingClientRect()
if (elementPosition.bottom < navbarHeight && elementPosition.bottom > 0) {
invertedNavbar.style.clipPath = 'polygon( 0% 1000px, 100% 1000px, 100% ' + elementPosition.bottom + 'px, 0% ' + elementPosition.bottom + 'px)'
}
if (elementPosition.top > 0 && elementPosition.top < navbarHeight) {
invertedNavbar.style.clipPath = 'polygon( 0% 0px, 100% 0px, 100% ' + elementPosition.top + 'px, 0% ' + elementPosition.top + 'px)'
}
if (elementPosition.top < 0 && elementPosition.bottom > navbarHeight) {
invertedNavbar.style.clipPath = 'polygon( 0% -10px, 0% -10px, 0% -20px, 0% -20px )'
}
}
intersectionChecker()
window.addEventListener('scroll', intersectionChecker)
*{
margin: 0;
}
.navbar{
background-color: red;
height: 30px;
width: 100%;
position: fixed;
top: 0; left: 0;
}
.navbar--inverted{
background-color: blue;
}
.spacer{
height: 100vh;
}
.color-section{
background-color: orange;
height: 300px;
}
<div class="navbar"></div>
<div class="navbar navbar--inverted"></div>
<div class="spacer"></div>
<div class="color-section"></div>
<div class="spacer"></div>
现在,它工作得很好-除了当您滚动到该部分之外时,导航栏还剩下一些剪辑。似乎在实际滚动结束之前就触发了滚动事件。
我尝试了一些不同的选项-推迟使用requestAnimationFrame
进行位置检查(完全没有结果,甚至尝试等待两帧,出于某种原因也没有任何改变);顺应setTimeout 100
-效果很好,但也使整个过程看起来很滞后;将检查条件加倍,将其变为elementPosition.bottom < 2 * navbarHeight && elementPosition.bottom > -navbarHeight
-效果相对较好,但它既简单又不完全安全,用户仍然可以滚动得太快而无法抓住它。您有任何改进的想法吗?
答案 0 :(得分:1)
实际上,我们误以为该问题来自事件被触发的那一刻,而不是……。这完全是您的情况所致!保留在剪辑中的部分是因为,例如,当滚动达到0时,由于严格的>
比较而未触发样式更改。
不知道是否全部都是必需的,但是将它们更改为>=
和<=
可以部分解决问题。
还需要为元素完全低于导航栏添加一个案例:
let invertedNavbar = document.querySelector('.navbar--inverted'),
navbarHeight = invertedNavbar.scrollHeight,
element = document.querySelector('.color-section')
function intersectionChecker(e) {
let elementPosition = element.getBoundingClientRect()
if (elementPosition.top > navbarHeight) {
invertedNavbar.style.clipPath = ''
}else{
if (elementPosition.bottom <= navbarHeight && elementPosition.bottom >= 0) {
invertedNavbar.style.clipPath = 'polygon( 0% 1000px, 100% 1000px, 100% ' + elementPosition.bottom + 'px, 0% ' + elementPosition.bottom + 'px)'
}
if (elementPosition.top >= 0 && elementPosition.top <= navbarHeight) {
invertedNavbar.style.clipPath = 'polygon( 0% 0px, 100% 0px, 100% ' + elementPosition.top + 'px, 0% ' + elementPosition.top + 'px)'
}
if (elementPosition.top <= 0 && elementPosition.bottom >= navbarHeight) {
invertedNavbar.style.clipPath = 'polygon( 0% -10px, 0% -10px, 0% -20px, 0% -20px )'
}
}
}
intersectionChecker()
window.addEventListener('scroll', intersectionChecker)
*{
margin: 0;
}
.navbar{
background-color: red;
height: 30px;
width: 100%;
position: fixed;
top: 0; left: 0;
}
.navbar--inverted{
background-color: blue;
}
.spacer{
height: 100vh;
}
.color-section{
background-color: orange;
height: 300px;
}
<div class="navbar"></div>
<div class="navbar navbar--inverted"></div>
<div class="spacer"></div>
<div class="color-section"></div>
<div class="spacer"></div>