jQueryMobile-秘籍-二-

39 阅读6分钟

jQueryMobile 秘籍(二)

原文:zh.annas-archive.org/md5/55209463BC487F6190B6A043F64AEE64

译者:飞龙

协议:CC BY-NC-SA 4.0

第五章:表单

在本章中,我们将介绍:

  • 表单控件的原生样式

  • 禁用文本控件

  • 在网格中分组单选按钮

  • 自定义复选框组

  • 创建动态翻转开关和滑块控件

  • 使用选项来自动初始化选择菜单

  • 验证表单

  • 使用 POST 提交表单

  • 使用 GET 获取数据

  • 创建一个可访问的表单

介绍

jQuery Mobile 框架默认增强标准 HTML 表单元素,使其触摸友好,同时在多个设备和平台上运行。表单可以包含多个控件,而你可以使用在其上设置 data-role='controlgroup'fieldset 来对这些控件进行分组。默认情况下,控件以垂直方式列出。你可以使用 data-type='horizontal' 属性将它们水平排列。表单支持 HTTP GETPOST 和其他操作。在适当的情况下,使用 Ajax 进行表单提交。

表单控件的原生样式

jQuery Mobile 框架默认增强表单及其控件。这个配方向你展示了设置表单控件原生样式的不同方法,以及如何自动初始化这些控件。

准备工作

code/05/native-style 源文件夹中复制此配方的全部代码。可以使用 URL http://localhost:8080/05/native-style/main.html 启动此代码。

如何进行...

  1. <head> 部分中,向 main.html 添加以下脚本以使所有按钮以原生样式呈现:

    $(document).bind('mobileinit', function() {
     $.mobile.page.prototype.options.keepNative = 'button';
    });
    
  2. 在页面内容中添加一个表单,以设置控件的原生样式:

    <form action='#' method='post'>
      <p><label for='button1'>Button 1</label></p>
      <button name='button1'>Button: keepNative configuration</button>
      <p><label for='button2'>Button 2</label></p>
     <button name='button2' data-role='button'>Button: data-role='button'</button>
      <p><label for='button3'>Button 3</label></p>
      <button id='button3' name='button3'>Button: buttonMarkup()</button>
     <script>$('#button3').buttonMarkup(); </script>
      <p><label for='input1'>Input 1</label></p>
      <input type='submit' name='input1' value='Input: default'></input>
      <p><label for='input2'>Input 2</label></p>
      <input type='submit' name='input1' data-role='none' value="Input: data-role='none'"></input><p>
      <a href='#'>Default anchor link</a></p>
     <a href='#' data-role='button'>Anchor: data-role='button'></a>
    </form>
    

它是如何工作的...

main.html 中,添加一个事件处理程序,处理应用程序启动时触发的 mobileinit 事件。在这里,将页面插件的 keepNative 属性设置为 'button'。现在,框架将不会增强按钮控件,而是以原生样式呈现它们。现在在表单中添加 button1 ,它将以原生样式呈现。要覆盖这种原生样式,添加 button2 并设置属性 data-role='button'。类似地,添加 button3 并在脚本中调用 buttonMarkup() 方法,如前面的代码中所示。现在,button2button3 都通过覆盖默认的原生样式来进行增强。

它是如何工作的...

框架默认增强所有其他控件。添加一个输入按钮 input1,你会看到它已被增强。要使用原生样式控件,可以像上面代码中显示的那样使用 data-role='none' 属性来设置输入控件 input2

对于锚链接,默认情况下使用原生样式。你可以用 data-role='button' 属性来增强锚链接。创建的表单如上所示。

还有更多...

如前所述,框架会增强表单控件,使其在所有平台上都能轻松使用手指操作。但这些控件可能在其他小容器(如工具栏)中使用时会显得稍大。您可以通过在控件上设置data-mini='true'属性,使用控件的迷你版本。控件现在变小了一点,但仍然是手指友好的。您可以直接在controlgroup上设置此属性,所有子元素将自动缩小。访问 jQuery Mobile 在线文档,查看各种控件的比较:jquerymobile.com/test/docs/forms/forms-all-compare.html

设置多个控件使用原生样式

您可以使用页面插件指定多个控件以使用原生样式。下面一行代码会原生样式化表单中的所有按钮、输入控件和选择菜单:

$.mobile.page.prototype.options.keepNative = 'button, input, select';

data-role='none'属性

根据控件类型,框架通过使用相应的插件来初始化和增强控件。当指定data-role='none'时,控件不会被框架增强,并且控件会使用原生样式。使用data-theme属性设置控件主题等操作将被忽略。

注意

jQuery Mobile 提供的增强样式是轻触友好的,非常适合移动设备。尽量避免在应用程序中使用原生样式。

禁用文本控件

此教程向您展示了在表单中启用和禁用文本控件的不同方法。

准备就绪

code/05/text-controls源文件夹中复制此教程的全部代码。可以使用 URL http://localhost:8080/05/text-controls/main.html启动此代码。

如何做...

  1. main.html中,在表单中创建以下文本控件:

    <form action='#' method='post'>
      <input type='search' id='searchitem' name='searchitem' autofocus
          placeholder='Enter search text' value='' />
      <input type='text' id='textitem' name='textitem' 
          placeholder='Enter text item' value='' />
      <textarea id='textarea' name='textarea' 
          placeholder='Enter description'></textarea>
     <a href='#' data-role='button' class='ui-disabled'>More Details</a>
    </form>
    
  2. 将以下脚本添加到<head>部分以禁用所有控件:

      $('#main').live('pageinit', function(event) {
     $('#textitem').prop('disabled', true);
     $('#textarea').textinput('disable');
    
    
  3. 然后处理搜索文本控件的change事件来启用所有表单控件:

       $('#searchitem').bind('change', function(event, ui) {
          var str = $(this).attr('value');
     $('#textitem').prop('disabled', true);
     $('#textarea').textinput('enable').append(str
     + ' is absolutely awesome!');
          $('a').removeClass('ui-disabled');
       });
    });
    

它的运作方式...

main.html中,添加一个带有type='search'的搜索控件,并添加一个带有type='text'的文本。现在,按照上面的代码添加一个空的textarea。添加一个链接并通过设置class='ui-disabled'属性来禁用它。在脚本中,添加一个pageinit事件处理程序,在页面初始化后调用。在这里,通过调用prop('disabled', true)方法来设置其disabled属性来禁用文本输入。然后通过调用textinput 插件textinput('disable')方法来禁用textarea。现在,当应用程序加载时,除搜索输入外,表单上的所有控件都被禁用,如下面的屏幕截图所示:

它的运作方式...

注意

您不能在使用data-role='button'将增强为按钮的锚链接上使用disabled属性。此属性会被忽略。

现在,为了启用控件,将搜索控件的 change 事件绑定到事件处理程序上。在这里,通过调用 prop('disabled', false) 方法来启用 textitem 控件。接下来,在 textarea 上调用 textinput('enable') 方法来调用其 textinput 插件 上的 enable 方法。在 textarea 上调用 append() 方法以向其添加文本。最后,在锚链接上调用 jQuery removeClass() 方法来移除 'ui-disabled' 类。现在,一旦您在搜索字段中输入内容,表单控件都会被启用,如下图所示:

工作原理...

更多内容...

您还可以通过使用 attr()removeAttr() jQuery 方法将 disabled 属性添加到控件来启用或禁用控件,如下所示:

$('#textitem').attr('disabled', 'disabled'); // to disable
$('#textitem').removeAttr('disabled'); // to enable

文本控件的自动初始化

文本区域和文本输入控件(input type='text')会自动由框架增强。您还可以使用 data-theme 属性为文本控件设置主题。

将单选按钮分组到网格中

jQuery Mobile 框架允许您在水平或垂直方向上分组单选按钮。本示例向您展示如何在简单的座位预订表单中将单选控件分组为 3 x 3 网格。

准备工作

code/05/radiobutton-grid 源文件夹中复制此示例的完整代码。此代码可使用 URL http://localhost:8080/05/radiobutton-grid/main.html 运行。

如何执行...

  1. main.html 中,使用 3 x 3 布局网格创建九个单选控件。这些单选按钮是同一个控件组的一部分。

    <form action='#' method='post'>
      <fieldset data-role='controlgroup' data-type='horizontal' 
          class='ui-grid-a'>
        <div class='ui-block-a' style='width: 30%'>
            <legend>First Row</legend></div>
        <div class='ui-block-b' style='width: 70%'>
          <input type='radio' name='radio-1' id='radio-11' value='Seat-A1' checked />
          <label for='radio-11'>A-1</label>
          <input type='radio' name='radio-1' id='radio-12' value='Seat-A2' />
          <label for='radio-12'>A-2</label>
          <input type='radio' name='radio-1' id='radio-13' value='Seat-A3'/>
     <label id='l-13' for='radio-13' class='ui-corner-right'>A-3</label>
        </div>
        <div class='ui-block-a' style='width: 30%'>
            <legend>Mid Row</legend></div>
        <div class='ui-block-b' style='width: 70%'>
          <input type='radio' name='radio-1' id='radio-21' value='Seat-B1' />
     <label id='l-21' for='radio-21' class='ui-corner-left'>B-1</label>
          <input type='radio' name='radio-1' id='radio-22' value='Seat-B2' />
          <label for='radio-22'>B-2</label>
          <input type='radio' name='radio-1' id='radio-23' value='Seat-B3'/>
     <label id='l-23' for='radio-23' class='ui-corner-right'>B-3</label>
        </div>
        <div class='ui-block-a' style='width: 30%'>
            <legend>Last Row</legend></div>
          <div class='ui-block-b' style='width: 70%'>
            <input type='radio' name='radio-1' id='radio-31' value='Seat-C1' />
     <label id='l-31' for='radio-31' class='ui-corner-left'>C-1</label>
            <input type='radio' name='radio-1' id='radio-32' value='Seat-C2' />
            <label for='radio-32'>C-2</label>
            <input type='radio' name='radio-1' id='radio-33' value='Seat-C3'/>
            <label for='radio-33'>C-3</label>
        </div>
      </fieldset>
    </form>
    
  2. 将以下脚本添加到 <head> 部分以修复边缘单选按钮的样式:

    $('#main').live('pageshow', function(event) {
      $('#l-13').children('span').addClass('ui-corner-right ui-controlgroup-last');
      $('#l-23').children('span').addClass('ui-corner-right ui-controlgroup-last');
      $('#l-21').children('span').addClass('ui-corner-left');
      $('#l-31').children('span').addClass('ui-corner-left');
    });
    

工作原理...

main.html 中,通过指定 data-role='controlgroup'data-type='horizontal' 来添加水平单选控件组。现在将 ui-grid-a 类添加到此 fieldset 容器中,以创建两列布局网格。对于每一行,通过将 class='ui-block-a' 指定给 div 容器,在第一列添加图例,并通过 class='ui-block-b' 在第二列添加单选按钮。根据上述代码,添加九个具有适当标签的单选按钮,每行包含三个单选按钮。这将创建一个 3 x 3 单选按钮组的网格。

在上面的代码中,你会发现网格中的第一个和最后一个单选按钮样式正确,但所有其他边缘单选按钮(带有标签 l-13、l-21、l-23 和 l-31)样式不正确。它们具有矩形边缘而不是圆角。为了解决这个问题,你需要将框架为第一个单选按钮的标签生成的样式(class='ui-corner-left')复制到标签 l-21 和 l-31 的内部span中。同样地,将框架为最后一个单选按钮的标签生成的样式(class='ui-corner-right ui-controlgroup-last')复制到标签 l-13 和 l-23 的内部span中。现在单选按钮网格的样式已经正确,如下截图所示,你现在可以一次仅选择整个网格中的一个单选按钮:

工作原理...

还有更多...

当框架遇到一个带有type='radio'input控件时,它会自动使用checkboxradio 插件将其增强为样式化的单选按钮。你可以通过在初始化期间使用data-theme属性来为单选按钮设置主题。你可以通过使用data-role='none'属性来关闭自动初始化并使用原生样式。

另请参阅

  • 自定义复选框控件组 示例

自定义复选框控件组

默认的水平分组复选框控件没有图标,垂直分组的复选框控件不使用活动状态主题。这个示例向你展示了如何自定义复选框并添加这些样式。它还向你展示了如何调整布局以处理不同的屏幕尺寸。在这个示例中,你将创建一个简单的博客订阅表单。

准备工作

code/05/custom-checkbox源文件夹中复制这个示例的全部代码。你可以使用http://localhost:8080/05/custom-checkbox/main.html网址来运行这段代码。

如何实现...

首先创建一个包含水平和垂直复选框控件组的表单。通过 JavaScript 在pageshow事件处理程序中向水平复选框控件添加图标来自定义水平复选框控件。复选框控件的change事件指示复选框checked状态是否已更改。使用change事件处理程序来添加和切换复选框的活动状态。

  1. main.html中,创建一个带有垂直复选框控件组的表单:

    <form action='#' method='post'>
      <div data-role='fieldcontain'>
        <fieldset data-role='controlgroup'>
          <legend>Subscribe to:</legend>
          <input type='checkbox' name='posts' id='posts' />
     <label for='posts' id='postslbl'>New Posts</label>
          <input type='checkbox' name='comments' id='comments' />
     <label for='comments' id='commentslbl'>Comments</label>
        </fieldset>
      </div>
    
  2. 接下来添加两个水平切换集或复选框组:

      <div data-role='fieldcontain'>
        <fieldset data-role='controlgroup' data-type='horizontal'>
          <legend>Notify Me:</legend>
          <input type='checkbox' name='notify' id='notify' />
          <label for='notify'>Immediate</label>
          <input type='checkbox' name='digest' id='digest' />
          <label for='digest'>Daily Digest</label>
        </fieldset>
      </div>
      <div data-role='fieldcontain'>
        <fieldset data-role='controlgroup' data-type='horizontal'>
          <legend>Share To:</legend>
          <input type='checkbox' name='twitter' id='twitter' />
     <label for='twitter' id='twitterlbl'>Twitter</label>
          <input type='checkbox' name='facebook' id='facebook' />
     <label for='facebook' id='facebooklbl'>Facebook</label>
        </fieldset>
      </div>
    </form>
    
  3. 将以下脚本添加到<head>部分以向水平组添加图标:

    $('#main').live('pageshow', function(event, data) {
      $('#twitterlbl').children('span').append("<span class='ui-icon ui-icon-shadow ui-icon-checkbox-off'>").trigger('create');
      $('#twitterlbl').addClass('ui-btn-icon-left').trigger('refresh');
      $('#facebooklbl').children('span').append("<span class='ui-icon ui-icon-shadow ui-icon-checkbox-off'>").trigger('create');
      $('#facebooklbl').addClass('ui-btn-icon-left').trigger('refresh');
      updatePosts();
      updateComments();
      $('#posts').bind('change', updatePosts);
      $('#comments').bind('change', updateComments);
    });
    
  4. 接下来,绑定change事件来处理控件的checked状态变化:

    function updatePosts(event, ui) {
     if($('#posts').prop('checked')) {
        $('#postslbl').addClass('ui-btn-active').trigger('refresh');
      } else {
        if($('#postslbl').hasClass('ui-btn-active'))
          $('#postslbl').removeClass('ui-btn-active').trigger('refresh');
      }
    }
    
  5. 最后,根据垂直复选框的checked状态切换活动状态:

    function updateComments(event, ui) {
     if($('#comments').prop('checked')) {
        $('#commentslbl').addClass('ui-btn-active').trigger('refresh');
      } else {
        if($('#commentslbl').hasClass('ui-btn-active'))
          $('#commentslbl').removeClass('ui-btn-active').trigger('refresh');
      }
    }
    

工作原理...

main.html中,向博客订阅表单添加三个具有data-role='controlgroup'fieldset元素。向第一个fieldset元素添加一个垂直复选框组,其中包含文章评论的复选框。第二个控制组是用于选择博客通知的水平切换集合(立即作为每日摘要)。第三组复选框也是水平的,选项包括在TwitterFacebook上分享。

默认情况下,水平切换集合不带图标。你可以自定义并向其添加图标。为pageshow事件创建事件处理程序,并将所需的样式添加到第三个水平切换集合的标签中。在具有id='twitterlbl'id='facebooklbl'的标签中添加具有class='ui-icon ui-icon-shadow ui-icon-checkbox-off'的内部 span,并且还将ui-btn-icon-left类添加到标签中。这将在两个复选框的左侧添加一个图标,类似于垂直复选框控件提供的图标。将其与其他水平切换集合进行比较。

默认情况下,垂直复选框具有图标,并且在选中时这些图标显示为勾号。垂直复选框不会获得btn-active样式(与水平复选框不同)。要添加活动按钮样式,请为两个垂直复选框(具有id='posts'id='comments')创建change事件的事件处理程序。对于这两个复选框,使用prop('checked')调用来查找控件是否被checked,然后添加或删除ui-btn-active类以为垂直复选框设置样式,类似于水平复选框。屏幕显示如下截图所示:

它是如何工作的...

更多内容...

