Jquery Mobile pageshow event firing twice

3.2k Views Asked by At

I currently have a mobile site I am building and I am having trouble with integrating a custom JQuery widget. For some reason the the pageshow event is firing twice for whichever page is loaded first.

For ease of understanding I have created two HTML pages

Page 1

<!doctype html>
<head>
    <meta charset="utf-8">
    <title>One</title>

    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css" />
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script type="text/javascript">
    $(document).on("mobileinit", function () {
        $.mobile.changePage.defaults.reloadPage = true;
    });
    </script>
    <script type="text/javascript" src="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.js"></script>

</head>
<body id="default">
    <div data-role="page" id="content-one">
        <div role="main" class="ui-content" id="one-content">
            One<br/>
            <a href="two.html">back to two</a>
        </div>
        <script type="text/javascript">
        (function($, undefined) {
            $.widget("test.stuff", {
                _create : function() {
                    console.log("create");
                },
                _init : function() {
                    console.log("_init");
                },
                destroy: function () {
                    this.element.empty();
                    $.Widget.prototype.destroy.call(this);
                }
            });
        })(jQuery);
        </script>
        <script type="text/javascript">
        $(document).on("pageshow", "#content-one", function () { 
            console.log("pageshow1");
            $("#content-one").stuff({});
        });
        $(document).on("pagebeforeshow", "#content-one", function () { 
            console.log("pagebeforeshow1");
        });
        </script>
    </div>
</body>
</html>

Page 2

<!doctype html>
<head>
    <meta charset="utf-8">
    <title>Two</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.10.2.min.js">  </script>
    <script type="text/javascript">
    $(document).on("mobileinit", function () {
        $.mobile.changePage.defaults.reloadPage = true;
    });
    </script>
    <script type="text/javascript" src="https://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.js"></script>

</head>
<body id="default">
    <div data-role="page" id="content-two">
        <div role="main" class="ui-content">
            Two<br/>
            <a href="one.html">back to one</a>
        </div>
        <script type="text/javascript">
        $(document).on("pageshow", "#content-two", function () { 
            console.log("pageshow2");
        });
        $(document).on("pagebeforeshow", "#content-two", function () { 
            console.log("pagebeforeshow2");
        });
        </script>
    </div>
</body>
</html>

To recreate load page one first, navigate to page two using link, then navigate to page one using link.

When page one is loaded again the pageshow event is fired twice. I have the reloadPage set to true as I have dynamic content for my pages and I cannot serve cached pages.

I very well could be using the events incorrectly.

3

There are 3 best solutions below

0
On

Wasted about 2 hours trying to do all the fixes on here and other sites. I gave up and put an if statement in their to prevent it from firing again

var hasDownload = false;
$(document).on("pageinit", "#mypage",function(event){
    if (hasDownload === false) {
        hasDownload = true;
        // do some work
    }
);
0
On

Try to remove the page on hide event, like so :

$(document).on("mobileinit", function () {
        $.mobile.changePage.defaults.reloadPage = true;
        $(docuement).on('pagehide', function (event, ui) {
            $(event.target).remove();
        });
    });

Remenber that if you don't disable ajax, all request will be with AJAX

0
On

Try substituting your $(document).on("pageshow",...) with $(document).one("pageshow", ...), which restricts the event to one call http://api.jquery.com/one/.

The problem is that using on in the inline script creates a new event each time the page is loaded. So the first time you load the page, the inline script is executed and the pageshow event is triggered. The second time a new event is triggered again, but the first one is still listening to content-one pageshow. In fact, if you repeat the process you'll see the log three, four, ... times.

Another option could be to create a script in the head section which sets up all required triggers in $(document).on("pageshow", "#content-one", ...), $(document).on("pageshow", "#content-two", ...). In this case, the script will only be initialized once, so it will work.