I have the following code and I want to use ids to switch between slides, but with an id it doesn't work and als with JS scrollTo, scrollIntoView and other variations.
It works on the way down but not up.
I try to make a website which overlaps with itself and creates a nice progressive flow for surveys.
It should also be able to move to a previous slide, so you can enter or change some answer in such a survey.
I hope you can help me and maybe see something which i didn't see.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<div id="s1" class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2" class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3" class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4" class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5" class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6" class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7" class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8" class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9" class="slide">
<h1>Slide 9</h1>
</div>
</body>
</html>
After trying a long time I found a solution but it is very specific.
You need to have a parent element which only includes the slides (in this case it is main), then you need to give the parent element a height and an overflow auto.
After those steps add the javascript, which gets the selected element and its parent (here again main), then calculates the average height per element, after that it gets the index of the elem relative to the parent and multiplies it with the height to get the scrollOffset, which is in the last step set for the parent.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
window.onhashchange = function() {
let hash = document.body.querySelector(location.hash);
let parent = hash.parentElement;
let scrollOffset = parent.scrollHeight / parent.childElementCount;
scrollOffset *= Array.prototype.indexOf.call(parent.children, hash);
parent.scrollTop = scrollOffset;
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
main {
height: 100vh;
overflow: auto;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<main>
<div id="s1" class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2" class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3" class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4" class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5" class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6" class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7" class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8" class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9" class="slide">
<h1>Slide 9</h1>
</div>
</main>
</body>
</html>
Absolutely loved the implentation. Such small css and so powerful effect.
But seems like Browser don't do the # magic with sticky elements. Although this could have been solved with JS, but thought of having a HTML-CSS solution to it by a little tweak in the HTML (adding an extra static element for # reference). Hope you like the solution.
// set color for each slide
window.onload = function() {
let slides = [...document.getElementsByClassName("slide")];
for(let n in slides) {
let slide = slides[n];
slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
}
}
body {
font-size: 3vw;
margin: 0;
padding: 0;
position: relative;
}
#ref {
background-color: black;
position: fixed;
top: 0;
z-index: 1000;
}
#ref a {
color: white;
text-decoration: none;
}
.slide {
background-color: #404050;
border: 1px solid white;
color: white;
height: calc(100vh - 2px);
left: 0;
position: sticky;
top: 0;
width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="ref">
S1
S2
S3
S4
S5
S6
S7
S8
S9
</div>
<div id="s1"> </div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 1</h1>
</div>
<div id="s2"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 2</h1>
</div>
<div id="s3"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 3</h1>
</div>
<div id="s4"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 4</h1>
</div>
<div id="s5"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 5</h1>
</div>
<div id="s6"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 6</h1>
</div>
<div id="s7"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 7</h1>
</div>
<div id="s8"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 8</h1>
</div>
<div id="s9"></div><!--Extra static element for # reference-->
<div class="slide">
<h1>Slide 9</h1>
</div>
</body>
</html>
Related
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
right: 0;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
In the above code snippet, If you click on any item, then it will show a modal on the right side. As you can see, item 3 is larger in width. So if you click on item 3 then you have to scroll-right to view the modal.
So I want to show modal on mouse click position.
How can I do this?
There are at least two options
The first one will spawn the modal directly at the mouse position using JS
And the second one will spawn the modal on the left side. This can be achieved using CSS
First option
So basically you can get the mouse position and set the modal position to it.
In detail remove the top/left/right/bottom properties from the modal class in CSS (they aren't needed) and add some lines of JS.
Please write me in the comments if you want to align the modal a bit around the mouse cursor... It's just about a few numbers.
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
var rect = e.target.getBoundingClientRect(); // get some poition, scale,... properties of the item
mousePos.x = e.clientX - rect.left; // get the mouse position relative to the element
mousePos.y = e.clientY - rect.top;
item.querySelector('.modal').classList.toggle('show');
item.querySelector('.modal').style.left = mousePos.x + "px"; // set the modal position to the last stored position
item.querySelector('.modal').style.top = mousePos.y + "px";
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Second option
The second option uses basic CSS to align the modals on the left side - it is much easier to implement and you just have to remove thee left/right/top/bottom property from the modal class and add left:0:
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
var mousePos = {};
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position: relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
background: #4977d0;
left: 0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
Hope I could help :D
You can change the style dynamically and get the position X of your controller, then add the style using JS code.
Also, remove the right 0 from your modal class
let modal = document.querySelector('.modal');
let items = document.querySelectorAll('.item');
items.forEach(fe);
function fe(item, index){
item.addEventListener("click", function(e){
item.querySelector('.modal').style.left = e.clientX + "px";
item.querySelector('.modal').classList.toggle('show');
});
}
.horizontal-scrollable{
display: flex;
flex-direction: column;
padding: 10px;
background-color: #d2d2d2;
overflow-x:auto;
max-width: 450px;
}
.item {
background-color: #a29f9b;
margin: 5px;
padding: 0 5px;
cursor:pointer;
position:relative;
}
.item2{
min-width:500px
}
.item3{
min-width:700px
}
.modal{
display:none;
position: absolute;
top: 100%;
background: #4977d0;
z-index: 100;
}
.modal.show{
display:block;
}
<div class="horizontal-scrollable">
<div class="item item1">
<h1>Item 1</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item2">
<h1>Item 2</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item3">
<h1>Item 3</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
<div class="item item4">
<h1>Item 4</h1>
<div class="modal">
<p>I am modal.</p>
</div>
</div>
</div>
I got this problem that I've been trying to solve for quite a while. Ideally, I would love particles.js to have its "spawn box" stretch down to the bottom the page (7 x viewport as calculated by fullpage.js) so that when scrolling down with fullpage.js, the whole page's content just moves up one slide (hence having particles.js covering the entire height of the website from top to bottom)
This is what I got so far:
CODE
body, html {
margin: 0;
padding: 0;
}
#container {
max-width: inherit;
background: rgb(111, 210, 255);
}
#particles-js {
width: 100%;
height: 100%;
}
.logo {
position: absolute;
top: 50%;
left: 50%;
width: 256px;
height: 256px;
margin-top: -128px;
margin-left: -128px;
z-index: 2;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="PachiSquid">
<title>PachiSquid</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://raw.githubusercontent.com/alvarotrigo/fullPage.js/master/jquery.fullPage.css" rel="stylesheet" type="text/css">
<script src="https://raw.githubusercontent.com/alvarotrigo/fullPage.js/master/jquery.fullPage.js"></script>
<script src="https://raw.githubusercontent.com/VincentGarreau/particles.js/master/particles.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#fullpage').fullpage({
anchors: ['home', 'release', 'about', 'music', 'live', 'shop', 'contact'],
scrollingSpeed: 1000,
})
})
</script>
</head>
<body id="container">
<ul id="menu">
<li data-menuanchor="home">HOME</li>
<li data-menuanchor="release">RELEASE</li>
<li data-menuanchor="about">ABOUT</li>
<li data-menuanchor="music">MUSIC</li>
<li data-menuanchor="live">LIVE</li>
<li data-menuanchor="shop">SHOP</li>
<li data-menuanchor="contact">CONTACT</li>
</ul>
<div id="fullpage">
<div id="particles-js">
<canvas class="particles-js-canvas-el" style="width: 100%; height: 100%;"></canvas>
</div>
<div class="section active" id="section1">
<div class="intro">
<img class="logo" src="https://gdurl.com/7GCM">
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<p>
Release
</p>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<p>
About
</p>
</div>
</div>
<div class="section" id="section4">
<div class="intro">
<p>
Music
</p>
</div>
</div>
<div class="section" id="section5">
<div class="intro">
<p>
Live
</p>
</div>
</div>
<div class="section" id="section6">
<div class="intro">
<p>
Shop
</p>
</div>
</div>
<div class="section" id="section7">
<div class="intro">
<p>
Contact
</p>
</div>
</div>
</div>
<script>
particlesJS("particles-js",{"particles":{"number":{"value":13,"density":{"enable":true,"value_area":1000}},"color":{"value":"#ffffff"},"shape":{"type":"image","stroke":{"width":0,"color":"#000000"},"polygon":{"nb_sides":5},"image":{"src":"https://gdurl.com/0VzA","width":100,"height":100}},"opacity":{"value":0.5,"random":false,"anim":{"enable":false,"speed":1,"opacity_min":0.1,"sync":false}},"size":{"value":41.6,"random":true,"anim":{"enable":false,"speed":40,"size_min":0.1,"sync":false}},"line_linked":{"enable":false,"distance":150,"color":"#ffffff","opacity":0.4,"width":1},"move":{"enable":true,"speed":0.6,"direction":"top","random":false,"straight":false,"out_mode":"out","bounce":false,"attract":{"enable":false,"rotateX":600,"rotateY":1200}}},"interactivity":{"detect_on":"window","events":{"onhover":{"enable":false,"mode":"grab"},"onclick":{"enable":false,"mode":"push"},"resize":true},"modes":{"grab":{"distance":400,"line_linked":{"opacity":1}},"bubble":{"distance":400,"size":40,"duration":2,"opacity":8,"speed":3},"repulse":{"distance":200,"duration":0.4},"push":{"particles_nb":4},"remove":{"particles_nb":2}}},"retina_detect":true});
</script>
</body>
</html>
Basically my idea is: height: 100% is not working due to FullPage.js, so let's set a fixed height.
Here's your JSFiddle: https://jsfiddle.net/MrMavin/0gop9xp9/
Thanks to #Nic from How to get height of entire document with JavaScript?
I have built a slider with jQuery. But there is still a thing missing, I want indicators so the user can switch between the images. This should be possible through the .bullet-points and the .thumbnails img
I don't really find an approach with my special markup, how can I do that?
Here is the code
https://codepen.io/Insane415/pen/yXboEV
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var backgrounds = ["blue", "yellow", "green", "grey"];
i = 1;
var time = 3000;
setInterval(function() {
if (i != 0) {
images[i - 1].removeClass("active");
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
}
if (i == images.length) {
i = 0
}
images[i].addClass("active");
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
$(".slider").css("background-color", backgrounds[i]);
i++;
}, time);
});
.text-holder p {
margin: 0;
}
.slider {
padding: 20px;
margin: 50px;
/*background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHzNrZnq-4-FItozqSu2ZWCBXW4LjWKTlkOOgDlZFj-JtdTuclVQ');*/
background-color: blue;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.thumbnails {
height: 100%;
}
.thumbnails img {
max-width: 50px;
display: block;
margin-bottom: 10px;
}
.text-holder .text {
display: none;
}
/*display active image*/
.active {
display: block!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail {
display: none!important;
}
.bullet-points {
display: block;
text-align: center;
}
.bullet-points a {
font-size: 30px;
text-decoration: none;
color: inherit;
}
/*.image-holder{
max-width: 350px!important;
}
.image-holder img{
max-width: 350px!important;
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<div class="slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" style="display:none;" class="active">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg" style="display:none;">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg" style="display:none;">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg" style="display:none;">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-2">
<div class="thumbnails">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active-thumbnail">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="https://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
</div>
<div class="col-md-6">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h1>Giant Heading 1</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 2</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 3</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 4</h1>
<p>Some more text</p>
</div>
</div>
</div>
</div>
</div>
</div>
You can try something like this.
Create a slider function instead of using as an anonymous function like in your current code.
Bind an on click event to the .thumbnails img and .bullet-points a and you can control the logic in that event.
Create a variable to control current slide so when user jumping from slide to slide, the slideshow shows correctly.
$(document).ready(function() {
var images = [$(".image-holder img:first-child"), $(".image-holder img:nth-of-type(2)"), $(".image-holder img:nth-of-type(3)"), $(".image-holder img:last-child")];
var thumbnails = [$(".thumbnails img:first-child"), $(".thumbnails img:nth-of-type(2)"), $(".thumbnails img:nth-of-type(3)"), $(".thumbnails img:last-child")];
var text = [$(".text-holder .text:first-child"), $(".text-holder .text:nth-of-type(2)"), $(".text-holder .text:nth-of-type(3)"), $(".text-holder .text:last-child")];
var backgrounds = ["blue", "yellow", "green", "grey"];
var i = 0;
var currentSlide = 0;
var time = 3000;
var sliderTimer = setInterval(slider, time);
// slider navigation
$('.bullet-points a, .thumbnails img').click(function(e) {
e.preventDefault();
var pos = $(this).index();
clearInterval(sliderTimer); // stop auto slideshow
sliderTimer = false;
slider(pos);
});
function slider(pos) {
currentSlide = i;
if (typeof(pos) !== 'undefined') {
i = pos;
images[currentSlide - 1].removeClass("active");
text[currentSlide - 1].removeClass("active");
thumbnails[currentSlide - 1].removeClass("active-thumbnail");
}
if (i != 0) {
images[i - 1].removeClass("active");
text[i - 1].removeClass("active");
thumbnails[i - 1].removeClass("active-thumbnail");
}
if (i == images.length) { i = 0 }
images[i].addClass("active");
text[i].addClass("active");
thumbnails[i].addClass("active-thumbnail");
$(".slider").css("background-color", backgrounds[i]);
i++;
if (!sliderTimer) {
sliderTimer = setInterval(slider, time); // start auto slideshow
}
}
});
.text-holder p{margin: 0;}
.slider{
padding:20px;
margin: 50px;
/*background-image: url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTHzNrZnq-4-FItozqSu2ZWCBXW4LjWKTlkOOgDlZFj-JtdTuclVQ');*/
background-color: blue;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.thumbnails{
height: 100%;
}
.thumbnails img{
max-width: 50px;
display: block;
margin-bottom: 10px;
}
.text-holder .text{
display: none;
}
/*display active image*/
.active{
display: block!important;
}
/*hide thumbnail when image is active*/
.active-thumbnail{
display: none!important;
}
.bullet-points{
display: block;
text-align: center;
}
.bullet-points a{
font-size: 30px;
text-decoration: none;
color: inherit;
}
/*.image-holder{
max-width: 350px!important;
}
.image-holder img{
max-width: 350px!important;
}*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="image-holder">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" style="display:none;" class="active">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg" style="display:none;">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg" style="display:none;">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg" style="display:none;">
</div>
<div class="bullet-points">
•
•
•
•
</div>
</div>
<div class="col-md-2">
<div class="thumbnails">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993474/money_gsliha.jpg" class="active-thumbnail">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993472/rap_zduqat.jpg">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/rauch_oikfed.jpg">
<img src="http://res.cloudinary.com/somestuff/image/upload/v1497993471/girls_x07ay8.jpg">
</div>
</div>
<div class="col-md-6">
<div class="text-holder">
<div class="text active">
<p>Lorem Ipsum</p>
<h1>Giant Heading 1</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 2</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 3</h1>
<p>Some more text</p>
</div>
<div class="text">
<p>Lorem Ipsum</p>
<h1>Giant Heading 4</h1>
<p>Some more text</p>
</div>
</div>
</div>
</div>
</div>
</div>
I want to create three boxes with some short text and when you click on one of those boxes, it will expand on the full width of the page and displays the whole content. Then it can be closed by clicking on some kind of icon.
I created a gif so you can see what I mean. GIF
I have so far the basic structure on jsfiddle
When you click on one box it every time opens the box-3 content insted of the content of the clicked box. Also I dont know how to close the open box.
Is the animation you can see in the gif possible with css or does it need javascriptl?
$(".row.boxes-container .box").click(function (e) {
$(".box-content-full").addClass("open");
});
.row.boxes-container{
position:relative;
}
.box:hover{
cursor:pointer;
}
.box-content{
padding:30px;
background-color:#f03939;
}
.box-content-full{
display:none;
width:0%;
transition: width 1s;
}
.box-content-full.open {
position: absolute;
max-width: 100%;
width: 100%;
z-index: 2;
display:block;
transition: width 1s;
}
.box-content-full.open .inner{
padding:30px;
margin-left:15px;
margin-right:15px;
background-color: red;
}
<div class="container">
<div class="row boxes-container">
<div class="box first">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 1</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 1</h3>
</div>
</div>
</div>
<div class="box second">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 2</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 2</h3>
</div>
</div>
</div>
<div class="box third">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 3</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 3</h3>
</div>
</div>
</div>
</div>
</div>
I did not use your html code but tried to get a result as close as possible to your gif:
$('.box').on('click', function() {
var $element = $(this);
var $openElement = $('<div class="absoluteBox"></div>');
$openElement.css('left', $element.position().left);
$openElement.css('right', $element.width());
$element.html($openElement);
$openElement.animate({left : 0, width : $('.wrapper').width()}, 500);
});
.wrapper {
position:relative;
display:inline-block;
}
.box {
background-color:#CC0000;
width:150px;
height:200px;
display:inline-block;
margin-right:10px;
}
.box:last-of-type {
margin-right:0;
}
.absoluteBox {
position:absolute;
background-color:blue;
height:200px;
width:150px;
}
.box:hover {
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="wrapper">
<div class="box"></div>
<div class="box">
</div>
<div class="box"></div>
</div>
I made the opening box blue to be better noticed. This has to be changed via css of course to red.
Updated your fiddle:
EDIT 2:
Now it should reset when you click the box.
P.S. Click the second box for the effect.
P.P.S. The effect displays incorrectly because the page contracts automatically in JSFiddle. ALTHOUGH, if you try it elsewhere and it doesn't work, consider me proven wrong!
EDIT:
Updated answer to expand element that was clicked.
https://jsfiddle.net/bszv7f90/9/
$(".row.boxes-container .box").click(function(e) {
$(this).children().each(function(i) {
if ($(this).attr('class') == 'box-content-full') {
$(this).toggleClass("exp");
}
});
$(".box-content-full").toggleClass("open");
$(".box-content").toggleClass("clicked");
});
.container {
max-width: 600px;
}
.row.boxes-container {
position: relative;
}
.box:hover {
cursor: pointer;
}
.box-content {
padding: 30px;
background-color: #f03939;
}
.box-content-full {
display: none;
width: 0%;
transition: width 1s;
}
.box-content {
padding: 30px;
background-color: #f03939;
}
.box-content.clicked {
display: none;
}
.box-content-full.open {
position: absolute;
max-width: 0%;
width: 0%;
z-index: 2;
display: none;
transition: width 1s;
}
.box-content-full.open.exp {
position: absolute;
max-width: 100%;
width: 100%;
z-index: 2;
display: block;
transition: width 1s;
}
.box-content-full.open .inner {
padding: 30px;
margin-left: 15px;
margin-right: 15px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row boxes-container">
<div class="box first">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 1</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 1</h3>
</div>
</div>
</div>
<div class="box second">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 2</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 2</h3>
</div>
</div>
</div>
<div class="box third">
<div class="box-content-full">
<div class="inner">
<div class="inner-header">
<span class="close">x</span>
</div>
<h3>Box 3</h3>
<p>Lorem ipsum dolem filum</p>
</div>
</div>
<div class="col-md-4">
<div class="box-content">
<h3>Box 3</h3>
</div>
</div>
</div>
</div>
</div>
Now it should expand.
I preserved your code to make a quick copy-paste.
basically I have a function that resizes elements accordingly with jquery triggering the function on end of the resizing of the window.
it works perfectly apart from when I resize the window back to original size, I do not see the same thing as if I refresh the page. Which is weird considering the exact same function is being called.
The problem can be seen live here
The Js:
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms, uniqueId) {
if (!uniqueId) {
uniqueId = "Don't call this twice without a uniqueId";
}
if (timers[uniqueId]) {
clearTimeout (timers[uniqueId]);
}
timers[uniqueId] = setTimeout(callback, ms);
};
})();
$(window).resize(function () {
waitForFinalEvent(function(){
loadcontext();
//...
}, 10, "some unique string");
});
function loadcontext() {
var winwidth = window.innerWidth;
var winheight = window.innerHeight;
<!-- Fixes layout on screens -->
if (winwidth < 1200)
{
$('#blockscontainer').css("left", (winwidth / 2)*-1 );
$('.block').css("width", (winwidth - 30)/ 5 );
$('.block').css("height", (winwidth - 30)/ 7.5 );
$('#blockscontainer').css("width", winwidth -20);
}
else
{
$('#blockscontainer').css("left", (1200 / 2)*-1 );
$('.block').css("width", 1173 / 5 );
}
};
The CSS:
body { margin: 0px; padding: 0px; }
#contentcontain {clear: both; left: 50%; }
#blockscontainer {clear: both; height: 100%; max-width: 1180px; width: 100%; background- color: #EEE; padding: 10px; border-radius: 15px;}
#blockcontext {overflow: auto;width: 100% clear: both; position: relative; height: 100%; background-color: #DDD;border-radius: 7px; padding-bottom: 20px;}
#footer { width: 100%; margin-top: 30px; text-align: center; background-color: #666; }
#content { background-color: #333; padding-top: 50px;}
.block {display: inline-block; height: 150px; width: 200px; background-color: #FFF; float: left; margin-top: 20px; border: 1px solid #CCC;}
The HTML:
<body onload="loadcontext()">
<div id="content">
<div id="contentcontain" align="center">
<div id="blockscontainer">
<div id="blockcontext">
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
<div class="block">
test content
</div>
</div>
</div>
</div>
<center>
<div id="footer">
content
</div>
</center>
</div>
</body>
</html>
When you resize the window below a width of 1200 px, you call these lines:
$('.block').css("height", (winwidth - 30)/ 7.5 );
$('#blockscontainer').css("width", winwidth -20);
These are causing the issue you see, as they aren't reset to any kind of default when you increase the window size back about 1200px wide. This causes the page to look different because the width of #blockscontainer and the height of every .block element has changed.