Question

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?

Était-ce utile?

La solution 2

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();
});

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top