I want to make a menu which slides from right to left a h2 header and when it done from up to down information. If clicked different option if menu already exists, is firstly goes up and then left else just as said. So the major problem is that in some ways there need to appear 2 infos instead of one and I can't figure how to do, that all executed one after other. If using callbacks, some of text appears two or more times...
$("a[rel~='showinfo']").click(function () {
var info_id = $(this).attr('id');//getting needed id from menu to show info
if($('.info_name').is(':visible'))//if already exists - removing
remove_contact();
for(i=0; i<contact_status.length; i++){//checking all array for item
if(info_id == contact_status[i]){//if item exist
create_contact(i);//putting it in
//here starts problems....
$('#info_name'+i).show("slide", {direction: "right"}, 1000, function(){
$('#info_info'+i).show("slide", {direction: "up"}, 1000);
});
}
}
//$('.info_name').show("slide", {direction: "right"}, 1000);
//$('.info_info').show("slide", {direction: "up"}, 1000);
});
function create_contact(id){
$('.third').append('<div class="showinfo"><h2 id="info_name'+id+'" class="info_name">'+contact_name[id]+'</h2><span class="info_info" id="info_info'+id+'">lol</span></div>')
}
function remove_contact() {
$('.info_name').hide("slide", {direction: "right"}, 1000);
$('.showinfo').remove();
}
for(i=0; i<contact_status.length; i++){//checking all array for item
if(info_id == contact_status[i]){//if item exist
(function ( idx ) { // use a Anonymous funciton
create_contact(idx );//putting it in
//here starts problems....
var;
$('#info_name'+idx ).show("slide", {direction: "right"}, 1000, function(){
$('#info_info'+idx ).show("slide", {direction: "up"}, 1000);
});
})( i );
}
}
ah, I make a mistake... this time should be right
Related
I have laid out my page to have a "navigation" page that consists of 3 divs that span the page, all 33% height. When you click one of the divs the other two should slide out and the information pertaining to the div you clicked should slide in in their place. This works for the first element that is clicked, no matter which one it is. But the second one I click always wraps the element to the wrong line on slide in. Any help would be much appreciated. Each div has its own click event, I have included one of the 3 below.
$('#contactdiv').click(function(){
$('#aboutdiv').hide('slide', {direction: 'right'}, 1000);
$('#portfoliodiv').hide('slide', {direction: 'left'}, 1000);
$('#contactinfo1').show('slide', {direction: 'left'}, 1000);
$('#contactinfo2').show('slide', {direction: 'right'}, 1000);
$('#menutoggler').show('pulsate');
$('#menutoggler').click(function(){
$('#contactinfo2').hide('slide', {direction: 'right'}, 1000, function(){
$('#portfoliodiv').show('slide', {direction: 'left'}, 1000);
});
$('#contactinfo1').hide('slide', {direction: 'left'}, 1000, function(){
$('#aboutdiv').show('slide', {direction: 'right'}, 1000);
});
$('#menutoggler').hide('pulsate');
});
});
I'm assuming, you added the below piece of code in all (contactdiv, portfoliodiv, aboutdiv) of the click handlers.
$('#menutoggler').click(function(){})
So everytime you click one of the 3 menu divs, you are adding one click handler on #menutoggler.
Say you clicked on contactdiv and then aboutdiv. Now, if you click on menutoggler, the click handle on #menutoggler inside contactdiv will ALSO be executed along with the click handle on #menutoggler inside aboutdiv (sorry if i didn't explained it properly)
What you should probably do is write separate click handlers based on "task"
click handler on either of contactdiv, portfoliodiv, aboutdiv
toggle menutoggler
HTML
<div id="contactdiv" class="menuItem"></div>
<div id="portfoliodiv" class="menuItem"></div>
<div id="aboutdiv" class="menuItem"></div>
JS
var ids = ['contactdiv', 'portfoliodiv', 'aboutdiv'];
var activeMenu;
function hideOtherMenus(id) {
var otherMenus = ids.filter(function(i) {
return i !== id;
});
otherMenus.forEach(function(i) {
// you probably need more if/else conditions if you want to set the correct direction
$('#' + i).hide('slide', {direction: 'right'}, 1000);
});
}
function showInfo(id) {
if(id === 'contactdiv') {
['contactinfo1', 'contactinfo2'].forEach(function(i) {
// you probably need more if/else conditions if you want to set the correct direction
$('#' + i).show('slide', {direction: 'right'}, 1000);
});
}
// do the same for portfolio and about
}
$('.menuItem').click(function(){
activeMenu = this.id;
hideOtherMenus(activeMenu);
showInfo(activeMenu);
$('#menutoggler').show('pulsate');
});
$('#menutoggler').click(function(){
if (activeMenu === 'contactdiv') {
$('#contactinfo2').hide('slide', {direction: 'right'}, 1000, function(){
$('#portfoliodiv').show('slide', {direction: 'left'}, 1000);
});
$('#contactinfo1').hide('slide', {direction: 'left'}, 1000, function(){
$('#aboutdiv').show('slide', {direction: 'right'}, 1000);
});
}
// do the same for portfolio and about
$('#menutoggler').hide('pulsate');
});
Note: you could handle the if/else conditions better if you name the divs properly.
I'm trying to animate a div box for several times when a button is pressed. It shall go right, and again right, then it comes a bit down and the text inside should change, and then it shall go left, and again left to its original place. There are two problems that I need help with:
The text change doesn't occur when it should! It changes immediately after I press the button! What should I do to run the text change just AFTER the third animation?
I get the value of an input number box, and want to apply it as the
speed argument. But when I put number instead of speed, it does
not work. I have to set it manually like 2000. What is wrong here?
JavaSript Code:
$(document).ready(function(){
$("button").click(function(){
var d=$("#t");
var number=$("#number1").val();
var speed=2000;
if(state==true){
d.animate({left:'+=230px'}, speed);
d.animate({left:'+=230px'}, speed);
d.animate({top:'+=20px', backgroundColor: "#f09090", text:'12'}, speed/4);
$('#span').fadeOut(500, function() {
$(this).text('a1').fadeIn(500);
});
d.animate({left:'-=230px'}, speed);
d.animate({left:'-=230px'}, speed);
d.fadeOut();
}
});
});
You can also try this: use .when and .then
Here you go: http://jsfiddle.net/9RuTX/1/
In terms of your #2 problem. I tested it out and it seems to work fine. Have you consoled it out and see if its getting in your var number. Perhaps do a typeof on it and see what it is.
$(document).ready(function(){
$("button").click(function(){
var d=$("#t");
var number=$("#number1").val();
var speed=2000;
if(state==true){
$.when(
d.animate({left:'+=230px'}, speed),
d.animate({left:'+=230px'}, speed),
d.animate({top:'+=20px', backgroundColor: "#f09090", text:'12'}, speed/4)
).then( function(){
$('#span').fadeOut(500, function() {
$('#span').hide().text('a1').fadeIn(500);
})
}
).then( function(){
d.animate({left:'-=230px'}, speed)
d.animate({left:'-=230px'}, speed)
d.fadeOut()
}
)
}
});
});
This happens because jQuery enqueue's animations per-element, and the span is a different element. You should put the text changing code in a callback function for when the previous animation completes. Here's an example.
<script>
$(document).ready(function(){
$("button").click(function(){
var d=$("#t");
var number=$("#number1").val();
var speed=2000;
if(state==true){
d.animate({left:'+=230px'}, speed);
d.animate({left:'+=230px'}, speed);
d.animate({top:'+=20px', backgroundColor: "#f09090", text:'12'}, speed/4, "swing", function(){
$('#span').fadeOut(500, function() {
$(this).text('a1').fadeIn(500);
});
});
d.animate({left:'-=230px'}, speed);
d.animate({left:'-=230px'}, speed);
d.fadeOut();
}
});
});
</script>
If needed, you can also delay you following animation so that it will not run simultaneously with the text changing code like this.
d.delay(500).animate({left:'-=230px'}, speed);
Here is a working example based on you jsFiddle.
http://jsfiddle.net/LSegC/
Try this
d.animate({left:'+=230px'}, speed)
.animate({left:'+=230px'}, speed)
.animate({top:'+=20px', backgroundColor: "#f09090", text:'12'}, speed/4)
.queue(function(){
var q = $(this);
$('#span').fadeOut(500, function() {
$(this).text('a1').fadeIn(500, function(){ q.dequeue() });
});
})
.animate({left:'-=230px'}, speed)
.animate({left:'-=230px'}, speed)
.fadeOut();
Just add it to the animation queue and it will get executed after the previous animations are done.
Related demo: http://jsfiddle.net/DerekL/qn893/1/
In this demo http://jsfiddle.net/vHcXN you can see that wjen you click on the link a transitions starts. First the div height changes and then the slide effect.
How can I make both works at the same time?
$(".turn_next").click(function(){
$(".box2").hide();
$(".box1_content").animate({height:'300px'}, 300,function(){
$(".box3").show('slide', {direction: 'right'}, 500);
});
});
$(".turn_back").click(function(){
$(".box3").hide();
$(".box1_content").animate({height:'100px'}, 300,function(){
$(".box2").show('slide', {direction: 'left'}, 500);
});
});
Remove the second animation from the call back of the first one,
$(".turn_next").click(function(){
$(".box2").hide();
$(".box1_content").animate({height:'300px'}, 300);
$(".box3").show('slide', {direction: 'right'}, 500);
});
$(".turn_back").click(function(){
$(".box3").hide();
$(".box1_content").animate({height:'100px'}, 300);
$(".box2").show('slide', {direction: 'left'}, 500);
});
The animation effect which you have specified in the call back function only get fired only after the initial animation completed. That's why you are seeing that effect.
DEMO
Since you're passing a function as an argument to animate, it's being used as a callback for after the animation finishes. Just call them successively:
http://jsfiddle.net/wyE92/
$(".turn_next").click(function(){
$(".box2").hide();
$(".box1_content").animate({height:'300px'}, 300);
$(".box3").show('slide', {direction: 'right'}, 500);
});
$(".turn_back").click(function(){
$(".box3").hide();
$(".box1_content").animate({height:'100px'}, 300);
$(".box2").show('slide', {direction: 'left'}, 500);
});
Note that they don't sync up exactly because you passed different lengths to the animations.
Currently, you've got the .show('slide'... function firing as a complete callback for when the .animate({'left'... function completes. Remove the callback and apply the second animation below the first:
$(".turn_next").click(function(){
$(".box2").hide();
$(".box1_content").animate({height:'300px'}, 300);
$(".box3").show('slide', {direction: 'right'}, 500);
});
$(".turn_back").click(function(){
$(".box3").hide();
$(".box1_content").animate({height:'100px'}, 300);
$(".box2").show('slide', {direction: 'left'}, 500);
});
Here is your edited fiddle showing the new animations together. Note that because of the different time lengths the two animations do not line up.
Live Demo: Live Demo
HTML:
<div class="target">
<img src="bg-clock.png" alt="jQuery" />
</div>
<div class="target2">
<img src="bg-clock.png" alt="jQuery" />
</div>
CSS:
.target, .target2 {
display: none;
}
JQuery:
$(document).ready(function() {
$(".target").show( "drop",
{direction: "down"}, 1000 );
$(".target2").show( "drop",
{direction: "down"}, 1000 );
});
Right now both DIV appear at the same time but I want target2 to appear after target1 has completed it's animation and so forth for any other DIV.
use the complete callback of the first animation function: So that target2 is animated only once the target1's animation is completed.
$(document).ready(function () {
$(".target").show("drop", {
direction: "down",
complete: function () {
$(".target2").show("drop", {
direction: "down"
}, 1000);
}
}, 1000);
});
Fiddle
.show()
For a series of targets you can do this way:
Just provide a common class name called slideIn for your targets for collecting them using a single selector. You can also use multiple classnames in the selector or attribute startswith selector
var elems = $('.slideIn').get(); // get all the targets to an array.
function animate() {
var elem = elems.shift(); //remove the top element from the array
$(elem).show("drop", { //animate it
direction: "down",
complete: function () {
if(elems.length > 0)
window.setTimeout(animate); //use recursive callback
}
}, 1000);
}
animate(); //invoke for the first time.
Fiddle
If you have many targets I would not use a callback. The nesting would get nasty.
You could use a delay on each
$(document).ready(function() {
$(".target").show( "drop",
{direction: "down"}, 1000 );
$(".target2").delay(200).show( "drop",
{direction: "down"}, 1000 );
$(".target3").delay(200).show( "drop",
{direction: "down"}, 1000 );
$(".target4").delay(200).show( "drop",
{direction: "down"}, 1000 );
});
This will have a slight pause between each you can play with the time to achive your effect
I use the following code to slide out a div on a mouse-over, wait a couple of seconds and slide the div back.
$(document).ready(function()
{$("#divider").mouseover(function ()
{$("#slider").show("slide", {direction: "left"}, 1000).pause(2000).hide("slide", {direction: "left"}, 1000);}
);}
);
I'm sure this is simple, but I have limited Javascript/jQuery knowledge. How do I make it so any mouse activity on the trigger is ignored until the animation completes? Right now, if while the div is open you mouse over the trigger area it "remembers" and plays the animation for as many times as you've moved the pointer through the trigger area. Page
I'd suggest removing the event from your divider until the animation is finished, than using the hide callback function to add that event handler back in.
$(document).ready(function() {
function divider_mouseover() {
$('#divider').unbind('mouseover');
$("#slider")
.show("slide", {direction: "left"}, 1000)
.pause(2000)
.hide("slide", {direction: "left"}, 1000, function() {
$("#divider").mouseover(divider_mouseover);
});
};
$("#divider").mouseover(divider_mouseover);
};
Don't bind and unbind and rebind instead use a flag to decide if you should care about the event.
$(document).ready(function(){
$("#divider").mouseover(function(){
var $this = $(this);
if($this.data('nomouse')) return;
$this.data('nomouse',true);
$("#slider")
.show("slide", {direction: "left"}, 1000)
.pause(2000)
.hide("slide", {direction: "left"}, 1000, function() {
$this.data('nomouse',false);
});
});
});
Binding and unbinding was of one Paul Irish's jQuery Anti-Patterns in the yayQuery podcast
Swizzle out the event handler (not sure if this works, but something along these lines):
var omo = function() {
{$("#divider").mouseover(function () {});}
slide();
}
var slide = function() {
{$("#slider").show("slide", {direction: "left"}, 1000)
.pause(2000)
.hide("slide", {direction: "left"}, 1000);
}
{$("#divider").mouseover(omo);}
}
$(document).ready(function()
{$("#divider").mouseover(omo);}
);