Cycle with interval stops acting - javascript

Have been trying to learn some basics of web designing involving some simple HTML, CSS, JS/Jquery and have been coming up to certain obstacles that I haven't been able to find a way to work around.
One of the things I'm trying to implement is rotating a small number of divs. At the lack of some proper manner for it, what I rigged up was to .toggle off one of them while toggling on another div that was hidden from page load.
Not the prettiest thing, but it kind of works though oddly enough it only works twice before for some reason the cycle stops working.
function moveSide(){
var intervalId;
var childCount = 2;
var preLast = childCount + 2;
var newLast = childCount + 3;
intervalId = setInterval(function () {
$(".column:nth-of-type(" + childCount + ")").toggle("slide", function(){
$(".column:nth-of-type(" + preLast + ")").removeClass("last").delay(1, function(){
$(".column:nth-of-type(" + newLast + ")").addClass("last").delay(1).toggle("slide", function(){
childCount++;
preLast = childCount + 2;
newLast = childCount + 3;
//alert(childCount);
});
});
});
},5000);
}
I'm not sure if using nth-of-type is the right choice, but it seemed to be allowing me to pick amongst the divs. childCount is to pick which div is to be the first to be toggled off, pre(vious)Last is to identify what was the last div of those displayed in order to remove a class used for some properties, newLast is to identify the div that will become visible and give it the class to add CSS properties.
The alert cycle runs twice entirely (increasing childCount), but doesn't process a third time.
Any ideas what I'm doing wrong?

i don't now, if it's my not cured cold or the fact, that i just got up a few hours ago, but i don't understand your code.
what i understand, is what you want to achieve - and i suggest another method:
$(".column:gt(0)").hide(); //first of all, hide all columns but the first one
setInterval(function() {
$('.column:first') //select the first column
.toggle("slide") //slide it out
.next().next() //select the 3rd column
.toggleClass("last") //remove class "last"
.next() //select first invisible column
.toggleClass("last") //add class last
.toggle("slide") //slide it in
.end().end().end() //end the chain, to reselect the first element
// since we used .next() three times, we have to end it three times
.appendTo('#column-content'); //move the first element inside the dom to the end
}, 5000);
your interval should be running infinite now - always sliding out the first element, sliding in the next element end appending the first element to the end. therefore, the current element is always the first one...
see the fiddle: http://jsfiddle.net/sv5j85df/2/

Related

Trigger a fade when swapping between classes using jQuery

I have following code working so far: JSFIDDLE DEMO
The relevant JS is here:
// Define classes & background element.
var classes = ['bg1','bg2','bg3','bg4'],
$bg = document.getElementById('blah');
// On first run:
$bg.className = sessionStorage.getItem('currentClass') || classes[0];
// On button click:
$('.swapper').mousedown(function () {
// (1) Get current class of background element,
// find its index in "classes" Array.
var currentClassIndex = classes.indexOf($bg.className);
// (2) Get new class from list.
var nextClass = classes[(currentClassIndex + 1)%classes.length];
// (3) Assign new class to background element.
$bg.className = nextClass;
// (4) Save new class in sessionStorage.
sessionStorage.setItem('currentClass', nextClass);
});
For my purposes, this functionally working great -- I can click a single button to continually swap between those four classes while also storing the current class to sessionStorage, so that when I click links on my website, the currentClass is loaded right away. (Note: on my website the setup is the same, but the classes bg1, bg2, bg3, and bg4 contain background images.)
What I'd like it to do:
When swapping from one class to another, I'd like it to do a quick/short cross-fade. Right now it just snaps from one class/background to another.
My thinking was: is there a way I can trigger a CSS class transition or animation that contains the fade, perhaps as a parent class? I know there's a jQuery fade function, but I haven't been able to get it working with my setup so that it triggers on mouseClick.
Here's an updated jsfiddle based on your comment where you said you've sort of having it work.
I've added the timeout functions
setTimeout(function(){$bg.className = nextClass}, 500);
setTimeout(function(){$($bg).fadeIn(500)}, 500)
The first timeout makes it so that the image is swapped right after the first image fades out. The second timeout gives it a bit of time to load in so it's not so jittery.
You can play with the }, 500); number to get it timed just like you want, 500 is half a second, 1000 is a second etc.

This object at .mouseenter() function

