I'm facing an issue with sliding an image from left to right.
What do I want: Image should slide from the left side of the screen to the right side.
My code is:
$('image').show("slide", { direction: "right" }, 1200);
But this solution is not working a per the expectations. Image slides from left to right, but not the whole image is loaded and the full image is visible only at the end of the animation.
here you can check:
$('#hello').show('slide', {direction: 'right'}, 1000);
you can also use: toggle
$(".slide-toggle").click(function(){
$(".box").animate({
width: "toggle"
});
or:
$(".slidingDiv").toggle("slide");
you can use animate instead of show as using show will show complete image after the animation
$('#image').animate({right:'0px'},1200)
img{
width: 100px;
height: 100px;
position: absolute
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image" src="https://yt3.ggpht.com/-v0soe-ievYE/AAAAAAAAAAI/AAAAAAAAAAA/OixOH_h84Po/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"/>
I think your problem is that the animation started before image object was loaded completely to the browser.
You should check out jquery load event: https://api.jquery.com/load-event/
And search for answers for question "jquery image load callback",
e.g.: jQuery or Javascript check if image loaded
In my opinion the best way is create image object with JS, push it to DOM element and start animation, when image will be loaded completely.
In short:
$("<img/>")
.attr("src", "/images/your-image.jpg")
.on('load', function() { startAnimation() })
.appendTo($('#imageContainer'));
var startAnimation = function(){
$('#hello').show('slide', {direction: 'right'}, 1000);
}
$(document).ready(function() {
$("img").animate({
marginLeft: "0px"
}, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div class="frame" style="width: 300px; height:300px; overflow:hidden;">
<img id="image" src="https://www.filterforge.com/more/help/images/size400.jpg" style='margin-left:-300px; height: 100%; width: 100%; '>
</img>
</div>
Related
I am very new to JS/JQuery/JQueryUI but have made a few things work on a new site I'm working on.
I've set up a basic navbar where a .click makes different divs slide into view with .show while the other three pop out of existence with .hide. I was extremely proud of myself even though this is super basic.
My issue is that one of these divs contains a YouTube iframe. To get it to stop playing when another div is shown, I just remove the src with .attr (clunky, I know). This means that since the source is re-appended to the iframe each time, going back to that div is slower than I want it to be, and jQuery stutters.
I've put a stripped down version into a JSFiddle. Any suggestions on improving the performance would be greatly appreciated!
PS: The video I have as a placeholder is hilarious and you should enjoy it! :)
HTML:
<div class="button" id="home">1</div>
<div class="button" id="about">2</div>
<div class="button" id="latest">3</div>
<div class="button" id="contact">4</div>
<div class="home"><iframe class="video" id="homeVid"
src="https://www.youtube.com/embed/gspaoaecNAg?controls=0?showinfo=0?rel=0?enablejsapi=1"
frameborder="0" allowfullscreen></iframe></div>
<div class="content about"></div>
<div class="content latest"></div>
<div class="content contact"></div>
CSS
.content {
width: 600px;
height: 480px;
display: none;
clear:both
}
.home, .video {
width: 600px;
height: 480px;
display: flex;
clear:both;
background-color: #CCC
}
.about {background-color: #F00}
.latest {background-color: #0F0}
.contact {background-color: #00F}
.button {
width: 25px;
height: 25px;
border: 1px solid black
}
JavaScript
$(document).ready(function() {
var urlhome = $('#homeVid').attr('src');
$('#home').click(function() {
$('.home').show('slide', {direction: 'right', easing: 'swing'}, 400);
$('.about, .contact, .latest').hide(0);
$('#homeVid').attr('src', urlhome);
});
$('#about').click(function() {
$('.about').show('slide', {direction: 'right', easing: 'swing'}, 400);
$('.home, .contact, .latest').hide(0);
$('#homeVid').attr('src', ' ');
});
$('#latest').click(function() {
$('.latest').show('slide', {direction: 'right', easing: 'swing'}, 400);
$('.home, .contact, .about').hide(0);
$('#homeVid').attr('src', ' ');
});
$('#contact').click(function() {
$('.contact').show('slide', {direction: 'right', easing: 'swing'}, 400);
$('.home, .about, .latest').hide(0);
$('#homeVid').attr('src', ' ');
});
});
Indeed, adding and removing the iframe is costly in terms of performance. Instead we must stop the playback and hide it.
This necessitates to insert it differently into the document, using the YouTube Player API Reference for iframe Embeds. Then we do this:
HTML
<div class="content home">
<div id="player"></div>
</div>
var player;
JavaScript
$(window).load(function(){
player = new YT.Player('player', {
height: '480',
width: '600',
videoId: 'gspaoaecNAg',
});
});
We can simply use player.stopVideo(); whenever we hide the home element. But if only it was so simple.
Using jQuery's hide() has side effects, because the way it hides elements is by setting their CSS to display:none which effectively removes them from the document. This destroys the iframe and recreates it on show(), which presents the same performance issue as before.
We need something more subtle, hiding the elements by putting them aside. For this we use positionning:
.hidden {
position:fixed;
left:200%;
}
This puts them further on the right of the document, outside the viewport and since the units are relative, it can never be vsible no matter how much we stretch the window. This necessitates a few changes in HTML, plus some others for an optimization I will detail further below.
HTML:
<div class="button" id="home">1</div>
<div class="button" id="about">2</div>
<div class="button" id="latest">3</div>
<div class="button" id="contact">4</div>
<div class="content home">
<div id="player"></div>
</div>
<div class="content about hidden"></div>
<div class="content latest hidden"></div>
<div class="content contact hidden"></div>
We have added the class hidden to all elements not visible at the start. We also added a class describing the elements themselves and set to the id of their corresponding button. And we have the content class in each element.
JavaScript:
var player;
$(window).load(function(){
player = new YT.Player('player', {
height: '480',
width: '600',
videoId: 'gspaoaecNAg',
});
});
$(document).ready(function() {
var all = $('.content');
$('.button').click(function() {
all.addClass('hidden');
player.stopVideo();
$('.'+this.id).animate({
'left': '0px',
easing: 'swing'
}, 400, function(){
$(this).removeClass('hidden')
.removeAttr('style');
});
});
});
This has been optimized to avoid checking each element individually. The first part has been explained before, here is how the rest goes:
var all = $('.content');
This selects all the .content elements and keeps them referenced outside the callback in the variable all, so we only have to do this once when the document loads.
We create the callback on all button elements. The next step assumes a click event has been received.
We set all .content elements to hidden. Effectively this should only affect the one currently not hidden.
We stop the video. This will only affect the embedded iframe and we don't bother checking which .content element is active because stopping an already stopped video does nothing special.
Using the id of the button that triggered the click event, we select the corresponding .content element.
We replace show() with animate() and use it to modify the CSS property that is used in the class hidden. This will slide the element from its hidden position to it's normal position.
The animation has a callback executed when it's done. We use it to first remove the hidden class from our now visible element, then to remove the style attribute in which our animation has set left:0px;, as leaving this there would interfere later.
And we're done. This should now be smooth. A demo is available on this JSFiddle.
I am trying to use jQuery slide-in animation and it seems to work fine, but my the second animation doesn't work. Can anyone tell me what I am doing wrong?
This line:
$('#headline1Txt').animate({'marginLeft': "100px"}, 1000);
is working fine, but this one:
$("#headline1Txt").animate({left: "+=30"}, 500);
is not working.
My Code
HTML
<div id="mainContainer">
<div id="headlineText">
<p id="headline1Txt" >Striped Bag</p>
</div>
</div>
JS
$(document).ready(function () {
$('#headline1Txt').animate({'marginLeft': "100px"}, 1000);
$("#headline1Txt").animate({left: "+=30"}, 500);
});
CSS
#headlineText {
margin: 60px 80px;
}
The left CSS property specifies part of the position of positioned
elements.
For absolutely positioned elements (those with position: absolute or position: fixed), it specifies the distance between the left margin
edge of the element and the left edge of its containing block.
https://developer.mozilla.org/en-US/docs/Web/CSS/left
As the CSS left property is part of position:*; property's, fix by adding the position property, so jquery knows what to increment a left value to.
In Action
CSS
#headlineText
{
margin:60px 80px;
}
#headline1Txt
{
position:relative;
}
HTML
<div id="mainContainer">
<div id="headlineText">
<p id="headline1Txt">Striped Bag</p>
</div>
</div>
jQuery
$(document).ready(function () {
$('#headline1Txt').
animate({ 'marginLeft': "100px" }, 1000).
animate({ left:"+=30" }, 5000);
});
What are you trying to achieve?
You want the text to slide in (heading right across the screen) then slide another 30px?
Thats what $("#headline1Txt").animate({ 'marginLeft': "+=30" }, 500); will achieve.
'marginLeft' not just left.
The left property of css only works with elements with absolute position. To make your animation work you have to put you element at absolute position.
I'm using jquery in my webpage but fadeIn and fadeOut doesn't work after the first two times. i had tried with show(500,...), hide and animate, with easing and without it, but it behaves the same.
here is one of the div's i want to fadeIn
<div id="rfcdiv" style="position: absolute; display: none" >
<img alt="Ticket" src="images/DATOSfiscales.png" style="position:absolute;width:fit-content;left:0px;top:230px;z-index:18"></img>
<div id="text1" style="position:absolute; overflow:hidden; left:45px; top:341px; width:37px; height:21px; z-index:20"><div class="wpmd"><div><font face="Myriad Pro Light"><B>RFC:</B></font></div></div></div>
<input name="RFC" id="RFC" type="text" maxlength=13 value="<?php if (isset($_GET['rfc'])){echo $_GET['rfc'];}?>" style="position:absolute;width:276px;left:79px;top:340px;z-index:13">
<div id="ValidacionRfc" style="position:absolute; overflow:hidden; left:360px; top:341px;width: fit-content;height: fit-content;z-index:14;display: none" onmouseover="mostrarglobo(1)" onmouseout="mostrarglobo(0)"></div>
here is the code that shows it:
$("#image1").animate({ height: "450px" }, 800, function () {
$("#ingresarfolio").animate({ top: "170px" }, 800, function () {
$('#rfcdiv').fadeIn(500, function () {
recheck_ticket(1);
});
});
});
you can try here: MyPage
(just pressing Enter on the textbox)
//apologize about my english
edit:
When the page loads it fades in correctly, if you put a leter on the textbox it will fadein an icon correctly but when you only press enter it will just appear after a time.
Sorry, i cant show the code correctly so the code is the first commented code in MyPage
In you script (facturar.js)
the fadeIn syntax is
$('#rfcdiv').fadeIn(function () {
recheck_ticket(1);
}, 2000);
try changing it to
$('#rfcdiv').fadeIn(2000, function () {
recheck_ticket(1);
});
Refer .fadeIn()
Then,
Remove position:absolute from all components inside #rfcdiv and let them placed in document flow.
and position #rfcdiv whereever you want by applying position:absolute, top and left to it.
like this
#rfcdiv {
display: none;
position: absolute;
top: 150px;
z-index: 999;
left: 10px;
}
From my first look without going to your website, your timing is incorrect. See edit below.
$('#rfcdiv').fadeIn(function () {
recheck_ticket(1);
}, 500);
I'm trying to have just one link on my website that links to the 'below-the-fold area' that I'll have a simple contact form at; the idea is to have that link do a nice transition similar to js parallax and once it reaches the below the fold area it kind of subtly 'bounces' a few pixels back up. (The space between anchors is about 800px)
My attempts in the code below, but it's still just being read as an anchor-point without any transition. (Should I be loading a different jQuery library, or load them in a different order?)
Updated Attempt 12-16:
Calling in the head
Libraries being called:
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
Just About before closing head tag. (A few inline styles are right before closing </head> if matters)
<script type="text/javascript">
$('a').on('click', function (event) {
event.preventDefault();//stop the browser from jumping to the anchor
var href = $(this).attr('href'),
oset = $(href).offset().top;
$('html, body').stop().animate({
scrollTop : oset
}, 700, function () {
location.hash = href;
});
});
</script>
Mark-up, CTA divs
<div id="top" class="scrollpls"><img src="http://www.mysite.com/imgs/down_btn.png" border="0" style="float:right; margin-top:200px;"></div>
..and near bottom of doc
<div id="bottom" class="scrollpls"><a href="#top">
<img src="http://www.mysite.com/imgs/upsubway.png" style=" float: right;
float: right;
margin-right: -74px;
margin-top: 700px;
}"></a></div>
http://jsfiddle.net/Hpegt/1/
A fiddle created from an early Question regarding this function and states creating a style with the div height in it. Since declaring this for all divs as in the fiddle would break my layout, I tried it with a class
.scrollpls {
height : 500px;
border :0px solid #000;
}
What am I doing wrong here? After I someday get this, I'll be trying to figure out how to implement an 'ease' with a subtle bounce back after it navs to the points.
Thanks for any help
There are tons of built-in easing effects if you include jQueryUI.
Try this modification to your fiddle - http://jsfiddle.net/CzQXC/
$('a').on('click', function (event) {
event.preventDefault();//stop the browser from jumping to the anchor
var href = $(this).attr('href'),
oset = $(href).offset().top;
$('html, body').stop().animate(
{
scrollTop : oset
},
1000,
'easeInOutElastic',
function ()
{
location.hash = href;
}
);
});
Try this:
<script type="text/javascript">
$(function() {
// this should really be in a click handler, but just for an example:
$('html,body').animate({
scrollTop: $("#testtop").offset().top
}, 2000, 'bounce');
});
</script>
Note: the bounce parameter specifies the easing to use. This is part of jQueryUI so you'll need to download that and include it on your page for the effect to work properly.
For some reason it took a few minutes to function after I put the code in, but finally it resolved and I think this was the solution:
#top, #bottom {
height : 130px;
border : 0px solid #000;
overflow:hidden;
}
How can I fade one image into another with jquery? As far as I can tell you would use fadeOut, change the source with attr() and then fadeIn again. But this doesn't seem to work in order. I don't want to use a plugin because I expect to add quite a few alterations.
Thanks.
In the simplest case, you'll need to use a callback on the call to fadeOut().
Assuming an image tag already on the page:
<img id="image" src="http://sstatic.net/so/img/logo.png" />
You pass a function as the callback argument to fadeOut() that resets the src attribute and then fades back using fadeIn():
$("#image").fadeOut(function() {
$(this).load(function() { $(this).fadeIn(); });
$(this).attr("src", "http://sstatic.net/su/img/logo.png");
});
For animations in jQuery, callbacks are executed after the animation completes. This gives you the ability to chain animations sequentially. Note the call to load(). This makes sure the image is loaded before fading back in (Thanks to Y. Shoham).
Here's a working example
$("#main_image").fadeOut("slow",function(){
$("#main_image").load(function () { //avoiding blinking, wait until loaded
$("#main_image").fadeIn();
});
$("#main_image").attr("src","...");
});
Well, you can place the next image behind the current one, and fadeOut the current one so that it looks like as though it is fading into the next image.
When fading is done, you swap back the images. So roughly:
<style type="text/css">
.swappers{
position:absolute;
width:500px;
height:500px;
}
#currentimg{
z-index:999;
}
</style>
<div>
<img src="" alt="" id="currentimg" class="swappers">
<img src="" alt="" id="nextimg" class="swappers">
</div>
<script type="text/javascript">
function swap(newimg){
$('#nextimg').attr('src',newimg);
$('#currentimg').fadeOut(
'normal',
function(){
$(this).attr('src', $('#nextimg').attr('src')).fadeIn();
}
);
}
</script>
Are you sure you're using the callback you pass into fadeOut to change the source attr and then calling fadeIn? You can't call fadeOut, attr() and fadeIn sequentially. You must wait for fadeOut to complete...
Old question but I thought I'd throw in an answer. I use this for the large header image on a homepage. Works well by manipulating the z-index for the current and next images, shows the next image right under the current one, then fades the current one out.
CSS:
#jumbo-image-wrapper
{
width: 100%;
height: 650px;
position: relative;
}
.jumbo-image
{
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
HTML:
<div id="jumbo-image-wrapper">
<div class="jumbo-image" style="background-image: url('img/your-image.jpg');">
</div>
<div class="jumbo-image" style="background-image: url('img/your-image-2'); display: none;">
</div>
</div>
Javascript (jQuery):
function jumboScroll()
{
var num_images = $("#jumbo-image-wrapper").children(".jumbo-image").length;
var next_index = jumbo_index+1;
if (next_index == num_images)
{
next_index = 0;
}
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).css("z-index", "10");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).css("z-index", "9");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).show();
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).fadeOut("slow");
jumbo_index = next_index;
setTimeout(function(){
jumboScroll();
}, 7000);
}
It will work no matter how many "slides" with class .jumbo-image are in the #jumbo-image-wrapper div.
For those who want the image to scale according to width percentage (which scale according to your browser width), obviously you don't want to set height and width in PIXEL in CSS.
This is not the best way, but I don't want to use any of the JS plugin.
So what can you do is:
Create one same size transparent PNG and put an ID to it as
second-banner
Name your original image as first-banner
Put both of them under a DIV
Here is the CSS structure for your reference:
.design-banner {
position: relative;
width: 100%;
#first-banner {
position: absolute;
width: 100%;
}
#second-banner {
position: relative;
width: 100%;
}
}
Then, you can safely fade out your original banner without the content which placed after your image moving and blinking up and down