I'm using the vimeo api to slide a video off the screen after it finishes playing. Underneath the video player, hidden, I have an image that says 'replay'. The image though is slightly bigger than the player so I want to hide the image via .hide() or display: none in the css and then show it after the animation of the video player completes.
Here's my js:
$(document).ready(function() {
$(".vimeo-container img").hide();
$('iframe.vimeo').each(function(){
Froogaloop(this).addEvent('ready', ready);
});
function ready(playerID){
Froogaloop(playerID).addEvent('finish', onFinish);
}
function onFinish(playerID) {
var player = "#" + playerID;
$(player).animate({width: "0%"}, 750, function() {
$(player).next("img").show();
});
}
});
So the first line is hiding the image. And then when the onFinish function completes I'm trying to show() the image, but it won't work. I should note that when I reverse it and do:
$(player).next("img").hide();
it works.
Here's my HTML:
%section#container1
.row.video-left
.large-8.columns
.vimeo-container
.flex-video.widescreen.vimeo
%iframe.vimeo#player1{allowfullscreen: "", frameborder: "0", height: "225", mozallowfullscreen: "", src: "http://player.vimeo.com/video/60122989?api=1&player_id=player1", webkitallowfullscreen: "", width: "400"}
= image_tag "behind1.png", class: "behind1"
And CSS:
.vimeo-container {
position: relative;
.behind1 {
margin-top: -27em;
}
I've also tried setting display: none in the css, but that wont work either. Not sure what I'm missing.
Thanks.
EDIT
function onFinish(playerID) {
var player = "#" + playerID;
$(player).animate({width: "0%"}, 750, function() {
console.log($(player));
$(player).next().show();
});
}
When I log out ($(player) it returns:
And when I log out console.log($(player).next()); it logs out the image that I am trying to show.
According to the jQuery documentation on the animate method here:
Note: Unlike shorthand animation methods such as .slideDown() and .fadeIn(), the .animate() method does not make hidden elements visible as part of the effect. For example, given $( "someElement" ).hide().animate({height: "20px"}, 500), the animation will run, but the element will remain hidden.
I had a similar need in a project and what worked for me there was to set the z-index of the element I wanted to hide to be less than that of the background. Then, when I wanted to show (or, in your case, animate) I could apply the jQuery methods to the element as if they were hidden (by increasing the z-index so that the element becomes visible), yet not incur the undefined behaviour of attempting to manipulate a hidden element.
Another option would be to move the element off the screen by way of a negative (x, y) coordinate and work from there. I'm not sure which visually would be more appealing in your use case but mention it for completeness.
Related
I have a list-element that is initially set to max-height: 200px; overflow-y:hidden;. Beneath that element there is a h3-element you can click to show the entire list. For that purpose, I animated the maxHeight-property of the element with the jQuery animate() method. The animation should last 1.2 seconds. After that, the text below the list changes from "show more" to "show less". When you click on it, this animation is reversed, again with a duration of 1.2 seconds, after which the text changes back to "show more".
Everything works fine, except for some unexpected delays: After the first animation which raises the maxHeight-property of the list, it takes another second or so for the text to change as well. Then, if you click the "show less" text, nothing happens for about a seconds before the animation starts.
What is causing these unexpected delays?
JS Fiddle
Edit: As Wa Kei explained, this delay is caused by the "excess" height, since the element is actually less than 1200px high. So how could I rework my function so that it works as intended while not having to use a fixed height value?
I can't use handy jQuery methods like toggle(), show() or hide() because all of those hide an object entirely instead of accepting a minimum and maximum height or something like that.
I'm open to different solutions with JS / JQuery / CSS, but the html structure should remain unchanged.
Here is an example for the first part:
if (!list.hasClass('opened')) {
list.animate({
maxHeight: '1200px'
}, {
duration: 1200,
progress: function(){
if(list.css('maxHeight') > list.css('height')) {
$(this).stop();
}
},
always: function() {
$('#show_more').text('(weniger anzeigen)');
list.addClass('opened');
}
});
}
Edit:
I reworked your code a bit: http://jsfiddle.net/z83cpbvj/1/
#progress (jQuery API) A function to be called after each step of the animation, only once per animated element regardless of the number of animated properties.
#always (jQuery API) A function to be called when the animation completes or stops without completing
I want to make an image on my site to opacity 0.5 and then i want to "pop out" on this image a word with opacity equal to 1. The problem is that when i set image on whatever speed it starts to queue all functions as many times as i enter/leave image with my cursor.
the word is loading faster (immadietly) than image with 'slow' and
the word doesn't change opacity to 1, cus it's loosing opacity with
image (which is set to 0.5)
How to make "word" to load later than image?
How to make function not repeatable whenever I'm moving my cursor through image (like 10x/sec) so it won't queue everything and
continue to fadeTo until everything is done?
(the most important) How to make word to not inherit opacity from image?
$(document).ready(function(){
$('#classic').mouseenter(function(){
$('#classic').fadeTo('slow', 0.25)
{
$('#classic').append("Classic");
$("Classic").fadeTo('slow', 1);
};
});
$('#classic').mouseleave(function(){
$('#classic').fadeTo('slow', 1);
{
$('#classic').empty();
};
});
});
First of all, make sure that either (a) the element that has id="classic" is not an img--because imges should not have children--or (b) you are adding the text after the img and not appending it to it. I'm going to assume that there's a div with id="classic" which has an img child:
1) You have it almost right. To make the word fade in after the image has faded out you need to use a callback function. The syntax for this is:
$('#classic').fadeTo('slow', 0.25, function() {
// now the fading is done!
});
And not
$('#classic').fadeTo('slow', 0.25)
{
....
}
You'll also probably want to add opacity: 0 for an initial value on the text that you add to the DOM so you can then fade it in.
2) jQuery has a function just for this called .stop(). Call this function whenever you need to stop animations from queuing up. So change the above to:
$('#classic').stop().fadeTo('slow', 0.25, function() {
// now the fading is done!
});
3) In CSS all elements inherit opacity from their parent. The easiest fix for this is simply to make the added element a sibling (or any other DOM element) of the transparent element and not a child. Then use negative relative positioning to stick it over the transparent element. So, assuming this structure:
<div id="classic">
<img src="myPicture" />
</div>
you'd use this jQuery:
$('#classic img').stop().fadeTo('slow', 0.25, function() {
$('#classic').append("<span>Classic</span>");
$("#classic span").fadeTo('slow', 1);
});
Make only the image fade out and in, so its siblings are unaffected. And in CSS:
#classic span {
display: inline-block;
opacity: 0; /* make it 0 initially so we can fade it in */
position: relative;
top: -48px; /* or whatever value */
left: -88px; /* or whatever value */
}
So here's the combined jQuery:
$('#classic').mouseenter(function () {
$('#classic img').stop().fadeTo('slow', 0.25, function() {
$('#classic').append("<span>Classic</span>");
$("#classic span").fadeTo('slow', 1);
});
});
$('#classic').mouseleave(function () {
$('#classic img').stop().fadeTo('slow', 1, function() {
$('#classic span').remove();
});
});
Here's a JSFiddle. Hope this helps!
I've updated your code here: http://jsfiddle.net/3dytbr3m/1/
You should use classes on your buttons. Classes are identifiers that can be applied on multiple elements. That way you don't have to use double code.
I also use $(this) which means that you are targeting the element that has the mouse over.
On a website, I have a list of news articles mentioning a certain thing. I want the articles to be able to be pressed, and when they are, the image source will switch with the image source of the actual article, and the image will grow to an arbitrary size. When you click the image again, it should go back to normal. I also want it to set itself to be absolutely positioned or something that way it doesn't push elements out of its way when it grows.
I guess my first question would be, is there already a code snippet or easy implementation of this or something similar? I have not been able to find one.
Second, I am in the process of making my own, and for whatever reason, when the page loads, every image just fades to disappearing without anything being pressed. Here is my code so far...
$(".newsCover").toggle(function () {
$(this).animate({
width: "auto",
height: "1000px"
}, 1500);
}, function () {
$(this).animate({
width: "auto",
height: "300px"
}, 1500);
});
Can anyone tell me what is wrong with it and how to fix it? I have a feeling its just something really stupid...
Thanks so much!
The .animate() method allows us to create animation effects on any
numeric CSS property.
All animated properties should be animated to a single numeric value, except as noted below;
http://api.jquery.com/animate/
However, you can hack it by determining the auto height/width as a hard number:
JavaScript jQuery Animate to Auto Height
The toggle function that you are using was deprecated in 1.8, and removed in 1.9, see here: http://api.jquery.com/toggle-event/ In v 1.9+, the toggle function now simply hides the element.
With no parameters, the .toggle() method simply toggles the visibility
of elements
The parameters that can be passed to the new toggle function can be found here: http://api.jquery.com/toggle/ With the new toggle function, you are unable to run the .animate() function within it. To achieve what you're trying to do, you could do something like:
$(".newsCover").click(function() {
if($(this).height() > 300) {
$(this).animate({
width: "auto",
height: "1000px"
}, 1500);
}
else {
$(this).animate({
width: "auto",
height: "300px"
}, 1500);
}
});
I am using jQuery animate to change the position of multiple elements on the page (decorative elements). I want the element to be deleted if it exits body area. (if left is larger than body width or top is larger than body height).
The following can not be used in my case:
overflow hidden for the body
manually animating the element. I want to use jQuery animate to keep it simple (I dinamically create elements, animate them then I don't care about them, don't keep track of them, they have a .remove() methode when the animation is complete)
http://jsfiddle.net/a7Nck/
So in this JSfiddle I want the red div to dissappear when it reaches right edge of the body so that no scrollbars will appear.
Isn't there any CSS3 media query for example so that if a div is not in the viewport it will be hidden?
EDIT:
I just thought of a solution: get the width of the body prior to triggering the animation and then animate the top and left by using the minimum between the body size and what the animation should do. The problem is that this will affect animation speed.
You can use animate's step function.
The second version of .animate() provides a step option — a callback function that is fired at each step of the animation. This function is useful for enabling custom animation types or altering the animation as it is occurring. It accepts two arguments (now and fx), and this is set to the DOM element being animated.
var w = $(window).width()
$('div').animate({
left: '20px'
}, 500).delay(1000).animate({
left: '2000px'
}, {
step: function(now, fx) {
if (now > w) {
$(fx.elem).remove()
}
}
}, 1000);
Fiddle
One possible workaround (assuming your first restriction is about globally adding overflow: hidden on your CSS): add overflow: hidden with js when the animation starts, and remove it when it ends:
$('body').css('overflow', 'hidden');
$('div').animate({left: '20px'},400).delay(1000).animate(
{left: '2000px'},1000, false, function(){
$(this).hide();
$('body').css('overflow', 'auto');
});
http://jsfiddle.net/a7Nck/3/
Just hide the div when the last animation get completed i.e.
$('div').animate({left: '20px'},400).delay(1000).animate({left: '2000px'},1000, function(){ $(this).hide(); });
See DEMO
As soon as the div leaves the visible area, the scrollbar will appear. If you want to prevent the scrollbar from appearing, you can't allow the div to leave the screen. Here's my solution:
$('div')
.animate({left: '20px'},400)
.delay(1000)
.animate(
{left: ($(window).width()-$('div').width()) + "px"},
1000,
null, // default easing
function() { $('div').hide() }
);
Jsfiddle: http://jsfiddle.net/j4rdA/1/
I have this code:
$('.pic_windows img').mouseenter(function () {
$(this).effect('shake', {
times : 4,
distance : 5
}, 15).attr('src', $(this).attr('src').replace(/.jpg/, '-1.jpg'))
});
$('.pic_windows img').mouseleave(function () {
$(this).attr('src', $(this).attr('src').replace(/-1.jpg/, '.jpg'))
});
where I'm using JQuery's .attr to swap the images, but I'd like the swapping to occur over the course of around 1 second. I've googled this and get all these complicated "CSS3 transitions with JQuery fallback" tutorials. Is there a way to 'animate' an .attr change?
I think I should do a fadeOut while the other fadeIn but I don't know how to write it, as I'm almost a complete JQuery newbie. I have a number of these transitions to do over the course of several pages. It'd be a cinch if I needed to write this for just one instance.
UPDATE On mouseenter, the image shakes and then should during this shake, fade from one picture to its swapped picture. On mouseleave, the image should just fade back to the original picture. Unfortunately I have also found that the shake effect is breaking on IE, all versions, as well as the image swap (it doesn't see image 2 at all)
No, you cannot animate an attribute change. What you can do is clone an element, change an attribute and transition between them.
var target = $(this).fadeOut();
var src = target.attr('src').replace(/-1.jpg/, '.jpg');
var copy = target.clone()
.attr('src', src)
.hide()
.insertAfter(target)
.fadeIn();
EDIT: Thank you for clarifying your intentions, I would advise not playing with the 'src', which will essentially require building a small stateful plugin. Instead, stick with the desired effect here, reveal an image on hover. jsFiddle
HTML
<div class="shaker">
<img src="http://lorempixel.com/output/nature-q-c-360-240-3.jpg" />
<img class="hover" src="http://lorempixel.com/output/technics-q-c-360-240-9.jpg" />
</div>
CSS
.shaker {
position: relative;
}
.shaker img {
position: absolute;
}
.hover {
display: none;
}
JS
$('.shaker').hover(function () {
$(this).effect('shake', {
times: 4,
distance: 5
}, 15);
$(this).find('.hover').fadeIn();
}, function () {
$(this).find('.hover').stop().fadeOut();
});
http://jsfiddle.net/eHQ3t/13/