I am designing a mobile website keeping in mind all leading browsers - Safari, Chrome, Dolphin, Opera.
I want to show a "loading" element as and when the page navigates / changes / new page is requested.
I cannot use click event on anchor tags as there are many ones present with preventDefault();
.
I tried the following:
$(window).on('beforeunload', function() { ... });
But it does not work in Dolphin or Opera.
Can someone suggest a cross-browser solution?
--
EDIT: I realize I wasn't very clear in asking my question, apologies. I created a fiddle here- http://jsfiddle.net/hiteshpachpor/7dadA/5/ based on the response. The example makes use of event bubbling.
Now here's the problem I am facing. I would be showing that loader ($('.jacket').show();
) each time page changes / navigates. But I don't want it to show up if a link is clicked; I want to do other operations on my page instead. Now, adding the $('.jacket').hide();
line in all such actions would totally suffice but it will not be very ideal for scaling reasons.
This is why I was evaluating the 'beforeunload'
method, but no luck there as it is not cross-browser compatible.
Any kind suggestions to tackle this issue?
As was mentioned in the comments. However I prefer event delegation instead of attaching events all over the dom.
// this is your original eventListener which prevents the default action (aka, navigating away)
$('#random-link').click(function(event){
event.preventDefault();
$('#result').text('I was clicked from random-link event.')
});
// this would be the delegated listener. It wouldn't have to be all "a" tags
// that you respond to. It could be any css selector that causes the
// loading message that you want.
$(window).on('click', 'a', function() {
alert('I still bubble up.');
});
Update:
Perhaps you should not trigger $('.jacket').show()
for "links".
$('.jacket').hide();
$('a:not(.prevent)').click(function() {
$('.jacket').show();
});
$('.prevent').click(function(event) {
event.preventDefault();
$('.jacket').hide();
});
I think what you are trying to achieve are basic AJAX requests? But you are going about it the wrong way. You could instead, used a div to load in the requested pages and then setup an ajax start handler to display your loading message.
your page markup would look something like
<nav>
<button data-url="homeURL">Home</button>
<button data-url="anotherURL">Other</button>
</nav>
<div id="loadhere"></div>
the resulting jquery would be like this:
//on button click
$('nav button').click(function(){
//set the url
url = $(this).attr('data-url');
//load the page
$('#loadhere').load(url);
});
//ajax start handler
$(document).ajaxStart(function(){
$('#loadhere').text('LOADING');
});
here is an example codepen
hope this helps
You could have a onLoad function in the body element that calls a loading div to appear, then setTimeout to lets say 3 seconds then hide loading div and show all other divs/the rest of body
EDIT:
I'm pretty sure this will work on all browsers. I'll attach a code snippet once I get on my computer (on my phone now) ;)
There is a jquery mobile widget for this. This is used till version 1.4
$.mobile.loading( "show", { //show loading image
text: "Your request is processing. please wait ...",
textVisible: true,
theme: "b",
textonly: false,
});
For help Jquery Mobile Loader Widget.
In response to your edit:
You can use event.isDefaultPrevented()
.
$(function() {
$('.jacket').hide();
$('.prevent').click(function(event) {
event.preventDefault();
});
$('a').click(function(event) {
if (!event.isDefaultPrevented())
$('.jacket').show();
});
});
JSFiddle: http://jsfiddle.net/F4uPx/
Caveat: Make sure you assign the $('a').click()
event handler after the other event handlers; otherwise it will execute first and will fail since preventDefault()
won't have fired yet.