2

I'm still new to Jquery Mobile and definitely it's a great framework.

I hope someone could help me. I'm having issues with jquery events after ajax page loading.

The following code will work on first page load, but after visiting other pages it won't work.

JS

   jQuery("#menu").tap(function () {
        jQuery("ul.sub-menu").slideToggle("slow");
    });

HTML

<input type="button" id="menu" value="Menu" data-icon="arrow-d"/>
<ul class="sub-menu" data-role="listview">     
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 1</a></li>
</ul>      

I've tried using pageinit() and pageshow() but still it won't work.

Any help would be greatly appreciated.

Code in my header.php in worpdress:

    <div data-role="page" id="indexPage" class="blog page">

    <script type="text/javascript"> 

        jQuery("div:jqmData(role='page'):last").bind('pageshow', function(){
              //your code here - $.mobile.activePage works now
            jQuery.mobile.activePage.on('tap', '.menu', function(){
                alert('test');
                jQuery.mobile.activePage.find('ul.sub-menu').slideToggle('slow');
            });
        });

    </script>


        <?php
        //Get data theme from theme options

        $options = get_option('touch_theme_options');
        $theme = $options['color_option'];

        ?>

        <div id="logo">
            <a href="<?php echo home_url(); ?>"><img src="<?php bloginfo('url'); ?>/wp-content/themes/converse/images/sofrep-logo-mobile.png" alt="<?php bloginfo('title'); ?>"></a>
        </div>

        <div data-theme="<?php echo $theme ?>">
            <input type="button" id="menu" class="menu" value="Menu" data-icon="arrow-d"/>
            <ul class="sub-menu" data-role="listview">     
                <li><a href="#">Link 1</a></li>              
                <li><a href="#">Link 2</a></li>         
                <li><a href="#">Link 3</a></li>     
            </ul>
        </div>
ZoulRic
  • 83
  • 1
  • 6

4 Answers4

2

A bit of background info is necessary here, jQuery loads pages via AJAX and inserts it IN THE SAME HTML PAGE, the only code it pulls in from the 2nd page is anything between the div[data-role="page"] which means if you have JS in the there it won't get pulled in.

You were originally referencing a DOM element by an ID and binding it, this doesn't really work, since jQM loads multiple pages into one html page, you can potentially have more than one element with the same id, what you need is a reference to the current page, which is $.mobile.activePage which is available after pageshow

I see in your comments that you used the live event, this is a step in the right direction, but if that code runs more than once, it will bind multiple live events, that's why you are getting 3 slides.

The solution is to use the jQuery on event handler to bind live event listeners at the root div page not the document, and listen for #menu

jQuery("div:jqmData(role='page'):last").bind('pageinit', function(){
    $(this).on('tap', '#menu', function(){
         $(this).find('ul.sub-menu').slideToggle('slow');
    });
});

You will need to run this code within the pageinit event handler of jQM, see below links


There's a similar question here: https://stackoverflow.com/a/9200797/737023, I have a more thorough solution on a good way to bind events without conflicts in jQM here: Jquerymobile - $.mobile.changepage

Community
  • 1
  • 1
Clarence Liu
  • 3,874
  • 2
  • 25
  • 29
  • Wow! Thanks a lot @Clay Liu It did work, thanks for the answer, it did help a lot, i'm still new and learning JQM. BTW, I've used this code. `jQuery("div:jqmData(role='page'):last").bind('pageshow', function() { //your code here - $.mobile.activePage works now jQuery.mobile.activePage.on('tap', '#menu', function(){ jQuery.mobile.activePage.find('ul.sub-menu').slideToggle('slow'); }); });` – ZoulRic Feb 10 '12 at 00:47
  • It works well when visiting other pages, but at the root div page, it slides 3 times. Do you know what's wrong? I've used the code above. – ZoulRic Feb 10 '12 at 01:26
  • I'm a bit confused, do you have a copy of all the code on each page? The way that snippet works is you only have code pertaining to the page you are loading there. It sounds like you're somehow binding more than one listener to your first page. Are you getting the multiple slides when pressing back to the original page? Regardless you're getting some conflict, I'd need to see all your code. But try using console.log or alerts with unique messages on each of those event handlers, you should be able to track down which is being called more than once. – Clarence Liu Feb 10 '12 at 02:53
  • Two alerts will occur if I'll go the next page and go back to the original page. – ZoulRic Feb 10 '12 at 03:43
  • Ah my bad, I should have said the pageinit event, not the pageshow event. The pageinit only fires once, it's like your document.ready from jQuery. The pageshow fired again when you pressed back, I've updated the snippet in the original answer. – Clarence Liu Feb 10 '12 at 05:03
  • Please note $.mobile.activePage is undefined in the pageinit handler – Clarence Liu Feb 10 '12 at 05:12
  • Thank you so much for the help, I've used your code, it doesn't work but I've managed to fixed it: ` jQuery("div:jqmData(role='page'):last").bind('pageinit', function(){ jQuery(this).on('tap', '#menu', function(){ jQuery("div:jqmData(role='page'):last").find('ul.sub-menu').slideToggle('slow'); }); });` Finally its now fixed, hope i will hear from you again if ever Il run to any JQM problem.. Kudos! – ZoulRic Feb 10 '12 at 05:50
0

Try to use the refresh function:

.refresh()

CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
Roy M J
  • 6,926
  • 7
  • 51
  • 78
0

I'm not sure if this also goes for jQuery Mobile.
But it seems like your menu is created or inserted to the DOM after the site has been completely loaded.
Which means that you can't add .tap() to it because you cannot access the menu, as far as it hasn't been created at this point ! Try to use .on() or .live() (even its depricated)

mas-designs
  • 7,498
  • 1
  • 31
  • 56
  • thanks for an answer. I've already tried `.on` and `.live` it won't still work. The event only work on first page load, jquery mobile loads a page using ajax. – ZoulRic Feb 09 '12 at 11:08
  • if it helped you could you accept the question :) ? And if not maybe I can help you further ! – mas-designs Feb 09 '12 at 11:09
  • I've tried this: `` It did work.. Unfortunately, the `slidetoggle()` function works weird, it slides 3 times after one tap. – ZoulRic Feb 09 '12 at 11:17
0

Here's the correct fix and code:

        jQuery("div:jqmData(role='page'):last").bind('pageinit', function(){
            jQuery(this).on('tap', '#menu', function(){
                 jQuery("div:jqmData(role='page'):last").find('ul.sub-menu').slideToggle('slow');
                console.log('clicked');
            });
        });

Thanks to Clay Liu!

ZoulRic
  • 83
  • 1
  • 6