Sunday, April 22, 2012

jQuery Mobile: Removing a Page from the DOM

By default jQuery Mobile loads pages via Ajax, allowing it to animate the page transitions. This behavior can sometimes cause a problem, especially if JavaScript is being used on the pages.

For example, if a website has two pages that contain elements with the same id attributes and a jQuery selector is used that refers to the elements by their ids, the jQuery may select the wrong element.

Page 1

<!DOCTYPE html>

<html>

       <head>

       <title>Page 1</title>

       <meta name="viewport" content="width=device-width, initial-scale=1">

       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />

       <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>

       <script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>

    <script type="text/javascript" src="UnloadExample.js"></script>

</head>

<body>

 

<div id="Page" data-role="page" data-theme="b">

 

       <div data-role="header" data-theme="b">

              <h1 id="header">Page 1</h1>

        <a href="UnloadPage2.htm" data-icon="arrow-r" data-iconpos="right" class="ui-btn-right">Page 2</a>

       </div><!-- /header -->

 

       <div data-role="content"> 

              <p>This is page 1.</p>

        <a id="ShowButton" data-role="button">Show</a>

       </div><!-- /content -->

 

</div><!-- /page -->

 

</body>

</html>

 

Page 2

<!DOCTYPE html>

<html>

       <head>

       <title>Page 2</title>

       <meta name="viewport" content="width=device-width, initial-scale=1">

       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />

       <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>

       <script type="text/javascript" src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>

    <script type="text/javascript" src="UnloadExample.js"></script>

</head>

<body>

 

<div id="Page" data-role="page" data-theme="b">

 

       <div data-role="header" data-theme="b">

        <a href="UnloadPage1.htm" data-icon="arrow-l" data-iconpos="left">Page 1</a>

              <h1 id="header">Page 2</h1>

       </div><!-- /header -->

 

       <div data-role="content"> 

              <p>This is page 2.</p>

        <a id="ShowButton" data-role="button">Show</a>

       </div><!-- /content -->

 

</div><!-- /page -->

 

</body>

</html>

 

UnloadExample.js

$(document).delegate("#ShowButton", "click", function () {

    alert($("#header").text());

});

If the Show button is clicked on the first page, an alert box is shown with the message "Page 1".

Page1

Then if the "Page 2" button is clicked, Page 2 is displayed. If the Show button is clicked on the second page, an alert box is shown with the message "Page 1", not "Page 2".

Page2Before

Since Page 1 is still in the DOM, jQuery selects the "#header" element on the hidden page (Page 1) instead of the one that is actually visible (the one on Page 2).

This issue can be avoided by removing the hidden page from the DOM after Page 2 is shown. The following JavaScript can be added to the UnloadExample.js page to accomplish this.

$('#Page').live('pagehide', function () {

    $(this).remove();

});

Now when the Show button on Page 2 is clicked, the alert box message will be “Page 2”.

Page2After

No comments: