4

I can't get all of these to work together. I have phonegap/JQM running with fastclick.js perfectly on iOS. It's a dream. But for some reason I still get a 300ms delay on android. I put some alerts in and the code is being called. It's baffling really. I am testing on a motorola droid razor maxx.

In my index.html file:

<!DOCTYPE html>
<html>
    <head>
        ...
        <script type='application/javascript' src='js/fastclick.js'></script>
    </head>
    <script>
    $(document).on("pagebeforechange", function (e, data) {
        FastClick.attach(document.body);
        alert('fastclick attached');
        var to_page = data.toPage[0].id;
        // skip showing #myPage if condition is true
        if (to_page == "index") {
            $.mobile.pageContainer.pagecontainer('change', 'event-list.html');
            e.preventDefault();
        }
    });

    </script>
    <body>
        <div id="index" data-role="page">
        This is the index page.
        </div>
    </body>
</html>

But it doesn't seem to work. I've also tried attaching it like:

window.addEventListener('load', function() {
    new FastClick(document.body);
}, false);

Which both work on iOS but don't seem to have any effect on android. Any suggestions?

edit: It seems if I remove the JQuery libraries it works fine. There has got to be a conflict somewhere. Any idea what it may be? I am using JQM 1.4.

edit: I have also tried using vclick to no avail

$("#test-element").bind('vclick',function() {
    $.mobile.pageContainer.pagecontainer('change', 'description.html?lunch_pk=2133',{
        transition: "slide",
    });
});
...
<h1 id='test-element'> CLICK HERE FOR TEST </h1>

I am also using gestures to change pages which are also being delayed by 300ms, so I don't think that even if vclick was working that it would be a complete solution.

edit: ok, so after some further testing, I am pretty sure the delay is coming from inside JQM pagechange functions. I did a console.log inside the vclick and I the log is pretty responsive when hitting the button. I am trying to dig through JQM but not being very successful, I mean why would it be seemless on iOS and not work on android? And maybe I just need to find a better mobile library.

Answer

I was never able to solve this problem. My solution was to switch libraries. I went to Intel's mobile app framework which was able to do everything I was doing with JQM only more successfully.

Chase Roberts
  • 9,082
  • 13
  • 73
  • 131

6 Answers6

1

You can try vclick without trying onclicks. These built-in jQuery Mobile vclick omits the 300ms delay. I do this by doing this.

$("#element").bind('vclick',function(event) {
   yourFunction(this.id);
   event.preventDefault();// this prevents the default click event
});
Omar
  • 32,302
  • 9
  • 69
  • 112
Juliyanage Silva
  • 2,529
  • 1
  • 21
  • 33
  • No dice, I am still getting a 300ms delay with this code. – Chase Roberts Mar 02 '14 at 00:15
  • I use this bind and working fine in android and even ios, I recommend you to test a bind to a normal element or maybe if the event.preventDefault() is not working then it triggers the plain old click event too. – Juliyanage Silva Mar 03 '14 at 07:36
  • I updated the question with some details, but it seems that vclick isn't doing the trick. The event is still firing and everything, it's just that the delay isn't gone.. – Chase Roberts Mar 03 '14 at 18:54
0

Have you tried opening jQueryMobile library file? There are some functions like:

setTimeout(function() {
    $link.removeClass( $.mobile.activeBtnClass );
    }, 300 );

I am sure, that searching this file for "delay" or "timeout" and changing it would give a good result. Line above is from

.mobile.popup.handleLink = function( $link ) {
    ...
}
Piotr Krysiak
  • 2,815
  • 3
  • 23
  • 35
  • I tried changing all the 300's in the JQM file to 13's. I don't get any change. (I then did a sanity check and removed an entire line from the JQM file just to make sure that the file was being included and not being cached or something weird and removing an entire line did in fact break it.) – Chase Roberts Mar 02 '14 at 00:29
0

Try registering FastClick inside the deviceready event handler:

document.addEventListener('deviceready', function() {
    FastClick.attach(document.body);
}, false);
Mobiletainment
  • 22,201
  • 9
  • 82
  • 98
0

Have you tryed to juse the tap event?

$("#test-element").off('tap').on('tap', function(event) {...do your stuff});

Note that .bind is deprecated - better use on / off

Note that depending upon, where you're attaching your eventhandler the eventhandler might get bound multiple times on pagechange and revisit.

You best bind your tap-event-handler in ther pageinit event in order to make sure, that you attaching to the event only once and not every time, you revisit a certain page.

In case you're attaching on pageshow use the "off" first (see above)

TorchMan
  • 274
  • 3
  • 12
0

I had the same problem with some menu buttons. My solution works for all platforms without a helper library, however, I wish there was a better way like setting a JQM variable:

$('#button').unbind('touchstart click').bind('touchstart click', function(event) {
    $('#button').addClass('ui-btn-active');
    //doSomethingHere();
    setTimeout(function() {
        $('#button').removeClass('ui-btn-active');
    }, 300); //this 300ms is just the delay for styling the button
    event.preventDefault(); //if touchstart is supported, do not let the event propagate to the click handler.  Having this here avoids a double trigger.
});

The key is binding to touchstart which triggers immediately.

NOTE- I have this code within a pageshow handler which is why I unbind and then bind it. Otherwise, you'd end up with the same event bound multiple times as the user navigates to and from this page.

Dave
  • 144
  • 4
  • Yeah but is this going to work if I want to be able to scroll on the page? – Chase Roberts Mar 06 '14 at 19:45
  • Yes, this will not affect the scrolling in any way. This is only intercepting and handling the click events. – Dave Mar 06 '14 at 20:53
  • Ok, so it didn't solve the problem. But I am convinced that the problem isn't lying in the click handler. With many of the proposed solutions, If I attach a console.log statement to the click handler then I can see that the button is pretty responsive. But whenever I try to call a pageChange then it takes 300ms. So I am pretty sure something in the pagechange is adding the 300ms back in or screwing up the fastclick. – Chase Roberts Mar 07 '14 at 15:29
0

There are durations associated with the page transition animations in JQM. Here is some of the CSS for the default 'fade' transition (from jquery.mobile.structure.css v1.4.2):

.fade.out {
  opacity: 0;
  -webkit-animation-duration: 125ms;
  -webkit-animation-name: fadeout;
  -moz-animation-duration: 125ms;
  -moz-animation-name: fadeout;
  animation-duration: 125ms;
  animation-name: fadeout;
}
.fade.in {
  opacity: 1;
  -webkit-animation-duration: 225ms;
  -webkit-animation-name: fadein;
  -moz-animation-duration: 225ms;
  -moz-animation-name: fadein;
  animation-duration: 225ms;
  animation-name: fadein;
}

JQM changes classes on the to and from pages when transitions start and complete, so in the case of the 'fade' transition, the page being changed to will become the active page 225ms after the from page has completed fading out (125ms) i.e. after 350ms.

You could try disabling the transition by specifying {transition: 'none'} in your call to $.mobile.pageContainer.pagecontainer('change' or by setting $.mobile.defaultPageTransition = "none"; in your mobileinit event handler to rule it as the cause of the delay.

I've always disabled page transitions in my Phonegap JQM apps because of the poor performance and flickering (Android), but I still have responsiveness issues, especially on Android. I think it is down to how the webview prioritises rendering the DOM. I've found that a strategically positioned setTimeout can make page changes seem more responsive by allowing the webview to postpone my application logic until after it has rendered the DOM.