On scroll progress bar move without using overflow css? - javascript

I have a very interesting question.
Actually, everything works fine.
I have one div in which some events when I scroll over this div my progress bar which is placed at the top of the page move.
and I have also done when my cursor on scroll detect my div then my progress bar div show otherwise it remains hidden.
So Finally I want there is no overflow on my div but when I scroll window over this my progress bar move.
Here, Is my code please review it and help will be appreciated.
$('#slide').scroll(function () {
var scroll = $(this).scrollTop();
var scroll_height = $(this).get(0).scrollHeight;
var height = $(this).height();
var percent = scroll / (scroll_height - height) * 100;
$("#progressbar").attr('value', percent);
});
$(window).scroll(function() {
if(isOnScreen($("#slide"))){
$("#progressbar").show();
console.log("dikhgya");
} else {
$("#progressbar").hide();
console.log("nhi");
}
});
var para = document.createElement("Progress");
para.setAttribute('id', 'progressbar');
para.setAttribute('value', 0);
para.setAttribute('max', 100);
document.getElementById("slide").appendChild(para);
progress {
height: 6px;
top: 46px;
left: 0px;
width: 100%;
/* bottom: 1326px; */
position: fixed;
margin-left: -1px;
margin-top: -1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div type="timeline" id="slide">
<section>
<header>Title one</header>
<article> Content</article>
</section>
<section>
<header>Title two</header>
<article> Content</article>
</section>
<section>
<header>Title three</header>
<article> Content</article>
</section>
<section>
<header>Title four</header>
<article> Content</article>
</section>
</div>

From what I understand is you want to scroll the page but not display scroll bar for this but rather a progress bar.
I have created a fiddle
https://jsfiddle.net/xpvt214o/8059/
<div id="timeline-wrapper" >
<div type="timeline" id="slide">
<section>
<header>Title one</header>
<article> Content</article>
</section>
</div>
</div>
In css you have to add properties overflow:hidden to timeline-wrapper and overflow:auto to slide. Then add padding-right:16px to slide where 16px is width of scrollbar in webkit based browsers.
#timeline-wrapper {
height: 100%;
width: 100%;
overflow: hidden;
}
#slide {
width: 100%;
height: 99%;
overflow: auto;
padding-right: 16px;
}
In this fiddle I have removed scroll bar and scrolling is portrayed by progress bar.
Hope this answers your question!!

Related

Fade in fade out images with scroll then scroll page content

When my page loads there is an image that will appear. What I want to do is on scroll, fade out that image and fade in another image. While this animation is happening, I don't want the images to be scrolled up. It's only when the second image has faded in completely that I want to be able to scroll to the content that follows on the page.
I used this answer to come up with part of a solution.
html
<body>
<div id="container">
<div id="mainImg">
<img src="images/1.png" style="height: 100%">
</div>
<div id="brandStatement">
<img src="images/2.png" style="height: 100%">
</div>
</div>
<img src="images/map.png">
<script type="text/javascript" src="main.js"></script>
</body>
js
let locked = false,
mainImage = document.getElementById('mainImg'),
brandStatement = document.getElementById('brandStatement');
window.addEventListener('scroll', function() {
if (!locked) {
window.requestAnimationFrame(function() {
brandStatement.style.opacity = Math.min(window.scrollY / window.innerHeight, 1);
if (brandStatement.style.opacity === '1') {
// scroll to next content
}
locked = false;
});
}
locked = true;
});
css
#container {
height: 200vh;
width: 100%;
}
#mainImg {
text-align: center;
width: 100%;
height: 100%;
position: fixed;
}
#brandStatement {
text-align: center;
width: 100%;
height: 100%;
position: fixed;
opacity: 0;
}
I didn't see a possible solution to the problem by improving your code. This is a personal approach.
What I'm doing here, is changing the opacity of the element one inside the cover container as the user scrolls down the page, revealing the image below. After the opacity changes have been done, the script will change the filling container display style property from none to block. This element is just meant to fill the upper side of the cover container to prevent it from moving up when the position style property is changed from fixed to null.
And the reversed logic applies when scrolling back up.
const one = document.getElementById('one')
const cover = document.getElementById('cover')
const filling = document.getElementById('filling')
window.addEventListener('scroll', () => {
let scrollY = window.scrollY
let bottomHeight = window.innerHeight
if(scrollY / bottomHeight <= 1){
one.style.opacity = 1 - ( scrollY / bottomHeight )
cover.style.position = 'fixed'
filling.style.display = 'none'
}
else{
cover.style.position = null
filling.style.display = 'block'
}
})
*{padding:0;margin:0;border-size: border-box}
body{
height: 3500px;
}
img {
width: 100%;
height: 100vh;
}
#filling{
height:100vh;
width:100%
}
#cover{
height:100vh;
width:100%;
}
#cover > div{
height:100vh;
width:100%;
position:absolute;
}
#one{
z-index:2;
}
#two{
z-index:1;
}
<body>
<div id='filling' style='display:none'>
</div>
<div id='cover' style='position:fixed'>
<div id='one'>
<img src='https://picsum.photos/id/200/1000/1000'>
</div>
<div id='two'>
<img src='https://picsum.photos/id/201/1000/1000'>
</div>
</div>
<div>
<img src='https://picsum.photos/id/206/1000/1000'>
</div>
<div style='margin-top:-10px'>
<img src='https://picsum.photos/id/204/1000/1000'>
</div>
<div style='margin-top:-10px'>
<img src='https://picsum.photos/id/208/1000/1000'>
</div>
</body>

