这是我的代码
<div class="titlediv" style='background:linear-gradient(90deg, #cc2900 79%, #b3b3b3 21%);'>
<h2> Hii
</div>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<p> My name is Josh and I need Help </p>
<div class="titlediv" style='background:linear-gradient(90deg, #cc2900 79%, #b3b3b3 21%);'>
<h2> Hii
</div>
如您所见,有2个<h2>
标签带有背景颜色。
我想在屏幕上显示背景颜色从左到右填充。
就像这个网站:http://html.wwwebinvader.com/MovieMe/MovieMe-Light/index.html
向下滚动并查看IMDB评级等。
答案 0 :(得分:1)
基本上,您需要聆听window
上的scroll
event,并使用.offsetTop
检查您的标题元素(h2
)是否在视口内offsetHeight
关于渐变动画,linear-gradient
are not animatable。
解决方案是将初始渐变作为元素的background
,然后使用另一个元素(或pseudo-element
)在另一个元素的顶部堆叠另一个渐变,并使用正确的{{1 }}然后使用其他可设置动画的属性来伪造渐变动画。
通常,您将使用z-index
从一个渐变过渡到另一个渐变(第一个示例)或opacity
,position
,left
,top
。 ..逐步填充渐变(第二个例子)。
width
// Get all the heading elements:
const titles = document.querySelectorAll('.title');
const total = titles.length;
let windowHeight = window.innerHeight;
// Track the current heading, as you don't need to recheck those that have already been shown once:
let current = 0;
function onScroll() {
// Get the bottom scroll position:
const bottomScrollY = window.scrollY + windowHeight;
// Check each heading that has not been shown yet:
for (let i = current; i < total; ++i) {
const title = titles[i];
// Check that the heading is completely visible (all of it inside the current viewport):
if (bottomScrollY > title.offsetTop + title.offsetHeight) {
// Add it the .active class:
title.classList.add('active');
// Skip this heading the next time:
++current;
// If all headings are already active, remove the listeners:
if (current === total) {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', onResize);
}
}
}
}
function onResize() {
// Update windowHeight:
windowHeight = window.innerHeight;
}
// Initialize for the first time:
onScroll();
// Start listening for scroll and resize events:
window.addEventListener('scroll', onScroll);
window.addEventListener('resize', onResize);
body {
margin: 0;
font-family: sans-serif;
}
.title {
position: relative;
margin: 0;
padding: 1rem;
color: #000;
background: linear-gradient(to right, #F00 0%, #FF0 100%);
z-index: 1;
}
.title::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0;
background: linear-gradient(to right, #00F 0%, #0FF 100%);
transition: opacity ease-in .25s;
}
.active::before {
opacity: 1;
}
<h2 class="title">TITLE 1</h2>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<h2 class="title">TITLE 2</h2>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<h2 class="title">TITLE 3</h2>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<h2 class="title">TITLE 4</h2>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<h2 class="title">TITLE 5</h2>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
<p>...</p>
// Get all the heading elements:
const titles = document.querySelectorAll('.title');
const total = titles.length;
let windowHeight = window.innerHeight;
// Track the current heading, as you don't need to recheck those that have already been shown once:
let current = 0;
function onScroll() {
// Get the bottom scroll position:
const bottomScrollY = window.scrollY + windowHeight;
// Check each heading that has not been shown yet:
for (let i = current; i < total; ++i) {
const title = titles[i];
// Check that the heading is completely visible (all of it inside the current viewport):
if (bottomScrollY > title.offsetTop + title.offsetHeight) {
// Add it the .active class:
title.classList.add('active');
// Skip this heading the next time:
++current;
// If all headings are already active, remove the listeners:
if (current === total) {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', onResize);
}
}
}
}
function onResize() {
// Update windowHeight:
windowHeight = window.innerHeight;
}
// Initialize for the first time:
onScroll();
// Start listening for scroll and resize events:
window.addEventListener('scroll', onScroll);
window.addEventListener('resize', onResize);
body {
margin: 0;
font-family: sans-serif;
}
.title {
position: relative;
margin: 0;
padding: 1rem;
color: #000;
z-index: 1;
opacity: 0;
transition: opacity ease-in .25s;
}
.title::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 0;
height: 100%;
z-index: -1;
background: linear-gradient(to right, #FF0 0%, #FFF 100%);
transition: width ease-in .25s;
}
.active {
opacity: 1;
}
.active::before {
width: 100%;
}