How to join setInterval and .on("click") function together? - javascript

I have an extremely primitive slider using fadeIn, fadeOut and some control bullets.
https://jsfiddle.net/c2dsnr8v/1/
<div class="view">
<ul class="list">
<li class="frst">
<img src="http://www.guessthelogo.com/wp-content/uploads/2012/11/random-dice.gif" />
</li>
<li class="scnd">
<img src="https://avatars.yandex.net/get-music-content/a19fc9b4.a.1767585-1/200x200" />
</li>
<li class="thrd">
<img src="http://randomacts.channel4.com/images/fb_logo.gif" />
</li>
<li class="frth">
<img src="http://cs620120.vk.me/v620120530/93f0/k7U9HGQOBkw.jpg" />
</li>
</ul>
<div class="ctrl">
<div class="bullet one"></div>
<div class="bullet two"></div>
<div class="bullet three"></div>
<div class="bullet four"></div>
</div>
</div>
$(".list li:gt(0)").hide();
var int = setInterval(function(){
$('.list > :first-child')
.fadeOut()
.next()
.fadeIn()
.end()
.appendTo('.list');} ,3000);
$(".bullet").on("click", function(){
clearInterval(int);
$(".list li").fadeOut();
var $this = $(this);
if($this.hasClass("one")){
$(".list li.frst").fadeIn();
}else if($this.hasClass("two")){
$(".list li.scnd").fadeIn();
}else if($this.hasClass("three")){
$(".list li.thrd").fadeIn();
}else if($this.hasClass("four")){
$(".list li.frth").fadeIn();
}
})
I figured out how I can make pictures appear on clicking bullets (green squares), and the setInterval function here is clear enough. But when I tried to join these mechanisms together, I found out that I can only clear setInterval with a click. So once I use bullets, automatic rotating doesn't work anymore.
Is there any way to join the two together, using this code? For example, I click on a bullet, the picture stands still for 5 seconds, and then it keeps rotating further with the same speed?
I tried to include a new setInterval after each bullet click, but failed.

I think what you are looking for is setTimeout. setTimeout will execute a function once after a set amount of milliseconds. So in this example you can do:
//clear timeoutid incase you click a lot
clearTimeout(timeoutid);
timeoutid = setTimeout(function(){
int = setInterval(function(){
//List stuff
},2000);
},3000);
So in this case the next fade wont happen for 5 seconds after the click, but the rotation will continue on a 2 second interval.
Example JSFiddle:
https://jsfiddle.net/u6sdb40j/1/

