Calling toggle takes a long time to load, so I'm trying to add a loading img while loading but it doesn't seem to load when you .showall is activated look at * in the following code
$('#loading').hide();
$(".showall").toggle(
function(){
$('#loading').show(1); // * added
$(".toggle_container").slideDown();
$('#loading').hide(); // * added
},
function () {
$('#loading').show(1); // * added
$(".toggle_container").slideUp();
$('#loading').hide(); // * added
}
);
The other response of calling hide in the callback is the correct approach, but I figured I'd answer to point out why.
There are actually multiple issues here. Your intention is to show #loading then slideup and once that is complete, hide #loading. However, when slideup is called, the animation is queued up and your code moves on, the code does not wait for slideup to complete and then move on to the next line. This is why you need to use the callback, to call hide after slideup completes.
Another thing that many people overlook is that show and hide when called with a duration are animations and are therefore queue, however, when no duration is passed these calls are NOT animations and will NOT be queued. So, calling show with a duration and then immediately calling hide with no duration will never show the element. See this for an illustration of that: http://jsfiddle.net/zZHhm/ notice that you never see DIV2.
Also, the durations passed to show and hide are in milliseconds, so hide(1) gives a duration of 1 millisecond (you may be aware of this).
I admit, something weird is happening while using show/hide with or without parameter. This version works, but I don't know why these methods without parameters doesn't behave as they should.
Code: ( http://jsfiddle.net/z3HRQ/2/ )
$('#loading').hide(1);
$('.showall').toggle(
function () {
$('#loading').show(1);
$('.toggle_container').slideUp(function () {
$('#loading').hide();
});
},
function () {
$('#loading').show(1);
$('.toggle_container').slideDown(function () {
$('#loading').hide();
});
}
);
Related
I'm very new to JavaScript / JQuery and having some issues with what should be a simple conditional formatting function. The conditional formatting function itself works fine, on initial page load; however, after performing an element reload set to run every 60 seconds, it breaks the conditional formatting again.
Here's the JavaScript:
$(document).ready(function(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
});
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*","");
}, 60000);
It's probably worth mentioning that it's only the ticker-item formatting that's going wrong after the element reload. The carousel-item formatting works fine. The ticker-items are inside the #top-bar element, whereas the carousel-items are not, so to me it's clear that the issue is within the #top-bar element as a result of the reload.
I've also tried the below code, to no avail:
$(document).ready(function(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
});
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*","");
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
}, 60000);
What's more strange is that with this code, if I change the interval for the reload to 10 seconds, it seems to break the formatting for a few seconds but then fix it again, almost as though it is waiting for the rest of the function to execute before catching up with itself.
As I said, I'm new to JS and I've searched everywhere for a solution to this. Am I doing something wrong?
If you need anything else (i.e. HTML), please let me know.
Thanks in advance for your help.
if you want it to be done again and again you should create a separate function to that.
And the load function will trigger a callback whenever it completes you can use that callback to reformat it again.
function reFormat(){
$('.ticker-item:contains("-")').css('color', 'red');
$('.ticker-item:contains("+")').css('color', '#2FA702');
$('.carousel-item h3:contains("Closed")').css('color', 'red');
$('.carousel-item h3:contains("Open")').css('color', '#2FA702');
}
$(document).ready(function(){
reFormat();
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*", function(){
reFormat();
});
}, 60000);
});
When you execute .load(), it takes some amount of time to go get the new data and insert elements into the DOM. However, the subsequent Javascript code there doesn't know that it's supposed to wait until .load() has finished and created the new elements.
In timeline form, what's currently happening is:
call .load()
find and style any .ticker-item elements that are present
data received back from .load()
create new .ticker-item DOM elements
What you want to happen:
call .load()
wait until data received back from .load()
create new .ticker-item DOM elements
find and style any .ticker-item elements that are present
Anees' answer is exactly what you want: consolidate your formatting code into a single function, then call that as a callback function after .load() has finished.
As you progress in learning JavaScript, check out Promises and async/await as well.
EDIT:
There may still be a subtle delay between .load() finishing and those elements being present in the DOM.
One way to find out if that's the case would be to add a delay before calling reFormat() in the callback:
var elementCreationDelay = 500; // experiment with this duration
var refreshTickers = setInterval(function () {
$("#top-bar").load(location.href+" #top-bar>*", function(){
setTimeout(reFormat, elementCreationDelay);
}, 60000);
I doing a little project which shows the internet speed by pinging the website and shows the network speed. but the problem is I have to reload every time to get the speed. How to make the div tag which contains the value of the speed to change dynamically.
I tried to load the value of the tag to itself but it doesn't work for me.
The HTML:
<h2> <span id="speed"></span> kbps</h2>
The JS:
kbitsPerSecond has the value of the speed.
$(document).ready( function () {
$('#speed').load('kbitsPerSecond');
refresh();
});
function refresh() {
setTimeout ( function() {
$('#speed').fadeOut('slow').load('kbitsPerSecond').fadeIn('slow);
refresh();
},200);
}
The tag has to be reloaded dynamically
First, you have two syntax problems.
The JQuery .load() method takes a URL as the first argument, you are passing the string 'kbitsPerSecond', which is not a URL:
$('#speed').load('kbitsPerSecond');
Your call to .fadeIn() is missing a closing quote and, if you want the fade in to happen after the .load has completed, you should not chain it after .load, but instead include it in the .load() callback:
$('#speed').fadeOut('slow').load('https://example.com').fadeIn('slow);
Now, setTimeout() is a one-time timer. Instead of making refresh() recursive, use setInterval() which is a continuous timer -- it counts to its supplied interval and then fires its callback function, then it counts again and fires again and so on. However, this will continue even after the page has finished loading, so you'll probably want to cancel the timer at some point.
Also, you don't need two separate .load() calls and a separate function as shown below:
let timer = null; // Will hold a reference to the timer
$(function () {
timer = setInterval (function() {
$('#speed').fadeOut('slow').load('https://example.com', function(){
$('#speed').fadeIn('slow');
});
},200);
});
// Uncomment and add the following to some callback that fires when you no longer want the timer to run
//clearInterval(timer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2> <span id="speed">TEST</span> kbps</h2>
I am appending an array to a div using jquery, I want to show a small loading indicator while this happens, so I threw a call back function onto my append logic. This works, however, my loader will fire off it's .hide() before my array is painted into the div.
Is there a way I can only run the .hide() after the array has finished painting?
var contentpush = [];
// create x-amount of divs (x being 'tabs')
for (var i = 0; i < tabs; i++){
contentpush.push('<li class="tab" role="tab"><span class="icon"><span class="'+contentformat[i].icon+'" ></span></span><span class="title">'+contentformat[i].title+'</span></li>');
}
$('.tablist').append(contentpush.join('')).ready(function(){$('#skeleton').hide(); });;
Here is a gif of what is going on as well:
As you can see, the skeletal frame loader will disappear long before my array is actually painted into the div. Any thoughts on this are greatly appreciated!
Have you tried setting a timeout for some milliseconds?
Unfortunately, the jQuery .append() function does not include a callback. There is no way to really check for completion of it, as it supposedly happens immediately. synchronously in the order they come, unless you explicitly tell them to be asynchronous by using a timeout or interval. see this
This means that your .append method will be executed and nothing else will execute until that method have finished its job. try following
// set a time interval for the event to complete.
$(contentpush).hide().appendTo(".tablist").fadeIn(1000);
// a small tweak to set a call back function.
$(".tablist").append(contentpush).append(function() { $('#skeleton').hide(); });
I am trying to prevent an element from being animated until a specific function is complete. The problem is that the animation starts while the function still is running, so the animation is extremely laggy and jumpy instead of smooth and calm as it is when I disable the function.
My code looks something like this:
function editElement() {
// Do a lot of calculations and edit what is inside #box (no Ajax)
}
$("#click").click(function() {
editElement();
$("#element").slideDown("slow");
});
How can force the slideDown animation to wait until the function is complete before running?
I have tried callbacks and $.Deferred suggested in other questions, but most of them seem to be directed towards Ajax and do not work for me. Thank you for your time!
slideDown is always executed after editElement has finished executing its code because JavaScript is a "linear language". The only exception is when there are asynchronous functions inside, including AJAX and setTimeout / setInterval.
One suggestion though is that you can do this:
function ediElement(..., callback){
//codes here....
//Make sure there is no asynchronous functions.
callback();
}
$("#click").click(function() {
editElement(function(){
$("#element").slideDown("slow");
});
});
There are several posts relating to this, but none actually gives a solution.
What actually happens is as follows:
function LoadSpinner()
{
$("#divSpinner").css('display','block'); // could have done with .show()
}
function UnloadSpinner()
{
$("#divSpinner").css('display','none'); // could have done with .hide()
}
function OnClickMyButton()
{
LoadSpinner();
AnAjaxCall(); // it's set to async: false, that means the ajax call must finish before execution continues
UnloadSpinner();
}
I tried commenting the UnloadSpinner() and it does show in IE 8. Could it be that it happens so fast that I don't see it. But I am not too sure about that, cause even for some slower operation it does not show up.
It's working fine on Firefox though.
Is the issue that you're doing a synchronous ajax call? I believe this freezes the browser from executing any other actions including repainting the screen to show your spinner. Try making your ajax call asynchronous and hide the spinner in the callback. I bet you that works. Something like this:
function OnClickMyButton()
{
LoadSpinner();
AnAjaxCall(function() { UnloadSpinner() } );
}
function AnAjaxCall(callback)
{
//do ajax. On complete, call callback. check the web for examples.
}
I would bet you the issue has nothing to do with jquery, but with the synchronous ajax call.
To test my theory try this code:
function OnClickMyButton()
{
LoadSpinner();
setTimeout(function() { UnloadSpinner() }, 2000);
}
I bet you the spinner appears for 2 seconds just fine. If it doesn't then ignore this post.. I'm completely wrong.
$(function() {
$("#d").hide();
$('#b').click(function() {
$('#d').show();
});
});
<div id="d">hello</div>
<input type="button" id="b" />
Works fine for me in IE.
Do you have a specific example ? I don't recall encountering that problem despite I use show() quite often.
I have done a bit of debugging on it and found that the Browser wasn't doing the necessary updates on time. That is why by the time it was suppose to be visible, the Unloader() was called and it got hidden again.