How to set dynamic height of parent(relative) based on height of responsive images in absolute container

I have a relative parent element that has multiple absolute child elements which wraps and adds rows of the images inside at bottom when the screen gets smaller. I wanted to achieve a height that resizes according to the height of its child element. However, my jquery code keeps adding the value on top of each other when resizing resulting in a large number. How can I achieve a height that changes when the window resizes and just get the last value.
Tried logging it on the console. Seems to work fine. However, what I wanted is just to get the last value and assign it as height when the window resizes.
http://evertaste-lislam.ga/ <--- This is the website im working with. Its the image gallery in the homepage.
$(window).resize(function () {
var pgContHeight = $('.pg-container').height();
var windowWidth = $(window).width();
if (windowWidth >= 992) {
pgContHeight *= 2; //<--Number of rows multiplied by height of image//
} else if (windowWidth <= 991 && windowWidth >= 768) {
pgContHeight *= 3;
} else if (windowWidth <= 767 && windowWidth >= 601) {
pgContHeight *= 4;
} else if (windowWidth <= 600) {
pgContHeight *= 8;
}
$('.photo-gallery-container').css('height', +pgContHeight + 'px');
})
$(window).trigger('resize');
})
.photo-gallery-container {
position: relative;
margin-top: 100px;
}
.photo-gallery-row-1 {
display: flex;
flex-flow: wrap;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.pg-container {
width: 25%; //**Width changes via media queries**//
position: relative;
}
.pg-container img {
max-width: 100%;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="photo-gallery-container">
<div class="photo-gallery-row-1"> <!-- I have 3 of these positioned absolute -->
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src=//via.placeholder.com/350x150>
</div>
<div class="pg-container">
<div class="overlay"></div>
<img src='//via.placeholder.com/350x150'>
</div>
</div>
</div>
I'm not sure of what you are trying to accomplish. Is that a responsive images' gallery? If so, you don't necessarily have to use javascript to reach your goal. Do you know the padding bottom tricks? It allows you to define a width and then a height (via the padding bottom) with a ratio to that width (for exemple, you want square images, you need a 1/1 ratio like if your width is 25%, then your padding bottom will be 25%) etc...
I don't necesseraly find the usefullness of javascript here but maybe your absolute positionning is important so I'll wait for some clarification from you. Hope I helped!
.photo-gallery-container {
position: relative;
margin-top:100px;
}
.photo-gallery-row-1{
display: flex;
flex-flow:wrap;
top:0;
bottom:0;
left:0;
right:0;
margin: -1%;
}
.pg-container {
margin: 1%;
width: 23%;
height: 0;
padding-bottom: 25%;
position: relative;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-image: url('//via.placeholder.com/350x150');
}
#media screen and (max-width:40rem) {
.pg-container {
width: 31%;
padding-bottom: 31%;
}
}
/*Etc....*/
<div class="photo-gallery-container">
<div class="photo-gallery-row-1">
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
<div class="pg-container">
<div class="overlay"></div>
</div>
</div>
</div>
This question got complicated because of the idea behind how the approach was and how it should work in JS. I found out that i can simply use data-filter and just eliminate the idea of using absolute positioning when creating image galleries or portfolio galleries like this.

jQuery full screen section slide left, slide right

I am playing with jquery recently and right now - trying to get animations to work.
Whole idea is basically a fullscreen slider. We have few sections with position absolute and height 100% of the document - in jquery we're playing with z-index. It's quite simply, but I can't figure out how to make a proper slide left and right animations. It's always breaking.
$(document).ready(function() {
var windowWidth = $(window).width();
var slideCount = $('.slide').length;
$('button#next').on('click', function() {
var slideActive = $('.slide.active');
var nextSlide = slideActive.next('.slide');
nextSlide.addClass('active').animate({
'z-index' : '2',
'left' : windowWidth
},500);
slideActive.removeClass('active');
});
});;
body, html {
height: 100%;
position: relative;
}
body {
font-size: 14px;
color: #fff;
}
nav {
position: absolute;
top: 2rem;
right: 2rem;
z-index: 99;
}
section {
height: 100%;
display: flex;
align-items: center;
position: absolute;
right: 0;
left: 0;
}
section#home {
background-color: #2c3e50;
}
section#aboutMe {
background-color: #e74c3c;
}
section#smthElse {
background-color: #1abc9c;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<nav>
<button id="prev">Back</button>
<button id="next">Next</button>
</nav>
<section id="home" class="slide active">
<div class="container">
<p>1</p>
</div>
</section>
<section id="aboutMe" class="slide">
<div class="container">
<p>2</p>
</div>
</section>
<section id="smthElse" class="slide">
<div class="container">
<p>3</p>
</div>
</section>
Before that I tried just by adding class with css defined in .css and animating it (jquery ui) but effect was more or less the same.
All I want to achive is a simple slide functions of my sections.
Example behaviour: http://codepen.io/jibbon/pen/BoisC
Also, I am not looking for ready solutions as I need as simple code as possible to learn and develop it in my way.
Thank you guys!
There are many things that you can improve in your code to achieve what you want.
First, active class is set to a slide but isn't applied any special CSS rule, as you set position: absolute to your divs, you must set z-index to overlap one above other, initializing your app.
Here there is a idea, how to implement what you want:
https://jsfiddle.net/nz2hL6vn/1/