I'm having a simple (I hope it's simple) question. I'm using 10 divs (div1, div2...) and I want to calculate the distance between two of them. I've already clicked one, that takes the class (img.home). I have the function to calculate the distance between two objects showdistance(div1, div2), but How can I use it to calculate showdistance($('img.home').parent()[0], $(this) ) where (this) is the div, that my cursor is point at at the moment ( .mouseenter(function() {$(this).text(showdistance)}); )
Thanks in advance,
If needed, I can make a jsfiddle with the whole code, but as I believe it is a rather easy thing, that I don't know and the code is a large piece it's easier this way.
Best regards.
Store your last clicked element in a variable.
Then compare the position when you enter an element.
You can apply top, left, right or bottom, if you like.
var clicked = null;
$("someSelection").click(function() {
clicked = $(this);
});
$("someSelection").mouseenter(function() {
// if-statement to ensure that the event won't fire if you haven't clicked one
if(clicked !== null) {
console.log($(this).position().top - clicked.position().top);
console.log($(this).position().left - clicked.position().left);
}
});

fadeIn() / fadeOut() animation not playing

Below I have this piece of code which I use to filter products with using a drop-down menu. The content of the #child_cat division changes based on the value attribute of the anchor tag:
$('#brandsort').change(function(){
$('#child_cat a').fadeOut(500);
$('[value="' + $(this).val() + '"]').fadeIn();
if ($('#brandsort option:selected').text() === "") {
$('#child_cat a').fadeIn(500);
}
});
The code will filter out the products that do not match their option value, but it won't play the animation. Right now, it acts more like a delayed .show() / .hide() function than anything. Please enlighten me from any wrongdoing in my code or what I could possibly be doing wrong aside from that.
EDIT:
I know the people on SO would normally like some hands-on help from one of you, but in this case I was specifically only asking for "enlightenment". Just some verbal input of what I could have been doing wrong.
To fulfill your request of providing some HTML, you'll find it here: http://jsfiddle.net/HJPN8/3/
There was a few mistakes in the logic that made this not work. Firstly, the reason you couldn't see the fade animate happen is because fade uses the css property opacity. Opacity only works on block and inline-block elements, and you were using the .fadeOut() on a tags which are display:inline. So that can be fixed easily with this:
#child_cat a{
display:block;
}
Next you're using .fadeOut() and .fadeIn() which both run at the same time meaning that the animations would both collide and not work properly. So you need to use callback functions to correctly time them. Below is the code I have refactored, I've included a lot of comments so you can see how it all works. The fade functions have been replaced with .animate() which is a lower end function that gives you more control which we need in this situation.
One last thing is that you were using the value attribute on your products, this isn't recommended as this property is specific to the options tag. If you wish to create custom attributes then the standard way is to prepend them with "data-" which you can see I've done here: http://jsfiddle.net/HJPN8/6/
$(function(){
var brandsort = $('#brandsort');
var products = $('#child_cat a');
brandsort.on('change', function(e){
var val = brandsort.val();
// If search is blank then select all products to show else filter specific products.
var filteredProducts = (val == '') ? products : products.filter('[data-value="' + val + '"]');
// Hide products and set callback for when the animation has finished.
// If we don't use a callback, the products will animate out and in at the same time, ruining the effect.
products.animate({opacity: 0}, 300).promise().done(function(){
// Now that he products' opacity is 0, we set them to display block to remove them from the flow of the DOM.
products.css({display: 'none'});
// Now Bring the filtered products back and animate them in again.
filteredProducts.css({display: 'block'}).animate({opacity: 1}, 500);
});
});
});

two buttons conflicting in javascript

I have two buttons that are divs and two paragraph, they each match up to each other. So you click button one, button one rotates 45 degrees and toggleslides paragraph one open, button two does the same except for paragraph two. For some reason though if you click the first button it opens both paragraphs, and if you click button two nothing happens, and I can't figure out why. I'm going to need to set up multiple buttons and paragraphs eventually.
var epidural_analgesia_INFO = document.images[0];
epidural_analgesia_INFO.style.setProperty("-webkit-transition", "-webkit-transform 0.3s ease-in-out");
var epidural_analgesia_DEG = 0;
epidural_analgesia_INFO.addEventListener('click', function() {
$("p#epidural_analgesia_TEXT").slideToggle("fast");
epidural_analgesia_DEG += 45;
epidural_analgesia_INFO.style.setProperty('-webkit-transform', 'rotateZ('+epidural_analgesia_DEG+'deg)');
});
var effects_of_yoga_INFO = document.images[0];
effects_of_yoga_INFO.style.setProperty("-webkit-transition", "-webkit-transform 0.3s ease-in-out");
var effects_of_yoga_DEG = 0;
effects_of_yoga_INFO.addEventListener('click', function() {
$("p#effects_of_yoga_TEXT").slideToggle("fast");
effects_of_yoga_DEG += 45;
effects_of_yoga_INFO.style.setProperty('-webkit-transform', 'rotateZ('+effects_of_yoga_DEG+'deg)');
});
I have a fiddle setup, but it's large and so I've pulled out the specific parts here, but if you want to see teh fiddle it's here: http://jsfiddle.net/loriensleafs/AM2a2/12/ thanks very much for helping me.
You're assigning your click handlers to the elements referenced by these two variables:
epidural_analgesia_INFO
effects_of_yoga_INFO
but both variables are initialised to reference document.images[0]. So clicking that image triggers both handlers. Should the second one perhaps use an index of 1 to get the second image?
(As an aside, why use addEventListener() when you seem to be using jQuery?)
got it, in teh first line
var epidural_analgesia_INFO = document.getElementById('epidural_analgesia_INFO');
instead of
var effects_of_yoga_INFO = document.images[0];

