Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery click event not firing in jQueryMobile

Using jQuery jquery-1.9.1.js and jQueryMobile 1.3.1 (Chrome 26/Windows 7) I cannot see why one of these 'click' events bound to #one1 fires and the other doesn't:

HTML:

<div data-role="page" id="one" data-theme="a">
    <div data-role="header" data-position="inline">
        <h1>One</h1>
    </div>
    <div data-role="content" data-theme="a">
        <a href="#" id="one1">[one]</a>
        <a href="#two">two</a>
        <a href="#three">three</a>
    </div>
</div>

JavaScript:

<script>
$(document).on( "mobileinit", function() {
    $(document).on('click', '#one1', function(e){
        console.log('firing');
    });
    $('#one1').on("click", function() {
        console.log('not firing');
    });
}); 
</script>

When I run it in JSFiddle both events fire when not wrapped in the "mobileinit" event: http://jsfiddle.net/9NRwa/

What am I missing here?

like image 214
Marc Avatar asked May 04 '13 15:05

Marc


1 Answers

Intro

First thing first, mobileinit event should not be used for event binding. While it CAN be used like that mobileinit was not created for that purpose. It was created for jQuery Mobile parameter auto-initialization, so it should not be used for event binding.

Correct way is to use proper page events like pageinit. For more information about page events take a look at my other answer that covers various jQuery Mobile page events and their difference towards usual jQuery document ready paradigm: jQuery Mobile: document ready vs page events.

Not let me answer this question. Events like click can be bound in a few different ways. Lets look at examples you have used:

Various ways of event binding with jQuery

First example

$(document).on('click', '#one1', function(e){
    console.log('firing');
});

This first example is something new that came to use first with now deprecated method live. Basically it's an event delegation mechanism that allows you to bind event handlers not just to all existing instances of a given node type, but also to any future instances of a given node type (by "type" I mean a set of DOM nodes matched by a given jQuery selector). What I want to say here is, during the event binding that element don't need to exist in a DOM, basically this method works by binding event handlers to the document itself and then reacting to all the events that bubble up through the DOM. So it doesn't matter if element #one1 exist or not during the event binding. You can create it dynamically later and it will still work.

Second example

$('#one1').on("click", function() {
    console.log('not firing');
});

This is on old way of event binding. It requires that event exists in the DOM before event can be bind. In your case you were trying to bind this click event to the element that didn't exist in a DOM at that point in time. It doesn't matter it was loaded after the binding process.

Working example

jsFiddle example: http://jsfiddle.net/Gajotres/QmNsa/

Take a look at this example. There you will see 5 different ways of click event binding in jQuery Mobile:

  • 2 click event are bound in HEAD, before page is initialized into the DOM
  • 2 click events are bound in HEAD in pagebeforeshow event, basically this is also a delegation of binding because event are bound when page is about to be shown and already inside a DOM
  • 1 click event is bound in a BODY after all page content. Because all content is loaded inside a DOM at this point this click event will work.

HTML :

<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>    
        <script>
                $(document).on('click', '#one1', function(e){
                    // This example will work because it was bind with event delegation process
                    console.log('Firing 1');
                });
                $('#one1').on("click", function() {
                    // This example will not work because event do not exist in this moment
                    console.log('Not firing');
                });
                $(document).on( "pagebeforeshow", function() {
                    // This example will work because it was bind with event delegation process            
                    $(document).on('click', '#one1', function(e){
                        console.log('Firing 2');
                    });
                    // This example will work because element exist in a DOM during the pagebeforeshow event
                    $('#one1').on("click", function() {
                        console.log('Firing 3');
                    });
                });             
        </script>
    </head>
    <body>
        <div data-role="page" id="index">
            <div data-theme="b" data-role="header">
                <h1>Index page</h1>
            </div>

            <div data-role="content">
                <a href="#" id="one1" data-role="button">[one]</a>
            </div>
        </div>    
        <script>
            $('#one1').on("click", function() {
                // This example will  work because we are binding it when element is already loaded into the DOM
                console.log('Firing 4');
            });            
        </script>
    </body>
</html>   

Conclusion

  • Do not use mobileinit event for event binding, it will trigger before page is loaded into the DOM and only events bind with delegation will work.
  • Bind your events in a correct jQuery Mobile page events.

Usefull links regarding this topic:

  1. jQuery Live() Method And Event Bubbling

    While live method is deprecated on method should be used instead. In some benchmarks on method is 2x faster.

  2. jQuery Mobile: document ready vs page events

  3. Various jQuery Mobile page events
  4. What does “event bubbling” mean?
like image 185
Gajotres Avatar answered Nov 19 '22 21:11

Gajotres