在滚动时更改堆叠图像的不透明度值



我有 4 张尺寸相同的图像。<img>使用 100% 的宽度(它们都堆叠在另一个之上),在它们下面我有标准内容。

所需的效果是:

  1. 一旦我开始向下滚动,当第二个图像开始出现时,必须阻止页面的实际滚动(通过将其opacity值从 0 平滑更改为 1)。
  2. 一旦达到 100%opacity,第 3 张图像应该开始出现,依此类推。
  3. 当第 4 张图像达到 100%opacity时,滚动行为应该规范化,以允许用户向下滚动到页面的其余部分。
  4. 如果用户向上滚动,则应应用相同的效果,只是向后滚动。

这是一个初始代码笔链接,真的不知道如何实现效果。提前感谢您的任何想法!

Idk 为什么每个人都让它变得如此复杂,但这里有一个简单的方法。

使用 gsap 库。

const tl = gsap.timeline({
scrollTrigger: {
trigger: document.querySelector(".images"),
pin: true,
start: "top 0%",
scrub: 1,
},
});
duration = 3;
tl.to(".img1", {
duration: duration,
opacity: 0,
ease: Power1.easeOut,
})

.to(".img2", {
duration: duration,
opacity: 0,
})

.to(".img3", {
duration: duration,
opacity: 0,
})

.to(".img4", {
duration: duration,
opacity: 0,
})

.to(".content", {
duration: duration,
opacity: 1,
},"-=1")
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.images {
width: 100vw;
height: 100vh;
}
.images img {
width: 100%;
display: block;
position: absolute;



top:50%;
left:50%;
transform: translate(-50%,-50%);
}
.images img.img1 {
opacity: 1;
}

