What I want to do:
Using three divs occupying the same dimensions, all display: none by default;
load 2 images into second div
show first div for 500ms
show second div for 500ms
then show 3rd div.
Seem simple enough?
The weird thing is that like 15% of the time it's like it appears to wait on the first div and display it longer, then the second div will never be seen, appearing to go directly to the third div.
html:
<div id="div1">...</div>
<div id="div2"><div id="img1"></div><div id="img2"></div></div>
<div id="div3">...</div>
Attempt #1:
var focus_length = 500;
var stimuli_length = 500;
// dummy values
var newimg1 = 'https://www.google.com/intl/en_com/images/srpr/logo3w.png';
var newimg2 = 'https://www.google.com/intl/en_com/images/srpr/logo3w.png';
console.log("step 1");
$("#div1").show();
$("#img1, #img2").empty();
$("#img1").append($(document.createElement('img')).attr('src', newimg1));
$("#img2").append($(document.createElement('img')).attr('src', newimg2));
window.setTimeout(
function () {
console.log("step 2");
$('#div1').hide();
$('#div2').show();
}, focus_length);
window.setTimeout(function () {
console.log("step 3");
$('#div2').hide();
$('#div3').show();
}, focus_length + stimuli_length);
Second variant (same apparent behavior):
console.log("step 1");
$("#div1").show();
$("#img1, #img2").empty();
$("#img1").append($(document.createElement('img')).attr('src', newimg1));
$("#img2").append($(document.createElement('img')).attr('src', newimg2));
window.setTimeout(
function () {
console.log("step 2");
$('#div1').hide();
$('#div2').show();
window.setTimeout(function () {
console.log("step 3");
$('#div2').hide();
$('#div3').show();
}, stimuli_length);
}, focus_length);
I've also tried setting opacity=1 or 0 rather than using jquery show/hide, with the same result.
What's really weird is that even when experiencing this issue the timings on the 3 console.log() messages are still 500ms apart! So it's like it's like javascript is calling it correctly but the browser just doesn't bother to actually show the redraw. Even stranger this happens on both Chrome and Safari.
update
I tried setting stimuli_length to 1000 above. With this change it will sometimes appear to lag a bit on the first div and show the second div for a smaller amount of time, but does not appear to ever completely skip it. 500ms is a strict design requirement, however.
Maybe there's something here with the dynamic appending of your images. Even if you show the div, if the images didn't have time to load, it will look exactly the same as if it was never shown.
Have you tried changing your delay for something like 10 seconds to be sure (or almost) that the images had time to load?
Adding $("#div2, #div3").hide(); after you show the first div makes it work for me in this jsfiddle.
Why don't you use
('#div1').show(timeinmiliseconds);
It could solve your problem and also use callback for one after another
like
('#div1').show(timeinmiliseconds,('#div2').show(timeinmiliseconds, ('#div3').show(timeinmiliseconds);););
Related
I am using localstorage to show a div only once, and although the code it works very well, I would like to know how I can delay the visibility of this div ( #alert ) for 1 - 2 seconds (the first time the visitor is shown), and then do a fade in, so that it does not appear suddenly.
My code:
const showMsg = localStorage.getItem('showMsg');
if(showMsg === 'false'){
$('#alert').hide();
}
$('.closebtn').on('click', function(){
$('#alert').fadeOut('slow');
localStorage.setItem('showMsg', 'false');
});
You can run the demo here:
https://jsfiddle.net/0966x2dw/7/
My problem has a solution?
Thanks.
EDIT:
Ops, right. I used CSS Transitions on my #alert div, and now it's much better.
Thanks.
https://jsfiddle.net/0966x2dw/23/
First add "display: none;" to your .alert. Then you can do something like:
if(showMsg === 'false'){
$('.alert').hide();
} else {
$('.alert').delay(1000).fadeIn();
}
This will cause your alert div to bump the content below it down. You may want to use slideDown() instead to make it less abrupt.
(Note that if your alert is critical to your users, you should adjust this to make sure it displays for the small % of people who have Javascript off.)
Hey guys I'm making my own website just for fun and the following code makes a list of shapes appear. Does anyone know how I could incorporate another button instead of the fadeOut code to make it so that when I click another button, a "hide menu" button. The shapes will fadeOut. This is because the code I have at the moment means that the shapes will fade out by themselves over time. Pls help!
<script>
$(document).ready(function(){
$("button").click(function(){
$("#div1aside").fadeIn(100);
$("#div2aside").fadeIn(200);
$("#div3aside").fadeIn(300);
$("#div4aside").fadeIn(400);
$("#div5aside").fadeIn(500);
$("#div6aside").fadeIn(600);
$("#div7aside").fadeIn(700);
$("#div8aside").fadeIn(800);
$("#div9aside").fadeIn(900);
$("#div10aside").fadeIn(1000);
$("#div11aside").fadeIn(1100);
$("#div12aside").fadeIn(1200);
$("#div13aside").fadeIn(1300);
$("#div14aside").fadeIn(1400);
$("#div15aside").fadeIn(1500);
$("#div16aside").fadeIn(1600);
$("#div17aside").fadeIn(1700);
$("#div18aside").fadeIn(1800);
$("#div1aside").fadeOut(17670);
$("#div2aside").fadeOut(17660);
$("#div3aside").fadeOut(17650);
$("#div4aside").fadeOut(17640);
$("#div5aside").fadeOut(17630);
$("#div6aside").fadeOut(17620);
$("#div7aside").fadeOut(17610);
$("#div8aside").fadeOut(17600);
$("#div9aside").fadeOut(17590);
$("#div10aside").fadeOut(17580);
$("#div11aside").fadeOut(17570);
$("#div12aside").fadeOut(17560);
$("#div13aside").fadeOut(17550);
$("#div14aside").fadeOut(17540);
$("#div15aside").fadeOut(17530);
$("#div16aside").fadeOut(17520);
$("#div17aside").fadeOut(17510);
$("#div18aside").fadeOut(17500);
$("section").fadeOut(0);
});
});
</script>
If I understood your question right, you should do a toggle, I find this the simpliest way to do that:
$(document).ready(function(){
var toggle = 0;
$("button").click(function(){
if (toggle === 0) {
$("#yourDivsToFadeIn").fadeIn(YourTimeToFadeIn);
toggle = 1;
}
else if (toggle === 1) {
$("#yourDivsToFadeOut").fadeOut(YourTimeToFadeOut);
toggle = 0;
}
});
});
EDIT: You also could use:
$(document).ready(function() {
$("button").click(function() {
$("#YourDivsIds").fadeToggle(YourTimeToToggleTheFade);
});
});
But I find the first way to do this better, because if you get to learn some more Javascript/jQuery, there arent always .toggle methods to toggle something. Then you better should learn - and get used to - the first method.
-But thats just my point of the view.
At first you need two buttons in your HTML:
<button id="infader">Fade all in</button>
<button id="outfader">Fade all out</button>
Then in your JS you first select all divs to fade with one jQuery selector and store them in a variable. It's faster, less to write and the attachment of the different fading times becomes easier.
// get all divs with an ID that ends with 'aside'
var asides = $("div[id$='aside']");
// get first button and attach the click-handler
$("#infader").click(function() {
// take all asides and use 'each() to execute a function on each of them
// keyword 'this' is one div-element, i is it's index in the collection
asides.each(function(i) {
// the divs gets a fading time depending on their index
// the first (i == 0) gets 100ms, the last (i == 17) gets 1800ms
$(this).stop().fadeIn((i + 1) * 100);
});
});
// get second button similar
$("#outfader").click(function() {
asides.each(function(i) {
$(this).stop().fadeOut((17 - i) * 10 + 17500);
});
});
What does the .stop() before fade? Lets say you have started a fadeIn and then click the out-button before it has completed. Now the fadeIn ist stopped and the fadeOut begins immediately. If you want instead the fadeIn finishing completely before fadeOut runs just remove the .stop().
Its easy to change the fade-times to fit your needs.
I have a page with a lot of elements (~1,500) of the same class on it, and when I execute
$(".pickrow").addClass("vis");
it takes a second or two for the page to reflect the changes. So that users aren't thinking the page was stuck, I'd like to pop-up a small message using:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").hide();
But the msgDiv never shows. If I remove the $("#msgDiv").hide(); the msgDiv appears simultaneously with the application of the added class (after the 1 or 2 seconds it took to add the class).
It seems like the jQuery functions get pooled and run together without any screen updates until they have all completed.
How can I get the msgDiv to appear while the $(".pickrow").addClass("vis"); is processing?
Here's a Demo
You probably want to delay the hide by a few seconds.
$("#msgDiv").show();
$(".pickrow").addClass("vis");
setTimeout(function(){ $("#msgDiv").hide(); },2000);
Or using jQuery's animations queue for timing:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").delay(2000).hide(1); //must make it at least 1 ms to go into the queue
You can go with this approach also
Working DEMO
$(document).on("click",".btn",function(){
$(".msg").show("fast",function(){
$(".pickrow").addClass("vis");
var interval = setInterval(function(){
var picLength = $(".pickrow").length;
var visLength = $(".vis").length;
if(picLength == visLength){
clearInterval(interval);
$(".msg").hide();
}
},500);
});
});
I think if you simplify the code, you would find that it is much more responsive and probably not require the loading message. In your code, you check every single element in an if statement. Rather than do that, you can check one value, then update all of them accordingly.
Here's a demo: http://jsfiddle.net/jme11/3A4qU/
I made a single change to your HTML to set the initial value of the input button to "Show Details". Then in the following code, you can just check whether the value is Show Details and remove the class that hides the .pickrow and update the value of the button to be "Hide Details" (which is better feedback for the user anyway). Likewise, you can add the .hid class to the pickrow if the button value is not "Show Details". This will also normalize all of the classes regardless if some were individually hidden or shown.
$('#showhide').on('click', function(){
if ($(this).val() === 'Show Details') {
$('.pickrow').removeClass('hid');
$(this).val('Hide Details');
} else {
$('.pickrow').addClass('hid');
$(this).val('Show Details');
}
});
I want to slideDown() a div when the appropriate radio is selected, and slideUp the active one.
However, as it is now, in some cases it's being pushed down, in other cases pushed up.
(Private -> Shop = Up, Shop -> Private = Down)
I want it to always be pushed down. What am I doing wrong?
Here's the current state on JSFiddle: http://jsfiddle.net/mfmU7/
And the raw Javascript code:
$(document).ready(function() {
$("#private").click(function() {
$('#registration-brand, #registration-shop').slideUp();
$('#registration-private').slideDown();
});
$("#shop").click(function() {
$('#registration-brand, #registration-private').slideUp();
$('#registration-shop').slideDown();
});
$("#brand").click(function() {
$('#registration-shop, #registration-private').slideUp();
$('#registration-brand').slideDown();
});
});
It's all about position in the DOM (or z-index):
$(document).ready(function() {
$('.btn').on('click', function() {
var that = $('#registration-'+this.id);
$('.registration-type:visible').not(that).slideUp().before(that.slideDown());
});
});
FIDDLE
I had same problem and I resolve it by adding:
position:absolute;
bottom:85%;
to CSS and it solves your isue here
but then u have to again place those divs
Here: http://jsfiddle.net/isair/mfmU7/4/
The problem (that some slide up visually and some slide down visually) is caused because, in your original code, all the animations are occurring at once and the divs are vertically placed one above the other. So the top one looks like it is sliding down but the other two, while sliding down, look like they are popping up from the bottom because of the one that is in the process of hiding.
I like doing it this way so one action doesn't start until the others are over:
$("#private").click(function() {
$('#registration-brand, #registration-shop').slideUp(function() {
$('#registration-private').slideDown();
});
});
FIDDLE HERE
The problem with doing that (like I usually do) is that the function gets called twice, once when the already hidden div finishes hiding, which is almost immediately, and once after the other div finishes hiding (4/10 sec later). The second one does nothing because the appearing div is already fully visible (or almost so).
So ... another solution is needed.
This one has a whole different look because it waits until both slide up actions are done (even though one div is already hidden) before starting the slide down. The 'promise()' creates something that will be finished when all the 'slideUp()' calls complete their animation and the 'always()' calls the function when that is done.
$("#private").click(function() {
$('#registration-brand, #registration-shop').slideUp().promise().always(function() {
$('#registration-private').slideDown();
});
});
ALTERNATE FIDDLE
I'm required to develop a slideshow (not an existing one) with jQuery. I was able to change picture with a function that I created named changePic (takes an image link). It incorporates the fading animation from the jQuery library.
For the slideshow I'm trying to use a while loop. It kind of works, except that it doesn't wait for the animation to finish.
How do I, a) wait for the animation to finish, b) delay the changing picture so it display the picture for a couple of seconds?
Also tried Settimeout, and it doesn't work.
Edit:
Basically changing image is like this:
function changePic(imglink){
var imgnode = document.getElementById("galleryimg");
$(imgnode).fadeTo(500, 0, function(){
$(imgnode).attr("src", imglink);
$(imgnode).fadeTo(1000, 1);
})
}
and the slideshow code is like this, but obviously it shouldn't.
function slideshow(gallerylinks){
var i=0;
while (i<gallerylinks.length){
changePic(gallerylinks[i]);
i++;
}
}
You could always try ditching the while loop, and going with a perpetually recursive function...
on the .animate, you could add a timeout function (at whatever interval) that calls the changePic function. As I have no idea what your code looks like, I will provide a fantastically generic outline.
/* array of imgUrls */
var imgUrls = new Array(); //populate it however
changePic(slideToShowIndex, fadeOutSpeed, fadeInSpeed, slideDelay)
{
$('#slideHolder').animate({ opacity: 0}, fadeOutSpeed , function(){
$('#slideHolder').attr('src', imgUrls[slideToShowIndex]);
$('#slideHolder').animate({ opacity: 1 }, fadeInSpeed, function() {
setTimeout(function() { changePic(slideToShowIndex+1, fadeOutSpeed, fadeInSpeed, slideDelay);}, slideDelay});
});
}});
}
$(document).ready(function() {
changePic(0, 5000, 5000, 10000);
});
This should (in theory) fade the image out, swap it with the new one, and fade it in (both taking 5 seconds) and then adding a delay to call itself with the next slide index in 10 seconds.
This is in no way perfect, but does outline the general idea. Since we have no idea what your code looks like, I can only assume your setTimeout was in the wrong spot. Doing it like this will make sure that the animation has finished before the timeout is set. This guarantees that the slide wont change until after the animation has changed.
of course you could always use a combination of the ':not(:animated)' selector and a setInterval to achieve much the same effect.
EDIT: made a slight change to stack the animations properly. The thoery behind this still works even with the OPs addition of code.
You could have provided more details or example code but have a look at stop() and delay() functions.