2

I have a page like this (index.php):

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
    <?php //add .min.js file when all programming done ?>
    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/_jquery.mobile-1.4.0.css">

    <script src="js/_jquery-2.1.0.js" type="text/javascript"></script>
    <script src="js/_jquery.mobile-1.4.0.js" type="text/javascript"></script>

    <script src="js/main.js" type="text/javascript"></script>
    <script src="js/sign.js" type="text/javascript"></script>
</head>
<body>
<div data-role="page">
    <div data-role="header" id="nav"><?php include_once 'nav.ui.php'; ?></div>
    <div data-role="main" class="ui-content" id="ui">

        <input type="button" id="optionUpdate">

    </div>
    <div data-role="footer" id="footer"><?php include_once 'footer.ui.php'; ?></div>
</div>
</body>
</html>

And in main.js I have:

$('#optionUpdate').click(function () {
    optionUpdate();
});

function optionUpdate() {
    alert('hi');
}

The problem is: when I click on the button, the event is not run. But if add the onclick event to the button with optionUpdate();, it works! Why? How can I fix this?

Jonathan Lonowski
  • 121,453
  • 34
  • 200
  • 199
Death Programmer
  • 896
  • 2
  • 11
  • 28
  • 2
    is your click handler inside of doc ready? – Huangism Feb 10 '14 at 21:22
  • 2
    Note: jQuery Mobile apps [should generally use](http://stackoverflow.com/questions/14468659/jquery-mobile-document-ready-vs-page-events) page events, like [`'pageinit'`](http://api.jquerymobile.com/pageinit/), rather than the typical `.ready()`. – Jonathan Lonowski Feb 10 '14 at 21:31

3 Answers3

4

In jQuery Mobile, you need to wrap functions in page events not in .ready(). The latter fires once per document, where page events fires per page / view.

If you are using jQuery Mobile with Ajax enabled and have multiple pages or load external pages, if you use .ready(), functions inside it will execute once only.

Important: Use $(document).bind('pageinit'), not $(document).ready():

The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event. This event is explained in detail at the bottom of this page.

The equivalent to .ready() in jQuery Mobile is pagecreate (pageinit is deprecated as of 1.4). Wrapping functions in pagecreate ensures that those functions fire whenever pagecreate event occurs.

$(document).on("pagecreate", function () {
  $('#optionUpdate').on("click", function () {
    optionUpdate();
  });

  function optionUpdate() {
    alert('hi');
  }
});

You can bind specific functions to a specific page by delegating event to that page.

$(document).on("pagecreate", ".selector or #page_ID", function () {
  /* functions for this page only */
});

Demo

Community
  • 1
  • 1
Omar
  • 32,302
  • 9
  • 69
  • 112
2

Note: this answer is more about jQuery than jQuery Mobile. With the mobile library, code that needs to run when the page is updated by the framework should use page events as described in other answers.


Because your "main.js" file is imported in the <head> of your page, when the code runs it won't find the "optionUpdate" element in the page: the browser will not have parsed that yet.

Three options:

  1. Use event delegation:

    $(document).on('click', '#optionUpdate', optionUpdate);
    
  2. Use a "ready" handler:

    $(function() {
      $('#optionUpdate').click(function () {
        optionUpdate();
      });
    });
    
  3. Move your <script> tag to the end of the <body>.

Pointy
  • 405,095
  • 59
  • 585
  • 614
-1

You're trying to reference elements before they exist. Wrap your code in a DOM ready handler:

$(document).ready(function() { 
    $('#optionUpdate').click(function () {
        optionUpdate();
    });
});
Jason P
  • 26,984
  • 3
  • 31
  • 45