在上述代码中,每个复选框组都包装在具有属性data-role='fieldcontain'的容器中。此属性将使框架根据屏幕大小动态调整控件的布局和其标签的位置。还添加了一个小的水平分隔线以显示分隔。在较宽的屏幕或使用横向方向时,显示如下截图所示:

更多内容...

复选框控件的自动初始化

当框架遇到具有type='checkbox'input控件时,它会自动使用checkboxradio 插件将其增强为样式化复选框。您可以在初始化期间使用data-theme属性为复选框设置主题。您可以通过使用data-role='none'属性关闭自动初始化并使用原生样式。

另请参阅

  • 在网格中对单选按钮进行分组 的方法

创建动态翻转开关和滑块控件

本方法向您展示了如何使用 JavaScript 将翻转开关滑块控件动态添加到页面,并处理其事件。在这里,您将创建一个简单的音量控制表单,其中包含一个音量滑块,在音量非常高时会向用户发出警告。

准备就绪

code/05/dynamic-slider源文件夹中复制这个配方的全部代码。可以使用 URL http://localhost:8080/05/dynamic-slider/main.html启动这段代码。

如何做...

  1. main.html中,向页面内容添加以下空表单:

    <form id='volumeForm' action='#' method='post'></form>
    
  2. <head>部分添加以下脚本,动态添加一个开关和一个滑块:

    $('#main').live('pageinit', function(event) {
      var str="<div data-role='fieldcontain' style='width: 50%'><label for='flipswitch'>Volume:</label>"
        + "<select name='flipswitch' id='flipswitch' data-role='slider' data-track-theme='d'>"
        + "<option value='no'>Off</option><option value='yes'>On</option></select></div>"
        + "<div id='volcontainer' data-role='fieldcontain' style='width: 100%'>"
        + "<input type='range' name='volume' id='volume' value='8' min='0' max='15' data-track-theme='b' disabled /></div>";
     $('#volumeForm').html(str).trigger('create');
    
    
  3. 处理翻转开关的change事件以启用音量滑块控件:

      $('#flipswitch').bind('change', function(event, data) {
     if ($(this).slider().val() == 'no') {
          $('#volume').slider('disable');
        } else {
          $('#volume').slider('enable');
        }
      });
    });
    
  4. 处理音量滑块的change事件以根据其值设置滑块样式:

    $('#main').live('pageshow', function(event) {
     $('#volume').bind('change', function(event, data) {
        if ($(this).slider().val() > 10) {
          $('#volcontainer').find('.ui-btn-down-b')
          .removeClass('ui-btn-down-b').addClass('ui-btn-down-e');
        } else {
          $('#volcontainer').find('.ui-btn-down-e')
          .removeClass('ui-btn-down-e').addClass('ui-btn-down-b');
        }
      });
    });
    

它是如何工作的...

main.html中添加一个空表单id='volumeForm'。为pageinit事件创建一个事件处理程序,该事件在页面初始化后触发。在这里,生成表单的 HTML 内容。使用带有data-role='slider'的选择控件添加一个翻转开关控件(id='flipswitch')。这个翻转开关将切换音量OnOff。添加一个带有type='range'的输入控件以创建滑块控件(id='volume')。在启动时将disabled属性添加到滑块上,以便控件在启动时被禁用。将此 HTML 内容设置为空表单并触发'create'方法以让框架初始化和增强控件。当页面加载时,您将看到音量控制表单,其中包含动态添加的翻转开关和禁用的滑块控件,如下图所示:

它是如何工作的...

接下来添加代码来处理#flipswitchchange事件,在事件处理程序中,使用slider().val()调用检查翻转开关是on还是off。根据这个值,通过调用slider('enable')slider('disable')来启用或禁用滑块音量控制。现在当你切换翻转开关的值时,你会看到滑块在屏幕截图中启用或禁用,如下所示:

它是如何工作的...

pageshow事件处理程序中绑定音量滑块控件的change事件,并在此处使用slider().val()调用检查滑块的值。如果值大于10的阈值音量,则将滑块设置为主题'e',如果尚未设置样式,则设置。如果值低于10的阈值,则将主题设置回主题'b'。您可以使用 jQuery 的find()方法并将ui-btn-down-b类替换为ui-btn-down-e类,反之亦然。现在当您设置一个高音量时,滑块会变成黄色,如下图所示:

它是如何工作的...

还有更多...

您可以使用data-theme属性为翻转开关和滑块控件设置主题,使用data-theme-track属性在初始化时使用滑块轨道。要在初始化后操作这些控件,您将不得不操作底层本机控件,然后在它们上调用'refresh'方法。

滑块的自动初始化

当框架遇到一个带有 type='range'input 控件时,它会自动使用 滑块插件 将其增强为滑块控件。同样地,滑块插件会将带有 data-role='slider' 的选择控件增强为翻转开关。你可以通过使用 data-role='none' 属性关闭自动初始化并使用原生样式。

使用选项自动初始化选择菜单

原生 HTML 选择菜单被 jQuery Mobile 框架增强,使其对移动设备更加友好。本示例展示了如何通过 JavaScript 设置其控件选项以自动初始化 选择菜单

准备工作

code/05/select-menu 源文件夹复制本示例的完整代码。可以使用 URL http://localhost:8080/05/select-menu/main.html 启动此代码。

怎样做...

  1. main.html 中,添加以下代码以创建选择菜单:

    <form action='#' method='post'>
      <div data-role='fieldcontain'>
        <label for='selectid' class='select'>Sample Select Menu</label>
        <select name='selectid' id='selectid' multiple data-native-menu='false' data-overlay-theme='e'>
          <option value='Sample Select Menu' data-placeholder='true'>Sample Select Menu</option>
          <option value='opt1'>Option 1</option>
     <option value='disabledopt' disabled>Disabled Option</option>
          <option value='opt2'>Option 2</option>
     <optgroup label='Options in Group1'>
            <option value='grp1'>&nbsp;&nbsp;&nbsp;&nbsp;Group Option1</option>
            <option value='grp2'>&nbsp;&nbsp;&nbsp;&nbsp;Group Option2</option>
          </optgroup>
     <optgroup label='Options in GroupA'>
            <option value='grpA'>&nbsp;&nbsp;&nbsp;&nbsp;Group OptionA</option>
            <option value='grpB'>&nbsp;&nbsp;&nbsp;&nbsp;Group OptionB</option>
          </optgroup>
        </select>
      </div>
    </form>
    
  2. 将以下脚本添加到 <head> 部分以设置选择菜单控件选项:

    $('#main').live('pageinit', function(event) {
     $('#selectid').selectmenu({ 
        theme: 'd', 
        inline: false, 
        corners: true,
        icon: 'star',
        iconpos: 'left',
        shadow: true,
        iconshadow: true
      });
    });
    

它是如何工作...

main.html 中,创建一个表单,并向表单添加一个带有 multiple 属性的选择控件以启用多选。设置属性 data-native-menu='false' 表示选择菜单应由框架增强。还设置 data-overlay-theme='e' 属性以指定应该使用 e(黄色)的样式覆盖层。

添加第一个带有 data-placeholder 属性的选项元素,表示此选项元素的文本必须用作选择菜单的标题。现在按照前面的代码所示添加不同的选项元素。opt1opt2 元素是常规选项项目。通过向选项元素添加 disabled 属性来禁用 disableopt 元素。然后使用 optgroup 元素添加两个选项组(Group1GroupA),如前面的代码所示。这些可以包含子选项元素。选择菜单显示如下截图所示:

![它是如何工作的...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d402a84259cc4194b0896411d1f3a06d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1771397954&x-signature=oBizwOm7YWfLaJ4PRKjPIq9LNV0%3D)

pageinit事件处理程序中添加脚本,该事件处理程序在启动时初始化页面后被调用。在这里,通过将选项值传递给 **selectmenu 插件** 来设置选择菜单控件的初始配置选项。在代码中,设置选择菜单的themeinlinecornersiconiconposshadowiconshadow 属性的值。现在当你点击选择菜单时,样式化的菜单选项如下截图所示:

![它是如何工作的...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6d67073cec744b2ea530e29c08f97a9e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1771397954&x-signature=jGlwBRLdF2S3O28PMtw8eumg0jE%3D)

更多内容...

当框架遇到一个 select 元素时,它会自动使用 selectmenu 插件 将其增强为选择菜单。你可以通过使用 data-role='none' 属性关闭自动初始化并使用原生样式。

打开和关闭选择菜单

您可以调用selectmenu插件上的openclose方法,并以以下屏幕截图所示的方式以编程方式打开或关闭选择菜单:

$('#selectid').selectmenu('open'); // open select menu
$('#selectid').selectmenu('close'); // close select menu