.content{
opacity: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="images">
<img
src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4"
alt="4"
class="img4"
/>
<img
src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3"
alt="3"
class="img3"
/>
<img
src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2"
alt="2"
class="img2"
/>
<img
src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1"
alt="1"
id="img1"
class="img1"
/>
<div class="content">
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
</div>
</div>
</body>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"
integrity="sha512-IQLehpLoVS4fNzl7IfH8Iowfm5+RiMGtHykgZJl9AWMgqx0AmJ6cRWcB+GaGVtIsnC4voMfm8f2vwtY+6oPjpQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"
integrity="sha512-wK2NuxEyN/6s53M8G7c6cRUXvkeV8Uh5duYS06pAdLq4ukc72errSIyyGQGYtzWEzvVGzGSWg8l79e0VkTJYPw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</html>

我希望这就是你要问的。

尝试使用whell事件

let images = $(".images img");
var imagesTotal = images.length;
var currentIndex = 0;
var isScrolling = false;
var isScrollFinish = false;
$(window).on("wheel", function (e) {
if(isScrollFinish) return;
let event = e.originalEvent;
clearTimeout(isScrolling);
isScrolling = setTimeout(function () {
if (event.deltaY < 0 && currentIndex > 0) {
images.eq(currentIndex).animate({ opacity: 0 }, 600);
currentIndex--;
images.eq(currentIndex).animate({ opacity: 1 }, 1000);
console.log("scrolling up", currentIndex+1);
} else if (event.deltaY > 0 && currentIndex < imagesTotal) {
images.eq(currentIndex).animate({ opacity: 0 }, 600);
currentIndex++;
images.eq(currentIndex).animate({ opacity: 1 }, 1000);
if (currentIndex == imagesTotal) {
isScrollFinish = true;
$("body").css("overflow", "auto");
}
console.log("scrolling down", currentIndex+1);
}
}, 200);
});
body {
overflow: hidden;
}
.images img {
width: 100%;
display: block;
position: fixed;
opacity: 0;
top: 0
}
.images img.img1 {
opacity: 1;
}
.as-console-wrapper{max-height:24px !important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="img1">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="img2">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="img3">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="img4">
</div>
<div class="content">
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
</div>

不确定这是否"完全"符合您的问题,但也许它会有所帮助......

我使用 bootstrap 4 的原生滚动间谍行为做了类似的事情。它读取元素 (id) 的滚动位置,并使用锚点 (#) 指向该匹配元素。您可以在锚标签中使用图像,几乎可以完成相同的操作。

源: https://getbootstrap.com/docs/4.0/components/scrollspy/

代码太多,无法放在这里,所以我做了一个小提琴: https://jsfiddle.net/ytdpmL9e/1/

所以无论如何都会让我添加一些代码,所以这里只是 CSS......

* {box-sizing: border-box;}
html {scroll-padding-top: 140px;}
body {position:relative;}
#main {background:#f6f6f6; padding:3em 2em; margin-top:-2.5em; max-width:600px;}
#header {opacity:0;}
#header.show {background:#fff; display:flex; flex-direction:column; position:sticky; top:0px; text-align:center; min-height:125px; opacity:1; transition:all 0.3s;}
#header.show .nav {height:125px;}
#header.show .nav a {color:#fff; display:flex; font-size:1.8em; align-items:center; justify-content:center; min-height:125px; max-width:600px; width:100%;}
#header.show .nav a:nth-child(1) {background:#6b78b9;}
#header.show .nav a:nth-child(2) {background:#8db33f;}
#header.show .nav a:nth-child(3) {background:#f68e1e;}
#header.show .nav a.active {animation:fade-in .5s; position:absolute; top:0; z-index:100;}
#header.show .nav a:not(.active) {animation:fade-out .5s; opacity:0; position:absolute; transition-delay:.1s;}
@keyframes fade-in {0% {opacity: 0;} 100% {opacity: 1;}}
@keyframes fade-out {0% {opacity: 1;} 100% {opacity: 0;}}

试试这个,把它粘贴到JS部分的jsfiddle中:

var scrollDirection = 0;
var scrollTimeout = null;
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
if (scrollTop > scrollDirection) {
// scroll down
if (scrollTimeout) {
clearTimeout(scrollTimeout);
}
scrollTimeout = setTimeout(function() {
$('.images img').each(function() {
var $this = $(this);
if ($this.css('opacity') == 0) {
$this.css('opacity', 1);
return false;
}
});
}, 500);
} else {
// scroll up
if (scrollTimeout) {
clearTimeout(scrollTimeout);
}
scrollTimeout = setTimeout(function() {
$('.images img').each(function() {
var $this = $(this);
if ($this.css('opacity') == 1) {
$this.css('opacity', 0);
return false;
}
});
}, 500);
}
scrollDirection = scrollTop;
});

您可能需要从齿轮图标启用jQuery,或者,您可以尝试将其粘贴到代码顶部:

import $ from "https://cdn.skypack.dev/jquery@3.6.1";

根据反馈更新了解决方案:

  • 版本 1 符合初步理解,未更改。 它启动了图像的自动平滑过渡,使用 用户更改滚动方向时的不透明度。
  • 版本 2 使用滚动操作本身来确定不透明度 转换,并再次以生成滚动事件的速率发生 当用户更改滚动方向时。
  • 版本 3 根据以下评论中的进一步反馈进行了改进。
  • 版本 4 根据以下评论中的进一步反馈进行了改进。不透明度 仅当滚动位于"顶部"时,即"在 图像"。

版本 1

我认为下面的代码符合您上面的要求。 希望嵌入的评论解释它是如何工作的。

此示例使用"setTimeout"通过排队来协调图像的淡入淡出。 也可以使用"setInterval"并遍历图像而不是排队来完成。

我对布局进行了一些调整。 请参阅代码中的注释。 根据您的最终布局,可能有无数种方法可以做到这一点。

var images;
var scrollContainer;
var noScrollDown;
var noScrollUp;
var scrollLeft;
var scrollTop;
var latch;
function setUp() {
images = document.getElementsByClassName("image");
scrollContainer = document.getElementById("content");
noScrollDown = true;
noScrollUp = true;
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
latch = false;
}
function doScrollUp () {
noScrollUp = false;
noScrollDown = true;
scrollContainer.style.overflow = "auto";
latch = false;
}
function doScrollDown () {
noScrollDown = false;
noScrollUp = true;
scrollContainer.style.overflow = "auto";
latch = false;
}
function fadeIn(ndx) {
if ( ndx > 3 ) {
//  Top image is showing so switch direction of allowable scrolling
doScrollDown();
} else {
//  Fade in an image and queue the fade in of the next image
images[ndx].style.opacity = 1;
setTimeout(fadeIn, 2000, ndx+1);        //  The time here, in milliseconds, should be the same as the transition time above
}
}
function fadeOut(ndx) {
if ( ndx < 1 ) {
//  Bottom image is showing so switch direction of allowable scrolling
doScrollUp();
} else {
//  Fade out an image and queue the fade out of the next image
images[ndx].style.opacity = 0;
setTimeout(fadeOut, 2000, ndx-1);       //  The time here, in milliseconds, should be the same as the transition time above
}
}
function transOpacity() {
if ( noScrollDown && scrollContainer.scrollTop >= scrollTop ) {
//  No scroll down allowed, and scroll event tried to go down

//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event

//  
if ( ! latch ) {
latch = true;       //  Stop double processing due to second scroll event triggered above
scrollContainer.style.overflow = "hidden";
fadeIn(1);
}
} else if ( noScrollUp && scrollContainer.scrollTop <= scrollTop ) {
//  No scroll up allowed, and scroll event tried to go up

//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
if ( ! latch ) {
latch = true;       //  Stop double processing due to second scroll event triggered above
scrollContainer.style.overflow = "hidden";
fadeOut(3)
}
} else {
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
latch = false;
}
}
.images img {
width: 100%;            /*  Note that 100% width will cover the scoll bar of the content, when the flow is decoupled with 'display: position;'  */
max-height: 25vh;       /*  Set a limit on the height of the images, for this example, so that the scroll bar of the content can be fully accessible */
display: block;
position: absolute;
top: 0vh;                 /*  Set the position, for this example, so that the scroll bar of the content can be fully accessible */
}

/*  Set up the required transition on the property relevant property  */
.images img.image {
opacity: 0;                     /*  The default initial opacity  */
transition-property: opacity;
transition-duration: 2s;        /*  The time here, in seconds, needs to be the same as the setTimeout times below  */
}

/*  Initialise the first image as showing, ie, full opacity.  */
.images img.image:nth-of-type(1) {
opacity: 1;
}
.content {
margin-top: 25vh;       /*  For this example, make sure the scroll container is below the images so that the scroll bar is fully accessible.  */
}
<body onLoad="setUp()">
<div>
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
</div>
<div id="content" class="content" onscroll="transOpacity()" style="height: 50vh; overflow:auto;">
<p>This should be scrolled down normally - line 1.</p>
<p>This should be scrolled down normally - line 2.</p>
<p>This should be scrolled down normally - line 3.</p>
<p>This should be scrolled down normally - line 4.</p>
<p>This should be scrolled down normally - line 5.</p>
<p>This should be scrolled down normally - line 6.</p>
<p>This should be scrolled down normally - line 7.</p>
<p>This should be scrolled down normally - line 8.</p>
<p>This should be scrolled down normally - line 9.</p>
<p>This should be scrolled down normally - line 10.</p>
<p>This should be scrolled down normally - line 11.</p>
<p>This should be scrolled down normally - line 12.</p>
<p>This should be scrolled down normally - line 13.</p>
<p>This should be scrolled down normally - line 14.</p>
<p>This should be scrolled down normally - line 15.</p>
<p>This should be scrolled down normally - line 16.</p>
<p>This should be scrolled down normally - line 17.</p>
<p>This should be scrolled down normally - line 18.</p>
<p>This should be scrolled down normally - line 19.</p>
<p>This should be scrolled down normally - line 20.</p>
<p>This should be scrolled down normally - line 21.</p>
<p>This should be scrolled down normally - line 22.</p>
<p>This should be scrolled down normally - line 23.</p>
<p>This should be scrolled down normally - line 24.</p>
<p>This should be scrolled down normally - line 25.</p>
<p>This should be scrolled down normally - line 26.</p>
<p>This should be scrolled down normally - line 27.</p>
<p>This should be scrolled down normally - line 28.</p>
<p>This should be scrolled down normally - line 29.</p>
<p>This should be scrolled down normally - line 30.</p>
</div>
</div>
</body>

版本 2

要更改平滑度,请调整恒定不透明度IncDec。 值越小,过渡越平滑,但需要的时间就越长。

var images;
var scrollContainer;
var noScrollDown;
var noScrollUp;
var scrollLeft;
var scrollTop;
var imgNdx;
const opacityIncDec = 0.025;
function setUp() {
images = document.getElementsByClassName("image");
scrollContainer = document.getElementById("content");
noScrollDown = true;
noScrollUp = true;
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
imgNdx = 1;
}
function doScrollUp () {
noScrollUp = false;
noScrollDown = true;
imgNdx = 1;
}
function doScrollDown () {
noScrollDown = false;
noScrollUp = true;
imgNdx = 3;
}
function fadeIn(ndx) {
var opacity;
if ( ndx > 3 ) {
//  Top image is showing so switch direction of allowable scrolling
doScrollDown();
} else {
//  Fade in an image or queue the fade in of the next image
opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity < 1 ) {
images[ndx].style.opacity = opacity + opacityIncDec
} else {
imgNdx += 1;
}
}
}
function fadeOut(ndx) {
if ( ndx < 1 ) {
//  Bottom image is showing so switch direction of allowable scrolling
doScrollUp();
} else {
//  Fade out an image and queue the fade out of the next image
opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity > 0 ) {
images[ndx].style.opacity = opacity - opacityIncDec
} else {
imgNdx -= 1;
}
}
}
function transOpacity() {
if ( noScrollDown && scrollContainer.scrollTop >= scrollTop ) {
//  No scroll down allowed, and scroll event tried to go down

//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
fadeIn(imgNdx);
} else if ( noScrollUp && scrollContainer.scrollTop <= scrollTop ) {
//  No scroll up allowed, and scroll event tried to go up

//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);  //  This will trigger another scroll event
fadeOut(imgNdx)
} else {
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
}
}
.images img {
width: 100%;            /*  Note that 100% width will cover the scroll bar of the content, when the flow is decoupled with 'display: position;'  */
max-height: 25vh;       /*  Set a limit on the height of the images, for this example, so that the scroll bar of the content can be fully accessible */
display: block;
position: absolute;
top: 0vh;                 /*  Set the position, for this example, so that the scroll bar of the content can be fully accessible */
}

