I have a list of div items which I am filtering/sorting via JS.
Each item animates in to place - in this case, scales up to its final size.
When I filter the items via buttons, anything already on screen DOES NOT play this animation again.
How can I RESET the filter every time a new button is selected, so EVERY item ALWAYS animates in to place no matter what is being filtered and whether or not it is currently on screen?
WORKING CODEPEN HERE
<div class="filter-list">
<button class="active btn" id="all">All</button>
<button class="btn" id="oranges">Oranges</button>
<button class="btn" id="apples">Apples</button>
<button class="btn" id="bananas">Bananas</button>
</div>
<div class="grid">
<div class="artist-img item oranges">oranges</div>
<div class="artist-img item apples">apples</div>
<div class="artist-img item bananas">oranges</div>
</div>
JS
var $items = $(".item");
var $btns = $(".btn").click(function () {
if (this.id == "all") {
$items.show();
} else {
var $el = $("." + this.id).show();
$items.not($el).hide();
}
$btns.removeClass("active");
$(this).addClass("active");
});
CSS
#keyframes entrance {
0% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
.grid > div {
padding: 1rem;
position: relative;
animation-duration: 0.5s;
animation-name: entrance;
}
To reset the elements you have to get them back to the 0% on the animation. The easiest way to do that is to hide them all first. So instead of hiding all the ones that are not currently selected, hide everything first, then show what you want to show after that. Now immediately hiding and showing does not give the time needed for the first element to get back to 0%, so set a timeout for 1 ms to give it time. Here is the modified code:
var $items = $(".item");
var $btns = $(".btn").click(function() {
$items.hide();
setTimeout(() => {
if (this.id == "all") {
$items.show();
} else {
$("." + this.id).show();
}
}, 1);
$btns.removeClass("active");
$(this).addClass("active");
});
button {
padding: 1rem;
}
.filter-list {
margin: 1rem;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1rem;
row-gap;
1rem;
}
.grid>div {
background: #000;
padding: 3rem;
animation-duration: 0.5s;
animation-name: entrance;
color: #fff;
}
#keyframes entrance {
0% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="filter-list">
<button class="active btn" id="all">All</button>
<button class="btn" id="oranges">Oranges</button>
<button class="btn" id="apples">Apples</button>
<button class="btn" id="bananas">Bananas</button>
</div>
<div class="grid">
<div class="artist-img item oranges">
oranges
</div>
<div class="artist-img item apples">
apples
</div>
<div class="artist-img item oranges">
oranges
</div>
<div class="artist-img item oranges">
oranges
</div>
<div class="artist-img item apples">
apples
</div>
<div class="artist-img item bananas">
bananas
</div>
<div class="artist-img item apples">
apples
</div>
<div class="artist-img item bananas">
bananas
</div>
</div>
Does this JS achieve what you want?
var $items = $(".item");
var $btns = $(".btn").click(function () {
if (this.id == "all") {
$items.show();
} else {
$items.hide();
var $el = $("." + this.id).show();
// $items.not($el).hide();
}
$btns.removeClass("active");
$(this).addClass("active");
});
Related
I have a dynamic slider with two buttons left and right.
that means for each slide, the slide parent width increases by 100%. 2 slides * 100% = 200%. In example class="slider"; width:'200%'
I want to center each slide's text in the middle of the page. But i want the text to slide not in just slides container, but in its parent-parent width (class='carousel' in example).
Code below, is example how the slider is looking right now.
JavaScript, you should ignore this. Implemented it, for the code to work.
document.addEventListener('DOMContentLoaded', function() { //Display function after HTML is loaded
const left = document.querySelector('.left');
const right = document.querySelector('.right');
var slider = document.getElementById('slider');
var leftImg = document.getElementById('left');
var rightImg = document.getElementById('right');
var sections = document.querySelectorAll('.slide').length; // get number of slides
var sectionIndex = 1;
slider.style.width = ' ' + 100 * sections + '%';
function changeOpacity() {
if (sectionIndex == 1) {
leftImg.style.opacity = '0.4';
} else {
leftImg.style.opacity = '1';
}
if (sectionIndex == sections) {
rightImg.style.opacity = '0.4';
} else {
rightImg.style.opacity = '1';
}
}
left.addEventListener('click', function() {
var leftImg = document.getElementById('left');
sectionIndex = (sectionIndex > 1) ? sectionIndex - 1 : 1;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
right.addEventListener('click', function() {
sectionIndex = (sectionIndex < sections) ? sectionIndex + 1 : sections;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
})
.slider-container {
padding: 25px 0px;
width: 40%;
margin: auto;
}
.slider-container .carousel {
overflow: hidden;
height: 260px;
width: 100%;
border:solid 2px black;
position:relative;
}
.slider-container .slider {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100%;
-webkit-transition: .5s;
transition: .5s;
}
.slider-container .slider .slide {
width: 100%;
}
.slider-container .arrow-container {
width: 70px;
position: absolute;
bottom: 0;
}
<div class="slider-container mobile-container text-left">
<div class="carousel relative">
<div id="slider" class="slider">
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
</div>
</div>
<div class="controls">
<div class="arrow-container d-flex justify-content-between ">
<div>
<button class="left" id="left" style="opacity: 0.4;">Left </button>
</div>
<div>
<button class="right" id="right">Right</button>
</div>
</div>
</div>
</div>
</div>
The Snippet below is what i want. But i should be centered, and i don't know how.
I have tried using fl
document.addEventListener('DOMContentLoaded', function() { //Display function after HTML is loaded
const left = document.querySelector('.left');
const right = document.querySelector('.right');
var slider = document.getElementById('slider');
var leftImg = document.getElementById('left');
var rightImg = document.getElementById('right');
var sections = document.querySelectorAll('.slide').length; // get number of slides
var sectionIndex = 1;
slider.style.width = ' ' + 100 * sections + '%';
function changeOpacity() {
if (sectionIndex == 1) {
leftImg.style.opacity = '0.4';
} else {
leftImg.style.opacity = '1';
}
if (sectionIndex == sections) {
rightImg.style.opacity = '0.4';
} else {
rightImg.style.opacity = '1';
}
}
left.addEventListener('click', function() {
var leftImg = document.getElementById('left');
sectionIndex = (sectionIndex > 1) ? sectionIndex - 1 : 1;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
right.addEventListener('click', function() {
sectionIndex = (sectionIndex < sections) ? sectionIndex + 1 : sections;
slider.style.transform = 'translate(' + (sectionIndex - 1) * (-100 / sections) + '%)';
changeOpacity();
});
})
.slider-container {
margin: auto;
padding: 25px 0px;
}
.slider-container .carousel {
overflow: hidden;
height: 260px;
width: 80%; /* the width i want */
border: solid 2px black; /* the border for your understading */
position: relative;
}
.slider-container .slider {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100%;
-webkit-transition: .5s;
transition: .5s;
}
.slider-container .slider .slide {
width: 100%;
}
.slider-container .comment {
max-width: 352px;
padding: 30px 0px;
}
.slider-container .arrow-container {
width: 70px;
position: absolute;
bottom: 0;
}
<div class="slider-container mobile-container text-left">
<div class="carousel relative">
<div id="slider" class="slider">
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
<div class="slide">
<div class="author d-flex flex-column">
<h3>Ken Ludden</h3>
<span class="regularText">Director, Margot Fonteyn Academy of Ballet</span>
</div>
</div>
</div>
<div class="controls">
<div class="arrow-container d-flex justify-content-between ">
<div>
<button class="left" id="left" style="opacity: 0.4;">Left </button>
</div>
<div>
<button class="right" id="right">Right</button>
</div>
</div>
</div>
</div>
</div>
</div>
You can see in this snippet that text is sliding from a lot further right than the previous example.
I need to center the slide, because i want the same for left side.
I have tried using flex-column, align-items:center on class="slide". And it works fine, but the class="controls" aren't centering because they are position:absolute and i tried to putting them elsewhere, but it didnt work..
I really hope you guys did understand what i want and really hope that i recieve atleast some suggestions. This is my 1st question, sorry for long code.
Thank you anyway :)
Your carousel is 80% of the width, so if you want that to be centered, you can do: margin: 0 auto on the carousel class.
I have 15 buttons, each button has content, but when I clicked button1 and followed by button 2, the button 1 is still open. How can I close the button 1 if I click button2?
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
div.panel {
position: absolute;
max-width: 0;
overflow: hidden;
opacity: 0;
}
div.panel.show {
opacity: 1;
max-width: 900px;
}
<button class="accordion">The Ball</button>
<div class="panel">
<h1>The Ball</h1>
</div>
<button class="accordion">The Cat</button>
<div class="panel">
<h1>The Cat</h1>
</div>
<button class="accordion">The Dog</button>
<div class="panel">
<h1>The Dog</h1>
</div>
You need to remove active and show classes from previous div before adding them to clicked div.
Your JS Code will be:
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
var previous = document.querySelector(".active"); //select previous button
if (previous) { // check because when first time no button has active class
previous.classList.remove("active");
previous.nextElementSibling.classList.remove("show");
}
this.classList.add("active");
this.nextElementSibling.classList.add("show");
};
}
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
var previous = document.querySelector(".active");
if (previous) {
previous.classList.remove("active");
previous.nextElementSibling.classList.remove("show");
}
this.classList.add("active");
this.nextElementSibling.classList.add("show");
};
}
div.panel {
position: absolute;
max-width: 0;
overflow: hidden;
opacity: 0;
}
div.panel.show {
opacity: 1;
max-width: 900px;
}
<button class="accordion">The Ball</button>
<div class="panel">
<h1>The Ball</h1>
</div>
<button class="accordion">The dog</button>
<div class="panel">
<h1>The dog</h1>
</div>
<button class="accordion">The cat</button>
<div class="panel">
<h1>The cat</h1>
</div>
So select the active one. If it is active remove it. If the current one is not the active class add it.
// select all the buttons
var btns = document.querySelectorAll('.accordion')
// loop over
btns.forEach(function (btn) {
// bind the click
btn.addEventListener('click', function (evt) {
// stop button click
evt.preventDefault()
// find the active one
var active = document.querySelector('.accordion.active')
// see if active button is the clicked button
var isSame = active == btn
// if we have an active button, remove the class
if (active) active.classList.remove('active')
// if the current button was not the active one add the class
if (!isSame) btn.classList.add('active')
})
})
button {
display: block;
}
button + div {
max-height: 0;
transition: max-height 0.25s ease-out;
overflow: hidden;
}
button.active {
background-color: green;
}
button.active + div {
max-height: 500px;
transition: max-height 0.5s ease-in;
}
<button class="accordion">The Ball 1</button>
<div><p>Ball 1</p><p>bounce bounce poounce</p></div>
<button class="accordion">The Ball 2</button>
<div><p>Ball 2</p><p> bounce pop</p></div>
<button class="accordion">The Ball 3</button>
<div><p>Ball 3</p><p>bounce bounce over the fence</p></div>
An alternative using JQuery.
I have changed the CSS to remove max-width and opacity and have set .panel elements to be display: none; initially:
div.panel {
position: absolute;
display: none;
}
And using JQuery, whenever we click an .accordion element, we hide the .panel elements (in case any others are showing), and then show the one that relates to the specifically clicked .accordion element.
// register clicks on accordion elements
$('.accordion').click(function() {
// hide each .panel related to every .accordion element
$('.accordion').next().hide();
// show the .panel next to our clicked .accordion element
$(this).next().show();
})
I need help with my coin flip. Basically what I wanted to do is to create two buttons. By pressing one of them, the player would pick a side, for example Global or Fortune.
I can't figure out how to do it so when the player presses the button it will actually pick a side without refreshing the site.
var result, userchoice;
function resetAll() {
var resetHTML = '<div class="tail"><img src="coin_F.png" /></div><div class="head"><img src="coin_G.png" /></div>';
setTimeout(function() {
$('.coinBox').fadeOut('slow', function() {
$(this).html(resetHTML)
}).fadeIn('slow', function() {
$('#btnFlip').removeAttr('disabled');
});
}, 2500);
}
// Checking User Input
$(document).on('change', '#userChoice', function() {
userchoice = $(this).val();
if (userchoice == "") {
$(this).parent('p').prepend("<span class='text text-danger'>Please select a coin side to play the game</span>")
$('#btnFlip').attr('disabled', 'disabled');
} else {
/**/
$('#btnFlip').removeAttr('disabled');
$(this).siblings('span').empty();
}
return userchoice;
});
// Final result declaration
function finalResult(result, userchoice) {
var resFormat = '<h3>';
resFormat += '<span class="text text-primary">You choose : <u>' + userchoice + '</u></span> |';
resFormat += '<span class="text text-danger"> Result : <u>' + result + '</u></span>';
resFormat += '</h3>';
var winr = '<h2 class="text text-success" style="color: #49DF3E;">You Won!!</h2>';
var losr = '<h2 class="text text-danger" style="color: #c34f4f;">You Lost...</h2>';
if (result == userchoice) {
$('.coinBox').append(resFormat + winr)
} else {
$('.coinBox').append(resFormat + losr)
}
}
// Button Click Actions
$(document).on('click', '#btnFlip', function() {
if ($('#userChoice').val() == "") return;
var flipr = $('.coinBox>div').addClass('flip');
var number = Math.floor(Math.random() * 2);
$(this).attr('disabled', 'disabled');
setTimeout(function() {
flipr.removeClass('flip');
//result time
if (number) {
result = 'Global';
//alert('Head = '+number);
$('.coinBox').html('<img src="coin_G.png" /><h3 class="text-primary">Global</h3>');
finalResult(result, userchoice);
resetAll();
} else {
result = 'Fortune';
//alert('Tail = '+number);
$('.coinBox').html('<img src="coin_F.png" /><h3 class="text-primary">Fortune</h3>');
finalResult(result, userchoice);
resetAll();
}
}, 2000);
return false;
});
#wrapper
{
width: 100%;
height: auto;
min-height: 500px;
}
.btn
{
width: 12%;
background-color: #c34f4f;
color: white;
padding: 14px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 22px;
}
.btn:hover
{
background-color: #A64242;
}
input[type=submit]:hover {
background-color: #A64242;
}
.container
{
padding: 50px 0;
text-align: center;
}
h1
{
margin-bottom: 100px;
}
.head
{
margin-top: -205px;
}
.flip img{animation: flipIt 0.5s linear infinite;}
.head img
{
animation-delay: 0.25s;
}
#keyframes flipIt
{
0%{width: 0px;
height: 200px;}
25%{width: 200px;
height: 200px;}
50%{width: 0px;
height: 200px;}
100%{width: 0px;
height: 200px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1>Coin Flip | <span>Global or Fortune</span></h1>
</div>
<div class="col-lg-12">
<!--blank-->
<div class="col-lg-4"></div>
<!--coin-->
<div class="col-lg-4">
<div class="coinBox">
<div class="tail">
<img src="coin_F.png" />
</div>
<div class="head">
<img src="coin_G.png" />
</div>
</div>
</div>
<!--user form elements-->
<div class="col-lg-4 text-left">
<p>
<div class="form-control">
<button name="Global" id="userChoice">Global</button>
<button name="Fortune" id="userChoice">Fortune</button>
</div>
<p>
<button class="btn btn-lg btn-primary" id="btnFlip" disabled>Flip It</button>
</p>
</div>
</div>
</div>
</div>
</div>
Try something like this:
HTML
<div class="choices">
<button name="Heads">Heads</button>
<button name="Tails">Tails</button>
<p>You have chosen: <span class="choice"></span></p>
</div>
<div class="flip">
<button class="disabled">Flip Coin</button>
<p></p>
</div>
CSS
.flip button {
background: #cc0000;
color: #fff;
padding: 5px;
}
.flip button.disabled {
cursor: not-allowed;
background: #ccc;
color: #eee;
}
JS
$(function() {
$(".choices button").on("click", function() {
var choice = $(this).attr("name");
//show selected choice
$(".choice").text(choice);
//enable flip button
$(".flip button").removeClass("disabled");
});
$(".flip button").on("click", function() {
//flip coin if a choice has been made
if(!$(this).hasClass("disabled")) {
//get random number
var flip = Math.floor(Math.random() * 2) + 1;
//determine side of coin and result of guess (ternary)
var flipSide = flip == 1 ? "Heads" : "Tails";
var result = flipSide == $(".choice").text() ? "correct" : "wrong";
//show flip result
$(".flip p").text(flipSide + ", you chose " + result);
}
});
});
You can also view it working here: https://jsfiddle.net/8jw1ogLd/
I'm trying to create a slideshow type effect on the homepage of my app, but I am fairly new to JS and am having trouble with some of the intricacies. I have a working slideshow with delays and setTimeouts that looks like this:
<script>
setTimeout(function() {
$("#hero-image-index").fadeOut().empty();
}, 6000);
setTimeout(function() {
$("#slide-1").fadeOut(500);
}, 6000);
$('#slide-2').delay(6000).fadeIn(3000);
setTimeout(function() {
$("#slide-2").fadeOut(500);
}, 12000);
$('#slide-3').delay(12000).fadeIn(3000);
setTimeout(function() {
$("#slide-3").fadeOut(500);
}, 18000);
$('#slide-4').delay(18000).fadeIn(3000);
setTimeout(function() {
$("#slide-4").fadeOut(500);
}, 25000);
$('#slide-5').delay(25000).fadeIn(3000);
setTimeout(function() {
$("#slide-5").fadeOut(500);
}, 32000);
$('#slide-6').delay(32000).fadeIn(3000);
setTimeout(function() {
$("#slide-6").fadeOut(500);
}, 39000);
$('#slide-7').delay(39000).fadeIn(3000);
$('#hero-image-index-2').delay(39000).fadeIn(3000);
</script>
However, now the client wants a navigation so the user can go from slide to slide at will, which I have set up using ionicons on each "slide". Here's a sample "slide":
<div class="slide text-center" id="slide-1">
<h1 style="margin: 75px 0 40px 0; font-size: 52px; color: white; font-weight: bolder">Genetic Golf</h1>
<h2 style="color: white">We don't guess, we test to find what works best for you!</h2>
<div class="index-icon-box" style="color: white">
<i class="icon go-to-7 ion-chevron-left"></i>
<i class="icon go-to-1 ion-android-radio-button-on"></i>
<i class="icon go-to-2 ion-android-radio-button-off"></i>
<i class="icon go-to-3 ion-android-radio-button-off"></i>
<i class="icon go-to-4 ion-android-radio-button-off"></i>
<i class="icon go-to-5 ion-android-radio-button-off"></i>
<i class="icon go-to-6 ion-android-radio-button-off"></i>
<i class="icon go-to-7 ion-android-radio-button-off"></i>
<i class="icon go-to-2 ion-chevron-right"></i>
</div> <!-- index icon box -->
</div> <!-- slide 1 -->
I was hoping to do something with the JS like "if user doesn't click inside .index-icon-box then run the js as I already have it, but if they click on an .icon then do something like this:
<script>
$(document).ready(function() {
$(".go-to-1").click(function(){
$("#slide-1").show();
$("#slide-2").hide();
$("#slide-3").hide();
$("#slide-4").hide();
$("#slide-5").hide();
$("#slide-6").hide();
$("#slide-7").hide();
});
$(".go-to-2").click(function(){
$("#slide-1").hide();
$("#slide-2").show();
$("#slide-3").hide();
$("#slide-4").hide();
$("#slide-5").hide();
$("#slide-6").hide();
$("#slide-7").hide();
});
};
</script>
However, any way I attempt this just ends up breaking the part I do have working. Can any js-wizards straighten me out?
If your intent on doing this yourself without using a library, you might want to try the following.
First consider putting your slides together in a container, and overlaying
the icons to select the slide over them. Then keep track of the images using the indexes of both the slides and the containers. This provides for an easily edited slideshow setup.
A simple example is shown below, this should be in the neighborhood of what you are looking for.
jQuery(document).ready(function($) {
// Hides all images except for one, the one is given by an
// index. Also updates the controller.
function showSlide(index) {
$('.slides .slide').each(function(i) {
if (i == index) {
$(this).fadeIn(500);
} else {
$(this).fadeOut(500);
}
});
var spans = $('.controller span').removeClass('active');
spans.eq(index).addClass('active');
}
// Show only the first element and set an interval to
// continue to cycle through elements.
var index = 0;
showSlide(index);
var intervalFunc = function() {
index = index >= $('.slides .slide').length ? 0 : index + 1;
showSlide(index);
};
var interval = setInterval(intervalFunc, 6000);
// Handle clicks which will reset the interval to each time.
$('.controller span').click(function() {
// Set the current picture.
index = $(this).index();
showSlide(index);
// Reset the interval
clearInterval(interval);
interval = setInterval(intervalFunc, 6000);
});
});
.slideshow-contianer {
position: relative;
/* For Deomnstation purposes*/
width: 400px;
height: 200px;
margin: 2em;
}
.slides img {
width: 100%;
height: auto;
position: absolute;
left: 0;
top: 0;
}
.controller {
position: absolute;
bottom: 10px;
left: 0;
width: 100%;
-webkit-display: flex;
display: flex;
-webkit-justify-content: center;
justify-content: center;
}
.controller span {
width: 4px;
height: 4px;
border-radius: 50%;
border: 2px solid #ccc;
cursor: pointer;
margin: 10px;
/* Transition is a personal asthetic. */
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.controller span.active,
.controller span:hover {
-webkit-transform: scale(1.5);
transform: scale(1.5);
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="slideshow-contianer">
<div class="slides">
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
<img class="slide" src="https://unsplash.it/400/200?random" />
</div>
<div class="controller">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
I have a list which serves as a menu. Every time user clicks on one of the elements in the list, I want a more detailed div to slide in from left to right.
So if the user was to click menu item A first, A slides from left to right. If the user then clicks B, A slides out from right to left (disappears off screen) and B slides in.
I searched for this problem and found this post. I incorporated the code from the jsfiddle, but it didn't work. No errors are being shown in the js log in Chrome debugging tool. Nothing happens when I click any item from the menu. What am I doing wrong?
<div class="project">
<ul id="project_menu" class="project_menu">
<li id="menu-php-mysql" data-projectID="php-project">PHP/MySQL</li>
<li id="menu-nodejs" data-projectID="node-project">NodeJS</li>
<!-- more code -->
</ul>
<div class="project-detail">
<div id="php-project">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
<!-- data about project -->
</div>
</div>
<div id="node-project">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
<!-- data about project -->
</div>
</div>
<!-- and so on.. -->
#php-project {
background-color: #9b59b6;
margin: 30px;
display: none;
}
$(document).ready(function() {
itemsToRender = [];
$('ul#project_menu li').click(function(e) {
menuItemId = (e.currentTarget.id);
$('.common').hide();
$(getProjectId(menuItemId)).css('display', 'inline');
var value = $(getProjectId(menuItemId)).css('right') === '100px' ? '-100px' : '100px';
$(getProjectId(menuItemId)).animate({
right: value
}, 800);
});
});
function getProjectId(menuItemId) {
if (menuItemId.indexOf('php') > 0) {
return '#php-project';
} else if (menuItemId.indexOf('node') > 0) {
return '#node-project';
} else if (menuItemId.indexOf('angular') > 0) {
return '#angular-project';
} else if (menuItemId.indexOf('mean') > 0) {
return '#mean-project';
}
}
Update1: #user5325596 pointed out that my display property for the detail div was set to none, so I fixed that by adding the following:
$(getProjectId(menuItemId)).css('display', 'inline-block');
right after $('.common').hide().
Now, I can see the detail div when I click on the menu item, but it does not animate.
Update2: I have uploaded a jsFiddle, it includes the jquery animation that I am successfully using (fadeIn, which is commented out), as well as the code suggested by elchininet.
Not sure if this is what you need or not
JS Fiddle - updated 2
// initializing
var prevID = '',
divs = $('.sliding-divs');
$("li").on("click", function() {
var theID, theDiv, theDivW, theCenter;
// get the id letter from the li, then pick the corresponding sliding
// div depending on its value.
theID = $(this).attr('id');
theID = theID.replace('li-', '');
theDiv = $('#div-' + theID);
// get the divs width to slide it into the center of the view
theDivW = theDiv.width();
theCenter = $(window).width()/2 - theDivW/2;
// if the user didn't click the link which its slide already
// in the view, this to avoid sliding out and in same div.
if(theID != prevID){
if (prevID == '') {
// if we don't have a previously slided in div, we just slide
// the just click link's div into the view
theDiv.animate({'left': theCenter}, 1000);
} else {
// animated the previous div to the right out of the view, then
// move all divs to their original position out from the left
// this is because if we don't do this, an already slided div
// will later be slided in from right instead in from left
// because we have already changed its position.
// slide the just clicked link's div into the view from left
$('#div-' + prevID).animate({'left': '110%'}, 800);
divs.css({'left':-(theDivW + 100)});
theDiv.animate({'left': theCenter}, 1000);
}
}
// change the value of the id representing previously slided in div
prevID = theID;
});
body {
overflow-x: hidden;
}
ul {
list-style: none;
padding: 0;
}
li {
width: 100px;
height: 25px;
margin: 2px 0;
color: white;
padding: 3px;
text-align: center;
background-color: green;
cursor:pointer;
}
.sliding-divs {
position: absolute;
width: 500px;
line-height: 250px;
background-color: orange;
font-size: 30px;
border: 2px gold solid;
text-align: center;
display: inline-block;
top: 150px;
left: -510px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li id="li-A">item 1</li>
<li id="li-B">item 2</li>
<li id="li-C">item 3</li>
<li id="li-D">item 4</li>
</ul>
<div class="sliding-divs" id="div-A">
DIV A
</div>
<div class="sliding-divs" id="div-B">
DIV B
</div>
<div class="sliding-divs" id="div-C">
DIV C
</div>
<div class="sliding-divs" id="div-D">
DIV D
</div>
Try with CSS transitions, will save a lot of code. Maybe this is not exactly that you want but I'm sure it'll helps you with your task.
HTML Code
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>
CSS Code
li{
-webkit-transition: all 1s;
-moz-transition: all 1s;
transition: all 1s;
}
li.open{
-webkit-transform: translateX(100px);
-moz-transform: translateX(100px);
transform: translateX(100px);
}
jQuery Code
$("li").on("click", function(){
$("li.open").removeClass("open");
$(this).addClass("open");
});
jsfiddle
Here you have a jsfiddle with your code modified and the div animations in css.
jsfiddle with part of your code.
There are some minor mistakes i found on fiddle like , comma between class name. : class="project-container,common"
You are hiding all div with class .common, but not show it after. so its style property get display:none even if you add class open to that div.
Here is my Updated and running code:
$(document).ready(function() {
itemsToRender = [];
$('ul#project_menu li').click(function(e) {
$('.common').hide();
menuItemId = (e.currentTarget.id);
var projectId = getProjectId(menuItemId);
console.log(projectId);
$('.project-container.open').removeClass('open');
$(projectId).addClass('open');
$(projectId).show();
/* $(projectId).fadeIn('slow'); <--- THIS WORKS! But I want the slide effect instead */
});
function getProjectId(menuItemId) {
if (menuItemId.indexOf('php') > 0) {
return '#php-project';
} else if (menuItemId.indexOf('node') > 0) {
return '#node-project';
} else if (menuItemId.indexOf('angular') > 0) {
return '#angular-project';
} else if (menuItemId.indexOf('mean') > 0) {
return '#mean-project';
} else if (menuItemId.indexOf('html5-css3-js') > 0) {
return '#html-css-js-project';
}
}
});
.project-detail {
float: right;
max-width: 50%;
margin-right: 75px;
color: #fff;
}
#php-project {
background-color:#9b59b6;
margin: 30px;
display:none;
}
#node-project {
background-color:#27ae60;
margin: 30px;
display:none;
}
.project-container{
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
}
.project-container.open{
transform: translateX(-200px);
-webkit-transform: translateX(-200px);
-moz-transform: translateX(-200px);
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="project">
<ul id="project_menu" class="project_menu">
<li id="menu-php-mysql" data-projectID="php-project">PHP/MySQL</li>
<li id="menu-nodejs" data-projectID="node-project">NodeJS</li>
</ul>
<div class="project-detail">
<div id="php-project" class="project-container common">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
<h2 class="project-label">Project title: <span class="project-name"> php project</span></h2>
</div>
</div> <!-- end of php-project -->
<div id="node-project" class="project-container common">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
<h2 class="project-label">Project title: <span class="project-name"> node project</span></h2>
</div>
</div> <!-- end of node-project -->
</div> <!-- end of project-detail -->
</div> <!-- end of project -->
I think you want this to work like in this fiddle
HTML Code
<div class="project">
<ul id="project_menu" class="project_menu">
<li id="menu-php-mysql" data-projectID="php-project">PHP/MySQL</li>
<li id="menu-nodejs" data-projectID="node-project">NodeJS</li>
<!-- more code -->
</ul>
<div class="project-detail">
<div id="php-project">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
PHP project text
<!-- data about project -->
</div>
</div>
<div id="node-project">
<i class="ion-ios-close-empty close-icon js-close-icon"></i>
<div classs="project-text">
Node Project Text
<!-- data about project -->
</div>
<!-- and so on.. -->
</div>
</div>
</div>
CSS Code
.project_menu > li{
cursor: pointer;
}
.project-detail{
width: 300px;
height: 100px;
background-color: #dedede;
overflow: hidden;
position: relative;
}
JQuery
$(document).ready(function() {
$('.project-detail > div:first-child').css("right","0px");
itemsToRender = [];
$('#project_menu li').click(function(e) {
menuItemId = (e.currentTarget.id);
$('.common').hide();
$(getProjectId(menuItemId)).css('display', 'inline');
var value = '0px';
$(getProjectId(menuItemId)).animate({
right: '0px'
}, 800);
var req = '.project-detail > div';
$('.project-detail > div').not($(getProjectId(menuItemId))).animate({
right: '300px'
}, 800);
});
});
function getProjectId(menuItemId) {
if (menuItemId.indexOf('php') > 0) {
return '#php-project';
} else if (menuItemId.indexOf('node') > 0) {
return '#node-project';
} else if (menuItemId.indexOf('angular') > 0) {
return '#angular-project';
} else if (menuItemId.indexOf('mean') > 0) {
return '#mean-project';
}
}