`#验证表单

在提交到服务器之前验证表单可以节省带宽和时间,因为错误可以在客户端捕获。因此可以避免服务器请求。在 jQuery Mobile 应用程序中,可以使用 JavaScript 验证表单。此配方向您展示了如何验证博客评论表单中输入的条目。

准备就绪

code/05/validate-form源文件夹中复制此配方的完整代码。可以使用 URL http://localhost:8080/05/validate-form/main.html启动此代码。

如何做...

  1. main.html中,添加以下代码以创建一个表单:

    <form id='commentform' action='#' method='post'>
      <div data-role='fieldcontain'>
        <label for='username'>Name</label>
        <input id='username' name='username' type='text' required placeholder='Enter Name' />
      </div>
      <div data-role='fieldcontain'>
        <label for='email'>Email ID</label>
        <input id='email' name='email' type='email' required placeholder='Enter Email' />
      </div>
      <div data-role='fieldcontain'>
        <label for='comments'>Comments</label>
        <textarea id='comments' name='comments' required placeholder='Enter Comments <10-100 chars long>'></textarea>
      </div>
      <div id='errmsg' style='color: #f00'></div>
      <input id='submitid' type='submit' data-transition='pop' value='Submit Comment'/>
    </form>
    
  2. 添加以下脚本来验证评论字段:

    $('#main').live('pageinit', function(event) {
     $('#commentform').submit(function() {
        var len = $('#comments').val().length;
        if ( len < 10 || len > 100 ) {
          $('#errmsg').text('Invalid comments. Length must be between 10-100 chars').show().fadeOut(5000);
          return false;
        }
        else
          return true;
      });
    });
    

它是如何工作的...

main.html中,添加一个表单(id='commentform'),并向表单添加以下三个字段,用户名type='text'),电子邮件type='email')和评论textarea)。对所有三个字段添加required属性以将它们指定为必填项。通过使用placeholder属性添加适当的提示给用户,如前述代码所示。向表单添加一个空的 div(id='errmsg')以在表单验证时显示任何错误消息。

当您加载表单并单击提交评论按钮而不输入姓名字段时,将显示以下错误消息:

它是如何工作的...

单击提交按钮而不输入有效的电子邮件 ID时,将显示以下错误:

它是如何工作的...

如上一个脚本中所示,添加pageinit事件处理程序。这将在页面在启动时被初始化后调用。在这里定义表单的submit()方法来验证评论的长度。如果评论长度无效,则在五秒后显示错误消息,然后淡出。现在因为有错误,所以从submit方法返回false;表单将不会被提交。

它是如何工作的...

在成功验证后,从submit()方法返回true以成功将表单提交到服务器。

还有更多...

在此配方中,表单的action设置为#或与当前 HTML 页面相同的 URL。这种表单称为自提交表单。在这种情况下的默认响应是表单内容本身。如果表单由 Web 服务器提供,则可以自定义生成 post 的响应。如果您使用的是随本书源代码一起提供的 nodejs Web 服务器,则会得到自定义成功响应,而不是表单内容。

表单中的唯一 ID

在 jQuery Mobile 应用程序中,由于多个页面可以同时存在于 DOM 中,因此应确保表单控件的 ID 是唯一的。ID 应该在整个应用程序中是唯一的,而不仅仅是在单个页面中。如果不遵循此规则,查找和表单行为可能会失败或表现不同。一些浏览器可能仍然在一定程度上支持重复的 ID,但这并不保证。

另请参阅

  • 使用 POST 提交表单 的方法

  • 使用 GET 获取数据 的方法

使用 POST 提交表单

这个方法向你展示了如何使用 Ajax POST 并提交表单,也展示了不使用 Ajax 时如何提交同一个论坛。在上一个方法中使用的博客评论表单在此用于提交。

准备工作

code/05/submit-form 源文件夹中复制此方法的完整代码。此代码可以使用 URL http://localhost:8080/05/submit-form/main.html 启动。要尝试此方法,您还需要启动随本书源代码一起提供的简单 nodejs web 服务器。使用以下命令启动服务器:

node jqmserver.js

怎么做...

  1. main.html 中,按照以下代码创建博客评论表单:

    <form id='commentform' action='/postComment' data-transition='pop' method='post'>
      <div data-role='fieldcontain'>
        <label for='username'>Name</label>
        <input id='username' name='username' type='text' required placeholder='Enter Name' />
      </div>
      <div data-role='fieldcontain'>
        <label for='email'>Email ID</label>
        <input id='email' name='email' type='email' required placeholder='Enter Email' />
      </div>
      <div data-role='fieldcontain'>
        <label for='comments'>Comments</label>
        <textarea id='comments' name='comments' required placeholder='Enter Comments <10-100 chars long>'></textarea>
      </div>
      <div id='errmsg' style='color: #f00'></div>
      <input id='submitid' type='submit' value='Submit Comment'/>
    </form>
    
  2. 将以下脚本添加到 <head> 部分以验证评论字段:

    $('#main').live('pageinit', function(event) {
     $('#commentform').submit(function() {
        var len = $('#comments').val().length;
        if ( len < 10 || len > 100 ) {
          $('#errmsg').text('Invalid comments. Length must be between 10-100 chars').show().fadeOut(5000);
          return false;
        }
        else
          return true;
      });
    });
    

如何运作...

main.html 中,创建博客评论表单。将表单的 action 设置为 '/postComment',并且还要指定 data-transition='pop' 属性。其余的代码和表单验证与前一个方法中的相同,并在那里详细解释。当你启动应用程序时,表单会显示如下截图所示:

如何运作...

填写表单,然后点击提交评论按钮。如果没有发现错误,表单将通过 Ajax 提交。自定义的 nodejs web 服务器响应 /postComment 请求,生成以下 HTML 内容作为带有 mime 类型 'text/html' 的响应:

<div data-role='page' data-theme='a'>
  <div data-role='header'>
    <h1>Comments Added</h1>
  </div>
  <div data-role='content'>
    Hi {User name entered}!
    <p>Your Email ID: {Email ID entered}</p>
    <p>Added your comment: {Comments entered}</p>
    <a href='#' data-role='button' data-rel='back'>Back</a>
  </div>
</div>

框架渲染响应如下截图所示:

如何运作...

页面过渡平稳,使用了 pop 动画。你可以点击返回按钮并导航回原始页面,因为也指定了 data-rel='back' 属性。

还有更多...

你可以通过向表单元素指定 data-ajax='false' 属性来提交此表单而不使用 Ajax。此代码在与 main.html 相同文件夹中的 non-ajax.html 文件中提供:

<form id='commentform' action='/postComment' method='post' data-ajax='false'>

当不使用 Ajax 时,响应会触发整个页面的刷新。在此方法中,服务器响应仅返回页面 div 容器,并且不返回具有任何链接到 jQuery Mobile 样式表的 <head> 元素。此外,响应中缺少对 jQuery 和 jQuery Mobile 库的引用。因此,结果页面如下截图所示。在此响应页面中没有样式,如果点击返回链接,它不起作用。

还有更多...

Ajax 响应

通过 Ajax 的服务器响应会替换请求表单的内容,就像本篇食谱中所示。您可以通过使用 DOM 检查器来查看此响应。但是,如果您查看页面源代码,则仍会显示原始页面。POST 请求不能被书签标记,因为它们在哈希中不包含任何查询参数。对 POST 请求的响应将返回与请求相同的 URL,并且不会更新 URL 哈希。

其他非 Ajax 提交表单的方式

本篇食谱向您展示了如何通过设置属性 data-ajax='false' 来提交表单,而不使用 Ajax。另一种不使用 Ajax 的方法是向表单指定一个 target 属性,如下所示:

<form id='commentform' action='/postComment' method='post' target='sometarget'>

这适用于 POST 和 GET 服务器请求。

Ajax 还可以通过使用 mobileinit 事件处理程序中以下代码中显示的全局配置来关闭应用程序:

$.mobile.ajaxEnabled = false;

参见

  • 验证表单 食谱

  • 使用 GET 获取数据 食谱

  • 在 第七章 中的配置 ajaxEnabled* 食谱,配置

使用 GET 获取数据

本篇食谱向您展示了如何使用 Ajax GET 请求并从服务器获取数据。在本篇食谱中,服务器会通过来自 足球联赛分数 表单的 GET 请求返回足球比分。

准备工作

code/05/get-request源文件夹中复制本篇食谱的完整代码。这段代码可以通过 URL http://localhost:8080/05/get-request/main.html 运行。要尝试这个食谱,您需要启动随本书源代码一起提供的简单 nodejs web 服务器。使用以下命令启动服务器:

node jqmserver.js

如何操作...

  1. main.html中,添加以下代码以创建一个表单:

    <div id='scores' data-role='fieldcontain'>
     <form id='scoreform' action='/getScores' method='get'>
        The latest scores are now available!
        <input id='submitid' type='submit' name='submitid' data-inline='true' value='Fetch Scores' />
      </form>
    </div>
    
  2. 将以下脚本添加到 <head> 部分以使用 Ajax 获取并显示分数:

    $('#main').live('pageshow', function(event) {
      $('#scoreform').submit(function() {
     $.get('/getScores').success(showScores).error(errMsg);
        return false; // cancel the default submit
      });
    });
    function showScores(data) { // on success
     $('#scores').html(data).trigger('create');
    }
    function errMsg() { // on error
      $('#scores').html('Unable to fetch scores, try later');
    }
    

它是如何工作的...

main.html中,添加一个<div>容器,其id='scores',并设置其属性data-role='fieldcontain'。这个<div>容器将显示分数。向页面添加一个表单(id='scoreform'),并将其action设置为'/getScores'method设置为'get'。在表单中添加一个文本为 获取分数 的提交按钮,以从服务器获取分数。您可以向页面添加一个装饰的页脚,使用class='ui-bar ui-bar-e'。加载应用程序后,显示以下屏幕:

它是如何工作的...

如前面代码所示,添加pageshow事件处理程序。当您单击submit按钮时,它调用 jQuery submit()方法。默认表单submit()的服务器响应将用新的内容替换整个页面。要获取部分页面更新,请调用 jQuery 的.get() Ajax 方法来从'/getScores'服务器 URL 获取数据。然后通过返回false取消默认的submit()方法。.get()方法指定了successerror的回调函数,如前面的代码所示。在成功的回调函数showScores()中,用从服务器获得的 HTML 响应替换#scores div 的内容。触发'create'方法以让 jQuery Mobile 框架初始化和增强新添加的内容。任何错误都由errMsg()错误处理程序处理,如前面的代码所示。

自定义的 Nodejs Web 服务器通过生成以下 HTML 内容作为响应来响应/getScores get 请求,MIME 类型为'text/html'

<ul data-role='listview'>
  <li data-role='list-divider'>Group A</li>
    <li>Team A beat Team B [ 5 - 3 ]</li>
    <li>Team C lost to Team D [ 1 - 2 ]</li>
  <li data-role='list-divider'>Group B</li>
    <li>Team E drew Team F [ 0 - 0 ]</li>
    <li>Team G lost to Team H [ 3 - 4 ]</li>
</ul>

现在,仅通过此服务器响应替换了#scores <div>容器的内容。标题和页脚保持不变。结果显示如下截图所示:

工作原理...

还有更多...

您可以通过向表单元素指定data-ajax='false'属性来提交不使用 Ajax 的表单,如下代码所示。当不使用 Ajax 时,响应会触发完整页面刷新。因此确保服务器响应中返回一个正确的 jQuery Mobile 页面,否则结果页面可能存在样式和其他问题。

<form action='/someAction' method='get' data-ajax='false'>

Ajax 响应

服务器通过 Ajax 响应完全替换了请求表单的内容。您可以使用 DOM 检查器查看响应。但如果您查看页面源代码,原始页面仍然会显示。GET 请求可以被收藏夹添加为它们支持哈希中的查询参数。GET 响应允许更新 URL 哈希。

表单提交默认值

您也可以提交一个没有指定任何动作或方法属性的表单,如下代码中所示:

<form>

表单将使用动作和方法属性的默认值。方法将默认为'get',动作将默认为当前页面的相对路径。您可以通过调用$.mobile.path.get()方法访问此路径。

注意

始终为表单指定actionmethod属性。

另请参阅

  • 验证表单 配方

  • 使用 POST 提交表单的 配方

  • 第七章中配置 ajaxEnabled 配方,配置

创建一个可访问的表单

jQuery Mobile 框架对无障碍功能(如WAI-ARIA)提供了很好的支持。这为无障碍工具(如屏幕阅读器)提供了支持。这使得您的应用程序屏幕可以被依赖这些辅助技术的用户阅读。此外,现在一些浏览器(如使用 Webkit 引擎的 Chrome)已经提供了语音输入控件。这些控件接受语音输入。本文介绍了如何生成支持语音输入并支持屏幕阅读器的无障碍表单控件。

准备工作

code/05/accessible-controls 源文件夹中复制本文的完整代码。您可以使用 URL http://localhost:8080/05/accessible-controls/main.html 启动此代码。

如何做…

  1. main.html 中,添加以下代码以创建一个表单:

    <form action='#' method='post'>
     <div data-role='fieldcontain' class='ui-hide-label'>
        <input type='text' name='username' id='username' placeholder='Enter Name' speech x-webkit-speech/>
        <label for='username'>Name</label>
      </div>
      <div data-role='fieldcontain'>
     <input type='number' name='age' id='age' placeholder='Enter Age' speech x-webkit-speech/>
        <label for='age' class='ui-hidden-accessible'>Age</label>
      </div>
      <div data-role='fieldcontain'>
        <input type='text' name='city' id='city' placeholder='Enter City' class='custom' speech x-webkit-speech/>
     <label for='city' class='ui-hidden-accessible'>City</label>
      </div>
      <input type='submit' name='submit' id='submit' value='Submit' />
    </form>
    

它是如何工作的…

main.html 中,按如下方式添加三个字段,用户名(输入 type='text')、年龄(输入 type='number')和 城市(输入 type='text')。为每个字段关联一个标签,并为每组标签和输入控件添加一个 div 容器,该容器具有属性 data-role='fieldcontain'。这有助于框架根据平台和设置动态重新排列和调整布局。placeholder 属性用于为用户提供适当的输入提示。

要启用语音输入,请按照之前代码中所示为每个输入控件添加 speechx-webkit-speech 属性。语音输入的支持完全取决于浏览器的实现,一些浏览器仍然没有实现它们。当页面加载时,您将看到以下截图:

它是如何工作的…

您将在每个输入控件的右上角看到一个小麦克风图标。用户可以点击此图标,然后会提示用户为输入控件说出值。一旦用户说完,语音转文字引擎会将声音转换为文本,并在控件中显示输入值文本。虽然不是完全准确,但语音转文字技术正在日益改进。

还有更多…

正如前面提到的,jQuery Mobile 框架对 WAI-ARIA 等无障碍功能提供了很好的支持。因此,请为所有表单元素添加有意义的标签。当页面初始化时,框架会自动向屏幕阅读器公开这些标签。如果您已经使用占位符为用户提供提示,那么标签可能是多余的。但如果您希望建立一个支持无障碍功能的应用程序,那么您也应该定义标签。

如果你想使用占位符功能并支持辅助功能,jQuery Mobile 提供了一个简单的选项,通过在表单控件上使用样式'ui-hidden-accessible'隐藏标签。你也可以通过在表单字段容器中添加样式'ui-hide-label'来隐藏标签,代码中已经展示。现在标签不会显示在屏幕上,但依然可以被屏幕阅读器访问。你可以通过运行你喜欢的屏幕阅读器并访问创建的页面来验证这一点。

移动设备的受欢迎的语音阅读器

当今市场上有许多语音阅读器,你可以根据你的平台尝试任何受欢迎的语音阅读器。苹果手机有VoiceOver (见 www.apple.com/accessibility/iphone/vision.html), 安卓手机有TalkBack , Spiel , Mobile Accessibility for Android, 以及安卓应用商店中的其他应用。

桌面语音阅读器

对于 Chrome 桌面浏览器,可以从 code.google.com/p/google-axs-chrome 安装ChromeVox 扩展,一旦启用,它将开始为你朗读表单控件。你可以验证屏幕阅读器是否也读出了隐藏的标签内容。

第六章:列表视图

在本章中我们将涵盖:

  • 使用嵌入式和非嵌入式列表

  • 创建自定义编号列表

  • 使用嵌套列表

  • 使用只读的嵌套列表

  • 格式化列表中的内容

  • 使用分隔按钮列表

  • 使用图标

  • 创建自定义搜索过滤器

  • 用 JavaScript 修改列表

介绍

通过以下代码创建 jQuery Mobile 中的简单列表:

<ul data-role='listview'>
  <li><a href='link1'>Item 1</a></li>
  <li><a href='link2'>Item 2</a></li>
</ul>

前面的代码是一个普通的 HTML 无序列表,你可以在其中添加属性data-role='listview'。框架现在可以增强、美化并移动端友好地呈现该列表。它为锚点元素添加了右箭头,并且当你点击列表中的任何项目时,链接的页面会被加载到 DOM 中,并在可能时使用 AJAX 过渡打开。

使用嵌入式和非嵌入式列表

嵌入式列表是嵌入在容器(页面、表单或其他列表)中的列表。本教程向你展示了如何创建嵌入式和非嵌入式列表,并强调了在使用非嵌入式列表与其他表单控件时需要注意的事项。

准备工作

code/06/inset-list源文件夹中复制本教程的完整代码。该代码可通过以下 URL 启动:http://localhost:8080/06/inset-list/main.html

如何实现...

  1. 按如下代码在main.html中创建三个列表和几个按钮:

    <div data-role='content'>
      <a href='#' data-role=button data-theme='b'>Button 1</a>
     <ul data-role='listview' data-inset='true'>
        <li data-theme='e'><a href='#'>Item 1</a></li>
        <li data-theme='e'><a href='#'>Item 2</a></li>
      </ul>
      <a href='#' data-role=button data-theme='b'>Button 2</a>
     <ul data-role='listview'>
        <li data-theme='e'><a href='#'>Item A</a></li>
        <li data-theme='e'><a href='#'>Item B</a></li>
      </ul>
      <a href='#' data-role=button data-theme='b'>Button 3</a>
     <ul data-role='listview' style='margin: 15px'>
        <li data-theme='e'><a href='#'>Item 3</a></li>
        <li data-theme='e'><a href='#'>Item 4</a></li>
      </ul>
      <a href='#' data-role=button data-theme='b'>Button 4</a>
    </div>
    

工作原理...

在代码中,第一个列表是嵌入式列表,其他两个是非嵌入式列表。你可以通过在列表中添加属性data-inset='true'来创建嵌入式列表。这样可以使列表的四周都有15px的美化边距。如果你将按钮或其他形式控件放在嵌入式列表旁边,布局会自动调整。

代码中的下一个列表是非嵌入式列表,没有data-inset属性。框架会给该列表加上-15px的填充,让它拉伸至整个屏幕宽度。如果你将按钮或其他表单控件放在该列表旁边,由于负填充,这些控件会重叠在一起。该列表具有矩形角落。

代码中的第三个列表也是非嵌入式列表。但这里通过使用属性style='margin: 15px'来处理控件重叠的问题。这样可以为列表增加15px的边距,并抵消默认填充。三个列表显示如下截图所示:

工作原理...

注意

当使用非嵌入式列表与其他表单控件时,添加额外的边距以避免控件重叠。

更多内容...

你可以配置框架在你的应用中默认使用嵌入式列表。通过在listview插件的mobileinit事件中将inset选项设置为true来实现这一点,如下代码所示:

$(document).bind('mobileinit',function(){
  $.mobile.listview.prototype.options.inset = 'true';
});

设置列表视图主题

你可以使用data-theme属性并像以下代码中所示为列表设置主题。以下代码中列表使用e色块:

<ul data-role='listview' data-theme='e'>

设置列表项主题

可以使用 data-theme 属性并为每个列表项设置不同的主题。以下代码将 swatch e 设置给列表项 Item 1,而列表项 Item 2 将使用 swatch d

<ul data-role='listview' data-theme='e'>
  <li>Item 1</a>
  <li data-theme='d'>Item 2</li>
</ul>

创建自定义编号列表

默认情况下,有序列表 在 jQuery Mobile 中使用十进制数。框架使用 CSS 添加编号。JavaScript 用于无法使用 CSS 的地方。本示例向您展示如何使用 JavaScript 为列表添加字母编号。

准备工作

code/06/custom-numbered-list 源文件夹中复制此示例的全部代码。可以使用 URL http://localhost:8080/06/custom-numbered-list/main.html 启动此代码。

如何做…

  1. main.html 中,按照以下代码创建一个有序列表和一个无序列表:

    <div data-role='content'>
     <ol data-role='listview' data-theme='e' data-inset='true'>
        <li>Soccer</li>
        <li>Basketball</li>
        <li>Hockey</li>
        <li>Tennis</li>
      </ol>
     <ul id='alphalist' data-role='listview' data-theme='e' data-inset='true'>
        <li>Soccer</li>
        <li>Basketball</li>
        <li>Hockey</li>
        <li>Tennis</li>
      </ul>
    </div>
    
  2. 添加以下脚本以为无序列表添加字母编号:

    $('#main').live('pageinit', function(event) {
      var alph = 'a';
      $('#alphalist').find('li').each(function() {
        var str = "<span style='font-weight: normal'>" + alph 
            + '.&nbsp;</span>' + $(this).html();
        $(this).html(str);
        alph = String.fromCharCode(alph.charCodeAt(0)+1);
      });
    });
    

工作原理…

代码中的第一个列表是一个有序列表,默认情况下使用十进制数。接下来的列表具有 id='alphalist',是一个无序列表。将给定的脚本添加到页面容器或 main.html<head> 部分。

在脚本中,将 pageinit 事件绑定到一个函数,该函数注入字母编号。在这个函数中,使用 jQuery 的 find('li') 方法获取列表中的所有列表项。使用 jQuery 的 each() 方法循环遍历每个列表项。在 each() 的回调函数中,使用 $(this).html() 获取列表项的当前文本,并在此文本前添加字母(使用 normal 字体重量)。通过使用 $(this).html(str) 将这个新字符串(str)设置给列表项。最后,通过使用 JavaScript 的 charCodeAt()fromCharCode() 方法在循环中增加字母。当页面显示时,两个列表现在显示如下截图中所示:

工作原理…

更多内容…

您可以使用 JavaScript 创建任何类型的编号列表(例如罗马数字、小写或大写字母、项目符号等)。但是,您必须确保处理这些列表的所有情况(例如,处理嵌套列表的项目编号)。

使用嵌套列表

嵌套列表 是一个嵌套在另一个列表项中的列表。默认情况下,列表项上显示右箭头图标,当您点击它时,框架会打开一个单独的子页面来显示嵌套列表。默认情况下,显示的子页面使用主题 b 作为页面标题。框架可以处理到 n 级的嵌套。本示例向您展示如何使用嵌套列表,并且还向您展示如何使用 JavaScript 获取嵌套列表的子页面。

准备工作

code/06/nested-list 源文件夹中复制此示例的全部代码。可以使用 URL http://localhost:8080/06/nested-list/main.html 启动此代码。

如何做…

  1. main.html 中,添加以下代码以创建作者列表。将书名添加到某些作者的嵌套列表中。

    <div data-role='content'>
      <ul data-role='listview' data-theme='b' data-inset='true'>
        <li><a href='#'>H.G. Wells</a></li>
        <li><a href='#'>Rabindranath Tagore</a>
     <ul data-role='listview' data-theme='a' data-inset='true'>
            <li><a href='#'>The Gardener</a></li>
            <li><a href='#'>Gitanjali</a></li>
          </ul>
        </li>
        <li><a href='#'>William Shakespeare</a>
     <ul data-role='listview' data-theme='a' data-inset='true'>
            <li><a href='#'>Merchant of Venice</a></li>
            <li><a href='#'>Romeo and Juliet</a></li>
          </ul>
        </li>
      </ul>
     <div id='nestedlists'></div>
    </div>
    
  2. 添加以下脚本以获取嵌套列表的子页面:

    $('#main').live('pageinit', function(event) {
      var str = '';
     $('ul').listview('childPages').each(function() {
        str = $(this).find("div[class$='ui-title']").html() + ', ' + str;
      });
      $('#nestedlists').html('Books available for authors : ' + str);
    });
    

工作原理...

在代码中,使用作者姓名作为带有锚链接的列表项添加作者拉宾德拉纳特·泰戈尔威廉·莎士比亚的书名的嵌套列表。作者H.G.威尔斯没有嵌套列表。

将给定的脚本添加到页面容器或main.html中的<head>标签中。在脚本中,将pageinit事件绑定到事件处理程序以调用listview 插件childPages方法。使用 jQuery 的each()方法遍历子页面数组。在each()的回调函数中,使用 jQuery 的find()方法获取子页面的标题文本。查找具有属性class='ui-title'的标题 div。将此文本连接到字符串中,一旦获取了所有作者子页面,将此字符串设置为空的'nestedlists' div 的内容。这将显示具有书籍嵌套列表的作者列表。作者H.G.威尔斯没有嵌套列表,不会显示。

工作原理...

嵌套列表嵌入在列表项<li>标签中的锚链接<a>标签之后。当您单击此列表项时,它会打开子页面,如以下屏幕截图所示。锚链接文本被设置为子页面的标题,并且标题默认使用主题b

工作原理...

更多内容...

您将注意到与主页面相比,子页面的主题差异。主页面使用主题a作为页面内容和标题的主题。它使用主题b作为列表的主题。子页面标题默认设置为主题b。由于嵌套列表使用了data-theme='a'属性,因此整个子页面,包括嵌套列表,都使用样式a。在您的应用程序中使用嵌套列表时,这可能不是理想的情况。请参阅第十章中的 主题化嵌套列表 示例,主题框架,了解如何正确设置嵌套列表的主题。

主题化嵌套列表的子页面标题

如本示例所示,默认情况下,嵌套列表的子页面标题设置为样式b。您可以使用以下代码中显示的data-header-theme属性来设置子页面的标题主题:

<ul data-role='listview' data-theme='d' data-header-theme='a'>

配置列表视图的标题主题选项

你可以通过设置listview插件的headerTheme选项来配置应用程序中嵌套列表的默认标题主题。以下代码将其设置为主题a并绑定到mobileinit事件:

$(document).bind('mobileinit',function(){
  $.mobile.listview.prototype.options.headerTheme = 'a';
});

另请参阅

  • 使用只读嵌套列表 示例

  • 第十章中的 主题化嵌套列表 示例,主题框架

使用只读嵌套列表

只读列表是包含非交互式项目或不包含锚链接的项目的列表。框架将只读项目与常规项目样式不同。只读项目具有主题颜色较浅的颜色,并且它们的大小也较小,因为预期用户不会点击它们。

此配方演示了如何创建只读嵌套列表,并使用选项配置列表视图。它还演示了如何将嵌套列表显示为插入式列表。

准备工作

code/06/read-only-list源文件夹复制此配方的完整代码。可以使用 URL http://localhost:8080/06/read-only-list/main.html 启动此代码。

它的操作方法...

  1. main.html中,添加以下代码以创建作者列表。为一些作者添加嵌套的书名列表。

    <div data-role='content'>
      <ul data-role='listview'>
        <li>H.G. Wells</li>
     <li><a href='#'>Mark Twain</a></li>
        <li>Rabindranath Tagore
     <ul data-role='listview'>
            <li>The Gardener</li>
            <li>Gitanjali</li>
          </ul>
        </li>
        <li>William Shakespeare
     <div><ul data-role='listview'>
              <li>Merchant of Venice</li>
              <li>Romeo and Juliet</li>
     </ul></div>
        </li>
      </ul>
    </div>
    
  2. 将以下脚本添加到页面以配置列表视图选项:

    <script>
     $.mobile.listview.prototype.options.theme = 'e';
     $.mobile.listview.prototype.options.headerTheme = 'a';
     $.mobile.listview.prototype.options.inset = true;
    </script>
    

工作原理...

在代码中,将作者名字作为无锚链接的列表项添加。为拉宾德拉纳特·泰戈尔威廉·莎士比亚添加嵌套书籍列表。作者H.G.威尔斯没有嵌套列表。作者马克·吐温有一个锚链接。该列表使用主题e,即黄色。没有嵌套列表或锚链接的项目以浅一些的色调和较小的字体显示。具有嵌套列表或锚链接的项目以常规颜色显示,并具有更大的字体。

工作原理...

将上述脚本添加到页面或main.html<head>标签中,如代码所示。该脚本配置了listview插件的默认选项。在此配方中,配置了themeheaderThemeinset选项。使用headerTheme选项将子页面头的主题设置为a,如上面的代码所示。现在,当您单击列表项拉宾德拉纳特·泰戈尔时,嵌套列表的子页面将打开。具有头部主题a的嵌套列表如下图所示:

工作原理...

还有更多...

有时,您可能想要将嵌套列表显示为插入式列表。您可以通过将内部列表包装在<div>标签中来实现这一点。框架现在不会为嵌套列表创建子页面。

listview插件上调用childPages方法将不返回嵌入了<div>标签的列表。

威廉·莎士比亚的书籍列表在此配方中嵌入在<div>标签中,因此没有创建嵌套列表。

使用插入嵌套列表会使您的列表垂直拉伸,用户将不得不滚动页面以查看所有内容。因此,请有选择地使用它们。

另请参阅

  • 使用嵌套列表 配方

  • 第十章中的 主题化嵌套列表 配方, 主题框架

在列表中格式化内容

这个配方向你展示了如何在列表项中格式化文本。它还向你展示了如何使用可折叠项目和计数气泡在列表项中。

准备工作

code/06/format-content源文件夹中复制此配方的完整代码。可以使用 URL http://localhost:8080/06/format-content/main.html启动此代码。

怎么做...

  1. main.html中,添加以下代码以创建一个交通方式列表:

    <div data-role='content'>
      <ul data-role='listview'>
        <li>
     <p class='ui-li-aside' style='font-size: 15px'>
              <strong>High Speed</strong></p>
          <div data-role='collapsible' data-theme='e'>
            <h2>Air</h2>
            <ul data-role='listview'>
              <li>Aeroplane</li><li>Helicopter</li>
            </ul>
          </div>
     <p class='ui-li-count'>2</p>
        </li>
        <li  data-theme='e'>
          <p class='ui-li-aside' style='font-size: 15px'>
              <strong>Moderate Speed</strong></p>
          <div data-role='collapsible' data-theme='e'>
            <h2>Land</h2>
            <ul data-role='listview'>
              <li>Bus</li><li>Car</li><li>Bike</li><li>Train</li>
            </ul>
          </div>
     <p class='ui-li-count'>4</p>
        </li>
        <li>
          <p class='ui-li-aside' style='font-size: 15px'>
              <strong>Slow Speed</strong></p>
          <div data-role='collapsible' data-theme='e'>
            <h2>Water</h2>
            <ul data-role='listview'>
              <li>Ship</li><li>Submarine</li><li>Boat</li>
            </ul>                
          </div>
     <p class='ui-li-count'>3</p>
        </li>
      </ul>
    </div>
    
  2. 将以下脚本添加到页面以配置列表视图选项:

    <script>
     $.mobile.listview.prototype.options.theme = 'e';
     $.mobile.listview.prototype.options.countTheme = 'a';
     $.mobile.listview.prototype.options.inset = true;
    </script>
    

它是如何工作的...

将上一个代码中显示的三种交通方式作为列表项添加。为每个列表项添加一个data-role='collapsible'的可折叠块。为每个可折叠块添加一个标题文本,并创建一个带有不同车辆类型的列表作为其内容。添加一个样式设置为class='ui-li-aside'的字符串。这将创建一个字符串,并将其位置设置在列表项的右上角。最后,通过使用class='ui-li-count'将所列车辆的数量设置为计数气泡的样式。对每个列表项都这样做。

将代码中显示的脚本添加到页面或main.html<head>标签中,以配置列表选项themeinsetcountTheme的默认值。现在列表显示如下所示:

它是如何工作的...

以下图片显示了展开了一个可折叠块的列表:

它是如何工作的...

还有更多...

您可以使用countTheme选项对计数气泡进行主题设置,如本配方中已提到的。您还可以在列表上设置属性data-count-theme,如下面的代码所示:

<ul data-role='listview' data-count-theme='a'>

在列表项中使用表单控件

这个配方向你展示了如何向列表项添加具有列表的可折叠内容。您还可以像下面的代码中所示向列表项添加任何表单控件。框架通过在列表项内添加所需的填充和边距来增强表单控件,并使表单控件更易于点击。

<li><input type='text' name='username' placeholder='Enter name'/></li>

请参阅

  • 使用分隔按钮列表配方

使用分隔按钮列表

分隔按钮列表是一个为同一列表项提供两种不同操作的列表。这是通过向列表项添加两个锚链接来创建的。然后,框架会自动将列表项转换为分隔按钮。添加到第一个链接的任何图像都会缩小为80 x 80px大小的缩略图。第二个链接将替换为一个称为分隔图标的图标,并位于分隔按钮的右上角。这个配方向你展示了如何创建一个分隔按钮列表来显示列表中的图像。

准备工作

code/06/split-button-list源文件夹中复制此配方的完整代码。可以使用 URL http://localhost:8080/06/split-button-list/main.html启动此代码。

怎么做...

  1. main.html作为多页面模板应用程序创建。在#main页面中添加一个分隔按钮列表,如下面的代码所示:

    <div data-role='content'>
     <ul data-role='listview' data-inset='true' data-theme='b' 
     data-split-theme='e' data-split-icon='arrow-d'>
        <li>
     <a href='#viewphoto' data-rel='dialog'>
            <img style='margin: 10px' 
                src='../../resources/images/img1.png' />
            <h3>Lal Bagh</h3>
            <p>Bangalore, India</p>
          </a>
     <a href='#download' data-rel='dialog'>Lal Bagh, Bangalore</a>
        </li>
        <li>
          <a href='#viewphoto' data-rel='dialog'>
            <img style='margin: 10px' 
                src='../../resources/images/img2.png' />
            <h3>Peacock</h3>
            <p>Mysore, India</p>
          </a>
          <a href='#download' data-rel='dialog'>Peacock, Mysore</a>
        </li>
        <li>
          <a href='#viewphoto' data-rel='dialog'>
            <img style='margin: 10px' height=75%
              src='../../resources/images/img3.png' />
            <h3>Ganesha</h3>
            <p>Bangalore, India</p>
          </a>
          <a href='#download' data-rel='dialog'>Ganesha, Bangalore</a>
        </li>
      </ul>
    </div>
    
  2. 添加将在点击拆分按钮左侧时打开的#viewphoto页面。

    <div id='viewphoto' data-role='page' data-theme='e' >
      <div data-role='header' data-theme='e'>
        <h1>Photo View</h1>
      </div>
      <div data-role='content'>
        Showing photo here ...
      </div>
    </div>
    
  3. 添加将在点击拆分图标时打开的#download页面。

    <div id='download' data-role='page' data-theme='e' >
      <div data-role='header' data-theme='e'>
        <h1>Download</h1>
      </div>
      <div data-role='content'>
          Downloading file ...
      </div>
    </div>
    

工作原理...

#main页面的列表中添加列表项,如前面的代码所示。每个列表项都有两个链接,通过设置data-rel='dialog'属性,这两个链接都会作为对话框打开。将第一个链接指向#viewphoto页面。添加指向照片的图像,并为锚链接文本添加格式化描述。根据缩略图像的大小,您可以像前面的代码所示添加填充。

将第二个链接指向#download页面。第二个链接会自动转换为拆分图标。默认情况下,拆分图标使用右箭头。您可以通过在列表视图上使用data-split-icon属性来配置这一点。使用data-split-theme属性对拆分图标进行主题设置。拆分按钮列表显示如下图所示:

工作原理...

点击照片图像或列表项中的左按钮会打开照片查看对话框,如下图所示:

工作原理...

点击拆分图标会打开下载对话框,如下图所示:

工作原理...

更多信息...

要在#viewphoto对话框中显示照片图像,您将需要编写一些 JavaScript 代码来处理pagechange事件。此在第九章 方法和实用程序中的 使用 changePage()更改页面 配方中有所介绍。

使用 listview 选项配置拆分按钮列表

您可以使用listview插件的splitThemesplitIcon选项配置拆分图标和拆分图标主题的默认值,并将其绑定到mobileinit事件。以下代码将星形图标和主题e设置为列表视图选项的默认值:

$(document).bind('mobileinit',function(){
  $.mobile.listview.prototype.options.splitIcon = 'star';
  $.mobile.listview.prototype.options.splitTheme = 'e';
});

另请参见

  • 在列表中格式化内容 配方

  • 使用图像图标配方

  • 第九章 方法和实用程序 中的 使用 changePage( )更改页面 配方

使用图像图标

jQuery Mobile 框架将图标添加到交互式列表项(具有链接的列表项)的右侧。您还可以将图标添加到列表项文本中,框架会将此图标大小调整为40 x 40px。此配方向您展示如何在列表项中显示图标。

准备工作

code/06/list-icons源文件夹中复制此配方的完整代码。可以使用 URL http://localhost:8080/06/list-icons/main.html 启动此代码。

如何操作...

  1. main.html中,添加一个包含如下代码的列表:

    <div data-role='content'>
      <ul data-role='listview' data-theme='b' data-inset='true'>
        <li data-icon='star'>
          <a href='#'>
     <img src='../../resources/images/img1.png' class='ui-li-icon'
     alt='Lal Bagh'/>
            <h3 style='margin-left: 25px'>Lal Bagh, Bangalore</h3>
          </a>
        </li>
        <li data-icon='star'>
          <a href='#'>
     <img src='../../resources/images/img2.png' class='ui-li-icon' 
     alt='Peacock'/>
            <h3 style='margin-left: 25px'>Peacock, Mysore</h3>
          </a>
        </li>
        <li data-icon='star'>
          <a href='#'>
     <img src='../../resources/images/img3.png' class='ui-li-icon'            alt='Ganesha'/>
            <h3 style='margin-left: 25px'>Ganesha, Bangalore</h3>
          </a>
        </li>
      </ul>
    </div>
    

工作原理...

在列表项的锚链接中为每个列表项添加图像。将 class='ui-li-icon' 属性设置为此图像元素。这会指示框架将图像样式化为图标,并且图像会自动缩小以适应列表项内。您可以设置所需的边距以便文本在调整图像大小后正确显示。列表显示如下截图所示:

工作原理...

还有更多...

对于具有链接的交互式列表项,默认情况下,框架会在列表项的右侧添加一个右箭头图标。可以使用列表项上的 data-icon 属性进行更改。本步骤中的代码使用 star 图标作为列表项。

另请参阅

  • 在列表中格式化内容 的步骤

  • 使用分割按钮列表 的步骤

创建自定义搜索过滤器

当使用 列表搜索过滤器 时,框架会遍历列表项并显示与过滤文本匹配的项。备用文本也可以与搜索过滤器一起使用。当使用备用文本时,将忽略列表项文本。搜索是一种通用匹配,文本中的任何出现都将显示在结果中。

本步骤向您展示如何使用可以同时搜索列表项文本和备用文本的搜索过滤器。它还向您展示了如何配置搜索过滤器,以及如何实现使用自定义搜索逻辑的自定义搜索回调函数。

准备工作

code/06/custom-search 源文件夹复制此步骤的完整代码。可以使用 URL http://localhost:8080/06/custom-search/main.html 启动此代码。

如何做...

  1. main.html 中,创建以下移动平台列表。列表项还包含属性 data-filtertext 中的操作系统制造商名称。

    <div data-role='content' data-theme='e'>
      <ul id='oslist' data-role='listview'>
     <li data-role='list-divider'>Open Source</li>
        <li data-filtertext='Google'>Android</li>
        <li data-filtertext='HP'>WebOS</li>
        <li data-filtertext='Samsung Intel'>Tizen</li>
        <li data-filtertext='Linux Foundation'>LiMo</li>
        <li data-filtertext='Mozilla'>Boot2Gecko</li>    
     <li data-role='list-divider'>Closed</li>
        <li data-filtertext='Apple'>iOS</li>
        <li data-filtertext='Nokia'>Symbian</li>
        <li data-filtertext='Nokia'>S40</li>
        <li data-filtertext='RIM'>Blackberry OS</li>
        <li data-filtertext='Microsoft'>Windows Phone</li>
        <li data-filtertext='Samsung'>Bada</li>
      </ul>
    </div>
    
  2. 将以下脚本添加到页面以配置默认列表选项:

    $.mobile.listview.prototype.options.theme = 'e';
    $.mobile.listview.prototype.options.inset = true;      
    $.mobile.listview.prototype.options.dividerTheme = 'e';
    $.mobile.listview.prototype.options.filter = true;
    $.mobile.listview.prototype.options.filterTheme = 'e';
    $.mobile.listview.prototype.options.filterPlaceholder = 'Search for ...';
    $.mobile.listview.prototype.options.filterCallback = customFilter;
    
    
  3. 以下代码片段包含搜索文本中的列表项文本:

    $('#main').live('pageinit', function(event) {
      $('#oslist').find('li').each(function() {
        $(this).attr('data-filtertext', 
            $(this).attr('data-filtertext') + ' ' + $(this).html());
      });
    });
    
  4. 自定义搜索回调定义如下代码:

    function customFilter(text, searchValue) {
      var regx='\\b'+searchValue;
     return !(text.match(new RegExp(regx, 'i')));
    }
    

工作原理...

main.html 中,创建一个带有 id='oslist' 的列表。按照代码所示为各种移动操作系统平台添加列表项。使用属性 data-role='list-divider' 创建列表项,并将列表项分为 开源闭源。使用 data-filtertext 属性将操作系统制造商名称作为备用搜索文本。

将给定的脚本添加到页面或 main.html<head> 标签中。设置各种列表视图配置选项,如 theme='e'inset='true'。这是一个 只读列表,列表项着以浅黄色阴影。使用 dividerTheme='e' 选项来对列表分隔符项进行主题化。列表分隔符项由框架以较深色调样式化。

接下来,添加 filter='true'filterTheme='e' 选项,为列表添加搜索过滤器,并使用 e 主题对其进行主题化。使用 filterPlaceholder 选项指定搜索过滤器文本控件的自定义文本(默认为 'Filter Items...')。最后,通过设置选项 filterCallback=customFilter 设置自定义搜索回调函数。列表显示如下所示:

工作原理...

列表中的默认搜索功能匹配文本中搜索字符串的任何出现。要覆盖此行为,请按照前面的代码所示定义自定义过滤器回调。该函数接受两个参数,textsearchValue。创建一个正则表达式来搜索给定文本中单词开头处的 searchValue 出现。忽略单词之间的搜索值出现。使用 match() 方法将正则表达式与文本进行匹配。参数 i 使其大小写不敏感。

如果使用 filtertext 属性与列表项,那么默认搜索仅使用此文本,忽略列表项文本。要同时使用列表项文本和过滤文本,请添加 pageinit 事件处理程序,如前面的代码所示。在此函数中,使用 jQuery find('li).each() 方法找到每个列表项,并在 each() 的回调中,获取列表项文本并将其添加到过滤文本中。这不会对列表项产生任何可见影响。但是列表项文本现在是过滤文本的一部分,因此可供搜索过滤器使用。因此,搜索 a 将列出 AndroidiOS(filtertext 的值为 Apple)。但这不会列出 SymbianBada,因为它们的单词中间包含 a,如下屏幕截图所示:

工作原理...

如果搜索 Bo,则仅将 Boot2Gecko 作为候选项,如下屏幕截图所示:

工作原理...

还有更多...

搜索回调函数返回一个布尔值,指示是否应通过搜索过滤器隐藏文本。因此,搜索过滤器回调应为所有匹配元素返回 false。不匹配的文本元素返回 true,并由搜索过滤器隐藏。

使用数据属性配置列表分隔主题

该示例使用 dividerTheme 选项对列表分隔项进行主题化。您还可以使用 data-divider-theme 属性,如下面的代码所示:

<ul data-role='listview' data-theme='e' data-divider-theme='e'>

使用数据属性配置列表搜索过滤器

该示例向您展示如何使用 filterfilterThemefilterPlaceholder 选项来配置列表视图。这些选项也可以使用 data-filterdata-filter-themedata-filter-placeholder 属性进行设置,如下面的代码所示:

<ul data-role='listview' data-filter='true' data-filter-theme='e' data-filter-placeholder='Search for...'>

使用 JavaScript 修改列表

您可以使用 JavaScript 动态修改列表及其内容。本示例向您展示如何使用 JavaScript 在只读列表中添加或删除列表项。

准备工作

code/06/scripting-lists 源文件夹复制此配方的完整代码。此代码可以使用网址 http://localhost:8080/06/scripting-lists/main.html 运行。

如何做...

  1. main.html 中,添加以下代码以在布局网格中创建一个空列表:

    <div data-role='content'>
      <div data-role='fieldcontain'>
        <fieldset class='ui-grid-b'>
          <div class='ui-block-a' style='width: 65%'>
     <ul id='numlist' data-role='listview' data-theme='e' 
     data-inset='true'>
     </ul>
          </div>
          <div class='ui-block-b'>
            <button data-theme='b' id='addBtn'>Add</button>
            <button data-theme='b' id='removeBtn'>Remove</button>
          </div>
        </fieldset>
      </div>
    </div>
    
  2. 添加以下脚本以动态添加或删除列表项:

    var count = 0;
    $('#main').live('pagecreate', function(event) {
     $('#numlist').listview({create: function(event, ui) {
        $('#addBtn').bind('click', function(event, ui) {
          var str = "<li><a href='#'>Item " + (++count) + '</a></li>';
          $('#numlist').append(str);
     $('#numlist').listview('refresh');
        });
        $('#removeBtn').bind('click', function(event, ui) {
          if (--count < 0) {
            count = 0;
            return;
          }
          $('#numlist').find('li').last().remove();
     $('#numlist').listview('refresh');
        });
      }});
    });
    

它是如何工作的...

main.html 中使用 class='ui-grid-b' 属性在 fieldset 容器上添加一个两列布局网格。在第一列中添加一个空列表,其 id='numlist'。在第二列中添加两个按钮,ID 分别为 addBtnremoveBtn。单击这些按钮时,列表项会动态更新到第一列的空列表中。

将给定的脚本添加到页面或 main.html<head> 部分。在脚本中,为 pagecreate 事件创建一个事件处理程序,在页面完全初始化之前触发。在此处,为 listview 元素的 create 事件添加一个事件处理程序。当创建 listview 元素时,将触发此事件。在其回调函数中,绑定 addBtnremoveBtn 按钮的 click 事件,如前述代码所示。

按下 addBtn 时,将一个列表项添加到列表中。列表项文本保存在内存中,并在添加新元素时递增。按下 removeBtn 时,通过调用 jQuery 的 find('li').last() 方法获取最近添加的列表项元素。通过调用 remove() 方法移除此最后一个元素。在对列表进行任何修改后,调用 listview 插件 上的 refresh() 方法来更新列表。

当启动应用时,显示如下截图所示,其中包含一个空列表:

它的工作原理...

按下添加按钮会向列表中添加新的列表项,如下面的截图所示:

它的工作原理...

按下删除按钮会删除最近添加的列表项。

它的工作原理...

还有更多...

正如此配方中所述,您必须在对列表进行任何修改后调用 listview 插件 上的 refresh() 方法。在添加新列表项或删除列表项时,refresh() 方法会触发列表的更新,并在列表项上应用必要的样式和增强效果。

$('#numlist').listview('refresh');

第七章:配置

本章将涵盖以下内容:

  • 配置活动类

  • 配置ajaxEnabled

  • 配置autoInitializePage

  • 配置默认转换

  • 配置ignoreContentEnabled

  • 配置页面加载和错误消息

  • 配置默认命名空间

  • 配置hashListeningEnabledsubPageUrlKey

  • 配置pushStateEnabledlinkBindingEnabled

介绍

jQuery Mobile 框架会在文档加载后立即增强标记和元素。您可以通过在文档对象上设置mobileinit事件处理程序中的值来调整用于这些增强的默认配置。本章向您展示了如何使用框架中提供的各种配置。

配置活动类

jQuery Mobile 框架默认使用 CSS 类activeBtnClass来为主题为b的活动状态的按钮设置样式。activeBtnClass类具有默认字符串值ui-btn-active。为了为活动页面(正在查看或正在过渡的页面)设置样式,框架使用 CSS 类activePageClass,该类具有默认字符串值ui-page-active。本配方向您展示如何配置框架以使用这些默认类的自定义类。

准备就绪

code/07/active-class源文件夹中复制此配方的完整代码。您可以使用以下网址启动此代码:http://localhost:8080/07/active-class/main.html

如何实现...

  1. main.html中,将以下样式添加到页面的<head>标签中,以定义自定义的活动按钮类和活动页面类:

    <link rel="stylesheet" 
      href="http://code.jquery.com/mobile
      /1.1.1/jquery.mobile-1.1.1.min.css" />
    <style>
     .ui-custom-btn-active {
        background: #53C584;
        background-image: -webkit-gradient(linear, left top, 
          left bottom, from( #53C584 ), to( #6FD598 ));
        background-image: -webkit-linear-gradient( #53C584 , 
          #6FD598 );
        background-image: -moz-linear-gradient( #53C584 , 
          #6FD598 );
        background-image: -ms-linear-gradient( #53C584 , 
          #6FD598 );
        background-image: -o-linear-gradient( #53C584 , 
          #6FD598 );
        background-image: linear-gradient( #53C584 , 
          #6FD598 );
      }
     .ui-mobile .ui-custom-page-active {
        border: 3px;
        border-style: dotted;
        width: 99%;
        display: block;
        overflow: visible;
      }
    </style>
    
  2. 在包含 jQuery Mobile 脚本之前添加以下脚本:

    $(document).bind("mobileinit", function() { 
     $.mobile.activePageClass = "ui-custom-page-active"; 
     $.mobile.activeBtnClass = "ui-custom-btn-active";
    });
    
  3. 创建带有链接以打开#page1#main页面,如下所示:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header" data-theme="e">
        <h1>Active Classes</h1>
      </div>
      <div data-role="content">
        <a href="#page1" data-role="button">Open Page 1</a>
      </div>
    </div>
    
  4. 创建#page1,并添加一个链接以返回到#main页面,如下所示;这是一个多页文档:

    <div id="page1" data-role="page" data-theme="e">
      <div data-role="header" data-theme="e">
        <h1>Page 1</h1>
      </div>
      <div data-role="content">
        <a href="#main" data-rel="back" data-role="button">
          Go Back
        </a>
      </div>
    </div>
    

工作原理...

main.html中,添加一个样式标签并定义类ui-custom-btn-active,以在活动按钮上设置不同的渐变背景(绿色阴影)。默认的活动按钮背景是明亮的蓝色阴影。还添加一个ui-custom-page-active类,该类为页面设置3px厚的虚线边框。接下来,在包含对jquery.mobile.js引用之前,添加给定的脚本。在脚本中,为mobileinit事件添加一个事件处理程序,该事件在应用程序启动时触发。在这里,将$.mobile.activePageClass$.mobile.activeBtnClass属性设置为这两个新类。最后,添加#main#page1页面容器。当您启动应用程序时,#main页面现在将显示为带有虚线边框,如下面的屏幕截图所示:

工作原理...

当您点击打开页面 1按钮时,按钮的活动状态在按下时显示绿色阴影,如下面的屏幕截图所示:

工作原理...

接下来,页面 #page1 打开,它也有虚线边框:

如何运作...

单击时,返回按钮也会变成绿色:

如何运作...

还有更多...

你可以使用 mobileinit 事件处理程序来自定义和配置 jQuery Mobile 框架的默认设置。你必须在包含 jquery.mobile.js 脚本之前添加此自定义脚本,以确保框架使用你的设置进行初始化。

使用 jQuery 的 .extend() 调用

你也可以使用 .extend() jQuery 调用来扩展 $.mobile 对象,而不是直接在 $.mobile 上设置属性,如下所示:

$.extend( $.mobile, {
  $.mobile.activeBtnClass = "ui-custom-btn-active";
});

另请参阅

  • 第二章, 页面和对话框, 使用 CSS 创建弹跳页面转换:此教程提供了供应商前缀的概述

配置 ajaxEnabled

在可能的情况下,jQuery Mobile 框架会自动使用 Ajax 处理链接点击和表单提交。这可以使用 $.mobile.ajaxEnabled 属性进行配置,默认情况下其布尔值为 true。如果禁用了 Ajax 或不支持它,则使用普通的 HTTP 请求并进行完整页面加载。URL 散列监听也被禁用。这个教程向你展示了如何配置 $.mobile.ajaxEnabled 属性。

准备就绪

code/07/ajax-enabled 源文件夹中复制此教程的完整代码。你可以使用以下 URL 启动此代码:http://localhost:8080/07/ajax-enabled/main.html

怎么做...

  1. main.html 中,在包含 jquery.mobile.js 之前添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.ajaxEnabled = true;
    });
    
  2. 创建包含链接以打开 page1.html 的主页面:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header" data-theme="a">
        <h1>Ajax Enabled</h1>
      </div>
      <div data-role="content">        
        <p>This is the main page</p>
        <a href="page1.html" data-role="button">
          <p>Open Page 1</p>
        </a>
      </div>
    </div>
    
  3. 最后,创建 page1.html,其中包含一个返回到 main.html 的链接,如下所示:

    <div data-role="page" data-theme="e" data-add-back-
      btn="true">
      <div data-role="header">
        <h1>Page 1</h1>
      </div>
      <div data-role=content>    
        <p>Sub Page Contents</p>
        <a href="main.html" data-role="button">Go back</a>
      </div>
    </div>
    

如何运作...

在包含对 jquery.mobile.js 的引用之前,在代码中添加给定的脚本。在脚本中,添加一个用于在应用程序启动时触发的 mobileinit 事件的事件处理程序。在这里,设置配置 $.mobile.ajaxEnabled=true

注意

由于 $.mobile.ajaxEnabled 默认为 true,因此您不必在代码中明确设置它。它包含在此教程中,因为您将在代码中稍后将此值更改为 false

添加 #main 页面。按照代码中所示创建 page1.html(请注意,page1.html 中没有 <head> 元素)。显示 #main 页面,如下图所示:

如何运作...

单击 打开第一页 按钮以打开 page1.html,如下所示。此页面通过 Ajax 加载,并且框架增强了控件。

如何运作...

然后,在 main.html 中将 ajaxEnabled 属性设置为 false,然后重新加载页面。现在,当打开 page1.html 时,元素不会被增强,如下图所示:

如何运作...

还有更多...

当禁用 Ajax 时,将加载整个页面。在page1.html中,由于缺少指向 jQuery Mobile 框架库的链接的<head>元素,因此页面不会获得任何样式或增强效果。

配置 autoInitializePage

当您导航到新页面或将页面加载到 DOM 中时,框架会初始化页面并使其可见。这由$.mobile.intializePage属性控制,默认情况下其布尔值为true。如果将其设置为false,则不会显示页面。您将不得不手动将其设置回true以显示页面。本示例向您展示了如何执行相同操作。

准备就绪

code/07/auto-initialize源文件夹中复制此示例的全部代码。您可以通过使用 URL 启动此代码:http://localhost:8080/07/auto-initialize/main.html

如何操作...

  1. main.html中,在包含jquery.mobile.js之前,添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.autoInitializePage = false;
    });
    
  2. 创建具有以下内容的主页:

    <div data-role="content">
      <a href="#" data-role="button">A button</a>
      <script>
     $.mobile.autoInitializePage = true;
      </script>
    </div>
    

工作原理...

在包含对jquery.mobile.js的引用之前,将给定的autoInitializePage脚本添加到代码中。在脚本中,添加一个在应用程序启动时触发的mobileinit事件处理程序。在这里,将配置$.mobile.autoInitializePage=false。最后,添加#main页面。页面内容将类似于以下屏幕截图:

工作原理...

初始化内容并将其设置为$mobile.autoInitializePage的值手动设置为true,如代码所示。您可以注释此行(在页面内容部分)并重新加载页面,以发现什么也没有显示。

还有更多...

您可以使用此功能延迟显示页面,同时在后台执行一些后台工作或从服务器后台获取数据时。在手动处理页面更改时很有用。

配置默认过渡效果

默认情况下,jQuery Mobile 框架在使用 Ajax 加载页面时使用fade过渡。在使用 Ajax 打开对话框时,默认使用pop过渡。本示例向您展示了如何为您的应用设置不同的默认过渡效果。

准备就绪

code/07/default-transitions源文件夹中复制此示例的全部代码。您可以使用以下 URL 启动此代码:http://localhost:8080/07/default-transitions/main.hml

如何操作...

  1. main.html中,在包含jquery.mobile.js之前,添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.defaultDialogTransition = "flow";
     $.mobile.defaultPageTransition = "turn";
    });
    
  2. 创建#main页面如下:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header">
        <h1>Configure Transitions</h1>
      </div>
      <div data-role=content>
        <a href="#page1" data-role="button">Open as Page</a>
        <a href="#page1" data-rel="dialog" data-role="button">Open as Dialog</a>
      </div>
    </div>
    
  3. 创建#page1如下;这是一个多页面文档:

    <div id="page1" data-role="page" data-theme="e" data-add-back-btn="true">
      <div data-role="header">
        <h1>Page 1</h1>
      </div>
      <div data-role=content>
        <p>Page 1 Content</p>
      </div>
    </div>
    

工作原理...

创建main.html并在代码中包含给定的脚本,然后再包含对jquery.mobile.js的引用。在脚本中,添加一个在应用程序启动时触发的mobileinit事件处理程序。在这里,使用$.mobile.defaultDialogTransition$.mobile.defaultPageTransition属性设置页面和对话框的默认过渡效果。最后,如所示,添加#main#page1页面容器。

#main中,有两个按钮。第一个按钮将#page1作为页面打开,第二个按钮将其作为对话框打开。您将看到默认转换已更改。页面现在使用turn转换,对话框使用flow转换。

还有更多...

您还可以将页面和对话框的默认转换都设置为none。这将只是加载页面或对话框而不使用任何转换:

$.mobile.defaultDialogTransition = "none";
$.mobile.defaultPageTransition = "none";

使用自定义转换

你可以配置框架以使用自定义转换作为默认转换。您必须按以下方式设置转换名称:

$.mobile.defaultDialogTransition = "myDialogTransition";
$.mobile.defaultPageTransition = "myPageTransition";

转换回退

fade转换是默认转换,它使用 2D。所有其他转换都使用 3D。不支持 3D 变换的旧浏览器和设备将退回到使用fade。您可以将此默认回退转换配置为none,或者您可以将其设置为自己的自定义 2D 转换。可以为每个单独的 3D 转换执行此操作,如下所示:

$.mobile.transitionFallbacks.slideout = "none";
$.mobile.transitionFallbacks.flip = "myCustom2DTransition";

另请参阅

  • 第二章, 使用 CSS 创建弹跳页面转换

  • 第二章, 使用 JS 创建滑动'淡出'转换

配置 ignoreContentEnabled

jQuery Mobile 框架会自动增强页面中找到的控件和标记。要跳过增强某些标记部分,您可以使用$.mobile.ignoreContentEnabled配置(默认为false)。此示例向您展示如何执行相同操作。

准备工作

code/07/content-enabled源文件夹中复制此示例的完整代码。您可以使用以下网址启动此代码:http://localhost:8080/07/content-enabled/main.html

如何做...

  1. main.html中,在包含jquery.mobile.js之前添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.ignoreContentEnabled = true;
    });
    
  2. 创建带有以下内容的#main页面:

    <div data-role="content">
     <div data-enhance="false">
        <input type="checkbox" name="chkbox1" id="chkbox1" 
          checked />
        <label for="chkbox1">Checkbox</label>
        <input type="radio" name="radiobtn1" id="radiobtn1" 
          checked />
        <label for="radiobtn1">Radio Button</label>
     </div>
      <div>
        <input type="checkbox" name="chkbox2" id="chkbox2" 
          checked />
        <label for="chkbox2">Enhanced Checkbox</label>
        <input type="radio" name="radiobtn2" id="radiobtn2" 
          checked />
        <label for="radiobtn2">Enhanced Radio Button</label>
      </div>
    </div>
    

它是如何工作的...

创建main.html并在包含对jquery.mobile.js的引用之前添加代码中的给定脚本。在脚本中,为在应用程序启动时触发的mobileinit事件添加事件处理程序。在这里,将属性$.mobile.ignoreContentEnabled=true设置为true。在#main中,添加两个 div。在每个div中添加一个复选框和一个单选按钮。将属性data-enhance=false设置为第一个div。现在,框架不会增强添加到此div中的元素。第二个div中的元素会自动增强。页面显示如下截图所示:

它是如何工作的...

还有更多...

当您使用$.mobile.ignoreContentEnabled=true配置时,它告诉框架避免增强某些标记部分。通过使用data-enhance="false"属性来执行此操作,如此示例所示。现在,当框架遇到每个控件或标记时,它首先检查父元素是否将data-enhance属性设置为false。如果是,则跳过将样式或任何增强应用于控件。

注意

使用 $.mobile.ignoreContentEnableddata-enhance 可能会在页面增强时导致性能下降。

配置页面加载和错误消息

默认情况下,jQuery Mobile 框架在加载新页面时显示一个带有主题 a 的旋转动画,不带任何文本。如果出现错误,页面加载超时,将显示错误消息 Error Loading Page,带有主题 e。本教程向你展示如何更改和自定义页面加载和错误消息。

准备工作

code/07/load-message 文件夹的源文件中复制此教程的全部代码。要尝试此教程,请使用该文件夹中可用的简单 nodejs web 服务器,使用以下命令:

node jqmserver.js

然后,您可以使用以下 URL 启动代码:http://localhost:8080/07/load-message/main.hml

如何做...

  1. main.html 中,添加以下脚本以在包含 jquery.mobile.js 之前使用:

    $(document).bind("mobileinit", function() {
     $.mobile.loadingMessage = "Fetching it...";
     $.mobile.loadingMessageTextVisible = true;
     $.mobile.loadingMessageTheme = "b";
     $.mobile.pageLoadErrorMessage = "Oops, it's missing!";
     $.mobile.pageLoadErrorMessageTheme = "b";
    });
    
  2. 创建以下内容的 #main 页面:

    <div data-role="content">
     <a href="/delay" data-role="button">Dummy page</a>
    </div>
    

它是如何工作的...

创建 main.html,并在包含对 jquery.mobile.js 的引用之前添加给定脚本。在脚本中,为 mobileinit 事件添加一个事件处理程序,该事件在应用程序启动时触发。在这里,设置默认的页面加载消息和错误消息如代码所示。

#main 中,有一个尝试打开 "/delay" 页面的链接。这是对 nodejs 服务器的 GET 操作。服务器处理此请求,并在暂停几秒钟后返回错误代码。在此持续时间内显示带有文本消息的旋转控件,如下截图所示:

它是如何工作的...

错误响应会导致以下错误消息显示:

它是如何工作的...

配置默认命名空间

本教程向你展示如何配置 jQuery Mobile 框架以使用你自定义的命名空间作为 data- 属性。

准备工作

code/07/namespace 源文件夹中复制此教程的全部代码。您可以使用以下命令启动此代码:http://localhost:8080/07/namespace/main.html

如何做...

  1. main.html 中,添加以下脚本以在包含 jquery.mobile.js 之前使用:

    $(document).bind("mobileinit", function() {
     $.mobile.ns = "my-";
    });
    
  2. <head> 标签中添加以下样式:

    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
    <style>
     .ui-mobile [data-my-role=page], .ui-mobile [data-my-role=dialog], 
     .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; 
     position: absolute; display: none; border: 0; } 
    </style>
    
  3. 创建主页面如下所示:

    <div id="main" data-my-role="page" data-my-theme="e">
      <div data-my-role="header" data-my-theme="a">
        <h1>Configure Namespace</h1>
      </div>
     <div data-my-role="content"> 
        <p>This is the main page</p>
        <a href="#dialog" data-my-role="button">
          Open Dialog
        </a>
      </div>
    </div>
    
  4. 创建 #dialog 页面如下;这是一个多页面文档:

    <div id="dialog" data-my-role="dialog" data-my-theme="e">
      <div data-my-role="header" data-my-theme="a">
        <h1>Dialog</h1>
      </div>
      <div data-my-role="content">
        <p>This is a dialog</p>
     <a href="#" data-my-role="button" data-my-
     rel="back">Go Back</a>
      </div>
    </div>
    

它是如何工作的...

要使用自定义命名空间,您必须在 jquery.mobile.css 文件中覆盖一个特定的选择器,即 .ui-mobile [data-my-role=page].ui-mobile [data-my-role=dialog] 选择器。按照代码中所示覆盖此样式。使用 data-my-role 意味着命名空间设置为 my

创建 main.html,并在包含对 jquery.mobile.js 的引用之前添加前述脚本以设置此配置。在脚本中,为 mobileinit 事件添加一个事件处理程序,该事件在应用程序启动时触发。在这里,使用 $.mobile.ns="my-" 配置设置默认命名空间。添加 #main#dialog 页面。

以下截图显示了通过 DOM 检查器看到的页面:

它是如何工作的...

您会注意到代码还使用了data-my-属性。您还会观察到框架已添加增强功能,甚至这些增强功能在整个页面上都使用自定义命名空间。

注意

对于自定义命名空间,使用尾随连字符,例如"my-"。这样增强代码更易读。

配置hashListeningEnabledsubPageUrlKey

当您使用嵌套listview时,jQuery Mobile 框架会生成一个子页面,形式为pagename.html&ui-page=subpageidentifier。在子页面 URL 键(&ui-page)之前的哈希段由框架用于导航。本示例向您展示了如何使用自定义子页面 URL 键。它还向您展示了如何使用$.mobile.hashListeningEnabled配置。

准备工作

从源文件夹code/07/sub-page中复制此示例的完整代码。您可以使用以下 URL 启动此代码:http://localhost:8080/07/sub-page/main.html

如何做...

  1. main.html中,在包含jquery.mobile.js之前添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.subPageUrlKey = "my-page";
     $.mobile.hashListeningEnabled = false; 
    });
    
  2. 在其内容中创建带有嵌套列表的#main页面如下所示:

    <div data-role="content">
     <ul data-role="listview" data-theme="e">
        <li>Main Page Item 1</li>
        <li>Sub Page Items
     <ul data-role="listview">
            <li>Sub Page Item A</li>
            <li>Sub Page Item B</li>
          </ul>
        </li>
      </ul>
    </div>
    

它是如何工作的...

创建main.html,并在包含对jquery.mobile.js的引用之前在代码中添加给定的脚本。在脚本中,添加一个在应用程序启动时触发的mobileinit事件的事件处理程序。在这里,设置$.mobile.subPageUrlKey="my-page"$.mobile.hashListeningEnabled=false配置。最后,在代码中添加#main页面与嵌套列表一样。输出将类似于以下截图:

它是如何工作的...

点击子页面项,并在子页面中打开嵌套列表。地址栏显示自定义的子页面 URL 键my-page,如下面的截图所示:

它是如何工作的...

现在,使用浏览器的返回按钮返回。地址栏中的 URL 会更新,但页面不会返回到上一个屏幕,如下面的代码所示:

它是如何工作的...

这是因为在启动时将hashListeningEnabled配置为false。这将阻止框架监听和处理位置哈希更改。如果将hashListeningEnabled设置为true(默认值)并重新加载页面,则页面导航将正常工作,并且主列表将再次显示为嵌套列表。

注意

只有在想要自定义管理哈希更改而不是允许框架处理它时,才配置hashListeningEnabled

另请参阅

  • 第七章,配置配置pushStateEnabledlink**BindingEnabled

配置pushStateEnabledlinkBindingEnabled

当您单击链接时,将进行导航并更新 URL 散列。框架允许您在支持 history.replaceState API 的浏览器中将 URL 散列替换为完整路径。此示例向您展示了如何使用 $.mobile.pushStateEnabled 配置来实现此目的。它还向您展示了如何使用 $.mobile.linkBindingEnabled 配置,该配置允许框架自动绑定文档中锚链接的单击事件。这两者默认值均为 true

准备工作

code/07/push-state 文件夹中复制此示例的完整代码。您可以使用以下 URL 启动此代码:http://localhost:8080/07/push-state/main.html

如何操作...

  1. main.html 中,在包含 jquery.mobile.js 前添加以下脚本:

    $(document).bind("mobileinit", function() {
     $.mobile.linkBindingEnabled = true;
     $.mobile.pushStateEnabled = false; 
    });
    
  2. 创建以下内容的 #main 页面:

    <div data-role="content">
      <a href="page1.html" data-role="button">Go to Page 1</a>
    </div>
    
  3. 创建 page1.html 如下:

    <div id="page1" data-role="page" data-theme="e">
      <div data-role="header">
        <h1>Header of Page 1</h1>
      </div>
      <div data-role="content">
        <a href="#" data-role="button" data-rel="back">Go Back</a>
      </div>
    </div>    
    

它的工作原理...

创建 main.html,并在引用 jquery.mobile.js 之前在代码中添加给定的脚本。在脚本中,为在应用程序启动时触发的 mobileinit 事件添加事件处理程序。在这里,设置 $.mobile.pushStateEnabled=false$.mobile.linkBindingEnabled=true 配置。最后,根据代码中所示添加 #main 页面内容和 page1.html。输出将类似于以下屏幕截图:

它的工作原理...

当您打开 页面 1 时,URL 地址栏将完整路径附加到 main.html,如下截图所示:

它的工作原理...

这是因为在启动时将 pushStateEnabled 设置为了 false。如果您将其设置为 true(默认值)并重新加载页面,URL 散列将被替换,并显示为 http://localhost:8080/07/push-state/page1.html

注意

当应用程序中未使用 Ajax 或者大量使用外部链接时,将 pushStateEnabled 配置设置为 false

还有更多...

在本示例中,在启动时将 linkBindingEnabled 配置设置为了 true(其默认值)。如果您将其设置为 false 并重新加载页面,您将注意到单击 转到页面 1 按钮时它未获得活动状态。在这种情况下,框架不会自动绑定链接点击。

注意

仅在您希望您的自定义代码(或其他库)处理链接点击时,使用 linkBindingEnabled 配置。

参见也

  • 第七章, 配置, 配置 hashListeningEnabled 和 subPageUrlKey

第八章:事件

在本章中,我们将涵盖:

  • 使用方向事件

  • 使用滚动事件

  • 使用触摸事件

  • 使用虚拟鼠标事件

  • 使用页面初始化事件

  • 使用页面加载和移除事件

  • 使用页面切换事件

  • 使用页面过渡和动画事件

  • 使用布局事件

介绍

jQuery Mobile 框架不仅提供了默认的本机事件,还为桌面和移动平台提供了特定的事件。它允许你使用 jQuery 的 bind()live() 方法绑定到这些事件,并允许你执行自定义操作。本章将向您展示如何使用 jQuery Mobile 框架中提供的事件。

使用方向事件

当移动设备的方向(纵向横向)改变时,jQuery Mobile 框架会触发一个 orientationchange 事件。这个示例向您展示如何使用 orientationchange 事件。

准备工作

code/08/orientation 源文件夹中复制此示例的完整代码。您可以通过使用 URL http://localhost:8080/08/orientation/main.html 启动此代码。

如何实现...

执行以下步骤:

  1. 创建 main.html 如下所示:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header" data-theme="a">
     <h1>Orientation Events</h1>
      </div>    
      <div data-role="content">
        <p>Change orientation</p>
      </div>
    </div>
    
  2. <head> 部分添加处理 orientationchange 事件的脚本:

    $(window).bind("orientationchange", function(event, data) {
     $("h1").html(data.orientation);
    });
    

工作原理...

创建 main.html,其中包含页面内容,如前面的代码片段所示。添加给定的脚本,并将 orientationchange 事件绑定到回调函数。在这里,将设备的当前方向设置为页面的 h1 标题。您可以通过回调函数的 data.orientation 属性获取设备的方向。

当页面加载时,改变设备的方向;头部文本将根据当前方向显示 纵向横向

更多信息...

在不支持 orientation 属性的平台($.support.orientationfalse)或者 $.mobile.orientationChangeEnabled 全局配置设置为 false 时,框架会绑定 resize 事件处理程序来处理设备方向的改变。

orientationChangeEnabled 全局配置

您可以在应用程序开始时调用的 mobileinit 事件处理程序中配置 $.mobile.orientationChangeEnabled 配置。这必须在包含 jquery.mobile.js 脚本之前完成。

$(document).bind("mobileinit", function() {
  $.mobile.orientationChangeEnabled = false;
});

使用滚动事件

当您滚动时,jQuery Mobile 框架会触发 scrollstart 事件。当您停止滚动时,会触发 scrollstop 事件。这个示例向您展示如何使用这两个事件。

准备工作

code/08/scroll 源文件夹中复制此示例的完整代码。您可以通过使用 URL http://localhost:8080/08/scroll/main.html 启动此代码。

如何实现...

执行以下步骤:

  1. 创建 main.html,其中页面内容的 div 元素使用一个较大的高度值进行样式设置,以便出现滚动条:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header" data-theme="a" data-
      position="fixed">
     <h1>Scroll Events</h1>
      </div>    
      <div data-role="content">
        <div style="height: 1000px">Scroll now</div>
      </div>
    </div>
    
  2. <head> 部分添加以下脚本来处理 scroll 事件:

    $(window).bind("scrollstart", function(event) {
      $("h1").html("Scrolling now...");
    });
    $(window).bind("scrollstop", function(event) {
      $("h1").html("Scrolling done!");
    });
    

工作原理...

在前面的代码中创建main.html。在页面内容中添加一个高度为1000pxdiv容器。这将使垂直滚动条出现。现在,在页面的<head>部分添加给定的脚本。将scrollstart事件绑定到一个回调函数,该函数更新页面头部文本。类似地,将scrollstop事件绑定到一个回调函数,该函数更新头部文本。现在,保持垂直滚动条手柄,滚动页面。您可以看到页面头部文本显示为"正在滚动...",当您停止或暂停滚动时,文本更新为"滚动完成!"

还有更多...

在 iOS 设备上,scrollstart事件的工作方式存在问题。在滚动期间不允许 DOM 操作,并且事件被排队,一旦滚动停止就会触发。因此,在处理 iOS 设备上的滚动事件时,请记住这一点。您将不得不在滚动开始之前进行更改,而不是一开始就进行更改。

使用触摸事件

jQuery Mobile 框架提供了五个触摸事件。它们是taptapholdswipeswipeleftswiperight事件。当您点击屏幕时,将触发tap事件。如果点击持续时间较长,则首先触发taphold事件,然后在您放开手指后触发tap事件。当您在屏幕上滑动时,首先触发swipe事件,然后根据您滑动的方向触发swipeleftswiperight事件。本配方向您展示了如何使用这些触摸事件。

在这个配方中,显示一个黄色框,显示您最后点击屏幕的位置。每次您点击并保持时,都会创建一个绿色框。您还可以通过将蓝色条拉到屏幕的左侧或右侧来查看滑动操作的工作方式。

准备工作

code/08/touch源文件夹复制此配方的完整代码。您可以通过使用 URL http://localhost:8080/08/touch/main.html 来启动此代码。

如何操作...

应该遵循的步骤是

  1. main.html中,在<head>标签中定义以下样式:

    <style>
      .box { width:60px; height:60px; position:fixed }
      .yellow { background-color:yellow; z-index:1 }
      .green { background-color:green; z-index:2 }
      .blue { background-color: blue; z-index:3; height:100% }
    </style>
    
  2. 使用两个带有蓝色条和黄色框样式的<div>标签添加页面内容:

    <div id="content" data-role="content">
      <div id="movingbox" class="box yellow" style="top:0px; left:0px"></div>
      <div id="edgebar" class="box blue" style="top:0px; left:0px"></div>
    </div>
    
  3. <head>部分添加以下脚本,以处理taptaphold事件:

    var tapholdflag = false;
    $("#main").live("tap", function(event) {
      var stylestr = "left:" + event.clientX + "px; top:" 
        + event.clientY + "px;"
      if (tapholdflag) {
        var str = "<div class=''box green'' style=''" + 
          stylestr + "''></div>";
        $("#content").append(str).trigger("create");
      } else {
        $("#movingbox").attr("style", 
          stylestr).trigger("refresh");
      }
      tapholdflag = false;
    });
    $("#main").live("taphold", function(event) {
      tapholdflag = true;
    });
    
  4. 最后,处理swipeswipeleftswiperight事件:

    $("#main").live("swipe", function(event) {
      $.event.special.swipe.scrollSupressionThreshold = 15;
      $.event.special.swipe.durationThreshold = 1250;
      $.event.special.swipe.horizontalDistanceThreshold = 25;
      $.event.special.swipe.verticalDistanceThreshold = 50;
    });  
    $("#main").live("swipeleft", function(event) {
      $("#edgebar").attr("style", "top:0px; 
        left:0px").trigger("refresh");
    });
    $("#main").live("swiperight", function(event) {
      $("#edgebar").attr("style", "top:0px; 
        right:0px").trigger("refresh"); 
    });
    

它是如何工作的...

main.html中,添加style标签,并定义boxyellowgreenblue类。添加一个空的div标签,设置属性id="movingbox",并设置属性class="box yellow"。这将创建一个60px宽的黄色方块。接下来,添加一个空的div标签,设置属性id="edgebar",并设置属性class="box blue"。这将在屏幕边缘创建一个60px宽的蓝色条,如下面的截图所示。黄色框隐藏在蓝色条下面,因为它具有较低的z-index值。

![它是如何工作的...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/abd8cf33ddfa4933b3bf0eabe6c4ef6d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1771397954&x-signature=nm6i%2FErvBrV2HjjxYLERi05zxWM%3D)

现在将给定的脚本添加到main.html<head>部分。将五个触摸事件中的每一个绑定到如所示的回调函数。如果触摸持续时间长,则为taphold。因此,定义一个布尔值tapholdflag来跟踪tap事件是否为taphold。在taphold事件处理程序中将其设置为true,并在触发tap事件后将其清除。

tap事件的回调中,首先检查 tapholdflag是否已设置。如果是,则这是一个taphold事件。创建一个新的绿色框并调用"create"方法,如所示。如果tapholdflagfalse,则这是一个简单的点击。更新黄色框的新位置,并触发"refresh"方法。最后,清除tapholdflag并将其设置为false

通过使用event.clientXevent.clientY参数,可以获取触摸位置。将这些值设置为盒子的lefttop样式属性,以更新其位置。在几次taptaphold事件后,屏幕看起来类似于以下截图:

它是如何工作的...

现在,将swipe事件绑定到回调函数,并按照代码中所示配置swipe事件属性。代码向您展示如何配置scrollSupressionThresholddurationThresholdhorizontalDistanceThresholdverticalDistanceThreshold属性。

swipeleft事件绑定到回调以设置蓝色条的lefttop样式属性,并调用"refresh"方法。这将将条移到屏幕的左边缘。类似地,将swiperight事件绑定到回调以设置蓝色条的righttop样式属性,并调用"refresh"。这将把条移到屏幕的右边缘。现在,当您向屏幕的右侧滑动时,该条将移动到右边缘,如以下截图所示;向左侧滑动,则该条将移回左边缘:

它是如何工作的...

还有更多...

在代码中,swipe事件的回调向您展示了如何配置swipe事件属性。可用的配置如下:

  • scrollSupressionThreshold(默认为10px):必须滑动距离超过此值才能触发事件,否则就是scroll事件。

  • durationThreshold(默认为1000ms):如果滑动持续时间超过此值,则阻止swipe事件的触发。

  • horizontalDistanceThreshold(默认为30px):水平滑动距离必须超过此值才能触发事件。

  • verticalDistanceThreshold(默认为75px):垂直滑动距离必须小于此值才能触发事件。

tapholdThreshold属性

每当您点击屏幕时,将触发 tap事件。如果点击持续时间超过一定值(默认为750ms),则将其视为 taphold事件。您可以通过设置$.event.special.tap.tapholdThreshold 属性来配置此持续时间,如下所示:

$("#main").live("tap", function(event) {
  $.event.special.tap.tapholdThreshold = 1000;
});

注意

默认 tap 事件配置对大多数平台都很有效。因此,只有在有非常强烈的理由时才修改它们。

另请参阅

  • 使用虚拟鼠标事件 示例

`# 虚拟鼠标事件

