I'm trying to create a seamless looping webpage where the content repeats over and over without having to actually duplicate the divs. I came across a THIS CODEPEN, which is exactly what I was looking for, but the mobile experience is really glitchy and flickers when repositioning to the top of the page.
Any solves for mobile? Or edits to this JS?
See below and thanks!
var doc = window.document,
context = doc.querySelector('.js-loop'),
clones = context.querySelectorAll('.is-clone'),
disableScroll = false,
scrollHeight = 0,
scrollPos = 0,
clonesHeight = 0,
i = 0;
function getScrollPos () {
return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}
function setScrollPos (pos) {
context.scrollTop = pos;
}
function getClonesHeight () {
clonesHeight = 0;
for (i = 0; i < clones.length; i += 1) {
clonesHeight = clonesHeight + clones[i].offsetHeight;
}
return clonesHeight;
}
function reCalc () {
scrollPos = getScrollPos();
scrollHeight = context.scrollHeight;
clonesHeight = getClonesHeight();
if (scrollPos <= 0) {
setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
}
}
function scrollUpdate () {
if (!disableScroll) {
scrollPos = getScrollPos();
if (clonesHeight + scrollPos >= scrollHeight) {
// Scroll to the top when you’ve reached the bottom
setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
disableScroll = true;
} else if (scrollPos <= 0) {
// Scroll to the bottom when you reach the top
setScrollPos(scrollHeight - clonesHeight);
disableScroll = true;
}
}
if (disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering
window.setTimeout(function () {
disableScroll = false;
}, 40);
}
}
window.requestAnimationFrame(reCalc);
context.addEventListener('scroll', function () {
window.requestAnimationFrame(scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(reCalc);
}, false);
// Just for this demo: Center the middle block on page load
window.onload = function () {
setScrollPos(Math.round(clones[0].getBoundingClientRect().top + getScrollPos() - (context.offsetHeight - clones[0].offsetHeight) / 1));
};
html,
body {
height: 100%;
overflow: hidden;
}
.Loop {
position: relative;
height: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
section {
position: relative;
text-align: center;
min-height: 100vh;
max-height: 100vh;
height: 100%;
}
::scrollbar {
display: none;
}
body {
font-family: "Avenir Next", Helvetica, sans-serif;
font-weight: normal;
font-size: 100%;
}
.red {
background: #FF4136;
}
.green {
background: #2ECC40;
}
.blue {
background: #0074D9;
}
.orange {
background: rebeccapurple;
}
h1 {
margin: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
font-size: 80px;
letter-spacing: 5px;
color: #fff;
text-transform: uppercase;
}
<main class="Loop js-loop">
<section class="green">
<h1>FIRST</h1>
</section>
<section class="red">
<h1>For</h1>
</section>
<section class="blue">
<h1>All</h1>
</section>
<section class="orange">
<h1>And</h1>
</section>
<section class="blue">
<h1>All</h1>
</section>
<section class="red">
<h1>LAST</h1>
</section>
<!--
These blocks are the same as the first blocks to get that looping illusion going.
You need to add clones to fill out a full viewport height.
-->
<section class="green is-clone">
<h1>FIRST</h1>
</section>
<section class="red is-clone">
<h1>For</h1>
</section>
</main>
Related
So this is my first time ever posting on stackoverflow, Usually I'm simply scouring for an answer I need , however this time after long time of searching for solutions and trying out different solutions, I've decided to try and ask some of the smart people on stackoverflow , I'm simply unable to make an image inside of a carousel to be clickable and lead to an address inside of its "href" link , on any computer this works correctly, however on the mobile phone it's just not .
I'm stumped i don't know if its related to an touch event handler+touchfingerpress event , or to it being inside of a carousel div overlapping, tried clearfix class, tried, different solutions, so far no luck lol.
this is the entire code with placeholder links for images and the rest, but you can see the mechanism none the less in this live w3space fiddle : https://menk-s-space.w3spaces.com/carousel.html
or the entire link in plain:
thanks for the helpers. I would love to learn and improve!
<!-- partial:index.partial.html -->
<div class="bootstrap-iso clearfix">
<div id="slider9" class="slider9 clearfix">
<div id="slide9r" class="slide9r clearfix d-flex aligns-items-center justify-content-center" >
<div class="wrapper9 clearfix" >
<div id="slide9s" class="slide9s clearfix" >
<span class="slide9 clearfix" >
<div class="gallery">
<a target="_blank" href="portfolio.php">
<img src="portfolio/portfolio1.png" alt="Cinque Terre">
</a>
<div class="desc">portfolio0</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio0</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9 clearfix">
<div class="gallery">
<a target="_blank" href="portfolio1.php">
<img src="portfolio/portfolio2.png" alt="Forest" >
</a>
<div class="desc">portfolio1</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio1</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9">
<div class="gallery">
<a target="_blank" href="portfolio2.php">
<img src="portfolio4.png" alt="Northern Lights">
</a>
<div class="desc">portfolio4</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9">
<div class="gallery">
<a target="_blank" href="portfolio3.php">
<img src="portfolio/portfolio5.png" alt="Mountains">
</a>
<div class="desc">portfolio6</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio5</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<!-- <span class="slide9">slide9 5</span>-->
</div>
</div>
<a id="prev" class="control prev"></a>
<a id="next" class="control next"></a>
</div>
</div>
</div>
<!-- partial -->
<script src="js/script.js"></script>
<style>
#import url("css?family=Roboto");
* {
box-sizing: border-box;
}
text-align: center;
letter-spacing: 0.15em;
font-size: 22px;
}
.slide9r {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 300px;
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
}
.wrapper9 {
position: relative;
width: 400px;
height: 300px;
z-index: 1;
}
.slide9s {
display: flex;
position: relative;
top: 0;
left: -400px;
width: 10000px;
}
.slide9s.shifting {
transition: left 0.2s ease-out;
}
.slide9 {
width: 400px;
height: 300px;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
transition: all 1s;
position: relative;
background: #FFCF47;
border-radius: 2px;
}
.slide9r.loaded .slide9:nth-child(2),
.slide9r.loaded .slide9:nth-child(7) {
/*background: #FFCF47;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(1),
.slide9r.loaded .slide9:nth-child(6) {
/*background: #7ADCEF;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(3) {
/*background: #3CFF96;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(4) {
/*background: #a78df5;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(5) {
/*background: #ff8686;*/
background:#7adcef00;
}
.control {
position: absolute;
top: 50%;
width: 50px;
height: 50px;
background: #fff;
border-radius: 50px;
margin-top: -20px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
z-index: 2;
}
.prev,
.next {
background-size: 22px;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.prev {
background-image: url(ChevronLeft-512.png);
left: -20px;
display: none;
}
.next {
background-image: url(ChevronRight-512.png);
right: -20px;
display: none;
}
.prev:active,
.next:active {
transform: scale(0.8);
}
div.gallery {
margin: 5px;
border: 1px solid #ccc;
float: left;
}
div.gallery:hover {
border: 1px solid #777;
}
div.gallery img {
width: 100%;
height: auto;
}
div.desc {
padding: 15px;
text-align: center;
}</style>
<script>
var slide9r = document.getElementById('slide9r'),
slide9rItems = document.getElementById('slide9s'),
prev = document.getElementById('prev'),
next = document.getElementById('next');
function slide9(wrapper9, items, prev, next) {
var posX1 = 0,
posX2 = 0,
posInitial,
posFinal,
threshold = 100,
slide9s = items.getElementsByClassName('slide9'),
slide9sLength = slide9s.length,
slide9Size = items.getElementsByClassName('slide9')[0].offsetWidth,
firstslide9 = slide9s[0],
lastslide9 = slide9s[slide9sLength - 1],
cloneFirst = firstslide9.cloneNode(true),
cloneLast = lastslide9.cloneNode(true),
index = 0,
allowShift = true;
// Clone first and last slide9
items.appendChild(cloneFirst);
items.insertBefore(cloneLast, firstslide9);
wrapper9.classList.add('loaded');
// Mouse events
items.onmousedown = dragStart;
// Touch events
items.addEventListener('touchstart', dragStart);
items.addEventListener('touchend', dragEnd);
items.addEventListener('touchmove', dragAction);
// Click events
prev.addEventListener('click', function () { shiftslide9(-1) });
next.addEventListener('click', function () { shiftslide9(1) });
// Transition events
items.addEventListener('transitionend', checkIndex);
function dragStart (e) {
e = e || window.event;
e.preventDefault();
posInitial = items.offsetLeft;
if (e.type == 'touchstart') {
posX1 = e.touches[0].clientX;
} else {
posX1 = e.clientX;
document.onmouseup = dragEnd;
document.onmousemove = dragAction;
}
}
function dragAction (e) {
e = e || window.event;
if (e.type == 'touchmove') {
posX2 = posX1 - e.touches[0].clientX;
posX1 = e.touches[0].clientX;
} else {
posX2 = posX1 - e.clientX;
posX1 = e.clientX;
}
items.style.left = (items.offsetLeft - posX2) + "px";
}
function dragEnd (e) {
posFinal = items.offsetLeft;
if (posFinal - posInitial < -threshold) {
shiftslide9(1, 'drag');
} else if (posFinal - posInitial > threshold) {
shiftslide9(-1, 'drag');
} else {
items.style.left = (posInitial) + "px";
}
document.onmouseup = null;
document.onmousemove = null;
}
function shiftslide9(dir, action) {
items.classList.add('shifting');
if (allowShift) {
if (!action) { posInitial = items.offsetLeft; }
if (dir == 1) {
items.style.left = (posInitial - slide9Size) + "px";
index++;
} else if (dir == -1) {
items.style.left = (posInitial + slide9Size) + "px";
index--;
}
};
allowShift = false;
}
function checkIndex (){
items.classList.remove('shifting');
if (index == -1) {
items.style.left = -(slide9sLength * slide9Size) + "px";
index = slide9sLength - 1;
}
if (index == slide9sLength) {
items.style.left = -(1 * slide9Size) + "px";
index = 0;
}
allowShift = true;
}
}
slide9(slide9r, slide9rItems, prev, next);
</script>
Tried clearfix in hopes of a div overlapping but didn't work, tried looking into eventhandlers for touch but i'm not on that level yet.
tried different carousels mechanisms , still didn't work.
tried outside of the carousel , it seemed to work, but than i lose the carousel functionality.
Would love someone to enlighten me , i want for any image in the carousel upon clicking for it to lead to another page within the href address on a mobile phone with a touch screen.
Thanks for the helpers !
Simpler example which causes the same issue:
document.querySelector('p').addEventListener('touchstart', e => {
e.preventDefault()
})
<a href="?123=2">
<p>test</p>
</a>
The problem is a typo in your <style> tag. Change this:
* {
box-sizing: border-box;
}
text-align: center;
letter-spacing: 0.15em;
font-size: 22px;
}
to
* {
box-sizing: border-box;
/* text-align: center;
letter-spacing: 0.15em;
font-size: 22px; */
}
I commented those 3 lines, because it messes the styles, but you can uncomment them if you need them.
Also tested the fix on a CodeSandbox too and it's working.
Furthermore, I added a debounce function for your dragStart so the drag will not interfere with your click event.
...
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
...
const debouncedDragStart = debounce(dragStart, 100);
...
items.addEventListener("touchstart", debouncedDragStart);
I'm looking for a soultion when a section is out of viewport, Locomotive scroll will change the css attributes on another element and when is in viewport, it reverts that back.
I couldn't find a soulution or a topic. basic knowledge of JS. So, appreaciate if someone can help me out to figure this out.
This function from https://stackoverflow.com/a/57279138/3807365 is pretty simple to incorporate on scroll.
function isInView(el) {
const box = el.getBoundingClientRect();
return box.top < window.innerHeight && box.bottom >= 0;
}
Lets try
function isInView(el) {
const box = el.getBoundingClientRect();
return box.top < window.innerHeight && box.bottom >= 0;
}
var div1 = document.querySelector(".div1")
var div2 = document.querySelector(".div2")
window.onscroll = function() {
if (isInView(div1)) {
div2.classList.add("active");
} else {
div2.classList.remove("active");
}
if (isInView(div2)) {
div1.classList.add("active");
} else {
div1.classList.remove("active");
}
}
body {
height: 1000px;
}
.div {
width: 50px;
height: 50px;
}
.div1 {
margin-top: 100px;
background: aqua;
margin-bottom: 100px;
}
.div2 {
background: magenta;
}
.active {
border: 2px solid red;
}
<body>
<div class="div div1"></div>
<div class="div div2"></div>
</body>
The title says it all. To see the issue, copy this code to the following online compiler: https://www.w3schools.com/php/phptryit.asp?filename=tryphp_compiler
<!DOCTYPE HTML>
<html>
<style>
/*MAIN*/
* {
margin: 0;
padding: 0;
user-select: none;
overflow: hidden;
}
body {
background-color: #FF0000;
margin: 0;
padding: 0;
}
/*ELEMENTS*/
div {
width: 100vw;
height: 100vh;
float: left;
margin-left: 0vw;
}
h1 {
font-family: verdana;
font-size: 5vh;
text-transform: uppercase;
}
h1.white {
color: #F4F4F4;
}
</style>
<body>
<div id = "main" style = "width: auto; margin-left: 0vw;">
<div id = "home" class = "container" style = 'background-color: #000000;'>
<h1 class = "white">click arrow to see how the next page doesn't appear until after the transition is complete</h1>
<!--ARROW BUTTON-->
<p id = 'arrowButton' style = 'color: #FFFFFF; position: absolute; height: 10vh; width: auto; margin: 45vh 0 0 75vw; font-size: 3vh;' onMouseDown = 'NextButtonClick();'>--></p>
</div>
<div id = "welcome" class = "container" style = 'background-color: #FFFFFF;'>
<h1 style = 'margin: 47.5vh 0 0 50vw'>welcome to my portfolio</h1>
</div>
</div>
<script>
var mainDiv, welcomeDiv;
var transitionSeconds = 0.5;
var isTransitioning = false;
function NextButtonClick() {
if(!isTransitioning) {
isTransitioning = true;
i = 0;
thisInterval = setInterval(function() {
mainDiv.style.marginLeft = (100 / i) - 101 + "vw";
i++;
if(i == 100) {
clearInterval(thisInterval);
mainDiv.style.marginLeft = "-100vw";
isTransitioning = false;
}
}, transitionSeconds);
}
}
window.onload = function() {
mainDiv = document.getElementById("main");
welcomeDiv = document.getElementById("welcome");
var arrowButton = document.getElementById("arrowButton");
var arrowButtonX, arrowButtonY;
var arrowButtonGlowDistance = 100;
arrowButtonX = arrowButton.getBoundingClientRect().left + arrowButton.getBoundingClientRect().width/2;//center
arrowButtonY = arrowButton.getBoundingClientRect().top + arrowButton.getBoundingClientRect().height/2;//center
document.onmousemove = function(e) {
x = e.clientX; y = e.clientY;
};
};
</script>
</body>
</html>
The background is red on purpose so that you can see how, even though the "welcome" div should be rendered over top the background, it is not being rendered until the very last second after the transition is completed and 100% of the element is on the screen.
I am stumped, and I'm not sure why this is since HTML usually doesn't seem to behave this way. Even when I highlight the element in Inspect Element, the Inspector doesn't show me where the element is on the screen until the final moment when it is rendered.
Any help would be greatly appreciated, and I look forward to hearing your feedback!
The problem here is that your DIVs are placed under each other and while one is moving horizontally, the next div is still underneath of it until first one is completely out of the way (just like Jenga game in reverse).
To solve this, you can try add display: flex, to place them horizontally instead:
var mainDiv, welcomeDiv;
var transitionSeconds = 0.5;
var isTransitioning = false;
function NextButtonClick() {
if (!isTransitioning) {
isTransitioning = true;
i = 0;
thisInterval = setInterval(function() {
mainDiv.style.marginLeft = (100 / i) - 101 + "vw";
i++;
if (i == 100) {
clearInterval(thisInterval);
mainDiv.style.marginLeft = "-100vw";
isTransitioning = false;
}
}, transitionSeconds);
}
}
window.onload = function() {
mainDiv = document.getElementById("main");
welcomeDiv = document.getElementById("welcome");
var arrowButton = document.getElementById("arrowButton");
var arrowButtonX, arrowButtonY;
var arrowButtonGlowDistance = 100;
arrowButtonX = arrowButton.getBoundingClientRect().left + arrowButton.getBoundingClientRect().width / 2; //center
arrowButtonY = arrowButton.getBoundingClientRect().top + arrowButton.getBoundingClientRect().height / 2; //center
document.onmousemove = function(e) {
x = e.clientX;
y = e.clientY;
};
};
* {
margin: 0;
padding: 0;
user-select: none;
overflow: hidden;
}
body {
background-color: #FF0000;
margin: 0;
padding: 0;
}
/*ELEMENTS*/
div {
width: 100vw;
height: 100vh;
float: left;
margin-left: 0vw;
display: flex; /* added */
}
h1 {
font-family: verdana;
font-size: 5vh;
text-transform: uppercase;
}
h1.white {
color: #F4F4F4;
}
<div id="main" style="width: auto; margin-left: 0vw;">
<div id="home" class="container" style='background-color: #000000;'>
<h1 class="white">click arrow to see how the next page doesn't appear until after the transition is complete</h1>
<!--ARROW BUTTON-->
<p id='arrowButton' style='color: #FFFFFF; position: absolute; height: 10vh; width: auto; margin: 45vh 0 0 75vw; font-size: 3vh;' onMouseDown='NextButtonClick();'>--></p>
</div>
<div id="welcome" class="container" style='background-color: #FFFFFF;'>
<h1 style='margin: 47.5vh 0 0 50vw'>welcome to my portfolio</h1>
</div>
</div>
I want to make a sliding table that shows the rows from bottom to top contentiously without having a white gap at the beginning or end.
var my_time;
$(document).ready(function() {
setTimeout(function() {
}, 200);
pageScroll();
$("#contain").mouseover(function() {
clearTimeout(my_time);
}).mouseout(function() {
pageScroll();
});
});
function pageScroll() {
var objDiv = document.getElementById("contain");
objDiv.scrollTop = objDiv.scrollTop + 1;
$('p:nth-of-type(1)').html('scrollTop : ' + objDiv.scrollTop);
$('p:nth-of-type(2)').html('scrollHeight : ' + objDiv.scrollHeight);
if (objDiv.scrollTop == (objDiv.scrollHeight - 106)) {
objDiv.scrollTop = -50;
}
my_time = setTimeout('pageScroll()', 25);
}
body {
font-family: 'helvetica';
}
#contain {
height: 100px;
overflow-y: scroll;
}
#table_scroll {
width: 100%;
margin-top: 100px;
margin-bottom: 100px;
border-collapse: collapse;
}
#table_scroll thead th {
padding: 10px;
background-color: #ea922c;
color: #fff;
}
#table_scroll tbody td {
padding: 10px;
background-color: #ed3a86;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="CC">
<table style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Company</th>
</tr>
</thead>
</table>
<div id="contain">
<table border="0" id="table_scroll">
<tbody>
<tr>
<td>User One</td>
<td>0123456789</td>
<td>Company1</td>
</tr>
<tr>
<td>User Two</td>
<td>000550050055</td>
<td>Company2</td>
</tr>
<tr>
<td>Another User</td>
<td>22221323123</td>
<td>Company3</td>
</tr>
<tr>
<td>Some more users.............</td>
<td>......................</td>
<td>...............</td>
</tr>
</tbody>
</table>
</div>
<p></p>
<p></p>
</div>
Currently its working fine, but there is a gap, i want it to be one after another without starting from the bottom or top, like rotating a ball.
hope my question is clear.
Thanks in advance!
I used another example for a different customer. Maybe you can use it:
/*
Ininite looping scroll.
Tested and works well in latest verions of Chrome, Safari and Firefox.
Not built/tested for mobile.
*/
'use strict';
var doc = window.document,
context = doc.getElementsByClassName('js-loop')[0],
clones = context.getElementsByClassName('is-clone'),
disableScroll,
scrollHeight,
scrollPos,
clonesHeight,
i;
function getScrollPos() {
return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}
function setScrollPos(pos) {
context.scrollTop = pos;
}
function getClonesHeight() {
clonesHeight = 0;
i = 0;
for (i; i < clones.length; i += 1) {
clonesHeight = clonesHeight + clones[i].offsetHeight;
}
return clonesHeight;
}
function reCalc() {
window.requestAnimationFrame(reCalc);
scrollPos = getScrollPos();
scrollHeight = context.scrollHeight;
clonesHeight = getClonesHeight();
if (scrollPos <= 0) {
setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
}
}
// Calculate variables
window.requestAnimationFrame(reCalc);
function scrollUpdate() {
if (!disableScroll) {
scrollPos = getScrollPos();
if (clonesHeight + scrollPos >= scrollHeight) {
// Scroll to the top when you’ve reached the bottom
setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
disableScroll = true;
} else if (scrollPos <= 0) {
// Scroll to the bottom when you reach the top
setScrollPos(scrollHeight - clonesHeight);
disableScroll = true;
}
}
if (disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering
window.setTimeout(function () {
disableScroll = false;
}, 40);
}
}
context.addEventListener('scroll', function () {
window.requestAnimationFrame(scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(reCalc);
}, false);
// Just for the demo: Center the middle block on page load
window.onload = function () {
setScrollPos(Math.round(clones[0].getBoundingClientRect().top + getScrollPos() - (window.innerHeight - clones[0].offsetHeight) / 2));
};
html,
body {
height: 100%;
overflow: hidden;
}
.Loop {
position: relative;
height: 100%;
overflow: auto;
}
section {
position: relative;
text-align: center;
min-height: 300px;
max-height: 700px;
height: 80%;
}
.inner-wrap {
animation: autoscroll 10s linear infinite;
}
#keyframes autoscroll {
from { transform: translate3d(0,0,0); }
to { transform: translate3d(0,-75%,0); }
}
::scrollbar {
display: none;
}
body {
font-family: "Avenir Next", Helvetica, sans-serif;
font-weight: normal;
font-size: 100%;
}
.red {
background: #FF4136;
}
.green {
background: #2ECC40;
}
.blue {
background: #0074D9;
}
.orange {
background: rebeccapurple;
}
h1 {
margin: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
font-size: 80px;
letter-spacing: 5px;
color: #fff;
text-transform: uppercase;
}
<main class="Loop js-loop">
<div class="inner-wrap">
<section class="green">
<h1>One</h1>
</section>
<section class="red">
<h1>For</h1>
</section>
<section class="blue">
<h1>All</h1>
</section>
<section class="orange">
<h1>And</h1>
</section>
<section class="blue">
<h1>All</h1>
</section>
<section class="red">
<h1>For</h1>
</section>
<!--
These blocks are the same as the first blocks to get that looping illusion going. You need to add clones to fill out a full viewport height.
-->
<section class="green is-clone">
<h1>One</h1>
</section>
<section class="red is-clone">
<h1>For</h1>
</section>
</div>
</main>
I tried to build a website similar to this. To do this I wrote the following code:
var $window = $(window);
var lastScrollTop = 0;
var shown_elements = 0;
var next_element = 0;
$window.on('scroll', scroll_to_next);
$window.trigger('scroll');
var window_height = $window.height();
var window_top_position = $window.scrollTop();
var window_bottom_position = (window_top_position + window_height);
var scroll = $(window).scrollTop();
function scroll_to_next() {
shown_elements = Math.ceil($(window).scrollTop() / window_height);
next_element = shown_elements * window_height;
if (lastScrollTop < $(window).scrollTop() && lastScrollTop != 0) {
//$window.scrollTop(next_element);
$('html, body').animate({
scrollTop: next_element
}, 'slow');
//alert(next_element);
}
lastScrollTop = $(window).scrollTop();
}
This is the HTML:
<div class="showroom1">
<div class="showroom_left">
<img class="fixed" src="mokups/frame.png">
<img class="screen" src="mokups/screen2.png">
</div>
<div class="showroom_right">
<h3>Hello</h3>
<h4>description</h4>
</div>
</div>
<div class="showroom2">
<div class="showroom_left">
<img class="screen" src="mokups/screen1.png">
</div>
<div class="showroom_right">
<h3>Hello</h3>
<h4>description</h4>
</div>
</div>
<div class="showroom1">
<div class="showroom_left">
<img class="fixed" src="mokups/frame.png">
<img class="screen" src="mokups/screen2.png">
</div>
<div class="showroom_right">
<h3>Hello</h3>
<h4>description</h4>
</div>
</div>
This code runs the first time. And scroll automatically to the second "showroom". But when I try to scroll a second time the page will not scroll.
What is wrong with my code?
I created a JSFiddle a while a go for another question with the same issue. https://jsfiddle.net/8zgsdzy0/
Here is the code:
var lastScrollPos = 0;
var scrollFired = false;
var textConainersElement = jQuery('.text-container p');
var mainElem = jQuery("[data-main='true']");
var firstElem = jQuery("section:first-child");
var lastElem = jQuery("section:last-child");
var wrapper = jQuery(".wrapper");
jQuery(document).on('DOMMouseScroll mousewheel', function(e) {
// if the scroll has occrued already then dont fire it again until transition ended
if (scrollFired == true) {
jQuery(window).scrollTop(lastScrollPos);
return false;
}
var inviewElem = jQuery("[data-inview='true']");
var nextElem = inviewElem.next();
var prevElem = inviewElem.prev();
var currentTop = parseInt(firstElem.attr('data-top'));
if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
// Scrolling down
// if viewed element is last element do nothing
if (inviewElem.index() >= lastElem.index())
return false;
// if main section is inview then scroll through its elements
if (inviewElem.index() == mainElem.index()) {
// if the active child is not the last element then process
var active = jQuery('.text-container .active');
if (active.index() != textConainersElement.length - 1) {
jQuery('.text-container .active').removeClass('active').next().addClass('active');
// Dont scroll further
return false;
}
}
var top = currentTop + 100;
firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
nextElem.attr("data-inview", 'true');
inviewElem.attr("data-inview", 'false');
} else {
// Scrolling up
// if viewed element is first element do nothing
if (inviewElem.index() <= firstElem.index())
return false;
// if main section is inview then scroll through its elements
if (inviewElem.index() == mainElem.index()) {
// if the active child is not the last element then process
var active = jQuery('.text-container .active');
if (active.index() != 0) {
jQuery('.text-container .active').removeClass('active').prev().addClass('active');
// Dont scroll further
return false;
}
}
var top = currentTop - 100;
firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
prevElem.attr("data-inview", 'true');
inviewElem.attr("data-inview", 'false');
}
// Set values to use for next scrolling event
lastScrollPos = jQuery(window).scrollTop();
scrollFired = true;
// reset scrollFired var after transition ended
firstElem.one('transitionend', function() {
scrollFired = false;
});
//prevent page fom scrolling
return false;
});
body {
margin: 0;
}
.wrapper {
display: block;
width: 100%;
height: 100vh;
overflow: hidden;
}
section {
display: block;
width: 100%;
height: 100vh;
border-bottom: 2px dashed black;
position: relative;
transition: all 0.5s;
background-color: #c4c4c4;
}
section[data-inview="true"] {
background-color: #929292;
}
.phone-container {
align-items: center;
background: #dedede none repeat scroll 0 0;
border-left: 5px solid black;
display: flex;
float: right;
height: 100vh;
justify-content: center;
width: 500px;
}
.phone {
width: 200px;
height: 500px;
background: #A6A6A6 none repeat scroll 0 0;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
}
section.long-scroll {
height: auto;
}
p {
margin-top: 80px;
}
p:first-child {
margin-top: 0px;
}
.text-container {
float: left;
width: 200px;
}
.spacer {
display: block;
width: 100%;
}
p.active {
color: #C1E7FF;
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix {
display: inline-block;
}
/* start commented backslash hack \*/
* html .clearfix {
height: 1%;
}
.clearfix {
display: block;
}
/* close commented backslash hack */
.stuck {
position: fixed;
top: 0;
}
.fixed {
position: fixed;
top: 0;
}
.sticky-wrapper {
height: auto !important;
}
.text-container {
padding-left: 40px;
padding-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='wrapper'>
<section data-inview='true' data-top='0'>
Scroll-down
</section>
<section class="long-scroll clearfix" id="pin" data-main='true'>
<div class="text-container">
<p class="active">Text - 1</p>
<p>Text - 2</p>
<p>Text - 3</p>
<p>Text - 4</p>
</div>
<div class="phone-container">
<div class="phone">Slide-1</div>
</div>
</section>
<section id="unhook"></section>
</div>
Please add your function scroll_to_next() to $(window).scroll();
Since you are not capturing the scroll event provided by $(window). So it happens for the first time.
Example
I think the problem is with this line of code:
if (lastScrollTop < $(window).scrollTop() && lastScrollTop != 0)
Specifically
lastScrollTop != 0
The first time the code runs through the variable "lastScrollTop" is set to 0, so the if statement evaluates false and doesn't scroll, but the variables "shown_elements" and "next_element" are changed. The second time you run the code through "lastScrollTop" has been changed but it doesn't work as you would expect as the other variables have been changed.
The solution is probably to change the if statement and change "lastScrollTop != 0".