Change colour of fixed text based on underlaying colours

I have a fixed menu that scrolls on top of both light and dark backgrounds.
If the text is white it becomes invisible when on top of white elements. I would like to find a way where the color of the text changes dynamically as I scroll on the page.
My menu:
<div class="nav-wrapper footer-wrapper">
<nav>
<div class="column">
Previous
</div>
<div class="column links">
Next
</div>
</nav>
A working JSFiddle: https://jsfiddle.net/ua06Lbwk/5/
Any ideas?
You can use jQuery to add/remove a css class depending on the height of the divs.
Like this:
HTML:
<nav>
link
</nav>
<div id="element1">
</div>
<div id="element2">
</div>
<div id="element3">
</div>
CSS:
.wrapper {
height: 100px;
}
nav {
position: fixed;
width: 100%;
color: white;
text-align: center;
}
#element1 {
height: 50vh;
background-color: gray;
}
#element2 {
height: 20vh;
background-color: white;
}
#element3 {
height: 100vh;
background-color: black;
}
.active {
color:black;
}
jQuery:
$(document).ready(function() {
$(window).scroll(function() {
var element1height = $( "#element1" ).height();
var element2height = $( "#element2" ).height();
var total = element1height + element2height;
var st = $(this).scrollTop();
if( st > element1height ) {
$("nav").addClass("active");
}
else {
$("nav").removeClass("active");
}
if( st > total ) {
$("nav").removeClass("active");
}
});
});
You can use jQuery to get the height of the divs - if the user scrolls past the height of <div id="element1">, it will add a class to <nav> which changes the color of the text within. If the user scrolls past the sum of <div id="element1"> & <div id="element2">'s height - it will remove the class.
JSFiddle Demo

Responsive horizontal page sliding