jQuery Mobile 框架提供虚拟 mousevmouse 事件来抽象鼠标和触摸事件。

您无需为每个受支持的平台或设备的触摸和鼠标事件编写单独的处理程序。您只需为 vmouse 事件编写事件处理程序,它将在各种平台上正常工作。框架支持七个 vmouse 事件:vmousemovevmouseovervmouseoutvmousedownvmouseupvclickvmousecancel。此示例向您展示如何使用这些 vmouse 事件。

准备工作

code/08/vmouse 源文件夹中复制此示例的完整代码。您可以通过以下 URL http://localhost:8080/08/vmouse/main.html 启动此代码。

如何实现...

应遵循以下步骤:

  1. 创建包含七个 div 标签的 main.html,用于展示七个 vmouse 事件,如下所示:

    <div data-role="content">
      <div id="move"></div>
      <div id="over"></div>        
      <div id="out"></div>        
      <div id="down"></div>
      <div id="up"></div>
      <div id="click"></div>
      <div id="cancel"></div>
    </div>
    
  2. 将以下脚本添加到 <head> 部分以处理 vmousemovevmouseovervmouseout 事件:

    $("#main").live("pageinit", function(e) {
     $("#main").bind("vmousemove", function(e) {
        $("#move").html("<p>Move: " + e.clientX + ", " 
          + e.clientY + "</p>");
      });
     $("#main").bind("vmouseover", function(e) {
        $("#over").html("<p>Over: " + e.clientX + ", " 
          + e.clientY + "</p>");
      });
     $("#header").bind("vmouseout", function(e) {
        $("#out").html("<p>Out: " + e.clientX + ", " + 
          e.clientY + "</p>");
      });
    
  3. 接下来,按如下方式处理 vmousedownvmouseupvclick 事件:

     $("#main").bind("vmousedown", function(e) {
        var whichbtn;
        switch (e.which) {
          case 1: whichbtn = "Left Button"; break;
          case 2: whichbtn = "Center Button"; break;
          case 3: whichbtn = "Right Button"; break;
          default: whichbtn = "Tap"; break;
        }                        
        $("#down").html("<p>Down: " + e.clientX + ", " 
          + e.clientY + " - " + whichbtn + " </p>");
      });
     $("#main").bind("vmouseup", function(e) {
        $("#up").html("<p>Up: " + e.clientX + ", " + 
          e.clientY + "</p>");
      });
     $("#main").bind("vclick", function(e) {
        $("#click").html("<p>Click: " + e.clientX + ", 
          " + e.clientY + "</p>");
      });
    
  4. 最后,按如下方式处理 vmousecancel 事件:

     $("#main").bind("vmousecancel", function(e) {
        $("#cancel").html("<p>Cancel: " + e.clientX + ", 
          " + e.clientY + "</p>");
      });
    });
    

工作原理...

创建 main.html,并添加七个空的 divs 来显示七个 vmouse 事件的位置。添加给定的脚本,并绑定每个 vmouse 事件的回调函数,如 pageinit 事件处理程序所示。使用传递给回调函数的事件参数的 e.clientXe.clientY 值来获取 vmouse 事件的位置。当您加载页面并执行描述的各种鼠标操作时,屏幕显示如下:

工作原理...

当鼠标移动(或在 touchmove 事件上)时,将触发 vmousemove 事件。当移动操作在事件绑定的元素上完成时,将触发 vmouseover 事件。当移动操作移出事件绑定的元素时,将触发 vmouseout 事件。在上述代码中,vmouseout 事件绑定到 h1 标题上。将鼠标移动到标题上,然后移出,以查看屏幕上的此参数是否更新。当鼠标点击(或在 touchstart 事件上)时,将触发 vmousedown 事件。当点击结束时(touchend 事件),vmouseup 事件紧随 down 事件。在点击或触摸动作时,将同时触发 vclick 事件和 vmousedownvmouseup 事件。在 vmousedown 事件处理程序中,您可以使用 event.which 属性来查找点击了哪个鼠标按钮。对于 tap 事件,此值为 0。您可以尝试点击鼠标上的不同按钮,以相应地查看屏幕更新。最后,当存在被取消的鼠标或触摸事件时,将触发 vmousecancel 事件。

还有更多...

框架为 vmouse 事件提供了以下三个配置:

  • $.vmouse.moveDistanceThreshold(默认为 10px):如果移动超过此值,则为 scroll 事件。将调用 vmousecancel 事件并取消 TouchMove 事件。

  • $.vmouse.clickDistanceThreshold(默认为 10px):如果已捕获 vmouse 点击事件,则它在阻止列表中。然后,所有小于此距离的 vmouse 点击都将被忽略。

  • $.vmouse.resetTimerDuration(默认为 1500ms):如果 vmouse 点击之间的间隔大于此持续时间,则不是触摸事件。ScrollTouchMoveTouchEnd 事件使用此值。阻止列表将被清除。

    注意

    默认的 vmouse 配置适用于大多数平台。因此,只有在有很强的理由时才修改它们。

鼠标坐标

此配方向您展示如何使用 event.clientXevent.clientY 属性获取鼠标坐标。您还可以使用 event.pageXevent.pageYscreen.pageXscreen.pageY 属性获取屏幕和页面坐标。

在触摸设备上使用 vclick 事件

在触摸设备上,webkit 浏览器会在触发 touchend 事件后大约 300 毫秒的延迟后处理点击事件。如果在此间隙内更改底层对象或背景,则可能选择不同的目标。另一个问题是由于时间延迟而将事件与相应目标匹配;例如,当使用 event.preventDefault() 时。为了避免这些问题,在触摸设备上使用 click 事件而不是 vclick 事件。

另请参阅

  • 使用触摸事件 配方

页面初始化事件

jQuery Mobile 框架提供了页面插件,它自动处理页面初始化事件。 pagebeforecreate事件在页面创建之前触发。 pagecreate事件在页面创建后但在小部件初始化之前触发。 pageinit事件在完全初始化后触发。此示例向您展示如何使用这些事件。

准备工作

code/08/pageinit源文件夹中复制此配方的完整代码。您可以使用 URLhttp://localhost:8080/08/pageinit/main.html启动此代码。

如何操作...

执行以下步骤:

  1. 创建main.html,其中包含三个空的<div>标签,如下所示:

    <div id="content" data-role="content">
      <div id="div1"></div>
      <div id="div2"></div>
      <div id="div3"></div>
    </div>
    
  2. 将以下脚本添加到<head>部分以处理pagebeforecreate事件:

    var str = "<a href='#' data-role='button'>Link</a>";
    $("#main").live("pagebeforecreate", function(event) {
      $("#div1").html("<p>DIV1 :</p>"+str);
    });
    
  3. 接下来,处理pagecreate事件:

    $("#main").live("pagecreate", function(event) {
      $("#div1").find("a").attr("data-icon", "star");
    });
    
  4. 最后,处理pageinit事件:

    $("#main").live("pageinit", function(event) {
      $("#div2").html("<p>DIV 2 :</p>"+str);
      $("#div3").html("<p>DIV 3 :</p>"+str);
      $("#div3").find("a").buttonMarkup({"icon": "star"});
    });
    

工作原理...

main.html中,如下所示将三个空的divs添加到页面内容中。将给定的脚本添加到页面中。在脚本中,str是一个具有data-role="button"属性的创建锚链接的 HTML 字符串。

添加pagebeforecreate事件的回调,并将str设置为div1容器。由于页面尚未创建,因此div1中的按钮会自动初始化和增强,如下图所示。

添加pagecreate事件的回调。使用 jQuery 的find()方法选择div1中的前一个锚按钮,并设置其data-icon属性。由于此更改是在页面初始化之后但在按钮初始化之前进行的,所以div1按钮自动显示为star图标,如下图所示。最后,添加pageinit事件的回调,并将str添加到div2div3容器中。此时,页面和小部件已经初始化和增强。现在添加一个锚链接将仅显示为div2的原生链接,如下图所示。但是,对于div3,找到锚链接,并在按钮插件上手动调用buttonmarkup方法,并将其图标设置为star。现在当您加载页面时,div3中的链接将被增强如下所示:

工作原理...

还有更多...

您可以在插件上触发"create""refresh",以让 jQuery Mobile 框架增强对页面或小部件进行的动态更改后的初始化。

页面初始化事件仅触发一次

页面初始化事件仅触发一次。因此,这是进行任何特定初始化或添加自定义控件的好地方。

不要使用$(document).ready()

$(document).ready()处理程序仅在加载第一个页面或 DOM 首次准备就绪时起作用。如果通过 Ajax 加载页面,则不会触发ready()函数。而pageinit事件在页面创建或加载和初始化时触发。因此,这是在应用程序中进行后初始化活动的最佳位置。

$(document).bind("pageinit", callback() {…});

页面加载和移除事件

jQuery Mobile 框架在将外部页面加载到 DOM 时会触发页面加载事件。它会在加载页面之前触发pagebeforeload事件,然后根据页面加载的状态触发pageloadpageloadfailed事件。当页面从 DOM 中移除时会触发pageremove事件。本教程向您展示如何使用页面加载和页面移除事件。

准备工作

code/08/pageload源文件夹中复制此配方的完整代码。您可以使用 URL http://localhost:8080/08/pageload/main.html启动此代码。

如何做...

执行以下步骤:

  1. 根据以下代码片段创建带有四个按钮和一个空的div元素的main.html

    <div id="content" data-role="content">
      <a href="page1.html" data-role="button" data-
        inline="true">Page 1</a>
      <a href="page2.html" data-role="button" data-
        inline="true">Page 2</a>        
      <a href="page3.html" data-role="button" data-
        inline="true">Page 3</a>
      <a href="page4.html" data-role="button" data-
        inline="true">Page 4</a>
      <div id="msgdiv"></div>
    </div>
    
  2. <head>部分添加以下脚本来处理pagebeforeload事件:

    $(document).bind("pagebeforeload", function(event, data) {
      var str = "<p>LOADING PAGE ...</p>"
        + "<p>url: " + data.url + "</p>"
        + "<p>absUrl : " + data.absUrl + "</p>"
        + "<p>dataUrl : " + data.dataUrl + "</p>"
        + "<p>options.type: " + data.options.type + "</p>";
      var re = /page2.html/;
      if ( data.url.search(re) !== -1 ) {
        str += "<p>ABORTED!!! page2.html does not 
          exist.</p>";
        event.preventDefault();
     data.deferred.reject( data.absUrl, data.options);
      }
      re = /page4.html/;
      if ( data.url.search(re) !== -1 ) {
        str += "<p>ABORTED!!! error dialog shown 
          instead.</p>";
        event.preventDefault();
     data.deferred.resolve( data.absUrl, data.options, 
     $("#subpage")); 
      }
      $("#msgdiv").html(str).trigger("refresh");
    });
    
  3. 接下来,处理pageload事件:

    $(document).bind("pageload", function(event, data) {
      var str = "<p>PAGE LOADED!</p><p>textStatus: " + data.textStatus 
        +   "</p><p>xhr.status : " + data.xhr.status + "</p>";
      $("#msgdiv").append(str).trigger("refresh");
    });
    
  4. 接着,处理任何pageloadfailed事件中的错误:

    $(document).bind("pageloadfailed", function(event, 
     data) {
      var str = "<p>PAGE LOAD FAILED!</p>"+ "<p>textStatus: " + data.textStatus + "</p>"
        + "<p>xhr.status : " + data.xhr.status + "</p>"
        + "<p>errorThrown : " + data.errorThrown + "</p>";
      $("#msgdiv").append(str).trigger("refresh");
    });
    
  5. 同样处理pageremove事件:

    $("#page1").live("pageremove", function(event) {
      $("#msgdiv").append("<p>PAGE 
        REMOVED!</p>").trigger("refresh");
    });
    
  6. 现在,按照以下步骤创建带有id="dialog"的对话框:

    <div id="dialog" data-role="dialog" data-theme="e" data-add-back-btn="true">
      <div data-role="header">
        <h1>Page Load Failed!</h1>
      </div>
      <div data-role="content">
        <p>There was an error</p>
      </div>      
    </div>
    
  7. 最后,根据以下代码片段创建带有返回到#main按钮的page1.html

    <div id="page1" data-role="page" data-theme="e">
      <div data-role="header">
        <h1>Header of Page 1</h1>
      </div>
      <div data-role="content">
        <a href="#" data-role="button" data-
          rel="back">Go to Main Page</a>
      </div>
    </div>
    

它是如何工作的...

main.html中创建#main页面,并添加四个锚链接,带有data-role="button"data-inline="true"属性,以创建四个内联按钮。这些链接指向page1.htmlpage2.htmlpage3.htmlpage4.html。同时添加一个空的div容器,带有id="msgdiv"用于显示消息。接着,在main.html中添加一个带有id="dialog"的对话框。最后,只创建page1.html,如下所示,其中包含一个返回主页的链接。其他三个页面不需要创建。将页面加载和页面移除事件绑定到脚本中给出的回调函数。这些回调函数有两个参数可用。第一个是event对象,第二个是data对象。

pagebeforeload事件的回调中,从data对象中获取urlabsUrl(绝对 URL)、dataUrl(数据 URL)和options.type属性。将它们显示在msgdiv容器中。options对象与传递给$.mobile.loadPage()调用的相同。

pageload事件的回调中,获取xhr.status(jQuery XMLHttpRequest对象)和textStatus属性,指示页面加载成功,并在msgdiv容器中显示它们。

添加pageloadfailed回调函数以在页面加载错误时显示data.xhr.statusdata.errorThrown属性。最后,添加pageremove回调函数并显示页面已被移除的消息。

现在,当您首次加载应用程序并点击页面 1按钮打开page1.html时,首先触发pagebeforeload事件,然后在完全加载页面之后触发pageload事件。返回主页时触发pageremove事件。您可以看到下面的屏幕截图中显示的这些消息:

它是如何工作的...

接下来,在pagebeforeload事件处理程序中,使用正则表达式搜索来检查所请求的页面或data.url是否为page2.html(该页面不存在)。如果请求了page2.html,则显示自定义错误消息。还通过调用event.preventDefault()来阻止对此请求的进一步操作。最后必须调用data.deferred.reject()方法来拒绝数据对象中包含的延迟对象引用。现在,当您单击Page 2按钮时,不会触发pageloadfailed事件,如下面的屏幕截图所示,而是显示自定义错误消息ABORTED!!! page2.html 不存在。

它的工作原理...

点击Page 3按钮;它现在尝试加载page3.html,但是找不到,并显示了默认的Error Loading Page错误消息,如下面的屏幕截图所示。您还可以在这里看到pageloadfailed事件处理程序的消息。在这种情况下没有进行自定义事件处理。

它的工作原理...

最后,在pagebeforeload回调函数中添加代码,以搜索data.url对象中的page4.html。如果找到字符串,则将请求重定向到加载#dialog对话框。还如果请求了page4.html,则显示自定义消息。现在,要阻止pagebeforeevent上的默认操作,请调用event.preventDefault()方法。还必须调用data.deferred.resolve()方法来解析data对象中包含的延迟对象引用。然后,通过将其作为参数传递给resolve方法,打开#dialog页面,如代码所示。现在,当您单击Page 4按钮时,将显示自定义错误对话框弹出窗口。当关闭对话框时,将显示您的自定义消息ABORTED!!!显示错误对话框。,如下面的屏幕截图所示。您会注意到pageloadfailed事件回调函数没有被调用。

它的工作原理...

还有更多...

如果通过调用event.preventDefault()方法来阻止默认的页面加载事件,那么在完成后,必须通知框架恢复处理其他changePage()请求。您可以通过在事件的回调函数中对传递给data.deferred对象调用reject()resolve()方法来实现这一点。

另请参阅

  • 在第九章方法和实用程序中的使用 loadPage()加载页面中的配方

页面更改事件

每当$.mobile.changePage()方法将页面加载到 DOM 中时,jQuery Mobile 框架都会触发页面更改事件。首先触发pagebeforechange事件,然后触发pagechange事件(成功时)或pagechangefailed事件(失败时)。本节介绍如何使用页面更改事件。

准备好了

code/08/pagechange 源文件夹中复制此配方的完整代码。你可以使用 http://localhost:8080/08/pagechange/main.html URL 启动此代码。

如何做...

执行以下步骤:

  1. 创建 main.html,其中包含两个链接以打开两个对话框,并在其页面内容中包含一个空的 div 元素,如下所示:

    <div id="content" data-role="content">
      <a href="#dialog1" data-role="button">Dialog 1</a>
      <a href="#dialog2" data-role="button">Dialog 2</a>        
      <div id="msgdiv"></div>
    </div>
    
  2. 将以下脚本添加到 <head> 部分以处理 pagebeforechange 事件:

    $(document).bind("pagebeforechange", function(event, data) {
      var str = "<p>CHANGING PAGE ...</p><p>toPage: ";
      str += (!!data.toPage.attr)? data.toPage.attr("data-
        url") : data.toPage;
      str += "</p>";
      $("#msgdiv").html(str).trigger("refresh");
      $("#dialogdiv").html(str).trigger("refresh");
    });
    
  3. 接下来,处理 pagechange 事件:

    $(document).bind("pagechange", function(event, data) {
      var str = "<p>CHANGED PAGE ...</p><p>fromPage: ";
      str += (!!data.options.fromPage && !!data.options.fromPage.attr)? 
      data.options.fromPage.attr("data-url") : "none";
      str += "</p><p>options.transition: " + data.options.transition + "</p>";
      $("#msgdiv").append(str).trigger("refresh");
      $("#dialogdiv").append(str).trigger("refresh");
    });
    
  4. 接下来,处理 pagechangefailed 事件中的任何错误:

    $(document).bind("pagechangefailed", function(event, 
     data) {
      var str = "<p>PAGE CHANGE FAILED ...</p>";
      $("#msgdiv").append(str).trigger("refresh");
    });
    
  5. 最后,按以下方式创建 #dialog1 对话框。第二个对话框 #dialog2 不会被创建。

    <div id="dialog1" data-role="dialog" data-theme="e" 
      data-add-back-btn="true">
      <div data-role="header">
        <h1>Dialog Header</h1>
      </div>
      <div data-role="content">
        <div id="dialogdiv"></div>
      </div>
    </div> 
    

工作原理...

main.html 中,将两个锚链接添加到 #main 页面的内容中,这些链接指向 #dialog1#dialog2 对话框。还添加一个带有 id="msgdiv" 的空 div 容器以显示消息。最后,只向 main.html 添加一个带有 id="dialog1" 的对话框。将一个空的带有 id="dialogdiv"div 容器添加到此对话框中。另一个对话框不会被创建。将页面更改事件绑定到给定的脚本中的回调函数。这些回调函数有两个可用参数。第一个是 event 对象,第二个是 data 对象。

pagebeforechange 事件的回调中,获取 data.toPage(目标页面)属性。这可以是字符串或对象。检查这是否是一个对象(是否具有 toPage 属性),然后使用 data.toPage.data-url 字符串。在两个消息 div 容器中显示 toPage 消息。

pagechange 事件的回调中,获取 data.fromPage(源页面)属性。再次检查这是对象还是字符串,并在消息 div 容器中显示 data.fromPage.data-url 字符串,如果它是一个对象。另外,data.options 对象具有属性,例如 transition,你可以使用。

最后,在 pagechangefailed 事件的回调中,显示自定义错误消息。当页面首次加载时,可以看到以下图像。main 文本显示为 toPage;这里没有 fromPage

工作原理...

单击 Dialog 1 按钮,将显示以下对话框。 toPage 值是 dialog1fromPagemain。所使用的转换显示为 pop,这是对话框的默认转换:

工作原理...

关闭此对话框,然后打开 #main 页面,显示与以下截图中显示的消息类似的消息。 toPagemainfromPagedialog1。所使用的转换再次显示为 pop

工作原理...

最后,单击 Dialog 2 按钮;由于 #dialog2 不存在,所以会显示自定义错误消息 PAGE CHANGE FAILED,如你在 pagechangefailed 回调中所见:

工作原理...

还有更多...

你可以在pagebeforechange事件处理程序中调用event.preventDefault()方法来阻止默认的页面更改操作。你可以使用$.mobile.changePage()方法将导航重定向到另一个页面。

页面转换事件的顺序

在触发pagebeforechange事件后, changePage() 请求将页面加载到 DOM 中,然后页面过渡发生。此刻触发pageshowpagehide事件。最后,只有在此之后才会触发pagechange事件。

参见

  • 第九章中的使用 changePage()来更改页面示例,方法和工具

页面过渡和动画事件

在页面导航期间,当前页面变换出去,新的活动页面变换进来。在支持的情况下会使用动画效果。jQuery Mobile 框架在页面导航期间会触发四个页面转换事件,如下所示:

  • pagebeforehide: 在当前页面隐藏之前触发此事件

  • pagehide: 当前页面隐藏后触发此事件

  • pagebeforeshow: 在新的活动页面显示之前触发此事件

  • pageshow: 一旦活动页面显示出来就会触发此事件

你也可以访问animationComplete插件,以便在动画完成后立即执行自定义操作。此示例向你展示如何使用页面过渡事件,以及如何使用animationComplete插件。

准备工作

code/08/transition源文件夹中复制此示例的完整代码。你可以使用 URLhttp://localhost:8080/08/transition/main.html运行此代码。

如何做...

执行以下步骤:

  1. 创建main.html,并添加带有指向打开#page页面的链接和一个空的div容器#main页面的代码片段如下所示:

    <div id="main" data-role="page" data-theme="e">
      <div data-role="header">
        <h1>Page Transition and Animation Events</h1>
      </div>
      <div id="content" data-role="content">
        <a href="#page" data-role="button" data-
          transition="slide">Page 1</a>
      <div id="msgdiv"></div>
    </div>
    
  2. 创建#page页面,包括一个回到#main的按钮和一个空的div容器来显示消息:

    <div id="page" data-role="page" data-theme="e">
      <div data-role="header">
        <h1>Page Header</h1>
      </div>
      <div data-role="content">
        <a href="#" data-rel="back" data-role="button">Go Back</a>
      <div id="pagediv"></div>
    </div>
    
  3. <head>部分添加以下脚本,以便在点击链接时清除消息div容器:

    $("#main").live("pageinit", function(event) {
      $("a").bind("click", function(event, ui) {
        $("#msgdiv").html("");
        $("#pagediv").html("");
      });
    });
    
  4. 处理pagebeforeshow事件:

    $(document).bind("pagebeforeshow", function(event, data) {
      var str = "<p>BEFORE PAGE SHOW ...</p><p>Previous 
        Page: ";
      str += (!!data.prevPage.attr)? 
        data.prevPage.attr("data-url") : "none";
      str += "</p>";
      $("#msgdiv").append(str).trigger("refresh");
      $("#pagediv").append(str).trigger("refresh");
    });
    
  5. 处理pagebeforehide事件:

    $(document).bind("pagebeforehide", function(event, 
     data) {
     $(data.nextPage).animationComplete(anim);
      var str = "<p>BEFORE PAGE HIDE ...</p><p>Current Page: ";
      str += (!!data.nextPage.attr)?
        data.nextPage.attr("data-url") : "none";
      str += "</p>";        
      $("#msgdiv").append(str).trigger("refresh");
      $("#pagediv").append(str).trigger("refresh");
    });
    
  6. 处理pageshow事件:

    $(document).bind("pageshow", function(event, data) {
      var str = "<p>PAGE SHOW!</p><p>Previous Page: ";
      str += (!!data.prevPage.attr)? 
        data.prevPage.attr("data-url") : "none";
      str += "</p>";
      $("#msgdiv").append(str).trigger("refresh");
      $("#pagediv").append(str).trigger("refresh");
    });
    
  7. 处理pagehide事件:

    $(document).bind("pagehide", function(event, data) {
      var str = "<p>PAGE HIDE!</p><p>Current Page: ";
      str += (!!data.nextPage.attr)? 
        data.nextPage.attr("data-url") : "none";
      str += "</p>";        
      $("#msgdiv").append(str).trigger("refresh");
      $("#pagediv").append(str).trigger("refresh");
    });
    
  8. 添加animationComplete()方法的回调函数:

    anim = function() {
      $("#msgdiv").append("ANIMATION 
        DONE!!!").trigger("refresh");
      $("#pagediv").append("ANIMATION 
        DONE!!!").trigger("refresh");          
    }
    

工作原理...

创建main.html,并添加一个带有data-role="button"的锚链接到#main页面的内容。此链接打开main.html中的#page页面。创建#page页面,如下所示,其中包含返回到#main的链接。分别向页面添加空的#msgdiv#pagediv容器来显示消息。在pageinit事件处理程序中绑定锚链接的click事件,并清除先前显示的消息。每当你在应用中点击链接时,都会触发此回调。

现在,按照脚本中给定的方式将四个页面转换事件绑定到它们的回调函数。这些回调函数有两个可用参数。第一个参数是event对象,第二个是data对象。

pagebeforeshow事件的回调函数中,获取data.prevPage(上一页)对象。第一次加载时可能为空。检查是否可用(是否具有prevPage属性),并使用data.prevPage.data-url字符串。在消息div容器中显示prevPage消息。在pagehide事件的回调函数中使用类似的逻辑。

类似地,在pagebeforehidepagehide事件的回调函数中,获取并显示data.toPage(源页面)属性。最后,调用animationComplete插件,并在pagebeforehide事件处理程序中定义anim回调函数,如下所示。在anim()函数中编写代码,在两个 div 容器中显示简单的**动画完成!!!**消息。

当页面首次加载时,您可以看到以下图片,显示了pagebeforeshowpageshow事件处理程序被调用。此时prevPage是未定义的。

它是如何工作的...

点击Page 1按钮打开#page。您可以看到来自pagebeforehidepagebeforeshow事件处理程序的消息,即当前页page上一页main。然后,您可以看到来自animationComplete()回调的**动画完成!!!**消息。此时页面可见,并且还可以看到来自pagehidepageshow事件的消息:

它是如何工作的...

点击返回按钮。现在,#main被显示,消息与之前一样显示。这次,当前页main上一页page

它是如何工作的...

还有更多...

第一次加载时,pagebeforeshowpageshow事件处理程序显示一个空的data.nextPage对象。为了在第一次加载时显示正确的值,这两个事件必须在mobileinit处理程序中绑定到它们的回调函数,即在页面加载之前以及加载jquery.mobile.js脚本文件之前,如下面的代码片段所示:

<script>
 $(document).bind("mobileinit", function() {
    $(document).bind("pagebeforeshow", function(event, data) {
    alert(data.nextPage);
  });
  $(document).bind("pageshow", function(event, data) {
    alert(data.nextPage);
  });
});
</script>
<script src="img/jquery.mobile-1.1.1.min.js"></script>

另请参阅

  • 在第七章的Configuring the default transitions一节中,配置

使用布局事件

用户交互动态调整大小的组件,例如列表视图和可折叠块,会导致控件重叠或定位问题。为防止此情况发生,这些组件会触发updatelayout事件,而 jQuery Mobile 框架会更新整个文档,确保所有组件都正确布局。本文介绍如何使用updatelayout事件。

准备工作

code/08/layout源文件夹中复制此配方的所有代码。您可以通过使用 URLhttp://localhost:8080/08/layout/main.html来启动此代码。

它是如何实现的...

执行以下步骤:

  1. 使用以下代码创建 main.html,其中包含三个可折叠块和一个 <div> 容器,如下面的代码片段所示:

    <div data-role="content">
     <div id="msgdiv">Collapsible Blocks</div>
      <div data-role="collapsible" data-theme="a" data-
        collapsed="false">
        <h3>Tallest Mountain</h3>
        Mt. Everest
      </div>
      <div data-role="collapsible" data-theme="a" data-
        collapsed="false">
        <h3>Longest River</h3>
        R. Nile
      </div>
      <div data-role="collapsible" data-theme="a" data-
        collapsed="false">
        <h3>Largest Ocean</h3>
        Pacific
      </div>
    </div>
    
  2. <head> 部分添加以下脚本,来处理 updatelayout 事件:

    $("#main").live("pageshow", function(event, ui) {
     $("div").bind("updatelayout", function(event) {
        $("#msgdiv").html("updatelayout on : " + event.target.innerHTML);
      });
    });
    

它是如何工作的...

main.html 中,向页面内容添加一个 id="msgdiv"div 容器。添加三个带有 data-collapsed="false" 属性的可折叠块。添加下面给出的脚本来绑定 pageshow 事件(在页面显示时触发),指向一个事件处理程序。在这里,把 updatelayout 事件绑定到一个回调函数。在这个回调函数中,使用 event.target.innerHTML 属性来获取触发 updatelayout 事件的可折叠块的文本。如所示,显示在 msgdiv 块中。现在,当加载页面时,这三个可折叠块都是展开的。

点击第一个块,显示 最高的山。你会看到它折叠,并且 msgdiv 文本被更新为显示 更新布局在:珠穆朗玛峰,如下面的截图所示:

它是如何工作的...

还有更多内容...

jQuery Mobile 框架在你在页面中添加或操作组件或切换它们的可见性的情况下,会根据大多数场景动态更新布局并调整位置。你必须在这些元素上触发 createrefresh 方法。但是在一些情况下,当你添加或操作控件或切换它们的可见性时,框架可能无法正确处理定位。在这种情况下,你可以触发 updatelayout 事件,并告诉框架更新所有组件并重新定位它们。你可以通过以下代码来实现:

(yourselector).trigger("updatelayout");