Use function to write to .js file

I've never particularly used JS much, with the exception of basic animations,
The page I'm working on requires me to fade out the active div and fade the requested one in, I have around 25 different div's I'll be fading between. At the minute I can't think of how to only fade the active one out so I'm trying to fade every div but the one that's requested out.
Here's the code I'm attempting to get working
var active = 0;
for (i=0;i<array.length;i++) {
if (i != active){
document.write("$('."+array[i]+"').fadeOut(900);");
}
naturally i know the document.write shouldn't be there, but ideally that code has to be printed into the .js file I'm using, however. I don't have a clue how to print it to the .js.
any suggestions would be greatly appreciated, or a way to do this in php without a page reload!
When you find yourself generating code on the fly, it usually indicates that you want to take a step back and re-evaluate your approach. :-)
In this case, there's no need to create the JavaScript dynamically. It's just a matter of running the code.
I wasn't sure what your definition of "active" was, so here's something that fades divs in/out on the basis of what buttons you press:
The HTML:
<input type='button' value='1'>
<input type='button' value='2'>
<input type='button' value='3'>
<input type='button' value='4'>
<input type='button' value='5'>
<input type='button' value='6'>
<div id='container'>
<div class='c1'>This is c1</div>
<div class='c2'>This is c2</div>
<div class='c3'>This is c3</div>
<div class='c4'>This is c4</div>
<div class='c5'>This is c5</div>
<div class='c6'>This is c6</div>
</div>
The JavaScript (teaching version):
jQuery(function($) {
// Hook our buttons; this selector hooks all of them,
// so you probably want to narrow that down, but I
// have no idea what your definition of "active" is,
// so I made one up.
$(":button").click(function() {
// Get the value of the button, e.g., 1, 2
var val = this.value;
// Get all of the divs in the container
var divs = $("#container div");
// Fade out all of the ones that aren't our target;
// fade in the one that is
divs.not(".c" + val).fadeOut(900);
divs.filter(".c" + val).fadeIn(900);
});
});
Live copy
That does this:
Uses the jQuery ready function (the shortcut form where I just pass a function into the jQuery function) to run the code when the page is "ready" (the DOM has been built)
Looks up all divs we want to be dealing with. In my case, it's all the divs in a container, but you can use just about any CSS3 selector you want (and then some).
Uses not with a class selector to filter out the div that has the target class, then uses fadeOut to start fading the other ones out.
Uses filter to reduce the set to just our target div, and fadeIn to start fading it in.
That version is for clarity. Here's a more concise version (still perfectly clear to people who know jQuery well, but tricky for folks still finding their feet):
The JavaScript (chained version using end):
jQuery(function($) {
// Hook our buttons; this selector hooks all of them,
// so you probably want to narrow that down, but I
// have no idea what your definition of "active" is,
// so I made one up.
$(":button").click(function() {
// Get the value of the button, e.g., 1, 2
var val = this.value;
// Get all of the divs in the container
// Fade out all of the ones that aren't our target;
// fade in the one that is
$("#container div")
.not(".c" + val).fadeOut(900)
.end()
.filter(".c" + val).fadeIn(900);
});
});
Live copy
Not sure why you are using document.write instead of simply executing the javascript.
var active = 0;
for (i=0;i<array.length;i++) {
if (i != active) {
$("."+array[i]).fadeOut(900);
}
Additionally, try using a jQuery selector to select all the non-active divs by adding an additional class to each div:
var active = array[0];
var classname = "some_class";
$("div." + classname + ":not(." + active + ")").fadeOut(900);
You could even just select the visible divs that are not the active one and fade them out:
var active = array[0];
var classname = "some_class";
$("div." + classname + ":not(." + active + "):visible").fadeOut(900);

Categories

Resources