I'm building a website which relies on jQuery effects and I have a problem with the jQuery Slide effect.
I'm using that through a toggle function for the moment, but that will change in a later stage.
The fact is that I'm hinding an element when a certain action is executed. When you use the function slide the content beneath those elements moves when the animation is completed to take up the free space which was created with the effect.
The problem is that the content is only moved as soon as the animation is completed. Is there any way to move the content when the animation is still running. With other words, I want to move the content together with the animation, but I don't want to call the slide function on my element that should move with it.
I've created a JSFiddle to demonstrate the problem: http://jsfiddle.net/6Lg9vL8m/6/
Edit: Question update and fiddle
Here's an update to the question, and please see my original updated fiddle.
When you execute the slide effect in jQuery UI, see the bottom example on my fiddle, the box is moved up, and is somewhere placed behind an invisible screen (tough to explain).
With the animate function, see the top example in my fiddle, the area is shrinked, and that's something which I want to avoid. I want to achieve the effect such as 'Slide' does, but the content under the box must move up immediately with the animation, and not after the animation has been completed.
Edit: Reworked the correct answer in a plugin.
Thanks to the answers I've received here, I found the correct code, modified a bit, and created a plugin from it which I'll place here.
The plugin is called 'Curtain' and can be described as rising the requested element as a curtain and thus move it out of the way.
Here's the source code:
(function($) {
$.fn.curtain = function(options, callback) {
var settings = $.extend( {}, $.fn.curtain.defaults, options);
var tabContentsHeight = $(this).height();
$(this).animate({height:0}, settings.duration);
$(this).children().animate({'margin-top':'-' + tabContentsHeight + 'px'}, settings.duration, function() {
$(this).css({"margin-top":0});
if ($.isFunction(callback)) {
callback(this);
}
});
return this; // Allows chaining.
};
$.fn.curtain.defaults = {
duration: 250
};
}(jQuery));
The plugin can be called like this:
element.curtain({ duration: 250 }, function() {
// Callback function goes here.
});
If someone has remarks or a better way to solve this problem, please share it in the comments.
You can do it by using the animate function like this:
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
});
Demo
Updated code to create a "curtain raising" like animation:-
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
$(this).children().animate({"margin-top":"-400px"},2500, function() {
$(this).css({"margin-top":0})
});
});
CSS:
`#square{
overflow:hidden;
}`
Demo 2
This is the effect you wanted?
$('#square').on('click', function(e) {
$(this).animate({height :0},2500 );
});
Related
So I created some pop-up code that will contain specific information from each link clicked in the pop-up. When closed, the content in the pop-up div gets deleted. Here is my code:
var $content = $('#popupcontent');
var $window = $('#popupwindow');
$('.open').click(function(){
//alert('runnning');
var a = $(this).contents('span');
$content.append(a);
$window.fadeIn(300);
});
$('.close').click(function(){
//alert('running');
var a = $content.contents('span');
$window.fadeOut(300);
$('#popupcontent span').remove();
});
My issue is that it is somehow removing the content before fading out, so the viewer can then see that the pop-up container goes blank. How can I make it so that it will surely fade out first and then remove the content? Here is a Jsfiddle to illustrate that: http://jsfiddle.net/kAdQK/4/
You may want to utilize the complete call back argument for the fadeout method, to remove the element once fadeout is completed. With your current code it will start the fadeout animation and then immediately remove the content without waiting for fadeout animation to complete, hence you get the visual effect that you are seeing now. Using the callback you make sure that it gets executed once the animation is complete.
$window.fadeOut(300, function () {
$('#popupcontent span').remove();
});
Syntax
.fadeOut( [duration ] [, complete ] )
Fiddle
You can use the animation complete to remove your element after the fadeout ends.
The following code will ensure that #popupcontent is removed only after it's faded out
$window.fadeOut('slow', function() {
$('#popupcontent span').remove();
});
Just use a setTimeout();
$window.fadeOut(300);
setTimeout(function(){
$('#popupcontent span').remove();},2000);
Example Here
I've a scenario that requires me to detect animation stop of a periodically animated element and trigger a function. I've no control over the element's animation. The animation can be dynamic so I can't use clever setTimeout.
Long Story
The simplified form of the problem is that I'm using a third party jQuery sliding banners plugin that uses some obfuscated JavaScript to slide banners in and out. I'm in need of figuring out a hook on slideComplete sort of event, but all I have is an element id. Take this jsfiddle as an example and imagine that the javascript has been obfuscated. I need to trigger a function when the red box reaches the extremes and stops.
I'm aware of the :animated pseudo selector but I think it will need me to constantly poll the required element. I've gone through this, this, and this, but no avail. I've checked jquery promise but I couldn't figure out to use that in this scenario. This SO question is closest to my requirements but it has no answers.
P.S. Some more information that might be helpful:
The element isn't created by JavaScript, it is present on page load.
I've control over when to apply the plugin (that makes it periodically sliding banner) on the element
Most of the slideshow plugins I have used use changing classes at the end of the animation... You could extend the "addClass" method of jQuery to allow you to capture the class change as long as the plugin you use is using that method like it should:
(function($){
$.each(["addClass","removeClass"],function(i,methodname){
var oldmethod = $.fn[methodname];
$.fn[methodname] = function(){
oldmethod.apply( this, arguments );
this.trigger(methodname+"change");
return this;
}
});
})(jQuery);
I threw together a fiddle here
Even with obfuscated code you should be able to use this method to check how they are sending in the arguments to animate (I use the "options" object when I send arguments to animate usually) and wrap their callback function in an anonymous function that triggers an event...
like this fiddle
Here is the relevant block of script:
(function($){
$.each(["animate"],function(i,methodname){
var oldmethod = $.fn[methodname];
$.fn[methodname] = function(){
var args=arguments;
that=this;
var oldcall=args[2];
args[2]=function(){
oldcall();
console.log("slideFinish");
}
oldmethod.apply( this, args );
return this;
}
});
})(jQuery);
Well since you didn't give any indication as to what kind of animation is being done, I'm going to assume that its a horizontal/vertical translation, although I think this could be applied to other effects as well. Because I don't know how the animation is being accomplished, a setInterval evaluation would be the only way I can guess at how to do this.
var prevPos = 0;
var isAnimating = setInterval(function(){
if($(YOUROBJECT).css('top') == prevPos){
//logic here
}
else{
prevPos = $(YOUROBJECT).css('top');
}
},500);
That will evaluate the vertical position of the object every .5 seconds, and if the current vertical position is equal to the one taken .5 seconds ago, it will assume that animation has stopped and you can execute some code.
edit --
just noticed your jsfiddle had a horizontal translation, so the code for your jsfiddle is here http://jsfiddle.net/wZbNA/3/
My question title may seem confusing, let explain my situation. Any help would be much appreciated.
I have never done this before, hence why I can't pin point a solution in google.
I have a jquery slideshow, which I wrapped inside a function because I have some addition animation to go with it, please see below...
// my slider function
bikeSlider = function () {
var slider = $('#bike-minislider').bxSlider({
displaySlideQty: 5,
infiniteLoop: false,
hideControlOnEnd: true
});
$('#bike-minislider-fade').fadeIn();
};
// this runs the function
bikeSlider();
As you can see, immediately after the bikeSlider function, I run the function using... bikeSlider();
Now later on, I hide some slides within the slideshow using jquery .hide().
Because my jquery slideshow function, calculates the number of visible slides within the #bike-minislider div, it means that the new number of visible slides causes the slideshow to not work. I guess it needs to re-calculate the new number of slides.
In a nutshell, I think this can be resolved by running the bikeSlider(); function again.
So I tried this below, but it did not work.
bikeFilter = function (y) {
$('.bike').fadeOut();
$('.bike[data-group=' + y + ']').fadeIn();
bikeSlider();
return false;
}
As you can see I am trying to re-run the function bikeSlider(); - but it seems to be running this over the top of the old one, so my question is, how do you remove the original slide function before running it again.
Or reloading/refreshing the original function so it re-calculate the new number slides?
Any pointers would be so helpful.
Thank You.
As i understood you dont need re-create slider, but you do exectly this by calling twice
bxSlider()
According doc you need reinit slider by
reloadShow()
//Reinitialize a slide show
For more info take a look here bxslider in section Public functions
You need to call reloadShow() for slider-object
var mySlider;
$(function(){
mySlider= $('#bike-minislider').bxSlider({
auto: true,
controls: true
});
mySlider.reloadShow();
})
I am programming a section of a website using jquery, where when you mouse over a button it hides a specific div and shows another one, then when the mouse leaves it hides that one and shows the original, and it works great, but when you go over the buttons to fast it gets flickery and starts showing all the divs(doesnt hide some)
My code:
function changeAddPanelText(element, element2) {
$(element).hover(function(){
$("#add-content-desc1").toggle();
$(element2).fadeIn(700);
},
function(){
$(element2).toggle();
$("#add-content-desc1").fadeIn(700);
});
}
any ideas ? thanks
Edit: I updated the code to the current version.
Try this
function changeAddPanelText(element, element2) {
$(element).hover(function(){
$("#add-content-desc1, element2").stop().toggle();
}, function(){
$("#add-content-desc1, element2").stop().toggle();
});
}
im currently working on my first website- but ive come to a slight problem with this piece of jquery... The page is:
http://beelinetest.site50.net/the_arts_and_culture_in_worcester.html
I have a rollover over effect throughout the completed pages on my website, (when you hover over the link, the word slightly moves to the right) this can be better seen on the events programme page.
But on this page ive got a lot of jquery going on... When clicked the word moves to the left off the page. But because of having the mouse over, (moving the word back to the right on release) the word shoots back on screen to its original place.
Please feel free to look into my code, id really appreciate it- i know you guys are great, so thanks in advance! Tom
Here are the two conflicting codes-
$("#exploretext").click(function(){
$(".moveeverythingleft").animate({"left":"-220px"}, 400);
return false;
});
$("#exploretext").hover(function(){
$("#exploretext").animate({"left":"227px"}, 50);
}, function(){
$("#exploretext").animate({"left":"217px"}, 150);
});
This will unbind your hover effect after a click event :
$("#exploretext").on("click",function()
{
$(this).off("hover", "**");
$(".moveeverythingleft").animate({"left":"-220px"}, 400); return false;
});
$("#exploretext").on('hover',function()
{
$("#exploretext").animate({"left":"227px"}, 50); }, function()
{
$("#exploretext").animate({"left":"217px"}, 150);
});
});
You may have to rebind it later, or to bind another, it depends on what you want to achieve.
It may be way easier to use another animate function, using += :
$("#exploretext").animate({"left":"+=10px"}, 50, 'linear');
edit :
I'm reading your code, the markup and the css is a bit of a mess, I think it makes your work harder than it should be.
I would advise you to try first to clean the HTML and the CSS, then to handle the JS part.
what u can do is store the state of the button in some variable like ..
var position = "LEFT OR RIGHT";
then when u send the button to the left change the variable to left.
and in the hover event check the value and then if the position is left then dont execute whole of the event and if the position is right then execute the event.
function OnExploreClick(){
position = 'left';
//ur code
}
function OnUnExploreClick()
{
//put the button to right side// ur code
then position = 'right';
}
function OnHover()
{
if (position == 'right')
{
//execute ur code
}
}