Here is an updated snippet that removes the jumpiness. Basically the issue was in the ".appendTo('.list');", which reordered the list items and made it difficult to continue the rotation once a bullet was clicked. The code significantly changed to get around this, but it should be more efficient since the dom isn't being reordered every time through. Also, I removed a bunch of unnecessary classes and and am now using .index() to coordinate between the bullets and list items, as mentioned previously.
(function() {
var start = function() {
var active = $('.active'),
next = active
.removeClass('active')
.fadeOut()
.next();
if (!next.length) {
next = $('ul li:first-child');
}
next
.addClass('active')
.fadeIn()
.end();
},
go = function() {
return setInterval(start, 2000);
},
int = go();
$(".bullet").on("click", function() {
var currentIndex = $('div.bullet').index(this),
currentLi = $('ul li').eq(currentIndex);
clearInterval(int);
$('.active').removeClass('active').fadeOut();
currentLi.addClass('active').fadeIn();
int = go();
})
}());
.view {
margin: 100px auto 0;
width: 200px;
position: relative;
}
ul {
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
ul li {
position: absolute;
top: 0;
left: 0;
}
.ctrl {
bottom: -215px;
display: flex;
justify-content: space-between;
position: absolute;
width: 100%;
}
.bullet {
background-color: green;
height: 10px;
width: 10px;
cursor: pointer;
}
<div class="view">
<ul>
<li class="active">
<img src="http://www.guessthelogo.com/wp-content/uploads/2012/11/random-dice.gif" />
</li>
<li style="display:none;">
<img src="https://avatars.yandex.net/get-music-content/a19fc9b4.a.1767585-1/200x200" />
</li>
<li style="display:none;">
<img src="http://randomacts.channel4.com/images/fb_logo.gif" />
</li>
<li style="display:none;">
<img src="http://cs620120.vk.me/v620120530/93f0/k7U9HGQOBkw.jpg" />
</li>
</ul>
<div class="ctrl">
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
<div class="bullet"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

You can use an immediate function to encapsulate your vars and functions and avoid calling setInterval twice:
(function() {
$(".list li:gt(0)").hide();
var start = function() {
$('.list > :first-child')
.fadeOut()
.next()
.fadeIn()
.end()
.appendTo('.list');
},
go = function(elem) {
return setInterval(start, 2000);
},
int = go();
$(".bullet").on("click", function() {
clearInterval(int);
$(".list li").fadeOut();
var $this = $(this);
if ($this.hasClass("one")) {
$(".list li.frst").show();
} else if ($this.hasClass("two")) {
$(".list li.scnd").show();
} else if ($this.hasClass("three")) {
$(".list li.thrd").show();
} else if ($this.hasClass("four")) {
$(".list li.frth").show();
};
setTimeout(function() {
int = go();
}, 2000);
})
}());
(function() {
$(".list li:gt(0)").hide();
var start = function() {
$('.list > :first-child')
.fadeOut()
.next()
.fadeIn()
.end()
.appendTo('.list');
},
go = function(elem) {
return setInterval(start, 2000);
},
int = go();
$(".bullet").on("click", function() {
clearInterval(int);
$(".list li").fadeOut();
var $this = $(this);
if ($this.hasClass("one")) {
$(".list li.frst").show();
} else if ($this.hasClass("two")) {
$(".list li.scnd").show();
} else if ($this.hasClass("three")) {
$(".list li.thrd").show();
} else if ($this.hasClass("four")) {
$(".list li.frth").show();
};
setTimeout(function() {
int = go();
}, 2000);
})
}());
.view {
margin: 100px auto 0;
width: 200px;
position: relative;
}
.list {
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
.list li {
position: absolute;
top: 0;
left: 0;
}
.ctrl {
bottom: -215px;
display: flex;
justify-content: space-between;
position: absolute;
width: 100%;
}
.bullet {
background-color: green;
height: 10px;
width: 10px;
cursor: pointer;
}
<div class="view">
<ul class="list">
<li class="frst">
<img src="http://www.guessthelogo.com/wp-content/uploads/2012/11/random-dice.gif" />
</li>
<li class="scnd">
<img src="https://avatars.yandex.net/get-music-content/a19fc9b4.a.1767585-1/200x200" />
</li>
<li class="thrd">
<img src="http://randomacts.channel4.com/images/fb_logo.gif" />
</li>
<li class="frth">
<img src="http://cs620120.vk.me/v620120530/93f0/k7U9HGQOBkw.jpg" />
</li>
</ul>
<div class="ctrl">
<div class="bullet one"></div>
<div class="bullet two"></div>
<div class="bullet three"></div>
<div class="bullet four"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
There is some initial "jumpiness" after clicking a bullet before it settles in that you might have to tweak. Also, you could probably clean up some of your code by using jQuery's .index() method, if desired.

Related

Dropdown menu - save the choice on reload

I need to create popup language dropdown menu with country name, flag and link to the language version of the site. After user select menu item - it should take you to the needed url (language version of the page) and this choice should stay visible on the new page (after reload). Example of the menu - https://prnt.sc/sjumj8 (https://www.farfetch.com/shopping/women/items.aspx)
Here is an example of what I'm trying to create: https://jsfiddle.net/Okean/8x0atLpy/62/
<body>
<ul class="list-unstyled" id="select-lang">
<li class="init">[SELECT]</li>
<li data-value="value 1"> <img src="https://image.flaticon.com/icons/svg/197/197615.svg"> Language 1 </li>
<li data-value="value 2"> <img src="https://image.flaticon.com/icons/svg/197/197386.svg">Language 2 </li>
<li data-value="value 3"> <img src="https://image.flaticon.com/icons/svg/197/197484.svg">Language 3 </li>
<li data-value="value 4"> <img src="https://image.flaticon.com/icons/svg/197/197380.svg">Language 4 </li>
</ul>
</body>
<script>
$("ul").on("click", "li:not(.init)", function() {
allOptions.removeClass('selected');
$(this).addClass('selected');
$("ul").children('.init').html($(this).html());
allOptions.toggle();
});
window.onload = function() {
var selItem = sessionStorage.getItem("SelItem");
$('#select-lang').val(selItem);
}
$('#select-lang').change(function() {
var selVal = $(this).val();
sessionStorage.setItem("SelItem", selVal);
});
</script>
<style>
body{
padding:30px;
}
ul {
height: 30px;
width: 150px;
border: 1px #000 solid;
}
ul li { padding: 5px 10px; z-index: 2; }
ul li:not(.init) { float: left; width: 130px; display: none; background: #ddd; }
ul li:not(.init):hover, ul li.selected:not(.init) { background: #09f; }
li.init { cursor: pointer; }
a#submit { z-index: 1; }
li img {
width: 20px;
}
</style>
<ul> tag element won't ever trigger a .change event,
you can't even use li.val() as it doesn't have an actual value attribue.
So you need to workaround a little, something like this
$(document).ready(() => {
// cache selectors for better performance
const listItem = $("ul");
const listSelected = listItem.find('.init');
const allOptions = listItem.children('li:not(.init)');
listItem.on('click', '.init', () => {
listItem.children('li:not(.init)').toggle();
});
listItem.on('click', 'li:not(.init)', (e) => {
const that = $(e.target);
const setHTML = that.html();
allOptions.removeClass('selected');
that.addClass('selected');
listSelected.html(setHTML);
allOptions.toggle();
sessionStorage.setItem('SelItem', setHTML);
});
const selectItem = $("#select-lang");
const storedItem = sessionStorage.getItem('SelItem');
if (storedItem) {
listSelected.html(storedItem);
}
});
this should work as expected, storing target <li> HTML inside SelItem on sessionStorage

Javascript If No Click This JS, Else This

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>

JS slider while mouseover/mouseleft

Hello I have problems with JS clients slider on website.
I want to stop it while mouseover and resume while mouseleft. I have searched and checked the code but I don't know why it still doesn't work, could somebody help me?
$(function(){
var $clientcarousel = $('#clients-list');
var clients = $clientcarousel.children().length;
var clientwidth = (clients * 400); // 140px width for each client item
$clientcarousel.css('width',clientwidth);
var rotating = true;
var clientspeed = 0;
var seeclients = setInterval(rotateClients, clientspeed);
function rotateClients() {
if(rotating != false) {
var $first = $('#clients-list li:first');
$first.animate({ 'margin-left': '-220px' }, 5000, "linear", function() {
$first.remove().css({ 'margin-left': '0px' });
$('#clients-list li:last').after($first);
});
}
}
});
$(document).on({
mouseover: function(){
rotating = false; // turn off rotation when hovering
},
mouseleave: function(){
rotating = true;
}
}, '#clients');
Please have a look at this approach:
$(function() {
var $clientcarousel = $('#clients-list');
var clients = $clientcarousel.children().length;
var clientwidth = (clients * 400); // 140px width for each client item
$clientcarousel.css('width', clientwidth);
var rotating = true;
var clientspeed = 0;
var seeclients = setInterval(rotateClients, clientspeed);
function rotateClients() {
if (rotating != false) {
var $first = $('#clients-list li:first');
$first.animate({
'margin-left': '-220px'
}, 5000, "linear", function() {
$first.remove().css({
'margin-left': '0px'
});
$('#clients-list li:last').after($first);
});
} else {
$('#clients-list li').stop();
}
}
$(document).on({
mouseenter: function(){
rotating = false; // turn off rotation when hovering
},
mouseleave: function(){
rotating = true;
}
}, '.clients');
});
/*Logo carousel*/
.clients {
display: block;
margin-left: auto;
margin-right: auto;
max-height: 20%;
}
.clients .clients-wrap {
display: block;
max-width: 100%;
margin: 0 auto;
overflow: hidden;
}
.clients .clients-wrap ul {
display: block;
list-style: none;
position: relative;
margin-left: auto;
margin-right: auto;
}
.clients .clients-wrap ul li {
display: block;
float: left;
position: relative;
width: 220px;
height: 60px;
line-height: 60px;
text-align: center;
}
.clients .clients-wrap ul li img {
vertical-align: middle;
max-width: 100%;
max-height: 100%;
-webkit-transition: 0 linear left;
-moz-transition: 0 linear left;
transition: 0 linear left;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
filter: alpha(opacity=40);
filter: grayscale(100%);
opacity: 0.40;
}
.clients .clients-wrap ul li img:hover {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
filter: grayscale(0%);
opacity: 1.0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="clients">
<p></p>
<div class="clients-wrap">
<ul id="clients-list" class="clearfix">
<li>
<img src="http://iconshow.me/media/images/logo/brand-logo-icon/png/256/cocacola-256.png">
</li>
<li>
<img src="img/logos/2.png">
</li>
<li>
<img src="img/logos/3.png">
</li>
<li>
<img src="img/logos/4.png">
</li>
<li>
<img src="img/logos/5.png">
</li>
<li>
<img src="img/logos/6.png">
</li>
<li>
<img src="img/logos/7.png">
</li>
<li>
<img src="img/logos/8.png">
</li>
<li>
<img src="img/logos/9.png">
</li>
<li>
<img src="img/logos/10.png">
</li>
<li>
<img src="img/logos/11.png">
</li>
<li>
<img src="img/logos/12.png">
</li>
<li>
<img src="img/logos/13.png">
</li>
<li>
<img src="img/logos/14.png">
</li>
<li>
<img src="img/logos/15.png">
</li>
</ul>
</div>
<!-- #end .clients-wrap -->
</div>
Simple jQuery carousel
$(window).on("load", makeCarousel);
function makeCarousel() {
var carousel = $('.carousel ul'),
interval = $(carousel).parent().data("interval") * 1000,
speed = $(carousel).parent().data("speed") * 1000,
count = $(carousel).children().length,
width = $(carousel).find("img:first").width(),
id, moveIt;
$(carousel)
.css({
width: count * width,
position: "relative",
margin: 0,
padding: 0,
listStyle: "none"
})
.parent().css({ width: width, overflow: "hidden" })
.animate({opacity: 1}, 250)
.on("mouseover", function() { clearInterval(id) })
.on("mouseout", function() { moveIt() })
.find("li").css({ float: "left" })
.find("img").css({ verticalAlign: "bottom" });
(moveIt = function() {
id = setInterval(function() {
$(carousel).animate({left: -width}, speed, function() {
$(this).css({left: 0});
$(this).children(":last").after($(this).children(":first"));
});
}, interval + speed);
})();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel" data-interval="1" data-speed="0.6" style="opacity:0">
<ul>
<li><img src='http://placehold.it/350x200/111111?text=First Slide'></li>
<li><img src='http://placehold.it/350x200/444444?text=Second Slide'></li>
<li><img src='http://placehold.it/350x200/777777?text=Third Slide'></li>
<li><img src='http://placehold.it/350x200/aaaaaa?text=Fourth Slide'></li>
</ul>
</div>

Unable to get div to animate from left to right in jQuery

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';
}
}

Animate a PNG sequence by scrolling

Basically, I want to dynamically add/remove the class .show to the images inside .container depending on the scroll position. I want to change the class after some position.
$(document).ready(function() {
var container = $('#container'),
nImg = 0; // active picture
imgNum = $('#container img').length;
var topDiv = (container).offset() || {
"top": NaN
}).top;
$(window).bind('scroll', function() {
var y = $(this).scrollTop();
if (y > topDiv) {
nImg++;
} else {
nImg--;
}
if (nImg >= imgNum) {
nImg = 0;
}
if (nImg < 0) {
nImg = imgNum - 1;
}
$(".animated").each(function() {
$(this).removeClass("show")
});
$(".animated").eq(nImg).addClass("show");
});
});
.animated {
display: none;
}
.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:200px"></div>
<div id="container">
<img src="http://i.imgur.com/2oVbl7z.png" class="animated show" />
<img src="http://i.imgur.com/S5s0Mv1.png" class="animated" />
<img src="http://i.imgur.com/0vBEXL7.png" class="animated" />
<img src="http://i.imgur.com/ffg7v9n.png" class="animated" />
<img src="http://i.imgur.com/9FD5kdE.png" class="animated" />
</div>
If you scroll slowly you see that it actually works, but much too fast - that's the problem. I just to move slowly and want to start it from after some position.
See the below example for how to animate sequence image when page scroll.
$(document).ready(function () {
$('.aniScrollContainer').aniScroll({});
});
.aniScrollContainer {
height:300px;
background-color:#a1a1a1;
}
.myAniScrollContainer200 {
height:200px;
}
#header {
display: block;
height: 500px;
width: 100%;
background-color:#e0e0e0;
}
.gap {
display: block;
height: 100px;
width: 100%;
background-color:#e0e0e0;
}
#footer {
display: block;
height: 1500px;
width: 100%;
background-color:#e0e0e0;
}
.aniScrollContainer {
position: relative;
height: 100px;
}
.aniScrollContainer img.animated {
position: absolute;
display: none;
top: 0;
left: 0;
height:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://www.durley.net/animate-on-scroll/js/aniscroll.js"></script>
<div id="header"></div>
<div class="aniScrollContainer myAniScrollContainer">
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-01.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-02.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-03.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-04.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-05.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-06.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-07.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-08.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-09.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-10.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-11.jpg"/>
<img src="http://www.durley.net/animate-on-scroll/images/armani-bag-1000-03-12.jpg"/>
</div>
<div id="footer"></div>
See this jsFiddle for an example for how to limit how often it can change.
function animationTimer(){
canChange = true;
}
$(window).bind('scroll', function() {
if(canChange)
{
canChange = false;
setTimeout(animationTimer, 250);
// ...
}
});
This will allow the image to change every 250 ms, so change the 250 to a number which suits you to throttle the speed of which it changes.
You can use a sleep function (setTimeout) to wait some time between actions. And to be sure that isn't executet more than 1 time, you can use semaphores to lock critical regions.
In the example below I add and remove a class (this is the semaphore). And I make use of setTimeout to wait a time to execute that code.
$(document).ready(function () {
var container = $('#container'),
nImg = 0; // active picture
imgNum = $('#container img').length;
var topDiv = ((container).offset() || { "top": NaN }).top;
$(window).bind('scroll', function() {
if(!container.hasClass('lock')) {
container.addClass('lock');
setTimeout(function() {
var y = $(this).scrollTop();
if(y>topDiv){
nImg++;
}else{
nImg--;
}
if(nImg>=imgNum){ nImg = 0; }
if(nImg<0){ nImg = imgNum-1; }
$(".animated").each(function(){
$(this).removeClass("show")
});
$(".animated").eq(nImg).addClass("show");
container.removeClass('lock');
},200);
}
});
});
.animated { display: none;}
.show { display: block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:200px"></div>
<div id="container">
<img src="http://i.imgur.com/2oVbl7z.png" class="animated show" />
<img src="http://i.imgur.com/S5s0Mv1.png" class="animated" />
<img src="http://i.imgur.com/0vBEXL7.png" class="animated" />
<img src="http://i.imgur.com/ffg7v9n.png" class="animated" />
<img src="http://i.imgur.com/9FD5kdE.png" class="animated" />
</div>
Note: You can change the value of setTimeout to match your speed needs.

Categories