Responsive horizontal page sliding - javascript

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

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>

Hiding scrollbar and making custom scrollbar

So I wanted to make a page like https://www.guillaumetomasi.com/ .How can I hide the scrollbar and make a custom one like that in the page.
With CSS attributes like overflow-x: hidden and overflow-y: hidden you can hide scrollbars.
The custom scrollbar and the scrolling proccess is controlled by Javascript via and events.
The thing is simple and that's, they are not using any scrolling at all, but what you feel is a modified scroll for those slides is actually a slideshow built by JavaScript functionalities. These side slideshow are nowadays in trend and gives you a feel of pseudo scroll. It will be better if you would ask how to achieve that slideshow in a web page instead of that scrolling...
The scroll bar can be hidden with css ::-webkit-scrollbar {width: 0px;}
The custom scroll bar is made with javascript. Here's an example of how it could be done:
window.addEventListener("scroll", function() {
var section1 = document.getElementById("section1");
var section2 = document.getElementById("section2");
var section3 = document.getElementById("section3");
var indicator = document.getElementById("scroll-indicator");
if (window.scrollY < section2.offsetTop ) { // If scroll height is above section 2
indicator.innerText = "1"
}
if (window.scrollY > (section1.offsetTop + section1.offsetHeight)) { // If scrolled past section 1
indicator.innerText = "2"
}
if (window.scrollY > (section2.offsetTop + section2.offsetHeight)) {// If scrolled past section 2
indicator.innerText = "3"
}
});
p {
position: fixed;
right: 15%;
top: 50%;
color: black;
font-size: 24px;
font-family: arial;
}
::-webkit-scrollbar {
width: 0px; /*This removes the scroll bar*/
}
<div id="section1" style="height: 500px; background-color: lightblue">Scroll Down</div>
<div id="section2" style="height: 500px; background-color: pink">Keep scrolling</div>
<div id="section3" style="height: 500px; background-color: Khaki">Almost there</div>
<p id="scroll-indicator">1</p>

On scroll progress bar move without using overflow css?

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!!

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

Grid of divs that are size of viewport

I want to make a grid of divs that are the size of the viewport. Just to set a few basic variables, lets say I want it to be 7 divs wide and 10 divs high.
Here is a code I have so far to set the div size:
function height() {
var height = $(window).height();
height = parseInt(height) + 'px';
$(".page").css('height',height);
}
$(document).ready(function() {
height();
$(window).bind('resize', height);
});
function width() {
var width = $(window).width();
width = parseInt(width) + 'px';
$(".page").css('width',width);
}
$(document).ready(function() {
width();
$(window).bind('width', width);
});
Right now I just have 2 divs that are stacked on top of each other. One is red and one is black, just so I can see them. I want to be able to put content inside the divs. I also made sure to put
body {
margin: 0px;
}
Later I am going to put some scrolling features with jQuery but for now I just want a way to make the grid.
Edit:
Each individual div is the size of the viewport
Edit:
I used this handy plugin for the scrolling that is much better then a small script at the end of the page
You won't need any javascript for this as it can be easier achieved with just CSS.
HTML
<div id="content1">
Place your content here.
</div>
<div id="content2">
Place your content here.
</div>
<div id="content3">
Place your content here.
</div>
CSS
* {
margin: 0;
}
html, body {
height: 100%;
}
#content1,#content2,#content3 {
min-height: 100%;
height: auto !important; /*min-height hack*/
height: 100%; /*min-height hack*/
}
EXAMPLE 1
All 3 divs have the size of the browser window and of course they adjust accordingly. Also you can add a anchor link to navigate from tab to tab with again just html/css
Go to Main Element
If a navigation like this is something you would like to have then you can have a look on the
EXAMPLE 2
PS: in the example i have separated the css of the boxes just to put different colors but you can have it as i posted it above.
I've also created another fiddle for you, as my first two versions were missing something...You asked for a couple of divs vertically and a couple horizontally.
EXAMPLE 3
This example has 3x2 divs (6 total) but with the same logic you can make them 7x10.
Please don't hesitate to ask if you don't understand anything in the code.
Also i've added a bit of jQuery to make the scrolling more smooth, which is optional, you can just remove it
JavaScript (don't forget to include jQuery)
var $root = $('html, body');
$('a').click(function () {
$root.animate({
scrollLeft: $($.attr(this, 'href')).offset().left,
scrollTop: $($.attr(this, 'href')).offset().top
}, 500);
return false;
});
Hope this helps you
EDIT: You need to include jQuery in your code and also wrap the javascript code with:
$(window).load(function(){
});
I can't tell if you want the div to be the entire size of the screen and then have the overflow scroll - and shoot over to the next panel, or if you want your grid of divs to be the size of the viewport. If it's the second, here is my answer.
fiddle is here:
HTML
<div class="block">01</div>
<div class="block">02</div>
<div class="block">03</div>
<div class="block">04</div>
<div class="block">05</div>
<div class="block">06</div>
<div class="block">07</div>
<div class="block">etc. (to 70)</div>
CSS
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
/* http://www.paulirish.com/2012/box-sizing-border-box-ftw/ */
margin: 0;
}
html {
height: 100%;
background-color: orange;
}
body {
height: 100%;
border: 1px solid blue;
}
.block {
width: 14.285714%%; /* 100/7 */
float: left;
height: 10%; /* 100/10 */
border: 1px solid rgba(255,255,255,.5);
}
Now, If that's not what you wanted, maybe this is.
fiddle is here:
HTML
<div id="content1" class="block">
<h2>block 01</h2>
</div>
<div id="content2" class="block">
<h2>block 02</h2>
</div>
<div id="content3" class="block">
<h2>block 03</h2>
</div>
<div id="content4" class="block">
<h2>block 04</h2>
</div>
<div id="content5" class="block">
<h2>block 05</h2>
</div>
<div id="content6" class="block">
<h2>block 06</h2>
</div>
<div id="content7" class="block">
<h2>block 07</h2>
</div>
<div id="content8" class="block">
<h2>block 08</h2>
</div>
<!-- you'll need 70... ? -->
<nav class="global-nav">
01
02
03
04
05
06
07
08
</nav>
CSS ( a little SASS in here for quickness )
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
}
html, body {
height: 100%;
}
html {
width: 700%;
/* overflow: hidden; */
/*This would hide the scroll bars but I'm leaving them for you to see */
}
.block {
min-height: 100%;
height: auto !important; /*min-height hack*/
height: 100%; /*min-height hack*/
width: 100%/7; /* SASS division to be quick*/
float: left;
border: 1px solid red;
}
.global-nav {
position: fixed;
bottom: 0;
left: 0;
}
.global-nav a {
display: block;
color: black;
}

Categories

Resources