I want to create horizontal responsive page navigation as illustrated by the below image :
This is what I have managed to do : DEMO
$(document).ready(function () {
var slideNum = $('.page').length,
wrapperWidth = 100 * slideNum,
slideWidth = 100/slideNum;
$('.wrapper').width(wrapperWidth + '%');
$('.page').width(slideWidth + '%');
$('a.scrollitem').click(function(){
$('a.scrollitem').removeClass('selected');
$(this).addClass('selected');
var slideNumber = $($(this).attr('href')).index('.page'),
margin = slideNumber * -100 + '%';
$('.wrapper').animate({marginLeft: margin},1000);
return false;
});
});
html, body {
height: 100%;
margin: 0;
overflow-x:hidden;
position:relative;
}
nav{
position:absolute;
top:0; left:0;
height:30px;
}
.wrapper {
height: 100%;
background: #263729;
}
.page {
float:left;
background: #992213;
min-height: 100%;
padding-top: 30px;
}
#page-1 {
background: #0C717A;
}
#page-2 {
background: #009900;
}
#page-3 {
background: #0000FF;
}
a {
color:#FFF;
}
a.selected{
color: red;
}
.simulate{
height:2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="wrapper">
<nav>
page 1
page 2
page 3
</nav>
<div id="page-1" class="page">
<h3>page 1</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
<div id="page-2" class="page">
<h3>page 2</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
<div id="page-3" class="page">
<h3>page 3</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
</div>
I have however hit a few brick walls, as mine is responsive to a certain degree, its just as you scale it needs to stick to the page its on and not reveal the others.
Also if the pages are long it shows a scroll bar which is perfect, but on the last slide there is a gap as wide as the scroll-bar.
I have the following Requirements:
Needs to be Responsive
pages need to be able to be long (800px) and still scrollable, without the gap on the last one.
needs to work on minimum ie9
Horizontal page sliding
with left-margin animation
This jQuery snippet :
Calculates the number of slides and set the width of the wrapper accordingly.
According to which link is clicked, left-margin is animated on the wrapper to show the corresponding slide with a smooth transition
Toggles the class of the clicked link for active link highlighting
Note that this solution:
Uses only one menu occurence to minimize markup and prevent content repetition.
Requires only the jQuery library
works for a dynamic number of slides
$(document).ready(function() {
var slideNum = $('.page').length,
wrapperWidth = 100 * slideNum,
slideWidth = 100 / slideNum;
$('.wrapper').width(wrapperWidth + '%');
$('.page').width(slideWidth + '%');
$('a.scrollitem').click(function() {
$('a.scrollitem').removeClass('selected');
$(this).addClass('selected');
var slideNumber = $($(this).attr('href')).index('.page'),
margin = slideNumber * -100 + '%';
$('.wrapper').animate({
marginLeft: margin
}, 1000);
return false;
});
});
html,
body {
height: 100%;
margin: 0;
overflow-x: hidden;
position: relative;
}
nav {
position: absolute;
top: 0;
left: 0;
height: 30px;
}
.wrapper {
height: 100%;
background: #263729;
}
.page {
float: left;
background: #992213;
min-height: 100%;
padding-top: 30px;
}
#page-1 {
background: #0C717A;
}
#page-2 {
background: #009900;
}
#page-3 {
background: #0000FF;
}
a {
color: #FFF;
}
a.selected {
color: red;
}
.simulate {
height: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="wrapper">
<nav>
page 1
page 2
page 3
</nav>
<div id="page-1" class="page">
<h3>page 1</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
<div id="page-2" class="page">
<h3>page 2</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
<div id="page-3" class="page">
<h3>page 3</h3>
<div class="simulate">Simulated content heigher than 100%</div>
</div>
</div>
"as you scale it needs to stick to the page its on and not reveal the others"
To achieve this, keep a reference to the current page element and then do a no-delay scrollTo this element when the window is resized:
var currentPage; //here is where we will hold the reference
jQuery('a.scrollitem').click(function () {
var targetPage = $(jQuery(this).attr('href'));
jQuery('a.scrollitem').removeClass('selected');
jQuery(this).addClass('selected');
jQuery('.toggle').css({'display':'none'});
jQuery('.wrapper').scrollTo(targetPage, 1200, function(){
jQuery('.toggle').css({'display':'block'});
});
currentPage = targetPage; //here is where we set the reference
return false;
});
//and here we do a no-delay scrollTo
$(window).resize(function(){
if(!!currentPage){
console.log('window resized. scrolling to: ', currentPage.attr('id'));
jQuery('.wrapper').scrollTo(currentPage);
}
});
This makes it pretty responsive, in my opinion.
pages need to be able to be long (800px) and still scrollable, without the gap on the last one.
To get rid of that gap, I just make all pages a little longer than they need to be. The scrolling is not affected by this since the pages are left-justified with left:0;. I suspect that the other pages had the same gap and and that the gaps on those pages were covered by the scroll bar.
.page {
width: 110%;
}
needs to work on minimum ie9
I'm afraid I can't help in this regard; I have only IE11 installed. But hey, it works great in IE11.
Working fiddle

Categories

Resources