When button.btn is clicked, div.img-box will move with animation.
I'd like to change the animation depending on the place of div.img-box.
First I click the button, it moves collectly.
Second I click, the image whose margin-right is now 10px does not move.
I have this code.
js
$(function(){
var mr = parseInt($('.img-box').css('margin-right'), 10);
$(".btn").click(function(){
if (mr == 10) {
$(".img-box").animate( { marginRight: '300px' }, 'slow' );
} else {
$(".img-box").animate( { marginRight: '10px' }, 'slow' );
};
});
});
html
<button class="btn"></button>
<div class="img-box"><img src="xxx.png"></div>
css
.img-box{
float: right;
width: 250px;
height: 350px;
margin: 200px 25%;
}
How do I fix it?
You need to put var mr = parseInt($('.img-box').css('margin-right'), 10); inside the click() function.
$(function(){
$(".btn").click(function(){
var mr = parseInt($('.img-box').css('margin-right'), 10);
if (mr == 10) {
$(".img-box").animate( { marginRight: '300px' }, 'slow' );
} else {
$(".img-box").animate( { marginRight: '10px' }, 'slow' );
};
});
});
JSFiddle
Your anonymous function is called only once, so that "mr" is only calculated once, so that when the function to attached to your button is called, it's using a global variable that was set to 200. even after it moves, the mr variable is still 200, because you never updated the variable.
imtheman seems to have answered this as i was typing this out, but he's right, put the mr variable definition in the function so that it's calculated every time the button is clicked, rather than one time when the javascript is run.
Related
I need to detect the total height of my div "collectionFilterPage" while the animate event is running. Is there any event to bind?
This is my ja code:
function showMoreItems() {
$("#collectionFilterPage").animate({
height: "+=720"
}, 1000, function() {
if ($("#collectionFilterPage").outerHeight() >= $(".lista").outerHeight())
unbindScrollEvent();
});
}
Basically I would want to fire the "unbindScrollEvent" when both div "collectionFilterPage" and "lista" have the same height.
thanks
You might want to switch to this $().aninate signature and use the step property which allows you to set a callback function that is called during each step of the animation.
function showMoreItems() {
function checkHeight() {
if ($("#collectionFilterPage").outerHeight() >= $(".lista").outerHeight())
unbindScrollEvent();
}
$("#collectionFilterPage").animate({
height: "+=720"
}, {
duration: 1000,
complete: checkHeight,
step: checkHeight
});
}
http://api.jquery.com/animate/
$(...).animate( properties, options );
Solved. It has been very easy
height: $("#collectionFilterPage").outerHeight() >=
$(".lista").outerHeight() ? "+=0" : "+=720"
I have a textarea field that I would like to have expand when it gains focus, and to contract back when it loses focus. Here is my test code:
$(function() {
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
$(this).animate({ rows: rows }, 250);
});
});
fiddle:
http://jsfiddle.net/p0t1pzh7/3/
The problem is when the textarea has focus, and the user clicks on another input element.
The textarea collapses back in this case, but the click event appears to be lost.
What I believe is happening, is the blur() handler is changing the page such that the target of the click changes position. Since blur runs before click, the click is in fact happening, but because the target has moved position, the click is no longer hitting an element. This is on Chrome 37.0.2062.120 under Linux.
The reason I think that, is if you comment out the resizing of the textarea in the blur handler, everything works as intended.
fiddle: http://jsfiddle.net/p0t1pzh7/4/
I've googled and searched SO for related issues and did find several discussions on the ordering of the blur and click events. Generally, solutions seemed to involve either adding a delay on the blur() action, or binding events on the other page element to keep track of what is occurring.
Both of those approaches seen rather fragile and error-prone. This behavior is really just a nicety, so if there's no "clean" way to do it, I'd rather just drop it altogether.
For reference, the delay approach does work, as can be seen in this fiddle:
http://jsfiddle.net/p0t1pzh7/5/
And I understand why blur is triggered before click, but found it surprising that the target of the click event isn't "set" prior to blur being triggered. Is that expected behavior or does this vary between browsers?
You may use setTimeout function:
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
setTimeout(function(){
$(this).animate({ rows: rows }, 250);
}.bind(this),400);
demo
Try this solution
$(window).load(function () {
$('textarea.expand').focus(function () {
$(this).addClass("expanding")
$(this).animate({
height: "10em"
}, 500);
});
$('textarea.expand').blur(function () {
$(this).animate({
height: "1em"
}, 500);
// $(this).removeClass("expanding")
});
});
<table>
<tr>
<td>
<textarea class="expand" rows="1" cols="10"></textarea>
</td>
</tr>
<tr>
<td>Here is some text just below. Does it move?</td>
</tr>
</table>
.expand {
height: 1em;
line-height: 1em;
width: 300px;
padding: 3px;
}
.expanding {
position: absolute;
z-index: 9;
}
textarea {
resize: none;
}
Here is a solution that works without using any timeouts. See http://jsfiddle.net/29sw1abb/
HTML:
<textarea name="details" rows="5"></textarea>
<p>
click me
</p>
JS
$(function() {
var target = undefined;
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
$(this).animate({ rows: rows }, 250);
});
$('.button').mousedown( function (e){
target = $(e.target).attr('class');
});
$(document).mouseup( function (e){
if (target) {
alert(target);
target = undefined;
}
});
});
I beleive you are correct in assuming the original click event is not firing because the target area moves out of position before the event can be evaluated. 'mousedown' seems to evaluate before the blur so we can capture the click target info with 'mousedown' and then action the event on 'mouseup'. Having larger targets, less dramatic animation and or slower animation also solves this issue.
Introducing a delay works:
$(function() {
var rows = parseInt(
$('textarea[name=details]').attr('rows')
);
$('textarea[name=details]').focus(function() {
if (typeof(toDetails) != "undefined") { clearTimeout(toDetails); }
$(this).animate({ rows: rows + 10 }, 250);
}).blur(function(e) {
toDetails = setTimeout(function() { $(this).animate({ rows: rows }, 250); }.bind(this), 250);
});
});
I have a problem with the animation. Here is my code:
<html>
<head>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
<title>title</title>
<style>
div{
width: 100px;
height: 100px;
background-color: green;
position:relative;
left: 0px;
}
</style>
</head>
<body>
<h1>Animation</h1>
<select id='text_1' type="text">
<option>100</option>
<option>200</option>
<option>300</option>
<option>400</option>
<option>500</option>
<option>600</option>
<option>700</option>
<option>800</option>
<option>900</option>
<option>1000</option>
</select>
<button>Animate Div</button><br/><br/>
<div></div>
<script>
$(document).ready(function(){
var number = 500;
$('#text_1').bind('change', function(){
var number_2 = $('#text_1').val() != '' ? $('#text_1').val() : 500;
animation(number_2);
});
animation(number);
});
function animation(num){
$('button').click(function(){
$('div').animate({
'left': num+'px',
}, 1000).animate({
'left': '0px',
}, 1000);;
});
}
</script>
</body>
</html>
When I change select option (example: 300) and click the button, then does a two animations.
when I change select option again, then does a tree animations.
What is wrong. Please help.
This isn't the most elegant solution, but if you modify your code to look like this:
function animation(num) {
$('button').unbind('click'); //this removes the old click event
$('button').click(function(){
....
}
}
then that should solve your problem.
Try
$(document).ready(function()
{
$('button').on('click',function()
{
var num = $('#text_1').val() != '' ? $('#text_1').val() : 500;
$('div').animate(
{
'left': num+'px',
}, 1000).animate(
{
'left': '0px',
}, 1000);
});
});
It might not matter for this, but you should learn how to use a Javascript debugger, like Firebug, if that might give you a clue.
If you used a debugger, and you set a breakpoint inside the "click" function, you'd see it getting hit multiple times, adding up to the number of times you've changed the option dropdown. I'm guessing that's because your "animation()" function is binding a NEW function to the "click" event every time it's called, and not removing the previous ones, so clicking the button will execute the "click" function multiple times.
This is what you probably meant
$(document).ready(function(){
var number = 500;
$('button').click(function(){
$('div').stop().animate({
'left': number+'px',
}, 1000).animate({
'left': '0px',
}, 1000);
});
$('#text_1').bind('change', function(){
number = $('#text_1').val() != '' ? $('#text_1').val() : 500;
});
});
otherwise you are binding the click event to the button every single time you animate which becomes the problem. The first time the click is binded once, so it animates once, then you animation binds to click again, so it animates twice. Also notice the stop() which causes the div to stop what it is doing and start a new animation to prevent stuff where you click the button multiple times and it keeps animating for several seconds.
You're binding the click event multiple times.
Change it to this:
$('button').off('click').on('click', function(){
$('div').animate({
'left': num+'px',
}, 1000).animate({
'left': '0px',
}, 1000);;
});
Keep in mind .off and .on replaced .bind and .unbind
Also, it's better for performance reasons to chain functions like this.
I want a photo/caption to be toggled on a webpage.
The user clicks, the photo comes up followed by the caption.
The user clicks again, the caption goes away then the photo goes away.
The user clicks, the photo comes up followed by the caption.
On the third click, the photo rapidly appears (does not animate).
Here is my code.
(jQuery-1.8.1.min.js)
$(document).ready(function() {
$('#photo').width(0).height(0).css('opacity',0);
$('#caption').hide();
$('#box').toggle(
function() {
$('#photo').stop().show().animate(
{
width: '400px',
height: '300px',
opacity: 1
}, 500, function() {
$('#caption').stop().fadeIn(500);
}); //end animate
},
function() {
$('#caption').stop().hide(function() {
$('#photo').stop().fadeOut(500);
});
}
); // end toggle
});
Any suggestions?
Need more code?
UPDATE
In order to get the image to animate-in every time it is toggled, then the image has to animate-out.
EDIT2
updated the JSFIDDLE
EDIT:
Another problem showed up, this time with animation.
The jsFiddle works fine but when used with an actual image it does not animate after the first cycle.
I'm trying to stick with your original code (I just added .show() in between the photo's stop and animate calls), but I can't see what's wrong. It seems to work, see jsFiddle here.
UPDATE: I changed the "hide" function per poster's request & also updated the jsFiddle code to reflect this.
$(document).ready(function() {
$('#photo').width(0).height(0).css('opacity', 0);
$('#caption').hide();
$('button').toggle(
function() {
console.log("show");
$('#photo').stop().show().animate({
width: '400px',
height: '300px',
opacity: 1
}, 100, function() {
$('#caption').stop().fadeIn(1000);
}); //end animate
},
function() {
console.log("hide");
$('#caption').stop().hide(function(){
$('#photo').stop().animate({
width: '0px',
height: '0px',
opacity: 0
}, 100);
});
}
);
});
EDIT 3: updated code to work after one cycle : http://jsfiddle.net/kLEFy/17/
$(document).ready(function() {
$('#photo').width(0).height(0).css('opacity', 0);
$('#caption').hide();
$('body').toggle(
function() {
$('#photo').stop().show().animate({
width: '400px',
height: '300px',
opacity: 1
}, 1000, function() {
$('#caption').stop().fadeIn(1000);
}); //end animate
},
function() {
$('#caption').stop().hide(function(){
$('#photo').stop().fadeOut();
$('#photo').width(0).height(0).css('opacity', 0);
});
}
);
});
Right now I have a div that slides right to left and then vice versa back to its original place. But overall its not really how I want it to work. My main goal: is for the user to hover over the main div which will then pull out the sliding div. The part that gets tricky is the following: If the user forgets to slide the dive back, I want to give it time frame that will cause it to close automatically after a certain time has passed. Here is my working code so far: jsfiddle.net/eMsQr/14/.
My JavaScript function:
$(document).ready(function() {
$("#arrow").hover(
function(){
$("#inner").stop().animate({marginRight: "0px", opacity: "1px", height: "100px"}, 500 );
},
function(){}
);
});
$("#arrow").click(function(e){
$("#inner").stop().animate({marginRight: "-100px", opacity: "1px", height: "100px"}, 500 );
});
Try this: http://jsfiddle.net/vansimke/cJ5pf/
I hooked into the mouseleave event and added a setTimeout. You might need to catch the timeout if you need to cancel it later (i.e. they reenter the arrow)
Here's a jsFiddle example that sets a 3 second delay via the setTimeout function.:
jQuery
var cto;
$("#arrow").hover(
function() {
clearTimeout(cto);
$("#inner").stop().animate({
marginRight: "0px",
opacity: "1px",
height: "100px"
}, 500);
}, function() {
cto = setTimeout(function(){$('#arrow').trigger('click')}, 3000);
});
$("#arrow").click(function(e) {
$("#inner").stop().animate({
marginRight: "-100px",
opacity: "1px",
height: "100px"
}, 500);
});
Note that if the user moves his mouse away and then returns it to the div, the box remains open again until they leave at which point the 3 second countdown timer begins.
You need to make sure you utilize the second function() in jQuery's hover method.
At the moment you're only animating your slide-out div when the user hovers over the main div. You want it to also animate on hover out.
Here's the updated jsFiddle.
Inside the hover function you can add an additional line to trigger the click event using the below line:
setTimeout(function() { $("#arrow").trigger('click'); }, 5000);
the 5000 is the number of milliseconds to wait before triggering the click.
see the fiddle here: http://jsfiddle.net/eMsQr/51/
it uses the mouseleave jquery and also delay. Change the value in the delay to get the time you want.
$("#arrow").mouseleave(function(){
$("#inner").stop().delay(500).animate({marginRight: "-100px", opacity: "1px", height: "100px"}, 500 );
});
You need to use setTimeout() to set the delay to closing the div. You also need to use clearTimeout() in the opening function to stop it auto closing if someone mousesout, then back over again:
var timeout;
$("#arrow").hover(
function() {
clearTimeout(timeout); // clear the timer which will close the div, as we now want it open
$("#inner").stop().animate({
marginRight: "0px",
opacity: "1px",
height: "100px"
}, 500);
}, function() {
timeout = setTimeout(function() {
$("#inner").stop().animate({
marginRight: "-100px",
opacity: "1px",
height: "100px"
}, 500);
}, 1000); // close the open div 1 second after mouseout.
}
);
Example fiddle