/*  Set up the required transition on the property relevant property  */
.images img.image {
opacity: 0;                     /*  The default initial opacity  */
}
/*  Initialise the first image as showing, ie, full opacity.  */
.images img.image:nth-of-type(1) {
opacity: 1;
}
.content {
margin-top: 25vh;       /*  For this example, make sure the scroll container is below the images so that the scroll bar is fully accessible.  */
}
<body onLoad="setUp()">
<div>
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
</div>
<div id="content" class="content" onscroll="transOpacity()" style="height: 50vh; overflow:auto;">
<p>This should be scrolled down normally - line 1.</p>
<p>This should be scrolled down normally - line 2.</p>
<p>This should be scrolled down normally - line 3.</p>
<p>This should be scrolled down normally - line 4.</p>
<p>This should be scrolled down normally - line 5.</p>
<p>This should be scrolled down normally - line 6.</p>
<p>This should be scrolled down normally - line 7.</p>
<p>This should be scrolled down normally - line 8.</p>
<p>This should be scrolled down normally - line 9.</p>
<p>This should be scrolled down normally - line 10.</p>
<p>This should be scrolled down normally - line 11.</p>
<p>This should be scrolled down normally - line 12.</p>
<p>This should be scrolled down normally - line 13.</p>
<p>This should be scrolled down normally - line 14.</p>
<p>This should be scrolled down normally - line 15.</p>
<p>This should be scrolled down normally - line 16.</p>
<p>This should be scrolled down normally - line 17.</p>
<p>This should be scrolled down normally - line 18.</p>
<p>This should be scrolled down normally - line 19.</p>
<p>This should be scrolled down normally - line 20.</p>
<p>This should be scrolled down normally - line 21.</p>
<p>This should be scrolled down normally - line 22.</p>
<p>This should be scrolled down normally - line 23.</p>
<p>This should be scrolled down normally - line 24.</p>
<p>This should be scrolled down normally - line 25.</p>
<p>This should be scrolled down normally - line 26.</p>
<p>This should be scrolled down normally - line 27.</p>
<p>This should be scrolled down normally - line 28.</p>
<p>This should be scrolled down normally - line 29.</p>
<p>This should be scrolled down normally - line 30.</p>
</div>
</div>
</body>

