I have this snippet.
I have the div bar on which I act with a listener for the mousemove event. Depending on the coordinates of the mouse, the hello elements move on the x-axis.
How can I, when the mouse is no longer on the bar, that is, outside, the hello elements in the bar, return to the initial position?
For example, while the mouse is over the bar, the hello elements move to the right, and when the mouse is no longer on the bar, they return to their original position.
const bar = document.querySelector('.bar');
const layer = document.querySelectorAll('.layer');
const eff = function(mouse) {
layer.forEach(layer => {
const x = (window.innerWidth - mouse.pageX) / 10;
const y = (window.innerHeight - mouse.pageY) / 10;
layer.style.transform = `translateX(${x}px)translateY(${y}px)`;
})
};
bar.addEventListener('mousemove', eff);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.bar {
height: 20vh;
background: black;
position: relative;
display: flex;
align-items: center;
justify-content: space-around;
}
#red {
color: red;
}
#blue {
color: blue;
}
<div class="bar">
<div class="hello">
<h2 id='red' class='layer'>Hello</h2>
<h2 id='blue' class='layer'>Hello</h2>
</div>
</div>
You can add another listener for the mouseleave event and then simply reset the translation to 0px for each layer.
const bar = document.querySelector('.bar');
const layer = document.querySelectorAll('.layer');
const eff = function(mouse) {
layer.forEach(layer => {
const x = (window.innerWidth - mouse.pageX) / 10;
const y = (window.innerHeight - mouse.pageY) / 10;
layer.style.transform = `translateX(${x}px)translateY(${y}px)`;
})
};
const reset = function(mouse) {
layer.forEach(layer => {
layer.style.transform = `translateX(0px)translateY(0px)`;
})
};
bar.addEventListener('mousemove', eff);
bar.addEventListener('mouseleave', reset);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.bar {
height: 20vh;
background: black;
position: relative;
display: flex;
align-items: center;
justify-content: space-around;
}
#red {
color: red;
}
#blue {
color: blue;
}
<div class="bar">
<div class="hello">
<h2 id='red' class='layer'>Hello</h2>
<h2 id='blue' class='layer'>Hello</h2>
</div>
</div>
Related
I created a CSS Grid layout with global variables:
#app{
--width-l: 0.5fr;
--width-c: 0.5fr;
}
So I have a bar in the middle of my screen. On the other hand, in JavaScript I have two events that observe if the mouse is pressed (mousedown) and in motion (mousemove) that move the div. It has a problem, the movement is above the mouse position and at the height of the #app. So it works in parts, when I'm near the top, the div#bar doesn't go up anymore, and near the bottom, the same thing happens but at a greater distance.
I'm looking for a solution to make the transition smoothly, using the grid positions.
This is the code I created to try:
var split = document.querySelector(".split");
var app = document.querySelector("#app");
var position = app.getBoundingClientRect();
var isMouseMove = false;
split.addEventListener("mousedown", (e) => {
isMouseMove = true;
this.addEventListener("mouseup", (e) => {
isMouseMove = false;
});
});
split.addEventListener("mousemove", (e) => {
if (isMouseMove) {
let fullSize = app.offsetHeight;
let average = (100 * (e.y - position.top)) / fullSize;
let up = (average / 100).toFixed(4);
let down = (1 - average / 100).toFixed(4);
app.style.setProperty("--width-l", `${up}fr`);
app.style.setProperty("--width-c", `${down}fr`);
}
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
header {
background: aquamarine;
height: 50px;
}
footer {
background: aqua;
height: 50px;
}
#app {
--width-l: 0.5fr;
--width-c: 0.5fr;
height: calc(100vh - 100px);
display: grid;
grid-template: "aside up" var(--width-l) "aside split" 50px "aside down" var(
--width-c
) / 100px auto;
}
#app .aside {
grid-area: aside;
background: blue;
}
#app .up {
grid-area: up;
background: yellow;
resize: horizontal;
}
#app .split {
grid-area: split;
background: floralwhite;
display: flex;
justify-content: center;
align-items: center;
font-weight: 900;
color: tomato;
user-select: none;
}
#app .down {
grid-area: down;
background: green;
}
#app .split:active {
cursor: move;
}
<header></header>
<div id="app">
<div class="aside"></div>
<div class="up"></div>
<div class="split"> CLICK AND MOVE </div>
<div class="down"></div>
</div>
<footer></footer>
I'm creating a simple etch-a-sketch that colors the created squares on a click and drag event.
When you run below code please note that in the very beginning, every div.square that is being catched by eventListener returns exactly one div.square and I consider this as a normal behaviour.
Now, every time you click on a "Rainbow mode" button a function listening('rainbow') is being called and now a single div.square is being returned twice (I added a console.log to catch it). When you press "Rainbow mode" again a single div.square will be called 3 times and it increases in this manner.
Why is it happening? Why when I run a debugger I can see that eventListener section of listening() function is being iterated several times and the number of iterations increases every time listening() function is being called?
const board = document.querySelector('#board');
let color = 'black';
function createSquares(squareSize) {
squareSize = (480/squareSize);
for (i=0; i<Math.pow((480/squareSize), 2); i++) {
const square = document.createElement('div');
square.classList.add('square');
square.style.cssText = `
width: ${squareSize}px;
height: ${squareSize}px;
background-color: transparent;`;
board.appendChild(square);
};
}
function listening(color) {
if (color === 'rainbow') {
console.log("rainbow selected");
const squaresAll = document.querySelectorAll('div.square');
squaresAll.forEach((square) => {
square.addEventListener('mouseover', (e) => {
if (e.buttons === 1 || e.buttons === 3) {
console.log(e.currentTarget);
let rainbowColor = "#" + ((1<<24)*Math.random() | 0).toString(16);
e.currentTarget.style.backgroundColor = rainbowColor;
return;
}
})
})
}
else {
console.log("other color selected");
const squaresAll = document.querySelectorAll('div.square');
squaresAll.forEach((square) => {
square.addEventListener('mouseover', (e) => {
if (e.buttons == 1 || e.buttons == 3) {
console.log(e.currentTarget);
e.target.style.backgroundColor = color;
}
})
})
}
}
function resetBoard() {
const squaresAll = document.querySelectorAll('div.square');
squaresAll.forEach((square) => {
square.style.backgroundColor = 'transparent';
})
}
const selectSizeButton = document.querySelector('#selectSizeButton');
selectSizeButton.addEventListener(('click'), () => {
let squareSize = prompt(`Enter the number of squares per side of a grid`, "50");
const squaresAll = document.querySelectorAll('div.square');
squaresAll.forEach((square) => {
square.remove();
});
createSquares(squareSize);
})
const resetButton = document.querySelector('#resetButton');
resetButton.addEventListener(('click'), resetBoard);
const rainbowButton = document.querySelector('#rainbowButton');
rainbowButton.addEventListener(('click'), function() { listening('rainbow');});
createSquares(30);
listening(color);
body {
margin: 0 auto;
display: flex;
justify-content: flex-start;
align-items: center;
width: 100vw;
height: 100vh;
flex-direction: column;
}
.controls {
width: 480px;
height: 50px;
flex: 0 0 auto;
background-color: aquamarine; /*to be deleted*/
margin-top: 10vh;
margin-bottom: 5vh;
display: flex;
align-items: center;
justify-content: center;
}
#board {
width: 480px;
height: 480px;
flex: 0 0 auto;
background-color:#f5f0ff;
display: flex;
flex-flow: row wrap;
margin: 0;
padding: 0;
}
.square {
border-color:#d7d3e1;
border-style: solid;
box-sizing: border-box;
border-width: 1px;
padding: 0;
margin: 0;
flex: 0 0 auto;
}
<!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>Etch-a-Sketch</title>
<script src="./script.js" defer></script>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="controls">
<button id="selectSizeButton">Change size</button>
<button id="resetButton">Reset</button>
<button id="rainbowButton">Rainbow mode</button>
</div>
<div id="board">
</div>
</body>
</html>
You have addEventListener inside an event listener - every time you click, you add another listener
Please delegate, it makes everything so much simplerr
const board = document.getElementById('board');
const controls = document.querySelector('.controls');
let color = 'black';
let rainbow = false;
controls.addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.matches("#selectSizeButton")) {
let squareSize = prompt(`Enter the number of squares per side of a grid`, "50");
const squaresAll = document.querySelectorAll('div.square');
squaresAll.forEach((square) => {
square.remove();
});
createSquares(squareSize);
} else if (tgt.matches("#resetButton")) {
board.querySelectorAll(".square").forEach((square) => {
square.style.backgroundColor = 'transparent';
})
} else if (tgt.matches("#rainbowButton")) {
rainbow = !rainbow;
if (rainbow) {
console.log("rainbow selected");
} else {
console.log("other color selected");
}
}
})
board.addEventListener("mouseover", function(e) {
const tgt = e.target;
if (e.buttons === 1 || e.buttons === 3) {
//console.log(e.currentTarget);
color = rainbow ? "#" + ((1 << 24) * Math.random() | 0).toString(16) : color;
tgt.style.backgroundColor = color;
}
})
const createSquares = squareSize => {
squareSize = (480 / squareSize);
console.log(squareSize );
for (i = 0; i < Math.pow((480 / squareSize), 2); i++) {
const square = document.createElement('div');
square.classList.add('square');
square.style.cssText = `
width: ${squareSize}px;
height: ${squareSize}px;
background-color: transparent;`;
board.appendChild(square);
};
};
createSquares(10);
body {
margin: 0 auto;
display: flex;
justify-content: flex-start;
align-items: center;
width: 100vw;
height: 100vh;
flex-direction: column;
}
.controls {
width: 480px;
height: 50px;
flex: 0 0 auto;
background-color: aquamarine;
/*to be deleted*/
margin-top: 10vh;
margin-bottom: 5vh;
display: flex;
align-items: center;
justify-content: center;
}
#board {
width: 480px;
height: 480px;
flex: 0 0 auto;
background-color: #f5f0ff;
display: flex;
flex-flow: row wrap;
margin: 0;
padding: 0;
}
.square {
border-color: #d7d3e1;
border-style: solid;
box-sizing: border-box;
border-width: 1px;
padding: 0;
margin: 0;
flex: 0 0 auto;
}
<div class="controls">
<button id="selectSizeButton">Change size</button>
<button id="resetButton">Reset</button>
<button id="rainbowButton">Rainbow mode</button>
</div>
<div id="board">
</div>
As I'm trying to make a carousel that rotates I wonder how to move the cards rotated and it scales from a minimum of 0.8(left and right cards) and a maximum scale of 1(center card) when the user keeps swiping
Scale:
left = 0.8
center = 1
right = 0.8
I'm trying to solve on how to rotate them using transform and z-index properties. The cards will also rotate however I'm still trying to make a formula on how to make a function that makes the cards rotate
Any alternative solutions are accepted The animation is
similar to this carousel from codepen however it doesn't swipe Carousel Rotate
const CONTAINER_FLEX = document.querySelector('.container-flex');
const items = document.querySelectorAll('.item');
let touchStartX = 0;
let touchMoveX = 0;
let count = 0;
let current_translate = 0;
let previous_translate = 0;
CONTAINER_FLEX.addEventListener('touchstart', (event) => {
touchStartX = event.touches[0].pageX;
});
CONTAINER_FLEX.addEventListener('touchmove', (event) => {
touchMoveX = event.touches[0].pageX;
current_translate = previous_translate + (touchMoveX - touchStartX);
console.log(current_translate);
items[1].style.transform = `translateX(${current_translate}px)`;
});
CONTAINER_FLEX.addEventListener('touchend', () => {
current_translate = touchMoveX - touchStartX;
previous_translate = current_translate;
});
*,
::before,
::after {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
font-family: Arial, Helvetica, sans-serif;
line-height: 1.5;
background-color: #131b24;
}
.main-container {
padding: 30px 0;
height: 300px;
width: 900px;
border-top: 1px solid #444;
border-bottom: 1px solid #444;
overflow: hidden;
background-color: white;
}
.container-flex {
height: 100%;
display: flex;
transition: transform 400ms cubic-bezier(0.165, 0.84, 0.44, 1);
}
.item {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
min-width: 300px;
max-width: 300px;
}
.item h1 {
font-size: 40px;
color: white;
}
/* ITEMS */
.item-1 {
background-color: #2c3e50;
transform: translateX(100px);
z-index: 1;
}
.item-2 {
background-color: #3498db;
z-index: 2;
}
.item-3 {
background-color: #1abc9c;
transform: translateX(-100px);
z-index: 1;
}
<div class="main-container">
<div class="container-flex" id="container-flex">
<div class="item item-1">
<h1>1</h1>
</div>
<div class="item item-2">
<h1>2</h1>
</div>
<div class="item item-3">
<h1>3</h1>
</div>
</div>
</div>
Here is a working example https://jsfiddle.net/4ue5sgm9/3/
I wonder how to move the cards when it goes from 0 to 200 however
Have all your cards in an array.
var cards = [ thing1, thing2, thing3];
Use % - modulus operator, it's the secret for cycling back to the beginning
cardIndex = (cardIndex + 1) % cards.length
Copied from the chat. I made it verbose for clarity
scrollLeft() {
nextIndex = items.indexOf(displayed[2])
nextIndex = ++nextIndex % items.length-1
displayed = items[nextIndex]
nextIndex = ++nextIndex % items.length-1;
displayed.push( items[nextIndex] );
nextIndex = ++nextIndex % items.length-1;
displayed.push( items[nextIndex] )
}
P.S. Write and iterator for items array. An iterator stops after the last item. An iterator is why "for (x in thisArray)" works. BUT write the next() function to return "% this.length-1" instead => now you have a never-ending looper. All that code just above goes away.
I'm having issue with creating loop inside carousel so it will go back to first card after reaching last one on a click event - rightButton.
So far carousel stops when reach last card.
const carousel = document.querySelector("[data-target='carousel']");
const card = carousel.querySelector("[data-target='card']");
const leftButton = document.querySelector("[data-action='slideLeft']");
const rightButton = document.querySelector("[data-action='slideRight']");
const carouselWidth = carousel.offsetWidth;
const cardStyle = card.currentStyle || window.getComputedStyle(card)
const cardMarginRight = Number(cardStyle.marginRight.match(/\d+/g)[0]);
const cardCount = carousel.querySelectorAll("[data-target='card']").length;
let offset = 0;
const maxX = -((cardCount / 3) * carouselWidth +
(cardMarginRight * (cardCount / 3)) -
carouselWidth - cardMarginRight);
leftButton.addEventListener("click", function() {
if (offset !== 0) {
offset += carouselWidth + cardMarginRight;
carousel.style.transform = `translateX(${offset}px)`;
}
})
rightButton.addEventListener("click", function() {
if (offset !== maxX) {
offset -= carouselWidth + cardMarginRight;
carousel.style.transform = `translateX(${offset}px)`;
}
})
.wrapper {
height: 100px;
width: 432px;
position: relative;
overflow: hidden;
margin: 0 auto;
}
.button-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
}
.carousel {
margin: 0;
padding: 0;
list-style: none;
width: 100%;
display: flex;
position: absolute;
left: 0;
transition: all 1s ease;
}
.card {
background: black;
min-width: 100px;
height: 100px;
margin-right: 1rem;
display: inline-block;
}
span {
color:#ffffff;
}
<div class="wrapper">
<ul class="carousel" data-target="carousel">
<li class="card" data-target="card"><span>1</span></li>
<li class="card" data-target="card"><span>2</span></li>
<li class="card" data-target="card"><span>3</span></li>
<li class="card" data-target="card"><span>4</span></li>
<li class="card" data-target="card"><span>5</span></li>
<li class="card" data-target="card"><span>6</span></li>
<li class="card" data-target="card"><span>7</span></li>
<li class="card" data-target="card"><span>8</span></li>
<li class="card" data-target="card"><span>9</span></li>
</ul>
<div class="button-wrapper">
<button data-action="slideLeft">L</button>
<button data-action="slideRight">R</button>
</div>
</div>
Code available on jsfiddle:
https://jsfiddle.net/2qv6mpb1/
Is there a chance that someone could point me in a proper direction on how to achieve that? I
You need to handle when your offset is equal to the maxX, and reset the offset back to zero.
rightButton.addEventListener("click", function() {
if (offset !== maxX) {
offset -= carouselWidth + cardMarginRight;
carousel.style.transform = `translateX(${offset}px)`;
} else {
offset = 0;
carousel.style.transform = `translateX(${offset}px)`;
}
})
This will use fixed widths with a gap of 10px (see CSS) - (to make it responsive you should modify the px used in JS to translate in % steps).
Also, it will work for any number of .Carousel elements on the page.
Also, simplify the HTML markup as per below, which is more consistent with the CSS for a better modular methodology
const Carousel = (EL) => {
const CARDS = EL.querySelector(".Carousel-cards");
const PREV = EL.querySelector(".Carousel-prev");
const NEXT = EL.querySelector(".Carousel-next");
const w = EL.offsetWidth;
const d = CARDS.offsetWidth - w; // widths diff
let x = 0;
const anim = (dir) => {
x += w * dir;
x = Math.min(d, Math.max(0, x));
CARDS.style.transform = `translateX(-${x}px)`;
};
PREV.addEventListener("click", () => anim(-1))
NEXT.addEventListener("click", () => anim(+1))
};
document.querySelectorAll(".Carousel").forEach(Carousel);
.Carousel {
height: 100px;
width: 430px; /* (100px * 4) + (10px * 3gap) */
position: relative;
overflow: hidden;
margin: 0 auto;
}
.Carousel-nav {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
}
.Carousel-cards {
position: absolute;
left: 0;
margin: 0;
padding: 0;
list-style: none;
display: flex;
transition: transform 1s ease;
gap: 10px;
}
.Carousel-cards > * {
background: black;
min-width: 100px;
height: 100px;
}
span {
color: #ffffff;
}
<div class="Carousel">
<ul class="Carousel-cards">
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
<li><span>6</span></li>
<li><span>7</span></li>
<li><span>8</span></li>
<li><span>9</span></li>
</ul>
<div class="Carousel-nav">
<button class="Carousel-prev">L</button>
<button class="Carousel-next">R</button>
</div>
</div>
There's more to improve, i.e: makes no sense to have buttons if the content does not require animating, or one of the buttons depending if a direction is completed.
I have a page where I was using JS - specifically window.pageYOffset - and HTML data to change the inner HTML of the h1 footer, use l1 links to scroll the page to each section, and to add classes to each li when I reached the top of each section.work-page.
However, after I implemented CSS scroll points and added the div.container over the scrollable sections my javascript stopped working. Specifically when I set the overflow-y: scroll.
Basically when I made the div.container overflow-y: scroll; the doWork function stopped working and I can't figure out why.
^^^^ div.container in CSS
const doWork = function () {
const p01Tag = document.getElementById("p01")
const p02Tag = document.getElementById("p02")
const p03Tag = document.getElementById("p03")
const p04Tag = document.getElementById("p04")
const container = document.querySelector("div.container")
const sections = document.querySelectorAll("section.work-page")
const clientTag = document.querySelector("h2.about")
document.addEventListener("scroll", function () {
const pixels = window.pageYOffset
console.log(pixels)
sections.forEach(section => {
if(section.offsetTop - 400 <= pixels) {
clientTag.innerHTML = section.getAttribute("data-client")
if (section.hasAttribute("data-seen-1")) {
p01Tag.classList.add("move")
} else {
p01Tag.classList.remove("move")
}
if (section.hasAttribute("data-seen-2")) {
p02Tag.classList.add("move")
} else {
p02Tag.classList.remove("move")
}
if (section.hasAttribute("data-seen-3")) {
p03Tag.classList.add("move")
} else {
p03Tag.classList.remove("move")
}
if (section.hasAttribute("data-seen-4")) {
p04Tag.classList.add("move")
} else {
p04Tag.classList.remove("move")
}
}
})
})
// scrolling between projects ============================
function smoothScroll(target, duration) {
const targetTag = document.querySelector(target);
let targetPosition = targetTag.getBoundingClientRect().top;
const startPosition = window.pageYOffset;
let startTime = null;
function animation(currentTime) {
if(startTime === null ) startTime = currentTime;
const timeElapsed = currentTime - startTime;
const run = ease(timeElapsed, startPosition, targetPosition, duration);
window.scrollTo(0,run);
if (timeElapsed < duration) requestAnimationFrame(animation)
}
function ease(t, b, c, d) {
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
}
requestAnimationFrame(animation)
}
p01Tag.addEventListener("click", function() {
smoothScroll('section.fn-up', 800)
})
p02Tag.addEventListener("click", function() {
smoothScroll('section.cameron', 800)
})
p03Tag.addEventListener("click", function() {
smoothScroll('section.truax', 800)
})
p04Tag.addEventListener("click", function() {
smoothScroll('section.romero', 800)
})
}
doWork()
const doInfo = function () {
const toggleTag = document.querySelector("a.contact")
const sectionTag = document.querySelector("section.info-page")
toggleTag.addEventListener("click", function () {
sectionTag.classList.toggle("open")
if (sectionTag.classList.contains("open")) {
toggleTag.innerHTML = "Close"
} else {
toggleTag.innerHTML = "Info"
}
})
}
doInfo()
html {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*, *:before, *:after {
-webkit-box-sizing: inherit;
-moz-box-sizing: inherit;
box-sizing: inherit;
}
body {
font-family: 'IBM Plex Mono', monospace;
font-size: 14px;
background-color: #050505;
color: #ffffff;
line-height: 1.1;
}
header {
width: 100%;
z-index: 3;
position: fixed;
top: 0;
left: 0;
padding-top: 40px;
padding-left: 40px;
padding-right: 40px;
}
.contact {
float: right;
}
ul {
font-family: 'IBM Plex Mono', Arial;
font-size: 14px;
}
p {
margin-bottom: 50px;
}
/* Info page -------------------- */
section.info-page {
z-index: 2;
position: fixed;
top: -100vh;
left: 0;
display: flex;
margin-top: 100px;
margin-left: 40px;
margin-right: 40px;
width: 100vw;
min-height: 100vh;
max-width: 100vw;
transition: top 0.5s;
}
section.info-page.open {
top: 0;
}
/* Work page ------------------------*/
div.container {
top: 0;
left: 0;
max-width: 100vw;
max-height: 100vh;
/* WHEN WE ADD THIS OVERFLOW SETTING IN ORDER TO GET THE CSS SCROLL SNAP POINTS TO WORK IT BREAKS THE JAVASCRIPT */
/* overflow-y: scroll; */
scroll-snap-type: y mandatory;
position: relative;
z-index: 1;
}
div.work-info {
width: 13vw;
top: 0;
left: 0;
height: 100vh;
position: fixed;
z-index: 2;
padding-right: 80px;
display: flex;
align-items: center;
margin-left: 40px;
}
div.work-info li {
padding-bottom: 30px;
transition: transform 0.3s;
}
div.work-info li.move {
transform: translateX(15px);
}
footer {
width: 100%;
z-index: 1;
position: fixed;
bottom: 0;
left: 0;
padding-left: 40px;
padding-right: 40px;
padding-bottom: 40px;
color: #979797;
}
section.work-page {
scroll-snap-align: start;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
position: relative;
}
section.work-page img {
max-width: 60vw;
}
<body>
<!-- hidden modal that runs off of the info.js script -->
<section class="info-page">
<h1>
Hello
</h1>
</section>
<header>
<a class="contact" href="#">Info</a>
</header>
<!-- objects that get new classes with javascript on pageYOffset -->
<div class="work-info">
<ul>
<li id="p01" data-number="FN-UP Magazine">01</li>
<li id="p02" data-number="Cameron Tidball-Sciullo">02</li>
<li id="p03" data-number="Jacob Truax">03</li>
<li id="p04" data-number="Alexander Romero">04</li>
</ul>
</div>
<!-- scollable sections using the scroll points and triggering the pageYOffset -->
<div class="container">
<section class="work-page fn-up" data-client="FN-UP Magazine" data-seen-1="yes">
<div class="content">
<img src="lib/fn-up.png">
</div>
</section>
<section class="work-page cameron" data-client="Cameron Tidball-Sciullo" data-seen-2="yes">
<div class="content">
<img src="lib/alex.png">
</div>
</section>
<section class="work-page truax" data-client="Jacob Truax" data-seen-3="yes">
<div class="content">
<img src="lib/old.png">
</div>
</section>
<section class="work-page romero" data-client="Alexander Romero" data-seen-4="yes">
<div class="content">
<img src="lib/alex.png">
</div>
</section>
</div>
<footer class="footer">
<h2 class="about">FN-UP Magazine</h2>
</footer>
</body>
You have added a event listener to the page's Document object.
document.addEventListener("scroll", function () {
Then you calculate the number of pixels the document is currently scrolled along the vertical axis using window.pageYOffset.
const pixels = window.pageYOffset
When you set the CSS attribute overflow-y to scroll in the div.container element, new scrollbars appears on the window. According to MDN:
scroll
Content is clipped if necessary to fit the padding box. Browsers display scrollbars whether or not any content is actually clipped. (This prevents scrollbars from appearing or disappearing when the content changes.) Printers may still print overflowing content.
From that moment on, you are not scrolling the document, you are scrolling div.container. That won't trigger you scroll event.
You need to bound the event to the div element:
const container = document.querySelector("div.container")
container.addEventListener("scroll", function () {
And, instead of calculating how much document has scrolled, get the scrollTop property of the div.container:
const pixels = container.scrollTop
You need to make the same changes in whatever part of the code that involves the above calculations. In smoothScroll():
// const startPosition = window.pageYOffset;
const startPosition = container.scrollTop;
// window.scrollTo(0,run);
container.scrollTo(0,run);