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>
Related
I am new to html and css. I have seen this question asked many times but I can't seems to get it working to fit my problem .
I have 3 div tags. when the user swipe the top div tag I want the the bottom div tag to increase its height and cause the web page to scroll. then move all the div tags align at the top.
The reason I am doing this is; this will cause webpage running on a mobile to go to full screen.
<div id="backExpander" style="height: 100%; display: inline-block; position: relative;">
</div>
<div id="canvasHolder" style="width: 100%; height: 100%;background-color: transparent;">
<canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
</div>
<div id="swipeUpHolder" style="height: 100%; width: 100%; display:block;" >
</div>
The script I am using is;
document.getElementById("swipeUpHolder").addEventListener('touchmove', onTouchMove, {passive: false});
function onTouchMove(e)
{
e.preventDefault
document.getElementById("backExpander").style.height = "120%";
setTimeout((function() {
document.getElementById("swipeUpHolder").style.display = "none";
window.scrollTo(0, 0);
}
), 50);
}
As you can see I am increasing the height of background div but it does not do anything.
if I increase height of top div, this will work
document.getElementById("swipeUpHolder").style.height = "120%";
But I want to hide the top div. use the bottom div to push the page to go into scroll.
Can anyone provide some advice on how to fix this ?
This is your original code w/ background colors:
document.getElementById("swipeUpHolder").addEventListener('touchmove', onTouchMove, {
passive: false
});
function onTouchMove(e) {
e.preventDefault
document.getElementById("backExpander").style.height = "120%";
setTimeout((function() {
document.getElementById("swipeUpHolder").style.display = "none";
window.scrollTo(0, 0);
}), 50);
}
<div id="backExpander" style="height: 100%; display: inline-block; position: relative; background: blue;">
</div>
<div id="canvasHolder" style="width: 100%; height: 100%;background-color: red;">
<canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
</div>
<div id="swipeUpHolder" style="height: 100%; width: 100%; display:block;">
</div>
This is when you use vh units for your dimension on #backExpander:
document.getElementById("swipeUpHolder").addEventListener('touchmove', onTouchMove, {
passive: false
});
function onTouchMove(e) {
e.preventDefault
document.getElementById("backExpander").style.height = "120%";
setTimeout((function() {
document.getElementById("swipeUpHolder").style.display = "none";
window.scrollTo(0, 0);
}), 50);
}
<div id="backExpander" style="height: 100vh; position: relative; background: blue;">
</div>
<div id="canvasHolder" style="width: 100%; height: 100%; background-color: red;">
<canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
</div>
<div id="swipeUpHolder" style="height: 100%; width: 100%; display:block;">
</div>
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.
I have a scrolling image gallery as follows. The CSS lays out the images in a row that scrolls horizontally. Underneath, I have a row of the same images, but as thumbnails. I want to be able to click on a thumbnail, and scroll the correct image into view.
HTML:
<div class="images_container">
<img id="image_1" src="/image1.jpg">
<img id="image_2" src="/image2.jpg">
<img id="image_3" src="/image3.jpg">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail">
<img src="/image2.jpg" class="thumbnail">
<img src="/image3.jpg" class="thumbnail">
</div>
CSS:
.images_container {
overflow-x: scroll;
overflow-y: hidden;
max-height: 50rem;
white-space: nowrap;
}
.images_container.thumbnails {
max-height: 10rem;
}
.images_container img {
vertical-align: top;
height: 50rem;
}
.images_container.thumbnails img {
height: 10rem;
}
This works up to a point, but jumping to the id of the image is problematic. If the larger image is even a few pixels into the visible viewport, it can't 'jump' to it, as it seems to be technically on the screen.
Is there a way I can use Javascript to 'scroll' the whole image into view when I click on it's corresponding thumbnail? I don't have access to jQuery on this project, but am happy to use JavaScript to make this work.
You can try this , no change in CSS, i add an id in html and call to scrollTo function :
<script>
function scrollTo(image_id){
var topLeft = document.getElementById(image_id).offsetTop;
document.getElementById('container').scrollLeft = topLeft;
}
</script>
<div id="container" class="images_container">
<img id="image_1" src="/image1.jpg" height="500px" width="500px">
<img id="image_2" src="/image2.jpg" height="500px" width="500px">
<img id="image_3" src="/image3.jpg" height="500px" width="500px">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail" onclick="scrollIntoView('image_1')">
<img src="/image2.jpg" class="thumbnail" onclick="scrollIntoView('image_2')">
<img src="/image3.jpg" class="thumbnail" onclick="scrollIntoView('image_3')">
</div>
To keep DOM cleaner I got this solution which requires only adding js
var elms = document.getElementsByClassName("thumbnail");
for (var i = 0; i < elms.length; i++) {
elms[i].onclick = function(event) {
event.preventDefault();
event.stopPropagation();
var id = this.parentNode.href.substr(this.parentNode.href.lastIndexOf('/') + 2);
var v = document.getElementById(id).getBoundingClientRect().left;
document.getElementsByClassName("images_container")[0].scrollLeft += v;
}
}
See on jsfiddle
Here's my attempt at a no (well, minimal) JS solution to a scrolling gallery. You could, in fact, remove the Javascript all together if you replaced the .active class with the :target pseudo-selector, allowing you to click your thumbnails to do the scrolling. It's just easier for me to do it this way through a fiddle
function removeClass(element, className) {
var classes = element.className.split(' ');
var key = classes.findIndex(function(name) {
return name == className
});
classes.splice(key, 1);
element.className = classes.join(' ');
}
function addClass(element, className) {
var classes = element.className.split(' ');
classes.push(className);
element.className = classes.join(' ');
}
setInterval(function() {
var current = document.querySelector('.images .image.active');
var next = current.nextElementSibling;
if (!next) {
next = document.querySelector('.images .image:first-child');
}
removeClass(current, 'active');
addClass(next, 'active');
}, 1500);
body {
margin: 0;
padding: 0;
width: 500px;
height: 500px;
}
.images {
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
}
.image {
width: 100%;
height: 100%;
top: 0px;
position: absolute;
left: -100%;
float: left;
transition: 1s;
}
.image.active {
left: 0%;
}
.image.active ~ .image {
left: 100%;
}
.black {
background-color: black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
<div class='images'>
<div class='image black active'></div>
<div class='image red'></div>
<div class='image blue'></div>
<div class='image yellow'></div>
</div>
Essentially the way it works is by making the div.images container a certain height and width, and therefore all images inside it can be positioned as you want. We initially set all .image to left: -100%, so that they're completely off screen to the left. We then set .image.active as left: 0 so that it's on screen. We then use the ~ selector to say that all siblings that come after the current (.image.current ~ .image) should be left: 100%, so completely to the right. Add in a transition, and you have a completely CSS scrolling gallery. The JS only acts as a way to change what the current active image is, and you can replace that with :target if you want.
I used div's, instead of img tags because it's easier to provide a POC with div's and background colors, but it's worked well with images in the past. Just put an <img> tag inside those <div class='image'></div> tags
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
I'm trying to use jQuery for the first time. I have some images that are loaded via an ajax call (not jQuery related). The page is made the way that if you refresh the page, the images loaded, stay.
I found this code somewhere else:
$(document).ready(function(){
$(".svg_chart").click(function(){
var address = $(this).attr("src");
address = address.replace(\'height=80\', \'height=300\');
$("#popup").fadeIn("slow");
$("#lightbox").attr("src",address);
});
$("#lightbox").click(function(){
$("#popup").fadeOut("fast");
});
});
<div id="popup">
<div id="center">
<img id="lightbox" src="images/blank.jpg" >
</div>
</div>
</div>
The code works fine on images already loaded when the page is loaded, but not on images fetched on the fly with Ajax, although they get the same class added. I guess it is because the doc.ready function only knows about content, after the initial page has loaded.
What can I do to make jQuery know about new content being added?
Dropping jQuery for this. It's overkill and doesn't work!
<img id="svg_1" class="svg_chart" style="float: left" width="49%" ondblclick="expand_me(this.id)" alt="" />
<div id="popup">
</div>
<div id="center">
<img onclick="expand_me(true)" id="lightbox" src="images/blank.jpg" />
</div>
<script type="text/javascript"><!-- // --><![CDATA[
function expand_me(el)
{
if (el !== true)
{
link = document.getElementById(el).src;
link = link.replace(\'height=80\', \'height=300\');
document.getElementById(\'popup\').style.display = "block";
document.getElementById(\'center\').style.display = "block";
document.getElementById(\'lightbox\').src = link;
}
else
{
document.getElementById(\'popup\').style.display = "none";
document.getElementById(\'center\').style.display = "none";
}
}
// ]]></script>
The css part:
#popup
{
background:#000000;
height:100%;
width: 100%;
position:fixed;
top: 0;
left: 0;
display: none;
opacity: 0.9;
}
#center
{
height:100%;
width: 100%;
max-width: 1200px;
position:fixed;
top: 0;
margin: 6% auto;
display: none;
}
#lightbox
{
width: 100%;
cursor: pointer;
}