jquery .show() and .hide() not working in safari - adding spinner to <a href
Solution 1
It appears that you function is named spinner
, yet you're attempting to fire loading()
inside your a
tag (onclick="javascript:loading();
). Changing your function name to loading
should fix it.
Here's a working example:
https://jsfiddle.net/nvzge1e8/5/
Edit for updated question:
You need to prevent the event, if you stick event.preventDefault()
at the top of your function, it should play the animation. Do note, doing this will prevent your link from actually sending your user to the page, so you may need to add a timed redirect to whatever page you're sending them to.
Example code:
$(function() {
$(".spin_click").click(function(event) {
event.preventDefault()
$("#logo_spinner").attr("src", "/static/images/loaders/spinner.gif");
$('.content').addClass('hide');
setTimeout(function() {
window.location.href = "/wait";
}, 4000);
});
});
Solution 2
I am unable to reproduce the issue with the code provided. However, I am adding an answer with a simple version of what you want to accomplish.
My guess is that the code not provided is more complex than you describe (or some dependencies are missing).
Since you already are using jQuery, I am giving you my answer using that library as well.
(updated: added other libraries, used by the OP, to test if their presence introduces the issue described)
See sample code below:
$(function() {
// add event listener to home (class) -
// used instead of inline binding using 'onclick'
$('.home').on('click', function() {
console.log('show spinner');
// show spinner right away
$("#loading").show();
console.log('waiting now...');
// simulate delay in fetching backend response (delay is 3 secs)
// contains the callback function to be invoked after your response is completed
setTimeout(function() {
// hide spinner
console.log('hide spinner');
$("#loading").hide();
// show content
console.log('show content');
$("#content").show();
}, 3 * 1000); // time is in ms so 1000ms = 1 sec (3*1000=3secs)
});
});
div#loading {
height: 50px;
position: relative;
display: none;
background: white;
}
.ajax-loader {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
max-width: 100px;
margin: auto;
}
#content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.min.js"></script>
<header>
Header here
</header>
<hr/>
<a href="#" class="home">Home</a>
<div id="loading">
<img class="ajax-loader" src="https://i.stack.imgur.com/akN6H.png?s=48&g=1" alt="" width="24" height="24" class="avatar-me js-avatar-me">
</div>
<hr/>
<div id="content">
content will be loaded here
</div>
<footer>footer here
</footer>
Solution 3
I have not tested this in Safari but you could try
$("#loading").fadeIn(0);
$("#content").fadeOut(0);
But make sure to remove the
display: none
from your CSS
Solution 4
Sorry haven't tried reproducing your bug but unless you must use elem.hide()
and elem.show()
.
Alternatively, You can work with addClass and removeClass functions
$('#loading').addClass('hide');
$('#loading').removeClass('hide');
with .hide { display: none; }
works perfectly on safari too.
Solution 5
Instead of $('elem').show()
and $('elem').hide()
try using...
$('elem').attr( 'data-display', 'block');
$('elem').attr( 'data-display', 'none');
In CSS add...
Attribute selector used twice to increase specificity ;)
[data-display][data-display='none'] {
display:none!important;
}
[data-display][data-display='block'] {
display:block!important;
}
Code will look like this...
$('h1').attr( 'data-display', 'block');
$('h2').attr( 'data-display', 'none');
[data-display][data-display='none'] {
display:none!important;
}
[data-display][data-display='block'] {
display:block!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>I'm displayed</h1>
<h2>I'm hidden</h2>
<p>
I'm unaffected ;)
</p>
This will hide it (even if there is some css forcing visibility by using !important
), if not try increasing specificity of selector even more. Inspecting the element would help ;)
Related videos on Youtube
archienorman
Updated on September 14, 2022Comments
-
archienorman over 1 year
I have some very basic code that acts as a loading gif for a webpage:
The loading and content containers sit in my base template. The
//header <a href="{{ url_for('welcome', id=id, profile=profile) }}" onclick="spinner();" class="home">Home</a> //more html <div id="loading"> <img src="/static/images/Loading.gif" class="ajax-loader"> </div> <div id="content"> {% block content %}{% endblock %} </div> <script type="text/javascript"> function spinner() { console.log('fire'); $("#loading").show(); $("#content").hide(); } </script>
div#loading { height: 350px; position: relative; display: none; background: white; } .ajax-loader { position: absolute; left: 0; top: 0; right: 0; bottom: 0; max-width: 100px; margin: auto; }
My code works perfectly well in firefox and chrome, but not in safari or on ios.
ps. I have checked that my function is working, the console shows 'fire' which i print straight after the onclick().
Edit
This is the only error in the console:
[Error] Failed to load resource: the server responded with a status of 404 (NOT FOUND) (jquery-ui.min.css, line 0)
Update 1
I have added a class to my
<a href="url" class="..."
and updated my javascript to the following:<script type="text/javascript"> $(function() { $( ".spin_click" ).click(function( event ) { event.preventDefault(); console.log('hiding content'); $(".content").hide(); console.log('show spinner'); $(".se-pre-con").show(); console.log('waiting now...'); }); }); </script> #html <div class="se-pre-con"></div> <div class="content"> {% block content %}{% endblock %} </div>
I can get safari to show the
se-pre-con
div when I click on a link, however it completely disables the href link. Is it possible to pursue the link click having executed the .show() command in the jquery? Perhaps I have misunderstoodpreventDefault();
- but I thought it might be able to act as a workaround. The issue still only exists in safariUpdate 2
As suggested by @maximast, I have decided to use addClass and removeClass. As usual it works in chrome and firefox, but not safari. The code is the same, I have just added a
hide
class which is added and removed as necessary.If I use the safari inspector and remove the hide class manually, the spinner does show up. When I click on a link in the page to trigger the jquery function, I can see the
hide
class removed correctly from thediv
. However, even though thehide
class is removed, the spinner does not appear. Perhaps I am missing something obvious here.Here are the libraries i am using:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.min.js"></script>
Update 3
Here is a link to a test page. There is a link which puts the app to sleep for 3 seconds giving enough time for the spinner to trigger. The spinner sits in the logo. The test page will show the spinner working in a Chrome and Firefox, but not safari. The implementation with this button is exactly the same as used elsewhere in my app.
http://ec2-54-88-245-245.compute-1.amazonaws.com/spinner-test
I have changed the link in the logo to:
<a href='#'
which for the first time render the spinner in all three browsers. (progress!). However when you click on the 'Click to trigger spinner.' link, the following happens:- Chrome - spinner works first time.
- Firefox - spinner works first time, however there were a couple of occasions when I had to click it a second time.
- Safari - no luck.
Here is the flask code with the managing the spinner-test page:
@app.route('/spinner-test', methods=['GET']) def spinner(): return render_template('spinner-test.html') @app.route('/wait', methods=['GET']) def wait(): time.sleep(3) return redirect(url_for('spinner'))
-
Admin over 7 yearsSince you seem to have an element ID somewhere called
loading
, try changing the name of the function to some other name. -
archienorman over 7 years
jquery-ui.min.css - Failed to load resource: the server responded with a status of 404 (NOT FOUND)
this is the only error. Change the function name did not help. Removedjavascript:
-
blurfus over 7 yearsCan you add some of the HTML to make it a minimal reproducible example? So far, code posted is not enough to replicate the issue for me
-
Mendy over 7 yearsYeah, at this point I doubt it's an issue with the snippet of code you provided (as all of the examples are working fine on my Safari). It's more likely an issue with your Safari (try updating it), or as @ochi mentioned, perhaps some dependencies are missing. I would perhaps check if there's any events bound to
.spin_click
.
-
archienorman over 7 yearsthis makes the
loading
div appear the whole time -
archienorman over 7 yearssorry that was a mistake on my part, i just the function name as per a comment earlier on. The functions names are the same in my code. The discrepancy is only on SO
-
Mendy over 7 yearsAh, no worries. Are you sure you've added jQuery before this function? Does my jsfiddle link work for you?
-
archienorman over 7 yearsi load jquery in the head:
script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
but it works in firefox, so surely the position of jquery wouldn't make a difference. unfortunately, the jsfiddle doesnt work for me -
blurfus over 7 yearsthe issue seems to be safari-specific (OP says it works on FF and chrome) so unless you can replicate the issue (which you didn't as you didn't test it in Safari) - this is not a good answer. I recommend testing it in safari or remove it
-
Mendy over 7 yearsCan you add
console.log (typeof jQuery)
to the top of your function, and let me know what the console logs? -
archienorman over 7 yearsthe log says:
function
-
archienorman over 7 yearsthank you for this detailed answer. i have added the changes you suggest and unfortunately see the same behaviour. It works with firefox, but not safari
-
blurfus over 7 years@user3939059 any error in console? - I will try safari shortly
-
archienorman over 7 yearsthere is no error. as an fyi, your code also works in chrome. but still no luck with safari or iOS
-
Mendy over 7 yearsAlright, that indicates jQuery is loading fine. What version of Safari are you working with?
-
archienorman over 7 years
Version 10.0.1 (12602.2.14.0.7)
-
archienorman over 7 yearsit works in firefox, but again does not work in safari logs:
n [div id="loading"] Could not fetch properties. Object may no longer exist.
-
archienorman over 7 yearsthanks for your answer. i have tried with
addClass
andremoveClass
and can see that the js works, thehide
class is added and removed respectively. However the spinner still does not appear in safari. Which makes me think this could be acss
issue. -
blurfus over 7 years@user3939059 I am sorry I didn't get back to you... I did try it on safari (on Sierra) and it did work for me as expected. - is it possible that you have other JS libraries that might be interfering with this?
-
blurfus over 7 yearswhy would you assume there is a bug in
hide()
andshow()
functions (pretty basic functionality) with such a popular library such as jQuery? Don't you think that it would have been fixed by now? did you look at their issue tracker to see if there is such a thing (maybe with certain versions of Safari only)? - no, instead, you assume there is a bug (blame someone else) and provide an alternative that, basically, does the exact same thing as the functions :( - (if you look at their code, it does what you suggest) -
blurfus over 7 yearsI tried Safari Version 10.0.1 (12602.2.14.0.7) - which version are you trying it with?
-
Qwertiy over 7 yearsSince what version does jQuery support setting inline
important
? As I remember, it didn't. -
blurfus over 7 years@user3939059 oh, and which version of JQuery are you using?
-
archienorman over 7 yearsHi, jsut adde the scripts being loaded into the question. the version is
2.1.1
-
blurfus over 7 years@user3939059 I added the dependencies and tested it in Safari again, I still cannot reproduce the issue. I am afraid there is something else in your code causing this issue. Can you share more of your code?
-
shramee over 7 yearsHi @Qwertiy, Yeah, thanks for pointing out updated my answer :)
-
maximast over 7 yearsnot blaming anyone just trying to help the guy get past his problem.
-
maximast over 7 yearsedited, now am not assuming anything hope that works for you. cheers
-
ViniH almost 5 yearsI am wondering if this might be the cause. OP: are you/were you using Bootstrap by any chance? stackoverflow.com/questions/51005067/…