版本 3

  • 当在滚动容器顶部时,图像会相互淡入 每次出现不透明度时逐渐增加的不透明度的手段 滚动事件。
  • 当在滚动容器的底部时,图像会相互淡出 它们的不透明度在每次出现时逐渐降低的手段 滚动事件。
  • 当图像完全淡入时,滚动已在 顶部,或完全淡出,卷轴一直在底部, 滚动容器的内容都正常滚动,并且 图像和文本一起。
  • 正常滚动时,图像不透明度不受影响。

var images;
var imgNdx;
var scrollContainer;
var atTop;
var atBottom;
var scrollLeft;
var scrollTop;
const opacityIncDec = 0.025;
function setUp() {
images = document.getElementsByClassName("image");
imgNdx = 1;
scrollContainer = document.getElementById("scrollContainer");
atTop = true;
atBottom = false;
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
}
function fadeIn(ndx) {
var opacity;
if ( ndx > 3 ) {
atTop = false;
imgNdx = 3;
} else {
opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity < 1 ) {
images[ndx].style.opacity = opacity + opacityIncDec
} else {
imgNdx += 1;
}
}
}
function fadeOut(ndx) {
var opacity;
if ( ndx < 1 ) {
atBottom = false;
imgNdx = 1;
} else {
opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity > 0 ) {
images[ndx].style.opacity = opacity - opacityIncDec
} else {
imgNdx -= 1;
}
}
}
function transOpacity() {
if ( atTop && scrollContainer.scrollTop >= scrollTop ) {
//  At top, and scroll event tried to go down
//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);
fadeIn(imgNdx);
} else if ( atBottom && scrollContainer.scrollTop <= scrollTop ) {
//  At bottom, and scroll event tried to go up
//  Scroll back to where the scroll was
scrollContainer.scrollTo(scrollLeft, scrollTop);
fadeOut(imgNdx)
} else {
atTop = scrollContainer.scrollTop <= 0;
atBottom = Math.abs(scrollContainer.clientHeight - scrollContainer.scrollHeight + scrollContainer.scrollTop) <= 1;
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
}
}
.scrollContainer {
height: 80vh;
overflow: auto;
}
.images {
position: relative;
height: 15vh;
}
.images img {
width: 100%;
height: 15vh;
position: absolute;
}
.images img.image {
opacity: 0;                     /*  The default initial opacity  */
}
/*  Initialise the first image as showing, ie, full opacity.  */
.images img.image:nth-of-type(1) {
opacity: 1;
}
<body onLoad="setUp()">
<div id="scrollContainer" class="scrollContainer" onscroll="transOpacity()" >
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
</div>
<div class="content">
<p>This should be scrolled down normally - line 1.</p>
<p>This should be scrolled down normally - line 2.</p>
<p>This should be scrolled down normally - line 3.</p>
<p>This should be scrolled down normally - line 4.</p>
<p>This should be scrolled down normally - line 5.</p>
<p>This should be scrolled down normally - line 6.</p>
<p>This should be scrolled down normally - line 7.</p>
<p>This should be scrolled down normally - line 8.</p>
<p>This should be scrolled down normally - line 9.</p>
<p>This should be scrolled down normally - line 10.</p>
<p>This should be scrolled down normally - line 11.</p>
<p>This should be scrolled down normally - line 12.</p>
<p>This should be scrolled down normally - line 13.</p>
<p>This should be scrolled down normally - line 14.</p>
<p>This should be scrolled down normally - line 15.</p>
<p>This should be scrolled down normally - line 16.</p>
<p>This should be scrolled down normally - line 17.</p>
<p>This should be scrolled down normally - line 18.</p>
<p>This should be scrolled down normally - line 19.</p>
<p>This should be scrolled down normally - line 20.</p>
<p>This should be scrolled down normally - line 21.</p>
<p>This should be scrolled down normally - line 22.</p>
<p>This should be scrolled down normally - line 23.</p>
<p>This should be scrolled down normally - line 24.</p>
<p>This should be scrolled down normally - line 25.</p>
<p>This should be scrolled down normally - line 26.</p>
<p>This should be scrolled down normally - line 27.</p>
<p>This should be scrolled down normally - line 28.</p>
<p>This should be scrolled down normally - line 29.</p>
<p>This should be scrolled down normally - line 30.</p>
</div>
</div>
</body>

