I have a text static text element that changes when user scrolls more than 600px and again when it scrolls more than 1400px
$(window).scroll(function () {
if ($(this).scrollTop() > 600) {
$('.p-circle').html('Text 1');
$('.p-circle-s').html('Text 2');
}
});
$(window).scroll(function () {
if ($(this).scrollTop() > 1400) {
$('.p-circle').html('Text 1 updated');
$('.p-circle-s').html('Text 2 updated');
}
});
How can I make a basic animation of fading for them, I tried next variants and they don't work well (it is fading 2 times)
if (scrollTop > 600 && scrollTop <= 1400) {
$('.p-circle').fadeOut(500, function() {
$(this).text('Text 1').fadeIn(500);
});
$('.p-circle-s').fadeOut(500, function() {
$(this).text('Text 2').fadeIn(500);
});
} else if (scrollTop > 1400 && scrollTop <= 2100) {
$('.p-circle').fadeOut(500, function() {
$(this).text('Text 1 updated').fadeIn(500);
});
$('.p-circle-s').fadeOut(500, function() {
$(this).text('Text 2 Updated').fadeIn(500);
});
}
CodePudding user response:
I think you're on the right track, however your logic in that last bit there isn't testing whether the transition already happened. Something along the lines of:
if ($(this).scrollTop() > 600 && $(this).scrollTop() <= 1400 && $(".p-circle").text() != 'Text 1')
I think I got your values wrong, but here's a fiddle to get you on the right track...
https://jsfiddle.net/64mj3k7n/3/
CodePudding user response:
A better solution would be to create a function (or Class) Waypoints
, to be used like:
Waypoints(window, [0, 100, 600, 1400], (wp) => {
console.log(wp); // {index:Int, value:Int}
});
which accepts three arguments:
- an Element (or String selector) to scroll-watch
- an Array of scrollY waypoints values
- a callback Function
The callbacks is triggered only once a scroll index changes — in order to prevent buildups on every scroll Event call.
/**
* Waypoints
* Trigger callbacks on a scrollY milestone
* @url https://stackoverflow.com/a/70520524/383904
* @param {string|object} el String selector or Element object
* @param {array} waypoints Array of px from lower to higher
* @param {function} cb Callback function
*/
function Waypoints(el, waypoints = [0], cb) {
el = (typeof el === "string") ? document.querySelector(el) : el;
const wp = [...waypoints].reverse();
const wpTot = wp.length;
const getIndex = (n) => {
const i = wp.findIndex(m => m <= n);
return wpTot - 1 - (i < 0 ? wpTot : i);
};
let index = -1;
const getTask = () => {
const i = getIndex(el.scrollY);
if (index === i) return; // No task to trigger
index = i; // Update index
const value = wp[wpTot - 1 - i]; // Get the waypoint name
cb({ index, value }); // Trigger the callback
};
el.addEventListener("scroll", getTask);
window.addEventListener("DOMContentLoaded", () => getTask);
window.addEventListener("load", () => getTask);
getTask();
}
/**
* YOUR APP:
*/
const $circle1 = $('.p-circle');
const $circle2 = $('.p-circle-s');
const circle1txt = ["Text 1 scroll", "Text 1", "Text 1 updated"];
const circle2txt = ["Text 2 scroll", "Text 2", "Text 2 updated"];
Waypoints(window, [0, 600, 1400], (wp) => {
$circle1.fadeOut(500, () => {
$circle1.text(circle1txt[wp.index]).fadeIn(500);
});
$circle2.fadeOut(500, () => {
$circle2.text(circle2txt[wp.index]).fadeIn(500);
});
});
body { height: 3000px; } /* Just to force some scrollbars for this demo */
[class^="p-"] { position: fixed; }
.p-circle-s { top: 2rem; }
<div ></div>
<div ></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>