版本 4

不透明度处理现在只发生在卷轴的"顶部"。 如果"图像滚动"只是部分,它将朝着图像中的"滚动方向"前进。

请注意,为了允许滚动事件继续触发,scrollTop 必须保持在 0 以上,否则甚至不会触发向上滚动。

据我所知,它工作正常(?),除了有时当它不堪重负并且仍然得到 scrollTop 为 0 时,滚动事件率非常高。 不过,只需一个向下滚动操作即可为用户重置内容。请参阅 https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event 中的警告。 这也提供了一些解决方案。 这可能是触摸设备上的问题,因为滑动滚动可能会淹没它。 但是,这将取决于您的背景并完全进入其他领域。

var images;
var imgNdx;
var scrollContainer;
var atTop;
var scrollLeft;
var scrollTop;
const opacityIncDec = 0.05;
function setUp() {
images = document.getElementsByClassName("image");
imgNdx = 1;
scrollContainer = document.getElementById("scrollContainer");
atTop = true;
scrollLeft = scrollContainer.scrollLeft;
scrollTop = scrollContainer.scrollTop;
}
function fadeIn(ndx) {
var opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity < 1 ) {
images[ndx].style.opacity = opacity + opacityIncDec
} else {
imgNdx += 1;
if ( imgNdx > 3 ) {
imgNdx = 3;
atTop = false;
}
}
}
function fadeOut(ndx) {
var opacity = images[ndx].style.opacity;
if ( opacity == "" ) {
opacity = 0;
} else {
opacity = parseFloat(opacity);
}
if ( opacity > 0 ) {
images[ndx].style.opacity = opacity - opacityIncDec
} else {
imgNdx -= 1;
if ( ndx < 1 ) {
imgNdx = 1;
}
}
}
var latch = false;
function transOpacity() {
if ( atTop ) {
if ( ! latch ) {
if ( scrollContainer.scrollTop > 1 ) {
//  Scroll event tried to go down
//  Scroll back to the "top"
latch = true;
scrollContainer.scrollTo(scrollLeft, 1);
fadeIn(imgNdx);
} else {
//  Scroll event tried to go up
//  Scroll back to the "top"
latch = true;
scrollContainer.scrollTo(scrollLeft, 1);
if ( imgNdx > 0 ) fadeOut(imgNdx);
}
} else {
latch = false;
}
} else {
scrollLeft = scrollContainer.scrollLeft;
if ( scrollContainer.scrollTop == 0 ) {
atTop = true;
latch = true;
scrollContainer.scrollTo(scrollLeft, 1);
}
}
}
.scrollContainer {
height: 80vh;
overflow: auto;
}
.images {
position: relative;
height: 15vh;
}
.images img {
width: 100%;
height: 15vh;
position: absolute;
}
.images img.image {
opacity: 0;                     /*  The default initial opacity  */
}
/*  Initialise the first image as showing, ie, full opacity.  */
.images img.image:nth-of-type(1) {
opacity: 1;
}
<body onLoad="setUp()">
<div id="scrollContainer" class="scrollContainer" onscroll="transOpacity()" >
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="image">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="image">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="image">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="image">
</div>
<div class="content">
<p>This should be scrolled down normally - line 1.</p>
<p>This should be scrolled down normally - line 2.</p>
<p>This should be scrolled down normally - line 3.</p>
<p>This should be scrolled down normally - line 4.</p>
<p>This should be scrolled down normally - line 5.</p>
<p>This should be scrolled down normally - line 6.</p>
<p>This should be scrolled down normally - line 7.</p>
<p>This should be scrolled down normally - line 8.</p>
<p>This should be scrolled down normally - line 9.</p>
<p>This should be scrolled down normally - line 10.</p>
<p>This should be scrolled down normally - line 11.</p>
<p>This should be scrolled down normally - line 12.</p>
<p>This should be scrolled down normally - line 13.</p>
<p>This should be scrolled down normally - line 14.</p>
<p>This should be scrolled down normally - line 15.</p>
<p>This should be scrolled down normally - line 16.</p>
<p>This should be scrolled down normally - line 17.</p>
<p>This should be scrolled down normally - line 18.</p>
<p>This should be scrolled down normally - line 19.</p>
<p>This should be scrolled down normally - line 20.</p>
<p>This should be scrolled down normally - line 21.</p>
<p>This should be scrolled down normally - line 22.</p>
<p>This should be scrolled down normally - line 23.</p>
<p>This should be scrolled down normally - line 24.</p>
<p>This should be scrolled down normally - line 25.</p>
<p>This should be scrolled down normally - line 26.</p>
<p>This should be scrolled down normally - line 27.</p>
<p>This should be scrolled down normally - line 28.</p>
<p>This should be scrolled down normally - line 29.</p>
<p>This should be scrolled down normally - line 30.</p>
</div>
</div>
</body>

这是一个简单的解决方案,在这种情况下,使用车轮事件的 deltaY 进行垂直滚动量计算。对于更高级的方案,可以按类似的方式处理其他事件(如touchmove):

const scroll = (() => {
let v = 0, i = 0;
const images = document.querySelector('.images');
const top = images.getBoundingClientRect().top;
const img = document.querySelectorAll('img');
const cls = document.body.classList;
const len = img.length, max = len - 1;
return (dy, step = 1) => {
if (images.getBoundingClientRect().top - top)
return;
v = Math.min(Math.max(v += Math.sign(dy) * step, 0), len * 100);
(i = (v - v % 100) / 100) === 0 && (v = 100);
let o = v - i * 100;
i > max ? (i = max, o = 100, cls.remove('fixed')) : cls.add('fixed');
for (let n = img.length; n--;)
img[n].style.opacity = `${n === i ? o : n < i ? 100 : 0}%`;
};
})();
scroll(0);
window.addEventListener('wheel', e => scroll(e.deltaY, 10), true);
.images img {
width: 100%;
display: block;
}
.images img:not(:first-child) {
position: absolute;
top: 0;
}
body.fixed {
overflow: hidden;
}
<div class="images">
<img src="https://dummyimage.com/1400x600/ff4400/fff.png&text=1" alt="1" class="img1">
<img src="https://dummyimage.com/1400x600/3c00ff/fff.png&text=2" alt="2" class="img2">
<img src="https://dummyimage.com/1400x600/44a10f/fff.png&text=3" alt="3" class="img3">
<img src="https://dummyimage.com/1400x600/d99f2b/fff.png&text=4" alt="4" class="img4">
</div>
<div class="content">
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
<p>This should be scrolled down normally.</p>
</div>

最新更新