首页 前端知识 jQuery Mobile 高级教程(二)

jQuery Mobile 高级教程(二)

2024-08-21 22:08:07 前端知识 前端哥 725 775 我要收藏

原文:Pro jQuery Mobile

协议:CC BY-NC-SA 4.0

五、列表视图

列表是一种流行的用户界面组件,因为它们使浏览体验变得非常简单和高效。列表也是一个非常灵活的组件,可以以多种方式进行样式化,并且可以很好地适应不同的屏幕尺寸。无论我们是在浏览邮件、联系人、音乐还是设置,这些应用都以略微不同的风格显示信息列表。从只包含文本的基本列表到包含图形和详细元数据的复杂列表,列表必须足够灵活以支持多种配置。幸运的是,jQuery Mobile 支持所有这些列表配置,甚至更多。在本章中,我们将探索在 jQuery Mobile 中设计和配置列表的细节。我们还将了解如何在列表中添加搜索过滤器。最后,我们将回顾列表视图插件 API,看看我们如何动态创建和更新列表的例子。

列出基础知识

当我们将data-role=”list”属性添加到列表元素中时,jQuery Mobile 会自动将任何本地 HTML 列表(<ul><ol>)增强到移动优化视图中。默认情况下,增强列表将显示边对边,如果我们的列表项包含链接,它们将显示为带有右对齐箭头图标的触摸友好按钮(参见图 5–1 和在清单 5–1 中产生它的代码片段)。默认情况下,列表将使用“c”色样(灰色)来设置样式。要应用替换主题,请将data-theme属性添加到列表元素或列表项中(<li>)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5–1。 基本列表

清单 5–1。 基本列表(ch5/list-basic.html)

`<ul data-role=“listview” data-theme=“c”>
        

  • Action

  •         
  • Adventure

  •         
  • Comedy
  • `

    插图列表

    插入列表不会边对边显示。相反,插入列表会自动包裹在圆角块中,并设置边距以增加间距。要创建一个插入列表,将data-inset="true"属性添加到列表元素中(参见图 5–2 和 5–3,以及清单 5–2 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–2。 插入列表(iOS)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–3。 插入列表(Windows Phone 7)

    清单 5–2。 插入列表(ch5/list-inset.html)

    `


    •     
    • Contact Options

    •     
    • Call

    •     

    `

    列出分隔符

    列表分隔线可以用作一组列表项的标题。例如,如果我们的应用有日历列表,我们可以选择按天对日历事件进行分组(参见 Figure 5–4)。列表分隔线也可以用作插入列表的标题。在前面的例子中,我们也用列表分隔线设置了插入列表的标题(参见图 5–2 和清单 5–2)。

    要创建列表分隔线,请向任何列表项添加data-role="list-divider"属性。列表分隔线的默认文本将左对齐。

    **提示:**在图 5–4 中,列表项同时包含左对齐和右对齐的文本。要右对齐文本,用包含 ui-li-aside 类的元素将它包装起来(参见清单 5–3)。

    默认情况下,列表分隔线将使用"b"样本(浅蓝色)的颜色。要应用另一个主题,请向 list 元素添加data-divider-theme="a"属性。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–4。 列表分隔符

    清单 5–3。 列表分隔符(ch5/list-dividers.html)

    `


    •   <li data-role=“list-divider” data-divider-theme=“a”>
           Mon <p class=“ui-li-aside”>Feb 6 2012


      
      

  •      6 PM Birthday Party
      
  • `

    带有缩略图和图标的列表

    我们可以在列表项的左侧添加缩略图,方法是在列表项中添加一个图像作为第一个子元素(参见图 5–5 和清单 5–4 中的相关代码)。该框架将图像缩放到 80 像素见方。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–5。 带缩略图的列表

    清单 5–4。 带缩略图列表(ch5/list-thumbnails.html)

    `


    •     

    •           
                      
                      

      Kung Fu Panda


                      

      Rated: PG


                      

      Runtime: 95 min.


                
          

    •     …

    `

    我们也可以使用更小的图标来代替缩略图。要在列表项中使用标准的 16x16 像素图标,请将类别ui-li-icon添加到图像元素中(参见图 5–6 和清单 5–5 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–6。 带图标的列表

    清单 5–5。 带图标列表(ch5/list-icons.html)

    `


    •         
    • User Reviews

    •         

    •             
                      <img src=“img/111-user.png” class=“ui-li-icon”>
                      

      Go See It!


                      

      This movie had a strong script and …


                  
              

    •         …

    `

    拆分按钮列表

    在您需要支持每个列表项的多个操作的情况下,我们可以创建一个拆分按钮列表,其中有一个主要和次要按钮可供选择。例如,我们可以修改原来的电影列表示例来支持多个动作。我们的主按钮将继续显示电影细节,我们新的辅助按钮可用于购买门票(参见图 5–7)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–7。 带拆分按钮的列表

    要创建一个拆分按钮,在列表项中添加一个二级链接,框架会添加一条垂直线来划分主要和二级动作(见清单 5–6)。

    清单 5–6。 带拆分按钮的列表(ch5/List-split-buttons . html)

    `<ul data-role=“listview” data-split-icon=“star” data-split-theme=“d”>
        


  •         
                
                

    Kung Fu Panda


                

    Rated: PG


                

    Runtime: 95 min.


            
            Buy Tickets
        

  •     …

    `

    要设置所有次级按钮的图标,请将data-split-icon属性添加到列表元素,并将其值设置为标准图标(参见 Table 4–1)或自定义图标。默认情况下,辅助按钮将使用“b”样本(浅蓝色)的颜色。要应用替代主题,请向 list 元素添加 data-split-theme 属性。

    编号列表

    使用有序列表<ol>时将创建编号列表(参见图 5–8 和清单 5–7 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–8。 列表与数字

    清单 5–7。 带编号的列表(ch5/list-numbered.html)

    `


    1.         
    2. The Amazing Spider-Man

    3.         
    4. The Dark Knight Rises

    5.         …

    `

    默认情况下,框架会在每个列表项的左边添加数字索引。当显示可以按顺序排列的项目列表时,这些列表非常有用。例如,我们的“收视率最高的”电影视图是一个编号列表的理想候选,因为该序列可以快速关联哪些电影是收视率最高的。

    只读列表

    列表视图也可以显示数据的只读视图。用户界面看起来非常类似于我们之前展示的交互视图,除了右箭头图标-唯一的图像已经被移除,字体大小和填充稍微变小。要创建一个只读列表,只需删除我们在前面的例子中使用的锚标签(参见图 5–9 和清单 5–8 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–9。 带有只读项目的列表

    清单 5–8。 带只读项的列表(ch5/list-readonly.html)

    `


    •         

    •                 
                      

      Kung Fu Panda


                      

      Rated: PG


                      

      Runtime: 95 min.


              

    •         …

    `

    列出徽章(数气泡)

    列表标记或计数气泡是突出显示的椭圆形,通常表示可供查看的新项目的数量。例如,徽章通常用在邮件应用中,用来指示您有多少未读邮件。在我们的示例中,徽章用于指示何时添加了关于电影评论的评论(参见 Figure 5–10)。徽章可以用来表达任何类型的元数据。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–10。 用徽章或数数气泡列表

    要创建一个徽章,用包含类ui-li-count的元素包装徽章的文本。默认情况下,徽章将使用“c”色样(灰色)进行设计。要应用一个替换主题,将data-count-theme属性添加到列表元素中(参见清单 5–9)。

    清单 5–9。 带徽章或计数气泡的列表(ch5/list-badges.html)

    <ul data-role="listview" data-inset="true" **data-count-theme="e"**>         <li data-role="list-divider">Comments</p></li>         <li>           <img src="img/111-user.png" class="ui-li-icon">
    `          

    Thanks for the review.  I’ll check it out this weekend.


              <span class=“ui-li-count”>1 day ago
             `

    用搜索栏过滤列表

    jQuery Mobile 有一个非常方便的过滤列表的客户端搜索特性。要创建搜索栏,将data-filter=”true”属性添加到列表中。然后,框架将在列表上方追加一个搜索过滤器,默认的占位符文本将显示单词“Filter items …”(参见图 5–11 和清单 5–10 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–11。 列表过滤(未过滤)

    清单 5–10。 列表过滤(ch5/list-filter.html)

    `<ul data-role=“listview” data-filter=“true” data-filter-                 placeholder=“Search…”>
        


  •         Mon

    Feb 6 2012


        

  •     

  •         
                

    6 PM Birthday Party


            
        
  • `

    有两个选项可用于配置占位符文本:

    1. 您可以通过在列表元素上添加data-filter-placeholder属性来配置占位符文本(参见清单 5–10)。
    2. 或者,您可以通过绑定到mobileinit事件并将filterPlaceholder选项设置为任意自定义占位符值:        $(document).bind('mobileinit',function(){          $.mobile.listview.prototype.options.filterPlaceholder="Search..";         });,将占位符文本全局设置为 jQuery Mobile 配置选项

    我们将在第八章“配置 jQuery Mobile”中更详细地讨论配置 jQuery Mobile。

    当您开始在搜索过滤器中输入文本时,客户端过滤器将只显示与通配符搜索匹配的项目(参见 Figure 5–12)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 5–12。 【列表过滤(已过滤)】

    如果您需要更改默认搜索功能,有两个选项可以覆盖用于过滤的回调:

    首先,您可以通过绑定到mobileinit事件并将filterCallback选项设置为任何自定义搜索功能,将搜索功能作为 jQuery Mobile 配置选项进行全局更新。例如,这里我们将回调设置为使用“开始于”搜索:

    $(document).bind('mobileinit',function(){     $.mobile.listview.prototype.options.filterCallback =       function( text, searchValue ){           // Use a "starts with" search           return !(text.toLowerCase().indexOf( searchValue ) === 0);       }; });

    回调函数有两个参数,textsearchValuetext参数包含列表项的文本,searchValue参数包含搜索过滤器的值。通配符搜索的默认行为编码为:

            return text.toLowerCase().indexOf( searchValue ) === -1;

    如果回调返回列表项的真值,它将从搜索结果中隐藏。

    或者,我们也可以在列表创建后动态配置我们的搜索功能。例如,在我们的页面加载之后,我们可以为特定的列表应用新的搜索行为:

    $("#calendar-list").listview('option', 'filterCallback',         function( text, searchValue ) {             // Use a "starts with" search             return !(text.toLowerCase().indexOf( searchValue ) === 0);         } );

    默认情况下,搜索框将从其父容器继承其主题。要配置一个替代主题,请将data-filter-theme属性添加到列表元素中。

    动态列表

    listview插件是自动增强列表的小部件。我们可以利用这个插件来动态地创建和更新我们的列表。有两个选项可用于创建动态列表。您可以使用标记驱动的方法动态创建列表,或者通过在listview插件上显式设置options(参见清单 5–11)。

    清单 5–11。 listview 插件示例(ch5/dynmic-lists.html)

    `// Create list with markup-driven options
    $( ‘


    •         
    • Genres

    •         
    • Action

    •         
    • Comedy
    ’ )
       .insertAfter( “#list0” )
       .listview();

    // Create list with plugin-driven options
    $( ‘

    • Genres

    •         
    • Action

    •         
    • Comedy
    ’ )
       .insertAfter( “#list1” )
       .listview({
            theme: “d”,
            dividerTheme: “a”,
            inset: true,
       });

    // Add a new item to an existing list
    $( “#list1” )
            .append(‘

  • Drama
  • ’)
            .listview(“refresh”);`

    列表选项

    listview插件有以下选项:

    **countTheme** *string*

    默认:“c”

    为徽章或计数气泡设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-count-theme=”a”.

    $( “#list1” ).listview({ countTheme: "a" });

    **dividerTheme** *string*

    **default:** "b"

    为列表分隔线设置主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-divider-theme=”a”.

    $( “#list1” ).listview({ dividerTheme: "a" });

    **initSelector** CSS selector string

    **default:** ":jqmData(role='listview')"

    initSelector 用于定义选择器(元素类型、数据角色等。)用于触发小部件插件的自动初始化。例如,默认选择器匹配的所有元素都将被listview插件增强。要覆盖这个选择器,绑定到mobileinit事件并根据需要更新选择器:

    $( document ).bind( "mobileinit", function(){

    $.mobile.listview.prototype.options.initSelector = "...";

    });

    **inset** *boolean*

    **default:** false

    当此选项设置为 true 时,将创建一个插入列表。默认情况下,将创建一个基本列表。该选项也作为数据属性公开:data-inset=”true”.

    $( “#list1” ).listview({ inset: true });

    **splitIcon** *string*

    **default:** "arrow-r"

    建立拆分按钮列表时设置次级按钮的图标。该选项也作为数据属性公开:data-split-icon=”star”.

    $( “#list1” ).listview({ splitIcon: "star" });

    **splitTheme** *string*

    **default:** "b"

    创建拆分按钮列表时,设置辅助按钮的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-split-theme=”a”.

    $( “#list1” ).listview({ splitTheme: "a" });

    **theme** *string*

    **default:** "c"

    设置列表的主题样本配色方案。这是一个从 a 到 z 的字母,映射到你的主题中包含的样本。该选项也作为数据属性公开:data-theme=”a”.

    $( “#list1” ).listview({ theme: "a" });

    列举方法

    listview插件有以下方法:

    refresh : 更新自定义列表。

    这将更新自定义列表以反映本地列表元素的值。例如,如果我们向现有列表中添加一个新项目,我们必须调用“refresh”来重建列表项目:

    `        // Add an item to an existing list and refresh the list item
            $( “#list1” )
                    .append(‘

  • Drama
  • ’)
                    **.listview(“refresh”);    **

    // Add list items to a new list and refresh the entire list
            var markup = ‘

  • item 1
  • item 2
  • ’;
           $( “#list2” )
                 .append(markup)
    **             .listview( “refresh”, true );**`

    列出事件

    listview插件支持以下事件:

    create: 创建列表时触发

    创建自定义列表时会触发此事件。它不用于创建自定义列表。

            $( '<ul><li data-role="list-divider">Genres</li>             <li><a href="#">Comedy</a></li></ul>' )            .insertAfter( "#list1" )            .listview({                  inset: true,                  create: function(event) {                          console.log( "Creating list..." );                  }             });

    总结

    在本章中,我们回顾了非常流行的列表视图组件。列表视图是常用的,因为它们使浏览体验非常简单和高效。jQuery Mobile 列表可以用许多独特的方式进行样式化和配置。从基本列表到带有图像、分割按钮、分隔线或徽章的列表,我们有许多配置选项可供选择。

    我们还看到了向列表中添加搜索过滤器是多么容易,并看到了如何在必要时覆盖默认搜索的例子。

    最后,我们回顾了listview插件 API,并看到了如何动态创建和更新列表的例子,以便为我们的用户提供更具交互性的体验。

    在下一章中,我们将探索另一个流行的用户界面组件,jQuery Mobile 灵活的网格布局。我们将看到如何使用网格来创建响应式设计,我们也将看看如何用 CSS 渐变来增强我们的用户界面。

    六、使用网格和 CSS 渐变格式化内容

    移动应用通常将网格用于需要灵活的内容,并将其分组。对于需要这种行为的设计,jQuery Mobile 的响应式网格是一个有用的解决方案。在本章中,我们将回顾 jQuery Mobile grid 组件的基础知识,并展示几个如何在网格中设计图标、图形和文本样式的例子。我们还将创建可折叠的内容块,并讨论它们与内联页面结构相比的优势。最后,我们将使用 CSS 渐变对我们的设计进行一些修饰,并讨论 CSS 渐变在性能和渐进增强方面的优势。

    网格布局

    jQuery Mobile 的网格可配置为支持两到五列的布局。从 HTML 的角度来看,网格是用 CSS 属性配置的div元素。网格是灵活的,会占用显示器的整个宽度。网格不包含边框、填充或边距,因此它们不会干扰其中包含的元素的样式。在我们看一个例子之前,让我们回顾一下标准的网格模板。

    网格模板

    当创建多列网格时,网格模板可能是一个有用的参考(参见清单 6–1)。

    清单 6–1。 网格模板

    `

    **
      

    `

    `    
        

    Block A
         Block B

    `

    创建网格时,您需要创建具有两个或更多内部块的外部网格容器:

    1. Grid container: The grid container requires the CSS attribute ui-grid-* to configure the number of columns in the grid (see Table 6–1). For instance, to create a two-column grid we would set our grid CSS attribute to ui-grid-a.

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    2. Blocks: The blocks are contained within the grid. The blocks require the CSS attribute ui-block-* to identify its column position (see Table 6–2). For instance, if we had a two-column grid, our first block would be styled with CSS attribute ui-block-a and the second block would be styled with CSS attribute ui-block-b.

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    两列网格

    两列(50%,50%)网格显示在图 6–1 中,其相关代码显示在清单 6–2 中。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–1。 两列网格

    清单 6–2。 【两列网格】ch6/grid-2col.html

    `


      <div class=“ui-grid-a”>
        <div class=“ui-block-a”>Block A
        <div class=“ui-block-b”>Block B
      

    `

    外部网格配置了 CSS 网格属性ui-grid-a。接下来,我们添加两个内部块。第一块被分配了一个 CSS 值ui-block-a,第二列被分配了一个 CSS 值ui-block-b。如图 Figure 6–1 所示,各列等距,无边界,每个块中的文本将在必要时换行。作为一个额外的好处,jQuery Mobile 中的网格是灵活的,可以在不同的显示尺寸上进行相应的渲染(参见图 6–2)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–2。 两列网格(风景)

    带有 CSS 增强功能的三列网格

    三列(33%,33%,33%)网格显示在图 6–3 中,其相关代码显示在清单 6–3 中。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–3。 带有 CSS 增强功能的三列网格

    清单 6–3。 【三列网格】ch6/grid-3col.html

    `


        <div class=“ui-grid-b”>
           <div class=“ui-block-a”>
              <div class=“ui-bar ui-bar-e” style=“height:100px”>Block A
           
           <div class=“ui-block-b”>
              <div class=“ui-bar ui-bar-e” style=“height:100px”>Block B
           
           <div class=“ui-block-c”>
              <div class=“ui-bar ui-bar-e” style=“height:100px”>Block C
           
        

    `

    除了网格的 CSS 属性被配置为支持三列(ui-grid-b)以及我们为第三列(ui-block-c)添加了一个额外的块之外,它与我们之前看到的两列示例非常相似。我们还用可主题化的类来设计块的样式,这些类可以添加到任何元素中,包括网格。在这个例子中,我们添加了ui-bar来应用 css 填充,添加了ui-bar-e来应用“e工具栏主题样本的背景渐变和字体样式。您可以使用ae范围内的任何工具栏主题(ui-bar-*)来设计您的模块。最后,为了创建一致的块高度,我们还设计了内嵌高度(style="height:100px")。从视觉上看,这些改进用线性背景渐变设计了我们的网格,我们的块现在用边界分隔开了。

    带应用图标的四列网格

    四列(25%、25%、25%、25%)网格显示在图 6–4 中,其相关代码显示在清单 6–4 中。

    清单 6–4。 【四柱格】ch6/grid-4col.html

    `


      <div class=" ui-grid-c" style=“text-align: center;”>
        <div class= “ui-block-a”> <img src=“img/cloud-default.png”>
        <div class= “ui-block-b”>
        <div class=" ui-block-c">
        <div class= “ui-block-d”>
      

    `

    除了网格的 CSS 属性被配置为支持四列(ui-grid-c,并且我们为第四列(ui-block-d添加了一个额外的块之外,它与三列示例类似。此外,为了平衡和一致性,我们将应用图标置于网格中央(style="text-align:center;)。视觉上,网格有均匀分布的应用图标,很像一个应用跳板。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–4。 带应用图标的四列网格

    带有表情图标的五列网格

    五列(20%,20%,20%,20%,20%)网格显示在图 6–5 中,其相关代码显示在清单 6–5 中。

    清单 6–5。 【五列网格】ch6/grid-5col.html

    `


      <div class=" ui-grid-d" style=“text-align: center;”>
         
         
         
         
         
      

    `

    这个例子非常类似于我们之前看到的四列网格,除了网格的 CSS 属性被配置为支持五列(ui-grid-d)并且我们已经用为第五列(ui-block-e)添加了一个额外的块。每个区块包含一个独特的表情图标。 1

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–5。 五列网格

    **注意:**表情图标是图像的一个很好的替代品,因为它们消耗零 HTTP 请求,并且它们的有效载荷只是几个字符的文本。不幸的是,表情符号图标目前仅在 iOS 中受支持。


    1[pukupi.com/post/1964](http://pukupi.com/post/1964).

    多行网格

    到目前为止,我们只看到了单行网格。要添加额外的行,只需为每个连续的行重复第一行的块模式(参见清单 6–6 中的图 6–6 及其相关代码)。生成的网格包含五列和三行。列的间距相等,可以在块组件上手动调整行高。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–6。 多行网格

    清单 6–6。 【多行网格】ch6/grid-multi-row.html

    `


      


        


         
         
         
          `

    `    
        


         
         
         
         

    `
    不均匀网格

    到目前为止,所示的每个网格示例都有均匀间隔的列,因为默认情况下 jQuery Mobile 会均匀间隔所有的列。但是,如果您需要定制列宽,我们可以在 CSS 中调整宽度。例如,我们可以通过设置每个块的自定义宽度,将两列网格的默认宽度修改为 25/75%(参见图 6–7 及其在清单 6–7 中的相关代码)。因此,我们的网格可以修改,以支持广泛的替代维度。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–7。 不均匀网格

    清单 6–7。 【网格不均匀】ch6/grid-uneven.html

    `

    /* Set 3-column grid to 25/50/25% */
            .ui-grid-b .ui-block-a {
                width: 25%;
            }
            .ui-grid-b .ui-block-b {
                width: 50%;
            }
            .ui-grid-b .ui-block-c {
                width: 25%;
            }                                                                        
    `

    跳板

    跳板是应用网格布局的理想选择。在下面的例子中,我们将看到两种类型的跳板。首先,我们会看到一个带有应用图标的跳板(见图 6–8),其次我们会看到一个带有雕刻图标的跳板(见图 6–9)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–8。 带 app 图标的跳板

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–9。 带有浮雕图标的跳板

    你准备好接受跳板挑战了吗?如果你是,我鼓励你创造一个和这两个人物非常相似的跳板。从网格的角度来看,这两个例子的配置是相同的。然而,带有 Glyphish 图标的跳板(见清单 6–9)的风格与带有应用图标的跳板(见清单 6–8)略有不同,以调整其不均匀的图标高度。

    清单 6–8。 带 app 图标的跳板(ch6/springboard1.html )

    `


      
        
          
          App A
        
      
      …

    `

    清单 6–9。 带有雕刻图标的跳板(ch6/springboard2.html )

    `


      
        
          
            Now Playing
            Now Playing
          
        
      
      …

    `

    可折叠的内容块

    你有没有发现自己反复滚动来浏览整个手机页面的内容?虽然这对于你的手指来说可能是一个很好的锻炼,但当用户必须重复滚动时,这可能是一个麻烦的用户体验。如果您正在寻找一个更有用的替代方案,您可能需要考虑将您的内容分组到可折叠的内容块中。

    **提示:**与内嵌页面结构相比,可折叠内容块有几个优点。首先,我们可以将内容折叠成分段的组,使它们在单个视图中可见(参见图 6–10)。其次,我们的用户会更有效率,因为我们已经从用户体验中消除了滚动。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–10。 内容块(所有块折叠)

    创建可折叠内容块所需的标记如清单 6–10 所示。

    清单 6–10。*ch6/collapsible-block.html*可折叠内容块

    `

    <div data-role=“collapsible” data-collapsed=“true” data-theme=“a” data-content-theme=“b”>
        

    Wireless


        

    •       
    •  Notifications

    •       
    •  Location Services

    •     
      

    <div data-role=“collapsible”> data-theme=“a” data-content-theme=“b”>
        

    Applications


        

    •       
    •  Faceoff

    •       
    •  LinkedOut

    •       
    •  Netflicks

    •     

      

    `

    创建可折叠块需要两个元素:

    1. Create a container and add the data-role="collapsible" attribute. Optionally, you may configure the container to be collapsed or expanded by adding the data-collapsed attribute. By default, a collapsible section will be shown expanded (data-collapsed="false"). To initially show the section as a collapsed block, add data-collapsed="true" to the container. For instance, if we launch the code in Listing 6–10, the initial view will appear as Figure 6–11. In the code listing, we have explicitly collapsed all content blocks except for the “Applications” section which will expand by default. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 6–11。 内容块(一个块展开)

    2. 在容器中,添加任何 header 元素(H1-H6).框架会将 header 设计成看起来像一个可点击的按钮,带有一个左对齐的加号或减号图标,表示它是可扩展的。

    在标题之后,您可以向可折叠块添加任何 HTML 标记。框架将把这个标记包装在容器中,当点击标题时,容器将展开或折叠。你可以通过在可折叠容器中添加data-themedata-content-theme属性来分别设置可折叠块及其相关按钮的主题(参见清单 6–10)。

    **注意:**一个可折叠块允许你一次展开或折叠多个块(见图 6–12)。在下一节中,我们将看到在处理可折叠集合时这是不允许的。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–12。 内容块(所有块展开)

    可折叠套

    可折叠组件(参见图 6–13)与可折叠积木相似,只是它们的可折叠部分在视觉上组合在一起,并且一次只能展开一个部分,这使得可折叠组件看起来像手风琴(参见图 6–14)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–13。 内容设置(折叠)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–14。 内容设置(扩展)

    当打开集合中的新节时,以前打开的任何节都将自动折叠。

    可折叠集合的标记与我们之前在构建可折叠块时看到的标记相同。然而,为了创建手风琴式的行为和分组,我们需要添加一个带有data-role="collapsible-set"的父包装器,如清单 6–11 所示。

    清单 6–11。 可折叠设置(ch6/collapsible-set.html)

    `

    <div data-role=“collapsible-set”> data-theme=“a” data-content-theme=“b”>
        


          

    Wireless


          

    •         
    •  Notifications

    •         
    •  Location Services

    •       

        


          

    Applications


          

    •         
    •  Faceoff

    •         
    •  LinkedOut

    •         
    •  Netflicks

    •       

        
        …
      

    `

    使用 CSS 渐变的样式

    想给你的移动用户界面添加一点润色吗?尝试在通常使用背景图像的地方使用 CSS 渐变。CSS 渐变为图像提供了一个高性能的替代品,它们在灵活的布局中工作得非常好,并且在不受支持的浏览器中优雅地退化。例如,我们可以将一个原始的跳板(见图 6–15)改造成一个更加优雅的展示(见图 6–16 和图 6–17)并添加渐变。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–15。 没有 CSS 渐变的跳板

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–16。 带有 CSS 渐变的跳板(iOS)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–17。 带有 CSS 渐变的跳板(安卓)

    任何使用背景图像的地方都可以使用渐变。例如,它们最常用于设计标题、内容和按钮的背景。此外,有两种类型的 CSS 渐变:线性和径向。线性渐变是两者中比较简单的,如果你不太熟悉它们的语法,CSS 渐变生成器 2 可以帮助你开始。产生背景线性渐变的 CSS 如清单 6–12 所示。

    清单 6–12。 背景渐变

    **.background-gradient** {   background-image: -webkit-gradient(     linear, left bottom, left top,     color-stop(0.22, rgb(92,92,92)),     color-stop(0.57, rgb(158,153,158)),
    `    color-stop(0.84, rgb(92,92,92))
      );
    }

    `

    2[www.westciv.com/tools/gradients/](http://www.westciv.com/tools/gradients/)[gradients.glrzad.com/](http://gradients.glrzad.com/).

    虽然这个 CSS 渐变是针对最流行的 WebKit 布局引擎(参见图 6–18)的,但是您可以通过包含特定于供应商的前缀来添加对其他浏览器的支持。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 6–18。 Webkit 用法

    例如,为了在 Mozilla 浏览器上渲染我们的渐变,我们将添加带有-moz-厂商前缀的版本(参见清单 6–13)。

    清单 6–13。 支持 Mozilla 的背景渐变

    .background-gradient {   background-image: **-webkit-gradient**(     linear, left bottom, left top,     color-stop(0.22, rgb(92,92,92)),     color-stop(0.57, rgb(158,153,158)),     color-stop(0.84, rgb(92,92,92))   );   background-image: **-moz-linear-gradient**(     90deg,     rgb(92,92,92),     rgb(158,153,158),     rgb(92,92,92)); }

    页眉的渐变实际上是三个独立渐变的叠加。包括一个线性梯度和两个径向梯度。径向渐变创建圆形渐变效果。创建标题渐变的代码如清单 6–14 所示。

    清单 6–14。 跳板坡度

    `.header-gradient {
      background-image:
        -webkit-gradient(
          linear, left top, left bottom,
          from( rgba( 068,213,254,0 )),
          color-stop(.43, rgba( 068,213,254,0 )),
          to( rgba( 068,213,254,1 ))),
        -webkit-gradient( radial,
          50% 700, 690,
          50% 700, 689,
          from( rgba( 049,123,220,0 )),
          to( rgba( 049,123,220,1 ))),
        -webkit-gradient(
          radial,
          20 -43, 60,
          20 -43, 40,
          from( rgba( 125,170,231,1 )),
          to( rgba( 230,238,250,1 )));
    }

    `

    总结

    在这一章中,我们回顾了 jQuery Mobile 基于网格的设计的有用性,并看到了我们如何快速地在网格模板中设计内容(参见清单 6–1)。jQuery Mobile grid 是需要响应和分组的内容的理想解决方案。我们的网格可以包含任何内容,我们看到了几个使用文本、图标和图形的网格示例。

    我们还回顾了可折叠的内容块,并讨论了它们与内联页面结构相比的优势。可折叠块可以是一种有效的可用性模式,因为它们有助于在单一视图中显示所有内容,并且有助于消除用户体验中的滚动。因此,用户对应用的体验将更加高效。

    最后,我们看到了如何用 CSS 渐变来润色我们的设计。CSS 渐变是图像的一种高性能替代品,它们在灵活的布局中工作得非常好,在不受支持的浏览器中会逐渐退化。

    在第七章中,我们将继续我们的布局设计之路,仔细看看 jQuery Mobile 的主题框架。

    七、创造主题化的设计

    jQuery Mobile 有一个内置的主题框架,允许设计人员快速定制或重新设计他们的用户界面。主题框架利用了 CSS3 的许多特性,这有助于构建更优雅、更具响应性的设计。例如,通过利用 CSS3,主题框架能够应用圆角、阴影和渐变,而不必依赖于图像。这是一个性能优势,因为该框架可以提供更有吸引力的接口,而没有额外的 HTTP 请求开销。本质上,我们有一个轻量级的主题框架,可以在所有浏览器上呈现统一的设计。

    在这一章中,我们将讨论主题框架的基础,并回顾 jQuery Mobile 中包含的默认主题。我们还将探索将主题分配给组件的三种方式。虽然所有的组件都可以使用data-theme属性显式地设置它们的主题,但是大多数组件也有默认的主题,并且也可以从父容器继承它们的主题。我们将讨论它们的优点,看看每一个的例子,并讨论主题应用于组件的优先级。

    最后,我们将看看如何创建我们自己的自定义主题。如果您需要创建更丰富的设计,或者如果您需要创建与您的公司品牌紧密匹配的设计,那么创建自定义主题将是必要的。创建自定义主题有两个选项,我们将一步步地看每一个的例子。第一种选择是手动方法,它让设计者完全控制他们的布局;第二种是使用主题滚轮 1 ,这是一种基于网络的工具,可以自动完成创建新主题的过程。


    1[jquerymobile.com/themeroller](http://jquerymobile.com/themeroller)

    主题基础知识

    在很多例子中,我们已经看到了如何使用data-theme属性将替换主题应用到页面容器(页面、页眉、内容、页脚)和表单元素中。例如,我们可以使用一个没有主题的页面(见图 7–1)并用一个不同的标题和列表主题(见图 7–2)重新设计它的样式,并简单地添加data-theme属性(见清单 7–1)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–1。 带有默认主题的列表

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–2。 列表与备选主题

    清单 7–1。 数据-主题属性(ch7/theme-list2.html)

    `


            <div data-role=“header” data-theme=“b”>
                    

    jMovies


            


                    <ul data-role=“listview” data-inset=“true” data-theme=“a”>
                            
    • Now Playing

    •                 
              

    `

    主题和样本

    jQuery Mobile CSS 文件总是我们在 head 元素中导入的第一个资产(参见清单 7–2)。该文件包含 jQuery Mobile 应用的默认结构和主题。花一点时间,用您最喜欢的编辑器探索这个文件的内容。

    清单 7–2。 jQuery Mobile CSS 导入

    `
    **   **
       

    `

    jQuery Mobile CSS 文档分为两个部分:主题部分和结构部分。

    • Theme – The top half of the document contains the default theme settings.  The theme settings manage the visual styling (backgrounds, borders, color, font, shadows) for all components.  When setting the data-theme attribute, we are able to choose from five different options (a, b, c, d, e).  These letters (a-e) are technically referred to as swatches.  As you were reviewing the jQuery Mobile CSS file you may have noticed that the first swatch to appear within the CSS file was swatch “a” (see Listing 7–3).

      清单 7–3。 jQuery Mobile CSS 样本“a”(部分列表)

      /* **A** ---------------------------------------------------------------------*/ .ui-bar-**a** {         border: 1px solid                 #2A2A2A;         background:                         #111111;         color:                                      #ffffff;         font-weight: bold;         text-shadow: 0 -1px 1px #000000;         ...         background-image:             linear-gradient(top, #3c3c3c, #111); } .ui-body-**a** {         border: 1px solid                   #2A2A2A;         background:                         #222222;         color:                       #fff;         text-shadow: 0 1px 0         #000;         font-weight: normal;         background-image**:**              linear-gradient(top, #666**,** #222**);** } ...

    主题部分分为以下几个小节:

    • 样本——默认情况下,jQuery Mobile 有五个样本可供选择(a、b、c、d、e ),您可以根据需要添加任意数量的独特样本。样本允许我们为组件配置独特的背景、边框、颜色、字体和阴影。为简单起见,新样本的命名约定是基于字母的(a-z)。但是,样本名称的长度没有限制。我们将在本章的后面看到创建我们自己的自定义色板的例子。

    • Global theme settings – Global theme settings are configured after the swatches. These settings add visual styling enhancements to buttons, such as rounded corners, icons, overlays, and shadows. Since these settings are global, they will be inherited by all swatch configurations (see Listing 7–4).

      清单 7–4。【jQuery 手机全球主题造型(部分上市)

      /* Active class used as the "on" state across all themes -----------------------------------------------------------------------*/ .ui-btn-active {         border: 1px solid                 #155678;         background:                       #4596ce;         font-weight: bold;         color:                  #fff;         cursor: pointer;         text-shadow: 0 -1px 1px #145072;         text-decoration: none;         ... }

    • Structure – The latter half of the jQuery Mobile CSS file contains structure styling that primarily includes positioning, padding, margin, height, and width settings (see Listing 7–5).

      清单 7–5。 jQuery Mobile 结构造型(部分清单)

      `/* some unsets - more probably needed /
      .ui-mobile
      *,** .ui-mobile body { height**😗* 100%; }
      .ui-mobile fieldset**,** .ui-page { padding**😗* 0**;** margin**😗* 0**;** }
      .ui-mobile a img**,** .ui-mobile fieldset { border**😗* 0**;** }

      .ui-checkbox, .ui-radio {
              position:relative;  margin: .2em 0 .5em; z-index: 1;  
      }
      .ui-checkbox .ui-btn, .ui-radio .ui-btn {
              margin: 0; text-align: left; z-index: 2;
      }`

      现在我们已经了解了 jQuery Mobile 的主 CSS 文件,让我们更仔细地看看 jQuery Mobile 包含的五个样本,看看它们是如何出现在几个不同的组件中的(参见 Figure 7–3–7–6)。

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–3。 格子色板

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–4。 列出色板

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–5。 纽扣布样

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–6。 表单字段样本

      为了在所有组件中保持样例的样式一致,以下视觉优先级约定用于每个样例:

    • “a”(黑色)视觉优先级最高。

    • “b”(蓝色)是二级水平。

    • " c" -(灰色)基线。

    • “d”-(白/灰)一个交替的二级水平。

    • “e”-(黄色)强调色。

    主题默认值

    如果您没有向页面添加data-theme属性,jQuery Mobile 将为所有页面容器和表单元素应用默认主题(参见 Table 7–1)。

    例如,如果我们创建一个基本的 jQuery Mobile 页面,而没有显式地设置它的主题,那么我们的元素将回到它们的默认主题或者继承它们的父容器的主题。在 Figure 7–7 中,默认主题应用于页面、页眉、页脚、内容和列表元素,而表单元素继承了它们的主题。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–7。 带有默认和继承主题的页面

    通过参考我们的“组件默认主题”表(参见表 7–1,我们可以确定每个组件将应用什么默认主题。让我们仔细看看内容和按钮组件。默认情况下,内容组件将应用data-theme=”c”。但是,按钮组件没有默认主题,因此它将从其父容器继承默认主题。在清单 7–6 中,按钮的父节点是内容容器;因此,按钮将继承主题“c”。此外,如果按钮在头部容器中,它将继承头部容器的主题。

    清单 7–6。 带有默认主题的页面(ch7/theme-defaults.html)

    `


        
            

    default = “a”


        


          default = “c”       

    •           
    • default = “b”

    •           
    • default = “c”

    •           
    • default = “c”

    •       


              

            
                  
                  
              


              


                  
                  
                      Off
                      On
                  
              

    Button (inherits “c”)
          
        


            

    default = “a”


        

    `

    主题传承

    组件也可以继承其父容器的主题。主题继承在两个方面是有益的。首先,它使设计者的设计过程更加有效,因为我们可以快速地在一个高层次(页面容器)设置一个主题,这个主题将级联到所有子组件,节省了宝贵的时间。其次,它使组件在整个应用中保持一致的风格。例如,在清单 7–7 中,我们用data-theme=”e”设计了页面容器。因此,内容主题从其父容器继承了“e”主题(参见图 7–8)。

    清单 7–7。 主题继承(ch7/theme-inheritance.html)

    `<div data-role=“page” data-theme=“e”>
            


                    

    No inheritance


            


                    Inherits “e”


    •                         
    • No inheritance

    •                         
    • No inheritance

    •                         
    • No inheritance

    •                 
                                                    
                    
                      

            
                        
                        
                      


                      


                        
                        
                            Off
                            On
                        
                      

    Button (Inherits “e”)
                    
            


                    

    No inheritance


            

    ` ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https://gitee.com/OpenDocCN/vkdoc-frontend-framework-zh/raw/master/docs/pro-jqmobi/img/0708.jpg&pos_id=img-gVCqDYEn-1723865550361)

    图 7–8。 主题传承

    **注意:**不是所有的组件都会继承其父容器的主题。参考表 7–1 中的“继承父主题”一栏,了解不会继承父主题的组件列表。

    我们还可以显式地设置单个组件的主题。这给了设计者在设计网站时的灵活性,可以帮助构建更丰富的设计(见图 7–9 和清单 7–8 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–9。 显性主题

    清单 7–8。 显性主题(ch7/theme-explicit.html)

    `<div data-role=“page” data-theme=“e”>
        <div data-role=“header” data-theme=“b”>
          

    Theme = “b”


        

    <div data-role=“content” data-theme=“d”>
          Theme = “d”

    <ul data-role=“listview” data-theme=“e” data-divider-theme=“e”>           

  • Theme = “e”

  •           
  • Inherits “e” from list

  •           <li data-theme=“b”>Theme = “b”
          


          

            
              
              <input type=“text” name=“text” id=“text” data-theme=“d” />
          


          


            
            <select id=“sound” data-role=“slider” data-theme=“b”>
               Off
               On
            
          

    <a href=“#” data-role=“button” data-theme=“a”>Button
          
        

    <div data-role=“footer” data-position=“fixed” data-theme=“b”>
          

    Theme = “b”


        

    `
    主题优先顺序

    主题按以下优先顺序应用于组件:

    1. 显式主题——如果在任何组件上显式设置了data-theme属性,该主题将覆盖任何继承的或默认的主题。

    2. 继承的主题—继承的主题将覆盖所有默认主题。例如,在清单 7–7 中,内容容器从它的页面容器继承了主题“e ”,而页面容器覆盖了它的默认主题“c”。关于可能继承其主题的组件列表,请参考表 7–1 中的“继承父主题”栏。

    3. Default themes—Default themes are applied when no themes are explicitly set or inherited. For a listing of default themes by component, refer to the “Default Theme” column in Table 7–1.

      **提示:**默认情况下,内容容器的最小高度只会拉伸里面组件的高度。当内容的主题与其页面容器的主题不同时,这就是一个问题(参见图 7–10)。我们可以用 CSS 来解决这个问题。例如,我们可以将内容容器的最小高度设置为屏幕的高度(参见图 7–11):

      ui-content { min-height:inherit; }

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–10。 内容高度不到 100%

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–11。 内容高度 100% (ch7/min-height.html)

    自定义主题

    jQuery Mobile 主题框架允许设计者快速定制或重新设计他们的用户界面。在本节中,我们将了解如何手动创建我们自己的自定义色板。如前所述,默认的 jQuery Mobile CSS 文档分为两个部分:主题部分和结构部分。在本练习中,我们将创建一个自定义样本,用于潜在危险动作的参考。例如,一个通用的用户体验指南鼓励开发者用红色突出显示控制潜在有害行为的按钮。在 jQuery Mobile 中,我们可以创建一个定制的样本来管理图标和/或按钮的视觉样式(背景、边框、颜色、字体、阴影),从而驱动我们的冒险行为。

    要手动创建自定义样本,必须执行以下步骤:

    1. First, create a separate CSS file for the custom theme (css/theme/custom-theme.css). This keeps the custom additions separate from the main jQuery Mobile CSS and will simplify future upgrades.

      **提示:**如果您计划使用自定义主题来设计整个 jQuery Mobile 应用,建议使用 jQuery Mobile 下载网站上的纯结构 CSS 文件。对于不需要默认主题的应用来说,这是一个轻量级的选择,它简化了定制主题的管理(参见清单 7–9)。

      清单 7–9。 jQuery Mobile 的无默认主题的结构文件

      `
        
        Custom Theme
        
      **  **
      **          **
        

      `
    2. 查找要作为基线参考的现有样本。在研究了现有的样本后,复制一个与你的新样本风格非常相似的样本。这将有助于最大限度地减少创建新样本所需的修改次数。对于我的新样本,我复制了“e”样本作为我的基线,因为“e”是一个重音样本,我们的潜在危险动作的新样本也可以划分到重音类别中。

    3. Next, copy the baseline swatch and paste it into the custom-theme.css file. Then, rename the swatch so it is associated to a unique letter (f-z). For example, replace all CSS suffixes with “-e” to “-v” (see Listing 7–10). The new swatch can now be referenced with data-theme=”v” for any components that perform dangerous actions.

      清单 7–10。 仿照样本“e”定制“v”样本(ch7/CSS/theme/Custom-theme 9781430239666 . CSS)

      /* **V** ----------------------------------------------------------------------*/ .ui-bar**-v** {   font-weight**:** bold**;**   border**:** 1px solid       #999**;**   background**:**             #dedede**;**   color**:**                  #000**;**   text-shadow**:** 0 1px 0px  #fff**;** **  …** } .ui-btn-up**-v** {   border: 1px solid       #999;   background:             #e79696;   color:                  #fff;   text-shadow: 0 1px 0px  #fff;   ... }

    4. Now the exciting task of updating the visual CSS settings (backgrounds, borders, color, font, and shadows) for our new swatch. For the new “v” swatch, I updated all buttons to have a red gradient background with white text (see Listing 7–11).

      清单 7–11。 用红色背景渐变和白色文字更新“v”色板按钮(ch7/CSS/theme/custom-theme 9781430239666 . CSS)

      /* V ----------------------------------------------------------------------*/ .ui-btn-up-v {   border: 1px solid       #999;   background:             **#e79696;**   color:                  **#fff;**   text-shadow: 0 1px 0px  #fff;   **background-image: -webkit-gradient(** **        linear, 0% 0%, 0% 100%, from(#E79696), to(#ce2021),** **        color-stop(.4,#E79696)** **  );** **  background-image: -webkit-linear-gradient(** **        0% 56% 90deg,#CE2021, #E79696, #E79696 100%** **  );** **  background-image:    -moz-linear-gradient(** **        0% 56% 90deg,#CE2021, #E79696, #E79696 100%** **  );**   ... }

    5. 接下来,我们需要将新的“v”样本与一个实际页面集成起来进行测试。我创建了两个页面来帮助测试新的“v”样本。在第一页,我想看看新的样本如何出现在一个只有图标的按钮上。在这个测试中,我创建了一个分割按钮列表,用二级按钮作为我们的删除图标,并用我们新的“v”样本设计二级按钮的样式(见图 7–12 和清单 7–12 中的相关代码)。


    2[jquerymobile.com/download](http://jquerymobile.com/download).

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–12。 红色图标背景为潜在危险动作

    清单 7–12。 带“v”形样本的拆分按钮(ch7/custom1.html)

    `
    **  **
    **  **
    **  …**

    我还在主 jQuery Mobile CSS 文件之前导入了新的 custom-theme.css 文件。对于我们的第二个测试,我想在一个删除按钮上应用我们新的“v”样本。对于这个测试,我创建了一个对话框来确认潜在的危险动作,并用我们新的红色渐变风格主题设计了删除按钮(参见图 7–13 和清单 7–13 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–13。 红色删除按钮用于删除动作

    清单 7–13。 带“v”的删除按钮样本(ch7/custom1.html)

    `


        
             Are you sure?

    <a href=“#home” data-role=“button” data-theme=“v”>Delete
            Cancel
        

    `

    最后,当您创建新的样本时,在颜色编码的样式指南中记录您的自定义样式会很有帮助,这样组织中的所有设计人员和开发人员都会熟悉它们的用法和样式。

    提示: CSS 渐变生成器 3 是可以自动生成你的渐变语法并帮助简化步骤 4 的工具。

    泰晤士报

    ThemeRoller 4 是一个基于 web 的工具,它帮助自动为 jQuery Mobile 生成新的基于 CSS 的主题。这是一个非常有用的工具,因为它允许您在左窗格中更新配色方案,并在右窗格中预览实际 jQuery Mobile 布局的结果(参见图 7–14)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–14。 主题人物


    3[www.westciv.com/tools/gradients/](http://www.westciv.com/tools/gradients/)[gradients.glrzad.com/](http://gradients.glrzad.com/).

    4[jquerymobile.com/themeroller](http://jquerymobile.com/themeroller).

    样本和全局设置

    在左侧窗格中出现的“全局”选项卡下,您可以快速调整全局应用于所有色板的 CSS 属性。在这里,您可以调整字体系列、活动状态颜色、拐角半径、图标和阴影(参见图 7–15)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–15。 全局主题设置

    “全局”选项卡旁边是样本特定选项卡(a-z)。您可以在此添加、编辑或删除主题中的样本(参见图 7–15)。

    预览检查器和快速观看栏

    为了更容易地构建自定义主题,预览面板顶部有两个独特的工具:预览检查器和快速观看栏。

    预览检查器是一个可以“开”或“关”的开关(见图 7–16)。打开开关后,单击预览窗格中的元素将自动在左窗格中显示其可编辑属性。当您需要快速编辑样式时,这将是一个宝贵的时间节省。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–16。 预览检查器和快速观看栏

    快速观察条是出现在检查器右侧的一系列颜色(参见 Figure 7–16)。这是一个强大的工具,允许您将任何颜色拖放到预览页面中的元素或左窗格中的颜色属性上。快速观察栏下面是两个滑块,用于调整调色板的亮度和饱和度。此外,最近选择的颜色将显示在色谱的右侧,以便快速重复使用。

    Adobe Kuler 集成

    当你需要从头开始创建一个调色板时,这可能是一个挑战。为了帮助简化这个过程,ThemeRoller 内置了 Adobe 的 Kuler 1 集成(参见图 7–17)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 7–17。 Adobe 的 Kuler App

    Kuler 是一个允许人们创建、分享和评价调色板的网站。要查看 Kuler 中可用的调色板,请单击出现在快速观察栏上方的“Adobe Kuler”链接。当 Kuler 应用打开时,搜索过滤器会出现在左侧窗格中,允许您按最新、热门、评级或自定义搜索进行过滤。当您找到感兴趣的颜色时,只需将该颜色拖放到预览窗格中的元素上。

    开始使用

    为了便于比较,我将在 ThemeRoller 中创建一个红色的强调色板,看看这种体验与我们在上一节中创建的手动色板相比如何。在本练习中,我将使用新的红色强调色板覆盖 jQuery Mobile 的默认“e”色板。在 ThemeRoller 中,要更新现有主题,需要执行以下步骤:

    1. In ThemeRoller, import an existing theme by clicking the “Import” link in the upper left corner (see Figure 7–18). For this exercise I am going to import and modify jQuery Mobile’s default theme. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–18。 导入已有的主题

    2. 导入主题后,确定要修改的样本。对于这一步,我将修改默认的“e”样本。

    3. 接下来,为我们的红色强调样本找到一个合适的基色。我们可以在快速观察栏或 Kuler 集成工具中找到合适的红色。

    4. 找到合适的基色后,我们现在可以用选择的颜色更新预览窗格中的元素。例如,我将用深红色强调色来设计标题和所有元素的样式。

    5. 在预览窗格中,进行任何必要的调整。例如,您可能想要稍微调整颜色或添加带有背景渐变的微妙效果。正如所料,ThemeRoller 使编辑和预览过程比手动方式更有效!

    6. After you are comfortable with the layout of the new theme, you can download the CSS of the theme by clicking on the “Download Theme” link in the upper left corner of ThemeRoller (see Figure 7–19). 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

      图 7–19。 下载主题

    7. We can now begin referencing the new theme in our application (see Listing 7–14 and its related screenshot in Figure 7–20). Again, to help simplify the management of the custom themes it is recommended to load the structure file and your custom themes separately.

      清单 7–14。 ThemeRoller 自定义主题导入(ch7/custom2.html)

      `
        
        Custom Theme
        
      **  **
      **          **
        

                    Are you sure?

      <a href=“#home” data-role=“button” data-theme=“e”>Delete
              Cancel
          

      `

    5[kuler.adobe.com](http://kuler.adobe.com).

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    **图 7–20。**滚轮的红色删除按钮

    总结

    jQuery Mobile 主题框架是一个面向对象的 CSS3 框架,它是轻量级的、可定制的,可以跨所有浏览器呈现统一的设计。在这一章中,我们讨论了主题框架的基础,并回顾了 jQuery Mobile 中包含的五个样例。

    我们还回顾了将主题分配给组件的三种方式。虽然所有组件都可以使用data-theme属性显式设置它们的主题,但是大多数组件也有默认主题,并且可以从父容器继承它们的主题。我们看到了每个主题的例子,并回顾了主题应用于组件的优先顺序。

    最后,我们看到了如何创建我们自己的定制样本。无论你是需要创建一个更丰富的设计,还是需要创建一个与你的公司品牌紧密匹配的设计,主题框架对于所有的需求都足够灵活。我们回顾了可用于创建自定义样本的两个选项,并查看了每个选项的分步示例。我们看到手动方式让我们完全控制了我们的布局,jQuery Mobile 的新 ThemeRoller 提供了一个更有效、更直观的工作环境。

    在下一章中,我们将深入了解 jQuery Mobile API。我们将学习如何配置 jQuery Mobile,还将回顾 API 的核心方法、事件、属性和数据属性。

    八、jQuery Mobile API

    所有编写良好的框架都允许开发人员扩展和覆盖默认的配置设置。此外,它们提供了方便的方法来帮助简化您的代码。jQuery Mobile 包括一个相当广泛的 API,它公开了这些便利的特性。首先,我们将看看如何配置 jQuery Mobile。我们将回顾 jQuery Mobile 中的每个可配置特性,突出显示其默认设置,并展示 API 如何允许您配置每个选项。然后,我们将探索 jQuery Mobile 公开的最流行的方法、页面事件和属性。当您需要以编程方式更新移动 Web 应用时,这些 API 特性非常有用。最后,我们将查看一个列出所有 jQuery Mobile 数据属性的排序表。对于每个属性,我们将包括其增强组件的简短描述、示例和图表。

    配置 jQuery Mobile

    当 jQuery Mobile 初始化时,它会在document对象上触发一个mobileinit事件。您可以绑定到mobileinit事件,并将覆盖应用到 jQuery Mobile 的($.mobile)默认配置设置。此外,您可以用附加的行为和属性来扩展 jQuery Mobile。例如,有两种配置 jQuery Mobile 的方法,如下例所示。您可以通过 jQuery 的extend方法或者单独覆盖这些属性。

    例子:

    `// Configure properties via jQuery’s extend method
    KaTeX parse error: Expected '}', got 'EOF' at end of input: … function(){   .extend( $.mobile, {
        // Override loading message
        loadingMessage: “Loading…”,

    // Override default transition from “slide” to “pop”
        defaultTransition: “pop”
      });
    }); // Configure properties individually
    KaTeX parse error: Expected '}', got 'EOF' at end of input: … function(){   .mobile.loadingMessage = “Initializing”;
      $.mobile.defaultTransition = “slideup”;
    });`

    自定义脚本放置

    由于执行 jQuery Mobile 时会立即触发mobileinit,所以您需要将您的定制脚本放在 jQuery Mobile JavaScript 文件之前。

    举例:

    `
        

    `
    可配置的 jQuery Mobile 选项

    以下是可配置的$.mobile选项,您可以在自定义 JavaScript 中覆盖这些选项。

    • activeBtnClass(string, default: “ui-btnactive”)

      这个 CSS 类用来标识“活动”按钮并设置其样式。这个 CSS 属性通常用于设计和识别标签栏中的活动按钮。

    • activePageClass(string, default: “ui-page-active”)

      分配给当前可见且活动的页面或对话框的 CSS 类。例如,当 DOM 中加载了多个页面时,活动页面将应用这个 CSS 属性。

    • ajaxEnabled(boolean, default: true)

      尽可能通过 Ajax 动态加载页面。默认情况下,除了外部 URL 或标记有rel="external"target="_blank"属性的链接之外,所有页面都启用 Ajax 加载。如果 Ajax 被禁用,页面链接将加载常规的 HTTP 请求,而没有 CSS 转换。

    • allowCrossDomainPages(boolean, default: false)

      使用 PhoneGap 开发时,建议将此配置选项设置为 true。这允许 jQuery Mobile 在 PhoneGap 中管理跨域请求的页面加载逻辑。

    • autoInitializePage(boolean, default: true)

      对于希望完全控制页面初始化顺序的高级开发人员,您可以将此配置选项设置为false,这将禁用所有页面组件的自动初始化。这允许开发人员根据需要手动增强每个控件。

    • defaultDialogTransition(string, default: “pop”)

      转换到对话框时使用的默认转换。您可以将过渡设置为“none”,不进行过渡。

    • defaultPageTransition(string, default: “slide”)

      转换到页面时使用的默认转换。您可以将过渡设置为“none”,不进行过渡。

    • gradeA(function that returns a boolean, default: browser must support media queries or support IE 7+);

      jQuery Mobile 将调用这个方法来确定框架是否会应用动态 CSS 页面增强。默认情况下,该方法将对所有支持媒体查询的浏览器应用增强功能;然而,jQuery Mobile 只会增强 A 级浏览器的页面。IE 7 及以上版本被列为 A 级浏览器,它们的显示也将得到增强,例如,这是$.mobile.gradeA的当前功能:

      $.mobile.gradeA: function(){   return $.support.mediaquery ||          $.mobile.browser.ie && $.mobile.browser.ie >= 7; }

    • hashListeningEnabled(boolean, default: true)

      基于location.hash自动加载并显示页面。jQuery Mobile 监听location.hash的变化以加载 DOM 中的内部页面。您可以禁用此选项并手动处理哈希更改,或者禁用此选项以深度链接的形式访问锚的书签。

    • loadingMessage(string, default: “loading”)

      设置在基于 Ajax 的请求期间出现的加载消息。此外,您可以指定一个false(布尔值)来禁用该消息。此外,如果您想在运行时逐页更新加载消息,您可以在页面内更新它。

      例如:

      `// Update loading message
      $.mobile.loadingMessage = “My custom message!”;

      // Show loading message
      $.mobile.showPageLoadingMsg();`

    • minScrollBack(string, default: 250)

      设置返回页面时记忆的最小滚动距离。当返回页面时,当链接的滚动位置超出minScrollBack设置时,框架将自动滚动到启动过渡的位置或链接。默认情况下,滚动阈值为 250 像素。如果您想取消最小设置,使框架总是滚动,而不管滚动位置如何,请将该值设置为"0"。如果您想禁用该功能,请将该值设置为"infinity"

    • nonHistorySelectors(string, default: “dialog”)

      您可以指定从浏览器的历史堆栈中排除哪些页面组件。默认情况下,任何带有data-rel="dialog"的链接或者任何带有data-role="dialog"的页面都不会出现在历史中。此外,这些非历史选择器组件在导航到它们的页面时不会更新它们的 URL,因此它们将不能被加书签。

    • ns(string, default: “”)

      jQuery Mobile 中自定义 data-*属性的名称空间。数据属性是 HTML5 中的新特性。例如,“data-role”是role属性的默认名称空间。如果你想全局覆盖默认名称空间,你可以覆盖$.mobile.ns选项。

      举例:

      // Set a custom namespace $.mobile.ns = "jqm-";

      因此,所有 jQuery Mobile data-*属性都需要前缀“data-jqm-”。例如,“??”属性现在变成了“??”。

      **重要提示:**如果您更新默认名称空间,您将需要更新 jQuery Mobile CSS 文件中的一个 CSS 选择器:

      `// Original CSS for default namespace:
      .ui-mobile [data-role=page],
      .ui-mobile [data-role=dialog],
      .ui-page {…}

      // Updated CSS for the new namespace “jqm-”:
      .ui-mobile [data-jqm-role=page],
      .ui-mobile [data-jqm-role=dialog],
      .ui-page {…}`

      为什么要覆盖默认名称空间?

      首先,如果您正在设计一个包含 HTML5 data-*属性的 JavaScript 框架,W3C 建议您包含一个钩子,允许开发人员定制名称空间,以避免与第三方框架冲突。每当您遇到与另一个第三方框架的名称空间冲突时,您将需要更改您的默认名称空间。

    • page.prototype.options.addBackBtn(boolean, default: false)”

      如果您希望后退按钮出现在整个应用中,请将此选项设置为true。jQuery Mobile 中的后退按钮是一个智能小部件。只有当历史堆栈中有页面可供返回时,它才会出现。

      举例:

      $.mobile.page.prototype.options.addBackBtn = true;

    • page.prototype.options.keepNative(string, default:

      :jqmData(role='none '),:jqmData(role='nojs ')"

      如果您想防止自动初始化而不将data-role="none"添加到您的标记中,您可以定制用于防止自动初始化的keepNative选择器。例如,为了防止框架初始化所有的选择和输入元素,我们可以更新这个选择器。

      举例:

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

    • pageLoadErrorMessage(string, default: “Error Loading Page”)

      Ajax 页面请求加载失败时出现的错误响应消息。

    • subPageUrlKey(string, default: “ui-page”)

      用于引用小部件生成的子页的 URL 参数。子页面 URL 的一个例子是“nested-list.html&ui-page = Movies-3”。嵌套列表视图是一个特殊的小部件,它将每个列表分割成单独的子页面。例如,前面显示的 URL 有一个“Movies”子列表,jQuery Mobile 将其转换为自己的子页面,以容纳深层链接引用。如果需要重命名这个 URL 参数,可以用$.mobile.subPageUrlKey来更改。

    • touchOverflowEnabled(boolean, default: false)

      为了实现具有本地动量滚动的真正的固定工具栏,浏览器需要支持位置:固定或溢出:自动。幸运的是,WebKit (iOS5)的新版本开始支持这种行为。默认情况下,很可能会启用该选项。在此之前,我们可以通过将此配置选项设置为 true 来启用此行为。

    方法

    jQuery Mobile 提供了一套方法,当您需要以编程方式更新移动 Web 应用时,这些方法非常有用。

    • $.mobile.changePage()

      changePage 函数处理从一个页面转换到另一个页面的所有细节。

      用法

      $.mobile.changePage( toPage, [options] )

      自变量

      • toPage (sting 或 jQuery 集合)。要转换到的页面。
      • toPage(字符串)。文件 URL(“contact . html”)或内部元素的 ID(“contact”)。
      • toPage(对象)。一个 jQuery 集合对象,包含一个页面元素作为其第一个参数:$("#contactPage ")

      options(对象)。配置 changePage 请求的一组键/值对。所有设置都是可选的。

      • allowSamePageTransition(布尔型,默认值:false)。changePage 方法将忽略转换到同一页面的请求。将此选项设置为true以允许同页转换。
      • changeHash(布尔,默认:true)。当页面更改完成时,将散列更新为 toPage 的 URL。
      • data(字符串或对象,默认:undefined)。发送到 Ajax 页面请求的数据。
      • dataUrl(字符串,默认:toPage URL)。设置要在浏览器的位置字段中显示的 URL。
      • fromHashChange(布尔型,默认值:false)。指示 changePage 是否来自 hashchange 事件。
      • fromPage(字符串,默认:$.mobile.activePage)。指定“从”页。
      • pageContainer (jQuery 集合,默认:$.mobile.pageContainer)。指定页面加载后应包含的元素。
      • reloadPage(布尔型,默认:false)。强制重新加载页面,即使它已经在页面容器的 DOM 中。
      • reverse(布尔型,默认:false)。以指示过渡应该向前还是向后。默认转换是向前。
      • role(字符串,默认:page)。显示页面时要使用的数据角色值。对于对话框,使用“对话框”。
      • showLoadMsg(布尔型,默认:true)。请求页面时显示加载消息。
      • transition(字符串,默认:$.mobile.defaultTransition)。申请变更页面的过渡。默认过渡是slide
      • type(字符串,默认:get)。指定方法("get或"post”) to use when making a page request.)

      例#1:

      `//Transition to the “contact.html” page.
      $.mobile.changePage( “contact.html” );

      Contact Us`

      例 2:

      `// Transition to the internal “#contact” page with a reverse “pop” transition.
      $.mobile.changePage( ”#contact”, { transition: “pop”, reverse: true } );

      Contact`

      例三:

      `/* Dynamically create a new page and open it */

      // Create page markup
      var newPage = $(“


          

      Hi

      Hello Again! ”);

      // Add page to page container
      newPage.appendTo( $.mobile.pageContainer );

      // Enhance and open new page
      $.mobile.changePage( newPage );`

    • $.mobile.hidePageLoadingMsg()

      移除或隐藏页面加载信息($.mobile.loadingMessage)。默认加载消息是“正在加载”,这也是可配置的。要显示加载信息,请参见$.mobile.showPageLoadingMsg().

      举例:

      // Remove the loading message $.mobile.hidePageLoadingMsg();

    • $.mobile.loadPage()

      loadPage 函数将页面加载到当前页面的 DOM 中并增强它。该方法也作为数据属性公开,可以附加到链接或按钮上(参见“数据属性”一节中的“数据预取”)。

      用法

      $.mobile.loadPage( url, [options] )

      自变量

      url(蛰)。要加载的页面。

      • url(字符串)。文件 URL(“contact . html”)。

      options(对象)。配置 changePage 请求的一组键/值对。所有设置都是可选的。

      • data(字符串或对象,默认:未定义)。发送到 Ajax 页面请求的数据。
      • loadMsgDelay(数字(毫秒),默认为 50)。在显示加载消息之前添加手动延迟。这种延迟允许框架在没有加载消息的情况下加载缓存的页面。
      • PageContainer (jQuery 集合,默认:
        $.mobile.pageContainer)。加载后应包含页面的元素。
      • reloadPage(布尔型,默认:false)。强制重新加载页面,即使它已经在页面容器的 DOM 中。
      • role(字符串,默认:@data-role 属性)。用于加载页面的数据角色。默认值是在元素上定义的@data-role 属性。
      • showLoadMsg(布尔型,默认为:真)。请求页面时显示加载消息。
      • type(字符串,默认:“get”)。指定发出页面请求时使用的方法(“get""post"

      例子:

      `// Dynamically load a page and transition to it.
      $.mobile.loadPage(“page1.html” );

      $.mobile.changePage(“#page1” ); // data-url value`

    • $.mobile.showPageLoadingMsg()

      显示页面加载信息($.mobile.loadingMessage)。

      举例:

      // Show the page loading message $.mobile.showPageLoadingMsg();

    • $.mobile.silentScroll(number)

      垂直滚动页面。在这个框架中,每当页面被恢复时,silentScroll就会被调用。例如,当你点击后退按钮时,silentScroll方法在显示前一页之前被触发,并将恢复前一页的滚动位置。重点将放在触发初始转换的组件上。在silentScroll期间scrollstartscrollstop事件不会被触发。

      举例:

      `// Hide the iOS address bar
      $.mobile.silentScroll(0);

      // Scroll down 400 pixels
      $.mobile.silentScroll(400);`

    • $.jqmData()

      这是 jQuery .data()方法的移动版本。 1 该方法提供了$.data()中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns)设置和检索所有数据。

      例子:

      `// Find all pages (data-role=“page”) in the DOM via a selector.
      var $pages = $( “:jqmData(role=‘page’)” );

      // Find the theme (data-theme) for the first page
      var firstPage = p a g e s . f i r s t ( ) ; v a r t h e m e = ∗ ∗ pages.first(); var theme = ** pages.first();vartheme=.jqmData**( firstPage, “theme” );`

    • $.jqmHasData()

      这是 jQuery .hasData()方法的移动版本。 2 该方法提供了$.hasData()中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns)检索所有数据。

      例子:

      // Does a theme exist for the first page var hasTheme = $.jqmHasData( firstPage, "theme" );

    • $.jqmRemoveData()

      这是 jQuery .removeData()方法的移动版本。 3 该方法提供了$.removeData()中的所有功能,并确保使用 jQuery Mobile 的数据命名空间($.mobile.ns)删除所有数据。

      例子:

      `// Set data on the first page
      $.jqmData(firstPage, “testData”, “testValue”);

      // Remove the data from the first page
      $.jqmRemoveData( firstPage, “testData” );`


    <sup>1</sup> [api.jquery.com/jQuery.data/](http://api.jquery.com/jQuery.data/)

    <sup>2</sup> [api.jquery.com/jQuery.hasData/](http://api.jquery.com/jQuery.hasData/)

    <sup>3</sup> [api.jquery.com/jQuery.removeData/](http://api.jquery.com/jQuery.removeData/)

    事件

    jQuery Mobile 还公开了几个事件,当您需要在移动 Web 应用中的页面更改期间以编程方式应用预处理或后处理时,这些事件会很有帮助。在这一节中,我们将回顾您可以在自己的代码中绑定的 jQuery Mobile page 事件的完整列表。对于 jQuery Mobile events 的介绍,让我们从一个图表开始(图 8-1 )。该图显示了 jQuery Mobile 中发生的主要页面事件,并有助于描述页面更改生命周期中每个事件的顺序。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 8-1。 jQuery 手机页面事件

    现在我们已经看到了页面变更生命周期中页面事件的触发顺序,让我们来看看每个特定事件的详细信息。

    事件概述
    • mobileinit

      当 jQuery Mobile 初始化时,它会在document对象上触发一个mobileinit事件。您可以绑定到mobileinit事件,并将覆盖应用到 jQuery Mobile 的默认配置设置。关于绑定到mobileinit事件的例子,请参考“配置 jQuery Mobile”一节。

    页面变更事件

    当您导航到另一个页面时,文档上会自动触发页面更改事件。在内部,当调用$.mobile.changePage方法时,这些事件被触发。在此过程中,将触发两个事件。第一个触发的事件是pagebeforechange.。下一个触发的事件取决于页面更改的状态。当页面更改成功时,将触发 page change 事件,如果页面更改失败,将触发pagechangefailed事件。

    • pagebeforechange

      这是页面更改期间触发的第一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。您可以通过调用事件上的preventDefault来取消页面更改。此外,您可以通过检查和更新数据对象来覆盖页面更改。作为第二个参数传递的数据对象包含以下属性:

      • toPage(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage().的参数相同
      • options(对象)。这些是通过to $.mobile.changePage的相同选项。

      举例:

      `$( document ).bind( “pagebeforechange”, function( e, data ) {
          console.log(“Change page starting…”);

      // Get the page
          var toPage = data.toPage;

      // Get the page options
          var options = data.options;

      // Inspect toPage or override options (redirect)…

      // Prevent a page change
          e.preventDefault();
      });`

    • pagechange

      这是页面更改成功后触发的最后一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • toPage(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage()的参数相同。

      • options (object). These are the same options that were passed to $.mobile.changePage.

        举例:

        $( document ).bind( "pagechange", function( e, data ){     console.log(“Change page successfully completed...”);     var toPage = data.toPage;     var options = data.options; });

    • pagechangefailed

      如果页面更改失败,将触发此事件。这个事件的回调传递了两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • toPage(字符串)。文件 URL 或 jQuery 集合对象。这与传递给$.mobile.changePage().的参数相同

      • options (object). These are the same options that were passed to $.mobile.changePage.

        举例:

        $( document ).bind( "pagechangefailed", function( e, data ){     console.log(“Page change failed...”); });

    页面加载事件

    当框架将页面加载到 DOM 中时,页面加载事件在文档上被触发。以编程方式,当调用$.mobile.loadPage时,该事件被触发。在这个过程中,loadPage()将触发两个事件。第一个是pagebeforeload,第二个事件是成功(pageload)或失败(pageloadfailed)事件。

    • pagebeforeload

      这是页面加载期间触发的第一个事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。如果您愿意,可以手动处理加载逻辑。为此,您必须在事件上调用preventDefault(),并在数据对象中包含的延迟对象引用上调用resolve()reject()。作为第二个参数传递的数据对象包含以下属性:

      • url(字符串)。发送给$.mobile.loadPage()的相对 URL。

      • absUrl(字符串)。URL 的绝对引用。

      • dataUrl(字符串)。实际存储在页面的 data-url 属性中的 URL 版本。此 URL 显示在浏览器的位置字段中。

      • deferred(对象)。调用preventDefault()来手动处理页面加载的回调函数必须调用这个对象上的resolve()reject(),这样changePage()请求才能继续处理。

      • options (object). This is the same options argument that was passed to $.mobile.loadPage().

        举例:

        `$( document ).bind( “pagebeforeload”, function( e, data ){
            console.log(“Page load starting…”);

        // Let the framework know we’re manually loading the page
            e.preventDefault();

        // Manually load the document and insert it into the DOM
            var response = manuallyLoadPage();

        if (response.status = “success”) {
              // Call resolve passing in the url, options, and jQuery
              // collection object containing the DOM element for the page
              data.deferred.resolve( data.absUrl, data.options, response.page);
            } else {
              // The load failed, call reject
              data.deferred.reject( data.absUrl, data.options );
            }
        });`

    • pageload

      该事件在页面成功加载到 DOM 后触发。向该事件的回调传递两个参数。第一个是事件,第二个是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • url(弦)。发送给$.mobile.loadPage的相对 URL。

      • absUrl(字符串)。URL 的绝对引用。

      • dataUrl(字符串)。实际存储在页面的 data-url 属性中的 URL 版本。此 URL 显示在浏览器的位置字段中。

      • options (object). This is the same options argument that was passed to $.mobile.loadPage().

        举例:

        $( document ).bind( "pageload", function( e, data ){   console.log("Page successfully loaded into DOM..."); });

    • 页面加载失败

    • This event is triggered if the page load fails. During this process, the framework will display a page failed message and call reject() on the deferred object. Callbacks can prevent this default behavior from executing by calling preventDefault() on the event.

      举例:

      $( document ).bind( "pageloadfailed", function( e, data ){   console.log("Page load failed..."); });

    页面初始化事件

    在 jQuery Mobile 增强页面之前和之后,页面初始化事件都会在页面上触发。您可以绑定到这些事件,在框架增强页面之前预解析标记,或者在之后设置 DOM ready 事件处理程序。这些事件在页面的生命周期中只触发一次。

    • pagebeforecreate

      在页面更改期间初始化页面时触发。此事件发生在页面容器插入 DOM 之后,但在页面增强之前。这是在框架增强页面之前预解析标记的首选位置。例如,在这种情况下,您可以动态地创建和添加新的页面小部件,或者修改现有的数据属性。

      举例:

      $( "#to-page-id" ).live( "pagebeforecreate", function(){ console.log( "Pre-parse the markup before the framework enhances the widgets" ); });

    • pagecreate

      在页面更改期间正在初始化的页面上触发。这是框架初始化所有页面插件时触发的事件。如果您创建自定义页面插件,这是初始化它们的首选位置。

      举例:

      `$( “#to-page-id” ).live( “pagecreate”, function(){
          console.log(“Page plugins are being initialized…”);

      // Initialize custom plugins
          (“:jqmData(role=‘my-plugin’)” ).myPlugin();
      });`

    • pageinit

      在增强完成后正在初始化的页面上触发。页面现在处于 DOM 就绪状态。

      举例:

      $( "#to-page-id" ).live( "pageinit", function(){     console.log(“The page has been enhanced...”);     // Attach event handlers or run other jQuery code... });

    页面过渡事件

    在页面转换期间,页面转换事件在“从”和“到”页面上触发。您可以绑定到这些事件来观察页面何时显示或从视图中移除。

    • pagebeforehide

      过渡开始时在“从”页面触发。该事件发生在pagebeforeshow事件之前。仅当页面更改请求有关联的“发件人”页面时,才会触发此事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • nextPage(对象)。一个 jQuery 集合对象,包含我们要转换到的页面元素。

      举例:

      $( "#from-page-id" ).live( "pagebeforehide", function( e, data ){   console.log( "The page transition is just starting..." ); });

    • pagebeforeshow

      在页面增强之后,页面转换开始之前,在“到”页面上触发。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • prevPage (object). A jQuery collection object containing the page element we are transitioning from.

        举例:

        $( "#to-page-id" ).live( "pagebeforeshow", function( e, data ){   console.log( "The page transition is just starting..." ); });

    • pagehide

      在转换完成之后和pageshow事件之前,在“from”页面上触发。仅当页面更改请求有关联的“发件人”页面时,才会触发此事件。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • nextPage (object). A jQuery collection object containing the page element we are transitioning to.

        举例:

        $( "#from-page-id" ).live( "pagehide", function( e, data ){   console.log( "The page transition is complete!" ); });

    • pageshow

      在转换完成和隐藏“从”页面后,在“到”页面上触发。向该事件的回调传递两个参数。第一个参数是事件,第二个参数是数据对象。作为第二个参数传递的数据对象包含以下属性:

      • prevPage (object). A jQuery collection object containing the page element we are transitioning from.

        举例:

        $( "#to-page-id" ).live( "pageshow", function( e, data ){   console.log( "The page transition is complete!" ); });

    **提示:**jQuery Mobile 团队已经创建了一个有用的书签小程序,允许您从浏览器控制台查看页面事件历史(参见图 8-2 )。当您浏览 jQuery Mobile 应用时,您将能够通过页面、URL 和时间戳查看事件的历史。要安装,请转到 jQuery Mobile event logger 页面 4 并按照它们的说明安装书签。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 8-2。 页面事件记录器控制台

    触发事件

    在构建动态页面时,触发 jQuery Mobile 页面事件会很有帮助。例如,如果您向页面添加几个新组件,您可以调用 create 事件来一次增强页面上的所有新部件。

    • trigger(“create”)

      我们可以触发这个事件来自动增强页面上的所有新元素。该事件在页面容器上触发。

      举例:

      `// Add two new buttons to the page
      $( ‘Button2’ ).insertAfter( “#b1” );
      $( ‘Button3’ ).insertAfter( “#b2” );

      // Enhance the new buttons on the page
      $.mobile.pageContainer.trigger( “create” );`

    4[jquerymobile.com/test/tools/log-page-events.html](http://jquerymobile.com/test/tools/log-page-events.html).

    属性

    jQuery Mobile 还公开了一组公共可用的属性,因此您不必编写自己的 jQuery 选择器来访问公共组件。

    • $.mobile.activePage

      获取当前活动或可见的页面或对话框元素。活动页面被分配了由$.mobile.activePageClass指定的 CSS 类。

    • $.mobile.firstPage

      这是页面容器($.mobile.pageContainer)中定义的第一个页面。例如,当不存在location.hash值或$.mobile.hashListeningEnabled被禁用时,将显示$.mobile.firstPage。例如,在多页文档中,默认情况下最初会显示$.mobile.firstPage

    • $.mobile.pageContainer

      所有页面所在的 HTML 容器。在 jQuery Mobile 中,body元素是包含所有页面的容器。所有 Ajax 加载的页面和多页面文档的所有内部页面都将存在于页面容器中。

    数据属性

    jQuery Mobile 的数据属性提供了用简单的 HTML 标记增强和配置移动应用的能力。所有数据属性的完整列表,按字母顺序排列,说明和示例如下(见表 8-1 )。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结

    在本章中,我们看到了如何配置 jQuery Mobile,并回顾了许多可用于构建更多动态页面的常见 API 特性。无论您是需要全局更改默认转换,还是希望在所有页面上显示后退按钮,jQuery Mobile 都允许我们重新配置许多常见设置。我们还回顾了 jQuery Mobile 公开发布的许多流行的方法、事件和属性。当您需要以编程方式更新移动 Web 应用时,这些 API 特性非常有用。最后,我们看到了所有 jQuery Mobile 数据属性的完整列表。希望这个列表可以为您在快节奏的 jQuery Mobile 项目中工作提供一个快速的参考。每个属性包括一个简短的描述,例子和数字。

    在下一章中,我们将深入探讨如何有效地使用服务。我们将看到如何将 jQuery Mobile 页面与客户端和服务器端集成解决方案集成。

    九、服务整合策略

    构建 Web 应用时,加载数据有两种主要的访问策略。有传统的服务器端访问策略和 Web 2.0 的客户端访问策略。在这一章中,我们将展示将 jQuery Mobile 与这两种访问策略集成的例子,并讨论每种策略的优点。jQuery Mobile 很好地集成了这两种策略,因此,您可以选择最适合您的应用需求的访问策略。

    首先,我们将展示两个客户端集成示例。随着社交媒体的流行,我们的第一个例子将演示如何与 Twitter 的 RESTful API 集成。RESTful APIs 是轻量级的 web 服务,由于其简单的设置和灵活的响应类型(JSON、XML),通常比传统的 web 服务更受欢迎。在我们的 Twitter 示例之后,我们将创建我们自己的 RESTful API,允许用户注册免费电影奖品。这个注册示例将有助于展示我们从 jQuery Mobile 应用向 RESTful API 提交内容的能力。此外,这个例子将让您熟悉如何在服务器端设置 RESTful API。

    然后,我们将过渡到服务器端集成策略,并实现一个获取数据的用例以及另一个发布数据的用例。为了进行比较,我们将把客户端注册示例重新实现为服务器端解决方案。当使用服务器端模型-视图-控制器(MVC)访问策略获取数据时,您可能会惊讶地发现我们页面标记变得更加整洁。

    最后,随着地理定位和地图视图的流行,我们将看到如何将 jQuery Mobile 与 HTML5 地理定位 API 和 Google Maps 集成。

    客户端与 RESTful 服务的集成

    大多数社交媒体网站都有一个公共 API 来访问它们的数据。Twitter、 1 LinkedIn、 2 和脸书 3 集成在 Web 上非常常见,RESTful 集成是它们中每一个的常见访问策略。在这一节中,我们将把 jQuery Mobile 与两个不同的 RESTful APIs 集成在一起,这样我们就可以看到这个策略在 jQuery Mobile 中运行得有多好。

    客户端 Twitter 与 Ajax 的集成

    在我们的第一个客户端示例中,我们将把 jQuery Mobile 与 Twitter 的 RESTful API 集成在一起。Twitter 是一个非常受欢迎的社交媒体网站,允许用户发送或“推特”关于主题、事件或随机观点的简短消息。在我们的电影应用中,允许用户实时搜索 Twitter 以获得他们可能感兴趣的电影的反馈可能是有价值的。例如,除了查看其他人对某部电影的评论,我们可能希望提供一个方便的 Twitter 链接,显示关于这部电影的最新推文。在我们的用户评论页面上,我们在标题中添加了一个 Twitter 按钮,用户可以点击它来查看关于这部电影的最新推文(参见图 9–1 及其在清单 9–1 中的相关代码)。


    http://dev.twitter.com/console

    2[developer.linkedin.com/community/apis](http://developer.linkedin.com/community/apis)

    3[developers.facebook.com/](http://developers.facebook.com/)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–1。 影评页面页眉的推特按钮

    清单 9–1。 电影评论页面页眉的 Twitter 按钮(ch9/reviews.html)

    `<div data-role=“page” id=“reviewsPage”>
        


            

    Reviews


            <a href=“twitter.html” id=“twitterBtn” class=“ui-btn-right”
                    data-icon=“custom” data-iconpos=“notext”>
        
        …

    `

    当用户点击 Twitter 按钮时,我们将在 Twitter 上搜索当前电影的最新推文,并将结果加载到我们的 Twitter 结果页面上(参见图 9–2 及其在清单 9–2 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–2。 推特结果页面

    清单 9–2。 推特结果页面(ch9/twitter.html)

    `<div data-role=“page” id=“twitterPage”>
            …
            


              <ul id=“tweet-list” data-role=“listview” data-inset=“true”>
                
    • Tweets


              
             `

    在清单 9–2 中显示的tweet-list id 是我们的占位符,我们将在这里追加我们的 Twitter 搜索结果。Twitter 的搜索 API 返回许多数据元素,然而,我们只对 tweet 文本、发布 tweet 的用户以及用户的个人资料图像感兴趣。

    **提示:**要查看 Twitter 的搜索 API 中所有可用的数据元素,在浏览器中启动这个字符串“[search.twitter.com/search.json?q=xmen](http://search.twitter.com/search.json?q=xmen)”。这是基本的搜索 API,其中“q”参数的值是我们的可搜索关键字。在这种情况下,我们在 Twitter 上搜索任何包含关键字“xmen”的推文。

    **提示:**大多数浏览器以无格式的样式显示 JSON 响应,这可能非常不友好:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    作为替代,Firefox 有一个 JSON 查看器插件 4 ,它以更结构化的格式格式化 JSON 响应:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    同样,如果你需要验证 JSON,JSONLint 5 可以是一个有用的工具。

    jQuery Mobile 内置了 Ajax 支持,这使得 RESTful 集成更加简单,不依赖于第三方 JavaScript 框架。这种支持来自 jQuery Mobile 扩展的 jQuery API 6 。在 jQuery 中,$。ajax 7 API 是 RESTful 集成的首选解决方案,因为它简单且具有灵活的配置选项(超时、缓存等)。).


    4[addons.mozilla.org/en-US/firefox/addon/jsonview/](https://addons.mozilla.org/en-US/firefox/addon/jsonview/)

    5 见【http://jsonlint.com/】的。

    6 见【http://jquery.com/】的。

    7API . jquery . com/jquery . Ajax/

    要将 jQuery Mobile 与 Twitter 的 RESTful API 集成,以下步骤是必要的(参见清单 9–3):

    1. 当点击 Twitter 按钮时,我们将首先显示 jQuery Mobile 活动指示器,这样用户就可以直观地意识到一个活动正在后台处理:$( "#twitterBtn" ).bind( "click", function(e) { **    $.mobile.showPageLoadingMsg();**
    2. 接下来,我们将把 Twitter 结果页面加载到当前页面的 DOM 中。如果页面已经存在于 DOM 中,我们将重新加载并更新缓存的页面:**$.mobile.loadPage("twitter.html", { reloadPage: true });**
    3. 在我们的 Twitter 页面得到增强之前,我们将向 Twitter API 发送一个 AJAX 请求来收集我们的搜索结果:$(“#twitterPage”).live("**pagebeforecreate**", function(){    **$.ajax**({...
    4. 我们的url选项被配置为 Twitter 的 RESTful API,我们的搜索查询被配置为查找所有包含关键字“xmen”的 tweets:**url:** "http://search.twitter.com/search.json?q=xmen"
    5. 由于 Twitter API 存在于另一个域中,我们需要将我们的dataType选项设置为jsonp.通常,跨域通信是不允许的,但是 JSONP 8 有助于促进跨域集成的可信方式:**dataType:** "jsonp"
    6. 最后,我们实现了我们的success回调来迭代搜索结果,为每一行创建一个列表项,并将新的标记附加到我们的列表容器中:

    success: function( response ) {...

    清单 9–3。 客户端 Twitter 集成(ch9/twitter.js)

    `KaTeX parse error: Expected 'EOF', got '#' at position 4: ( "#̲reviewsPage" ).…( “#twitterBtn” ).bind( “click”, function(e) {
    **        $.mobile.showPageLoadingMsg();**

    // Reload Twitter results page even if it’s already in the DOM
    **        $.mobile.loadPage(“twitter.html”, { reloadPage: true });**

    // Prevent default click behavior
            return false;     });
    });

    KaTeX parse error: Expected 'EOF', got '#' at position 3: ( #̲twitterPage" ).….ajax**({
          url: “http://search.twitter.com/search.json?q=xmen”,
          dataType: “jsonp”,
          success: function( response ) {
     *        // Generate a list item for each tweet*
             var markup = “”;
             $.each(response.results, function(index, result) {
                 var $template = $('

    ');              $template.find(".from").append(**result.from_user**);              $template.find(".tweet").append(**result.text**);              $template.find(".profile")                           .attr("src", **result.profile_image_url**);              markup += $template.html();          });

    *        // Append the Tweet items into our Tweet list and refresh the
             // entire list.*
             $( “#tweet-list” ).append(markup).listview( “refresh”, true );

    // Transition to the Twitter results page.
             $.mobile.changePage( $(“#twitterPage”) );
          },
       });
    });
    In this example, we have chosen to load the Twitter results on demand when the user
    clicks on the Twitter button. Alternatively, you may pre-fetch the Twitter data so users
    can see the Twitter results instantly when the button is clicked. To set up this
    strategy, add the data-prefetch attribute on the Twitter button:
    <a href=“twitter.html” id=“twitterBtn” class=“ui-btn-right” data-icon=“custom” data-
    iconpos=“notext” data-prefetch>`


    8[en.wikipedia.org/wiki/JSONP](http://en.wikipedia.org/wiki/JSONP)

    现在页面的改变可以通过按钮的默认点击行为来处理,这样我们就可以在 Twitter 结果被添加到列表后,删除这个按钮和$.mobile.changePage()调用的自定义点击处理程序。

    此外,在生产用例中,您将希望在$.ajax方法上配置timeouterror回调,以处理任何无响应或不可用的 API。例如,如果 Twitter API 没有响应,通知用户可能会有所帮助:

    `timeout: 6000, // Timeout after 6 seconds
    error: function(jqXHR, textStatus, errorThrown) {
        $.mobile.hidePageLoadingMsg();

    *   // Show error message*
         ( " < d i v c l a s s = ′ u i − l o a d e r u i − o v e r l a y − s h a d o w u i − b o d y − e       u i − c o r n e r − a l l ′ > < h 1 > " + ∗ ∗ ( "<div class='ui-loader ui-overlay-shadow ui-body-e      ui-corner-all'><h1>"+ ** ("<divclass=uiloaderuioverlayshadowuibodye     uicornerall><h1>"+.mobile.pageLoadErrorMessage** +“” )
            .css({ “display”: “block”, “opacity”: 0.96, “top”: 100 })
            .appendTo( **KaTeX parse error: Expected '}', got 'EOF' at end of input: … {             ( this ).remove();         });
    }`

    使用 Ajax 的客户端表单发布

    前面的例子是一个向 Twitter 的 API 发送 GET 请求的用例。从 API 读取时,GET 请求非常常见,当没有指定时,$.ajax方法将默认为这个type。在下一个例子中,我们将创建自己的 RESTful API,允许用户发送 POST 请求。让我们创建一个 API,这样用户就可以注册奖品。我们的用户界面将由一个简单的表单组成,只需要一个电子邮件地址(参见图 9–3 和清单 9–4 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    **图 9–3。**Ajax 客户端岗位登记表

    **清单 9–4。**Ajax 客户端发布登记表(ch9/register-client.html)

    <div data-role="page" **id="registrationPage"** data-theme="d">     <div data-role="header">       <h1>Registration</h1>     </div> `    


          <form id=“register” method=“post”>
            
            <input type=“email” name=“email” id=“email” placeholder=“Email”
    required />
            
          
        

    `

    **提示:**电子邮件地址的输入字段包括三个新的 HTML5 属性。type=”email”字段提供了两个好处。首先,当字段获得焦点时,它会提示 QWERTY 键盘几个有用的电子邮件键(参见 Figure 9–3)。其次,它还将在提交表单时验证该字段是否包含有效的电子邮件地址。例如,在较新的桌面浏览器中,如果用户输入了无效的电子邮件,系统会提示用户以下消息:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    此外,当用户提交时,required属性将断言 email 字段不为空。如果为空,用户将收到以下警告:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    最后,placeholder属性将向输入字段添加提示文本。虽然这些特性很有帮助,但并不是所有的特性都被今天的浏览器所支持。Peter-Paul Koch 有一个有用的站点 9 ,它显示了所有可用的输入属性及其相关的浏览器支持。

    为了在客户端处理表单提交,我们将在提交按钮上附加一个事件监听器。要向我们的 RESTful API 提交 POST 请求,必须执行以下步骤(参见清单 9–5):


    9[www.quirksmode.org/html5/inputs_mobile.html](http://www.quirksmode.org/html5/inputs_mobile.html)

    1. 首先,我们需要拦截并覆盖默认的提交行为。现在我们准备通过 RESTful API 提交表单:$("form").submit(function () {
    2. 其次,我们需要显示 jQuery Mobile 活动指示器,这样用户就可以直观地意识到活动正在后台处理:$.mobile.showPageLoadingMsg()
    3. 接下来,我们用所有必需的选项设置我们的$.ajax请求:
      • Our url option is configured to our new RESTful resource that was set up locally to handle the client-side registration:

        url: "http://localhost:8080/jqm-webapp/rest/register"

        我们一会儿将看看 RESTful 实现。

      • Next, we set the type option to POST. POST is the recommend type when creating new entities and it is slightly more secure than GET because it does not expose the data attributes as query string parameters on the URL:

        **type:** "POST

      • Again we set the dataType option to jsonp because our RESTful API is also running on a separate domain from our client:

        dataType:``jsonp

      • The jsonp option defines the callback function that will handle the response:

        jsonp: "**jsoncallback**"

        任何处理jsonp请求的 RESTful 资源都必须产生一个 JavaScript 响应。响应实际上是包装在 JavaScript 函数中的 JSON 数据。例如,我们的 RESTful API 的响应将包括成功注册的电子邮件地址,包装在回调函数中。这个回调函数的名称需要设置为我们的jsonp选项的值:

        **jsoncallback**({"email":"BradPitt@gmail.com"})

      • data选项包含我们想要发送给 RESTful 资源的数据。在这种情况下,我们将发送所有表单值,并用 jQuery 的serialize方法:**data:** $**(**"form#register"**).**serialize**(),**对它们进行 URL 编码

      • 最后一个选项是我们的success处理程序。这将在我们收到来自 RESTful API 的成功响应后得到处理。在我们的例子中,我们将用户转发到一个感谢页面,并传递成功注册的电子邮件地址作为数据参数进行确认:success: function( response ) {$.mobile.changePage( “register- thanks.html”, {         data: {"email": response.email}} );    }

    清单 9–5。 使用 Ajax 的客户端 POST(ch9/register . js)

    `KaTeX parse error: Expected 'EOF', got '#' at position 3: (“#̲registrationPag…(“form”).submit(function () {
    **    $.mobile.showPageLoadingMsg();**

    $.ajax({
            url: “http://localhost:8080/jqm-webapp/rest/register”,
            type: “POST”,
    **        dataType:** “jsonp”,
    **        jsonp:** “jsoncallback”,
    **        data:** KaTeX parse error: Expected 'EOF', got '#' at position 11: **(**"form#̲register"**).**….mobile.changePage**( “register-thanks.html”,
                    { data: {“email”: response.email}} );
            }

    return false; // Prevent a form submit
        });
    });`

    注册成功后,用户将被转到一个感谢页面,在这里我们向他们展示他们赢得的奖品以及奖品发送的电子邮件地址(参见图 9–4 及其在清单 9–6 中的相关代码)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–4。 用 Ajax 发布客户端帖子后的感谢页面

    清单 9–6。 用 Ajax 客户端发布后的感谢页面(ch9/register-thanks.html)

    `<div data-role=“page” id="thanksPage" data-theme=“d”>
      


        
            

    Thanks


      


        

    Thanks for registering.  One FREE movie pass was just sent to:   


        
      

    `

    提示:为你的网站设计导航策略时,为用户提供一些导航选项以避免死角是很重要的。在 jQuery Mobile 中,一个简单的解决方案是总是在标题栏中显示主页图标,并通过反向转换将其重定向回主页:

    <a href="home.html" data-icon="home" data-iconpos="notext" data- direction="reverse"></a>

    当我们执行changePage调用时,我们还将电子邮件地址作为数据属性传递给了感谢页面。该数据属性被附加到页面的data-url属性中:

    data-url="/ch9/register-thanks.html?email=BradPitt@gmail.com"

    在感谢页面增强之前,我们获取该电子邮件地址并将其绑定到感谢页面的电子邮件占位符中(参见清单 9–7)。

    清单 9–7。 将邮件附加到感谢页面(ch9/register.js)

    `$(“#thanksPage”).live(“pagebeforecreate”, function(){
    **    var email = getParameterByName(“email”, ( t h i s ) . j q m D a t a ( " u r l " ) ) ; ∗ ∗ ∗ ∗      (this).jqmData("url"));** **     (this).jqmData("url"));    (“.email”).append(email);**
    });

    function getParameterByName(param, url) {
        var match = RegExp(‘[?&]’ + param + ‘=([^&]*)’).exec(url);
        return match && decodeURIComponent(match[1].replace(/+/g, ’ '));
    }`

    服务器端处理注册的 RESTful 实现是用 Jersey 10 实现的,并部署在 Tomcat 11 上(参见清单 9–8)。

    清单 9–8。【com.bmb.jqm.resource.RegisterResourse.java RESTful 资源办理注册

    `@Path(“/register”)
    public class RegisterResource {

    **    @Produces(“application/x-javascript”)**
        public Response register(@QueryParam(“jsoncallback”)
            @DefaultValue(“jsoncallback”) String callback,
            @QueryParam(“email”) String email) {
            Registration registration = new Registration();
            registration.setEmail(email);
            // Save registration…

    // Return registration in response as jsonp
            return Response.status(Response.Status.OK).entity(new
            JSONWithPadding(registration, callback)).build();
        }
    }`


    10[jersey.java.net/](http://jersey.java.net/)

    11[tomcat.apache.org/](http://tomcat.apache.org/)

    在浏览资源时,让我们回顾一下 Jersey 的注释:

    • @Path注释定义了资源负责处理的路径。在这种情况下,RegisterResource 对象将处理发送到“*/rest/register”的所有请求。Jersey 在 web.xml 中配置,有两个配置项需要设置(参见清单 9–9)。首先,我们需要定义部署所有资源的包,其次,我们需要定义应该通过 Jersey 容器发送哪些 URL 模式。我们已经定义了所有 RESTful 资源都在包“com.bmb.jqm.resource”中声明,我们将通过 Jersey 容器路由所有带有“/rest/*”的 URL 路径。
    • @Produces注释定义了我们的响应的 MIME 类型。我们选择跨域公开我们的 RESTful API,这需要资源返回一个 JavaScript 响应。这允许客户端使用jsonp请求访问 API。
    • register 方法接受两个输入参数。第一个是回调函数名。客户端可以发送回调函数的名称,但这不是必需的。如果没有提供,服务器会将回调名称默认为“jsoncallback”。最后一个参数是注册用户的电子邮件地址。
    • 服务器现在可以处理注册并生成响应。在本例中,我们将返回一个响应,其中包含转换为 JSON 并包装在回调函数中的注册对象:jsoncallback({"email":"BradPitt@gmail.com"})

    清单 9–9。 球衣配置(web.xml)

    <servlet>   <servlet-name>Jersey REST Service</servlet-name>   <servlet-class>     com.sun.jersey.spi.container.servlet.ServletContainer   </servlet-class>   <init-param>       <param-name>com.sun.jersey.config.property.packages</param-name> **      <param-value>com.bmb.jqm.resource</param-value>**   </init-param>   <load-on-startup>1</load-on-startup>   </servlet>   <servlet-mapping>       <servlet-name>Jersey REST Service</servlet-name> **      <url-pattern>/rest/*</url-pattern>**   </servlet-mapping>

    正如我们所见,jQuery Mobile 与 RESTful API 集成得非常好。无论我们需要读取还是提交数据,内置的 jQuery 库都提供了在客户端管理 RESTful 生命周期的所有便利功能。

    服务器端与 MVC 的集成

    在这一节中,我们将把注意力集中在服务器端访问策略上。在 Web 上,一个非常常见的策略是集成模型-视图-控制器(MVC)框架。我们将看到两个 MVC 例子,它们在风格上与我们的客户端例子非常相似。在我们的第一个例子中,我们将把客户端注册用例转换成服务器端实现。这个例子将提供一个苹果对苹果的比较,说明如何在 jQuery Mobile 中使用客户端访问策略和服务器端访问策略实现相同的用例。在最后一个例子中,我们将看到如何实现从服务器获取数据的用例。

    使用 MVC 的服务器端表单发布

    为了便于比较,看一下我们的注册用例的服务器端实现是很有价值的。同样,我们将有一个注册表单,允许用户选择接收折扣或免费电影票(见图 9–5)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    **图 9–5。**MVC 服务器端岗位登记表

    我们注册页面的页面标记与客户端示例中显示的非常相似,只是我们不打算覆盖表单提交流程。在我们的服务器端注册示例中,当用户点击注册按钮时,我们将让表单向我们的动作提交请求(参见清单 9–10)。

    清单 9–10。 服务器端集成登记表(/web app/ch9/register-server . html)

    `


        
            

    Register


        


         <form id=“register” action=“/jqm-webapp/mvc/register” method=“post”>
             
             


         
        

    `

    将我们的客户端示例(register-client.html)的注册页面与这个示例(register-server.html)的注册页面进行比较时,有什么突出的地方吗?最显著的区别是这个页面不需要定制 JavaScript。因此,我们的页面标记更加干净。

    当提交表单时,POST 请求将被发送到我们的操作(/jqm-webapp/mvc/register)中定义的路径。这个请求将由部署在 Tomcat 上的 Spring MVC 12 控制器在服务器端处理。在我们的 web.xml 文件中,我们配置了 servlet 映射,因此所有的"/mvc/* " URL 都通过 Spring MVC 的 dispatcher servlet 进行路由(参见清单 9–11)。

    **清单 9–11。**Spring MVC servlet-mapping 配置(/WEB-INF/web.xml)

    <servlet>     <servlet-name>jqm-webapp</servlet-name>     <servlet-class>         org.springframework.web.servlet.DispatcherServlet     </servlet-class>     <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping>     <servlet-name>jqm-webapp</servlet-name> **    <url-pattern>/mvc/*</url-pattern>** </servlet-mapping>

    从用户界面的角度来看,工作流与我们的客户端注册示例相同。表单被提交、处理,然后显示我们的感谢页面。处理请求并将其重定向到感谢页面的控制器代码如清单 9–12 所示。


    12[static.springsource.org/spring/docs/current/spring-frameworkreference/html/mvc.html](http://static.springsource.org/spring/docs/current/spring-frameworkreference/html/mvc.html)

    清单 9–12。??【com.bmb.jqm.controller.RegisterController.java】春天 MVC 注册控制器

    `@Controller()
    public class RegisterController {

    **    @RequestMapping(method = RequestMethod.POST)**
        public String enroll(**@RequestParam(“email”)**String email, HttpSession
            session) {
            // Save registration…

    session.setAttribute(“email”, email);
    **        return “redirect:/mvc/register/thanks”;**
        }

    **    @RequestMapping(method = RequestMethod.GET)**
        public String thanks() {
            return “register-thanks”;
        }
    }`

    让我们在单步调试控制器时回顾一下 Spring MVC 注释:

    • @Controller注释将类定义为可以处理请求的控制器。Spring MVC 配置了路径到类名的映射。例如,所有的"/register/"请求将被分派给 RegisterController。这个配置是在 Spring MVC 的 dispatcher servlet 中设置的(参见清单 9–13)。
    • @RequestMapping注释定义了处理 POST 和 GET 请求的方法。当提交表单时,POST 请求将被发送到enroll方法。thanks方法将处理所有的 GET 请求。例如,我们在处理完表单后重定向到感谢页面,当感谢页面刷新时会触发thanks方法。
    • @RequestParam注释将表单上提交的电子邮件地址绑定到我们的电子邮件输入参数。当调用 enroll 方法时,我们保存注册,将电子邮件地址置于会话中,并重定向到感谢页面(/jsp/register-thanks.jsp)。

    清单 9–13。 Spring MVC 路径到控制器映射配置(/we b-INF/jqm-WEB app-servlet . XML)

    <!-- Enable controller mapping by convention. For example: /foo/* will map to FooController() --> <bean class="org.springframework.web.servlet.mvc.support.**ControllerClassNameHandlerMapping**" />

    感谢页面的外观将与我们的客户端示例相同(参见 Figure 9–6)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–6。 服务器端发布后的感谢页面用 MVC

    唯一的区别在于页面是如何生成的。该页面在服务器端生成为 JSP,电子邮件地址与 JSTL 表达式语法绑定在一起(参见清单 9–14)。动态生成页面不需要 JavaScript,与我们在客户端示例中看到的动态生成的感谢页面相比,这个标记更加简洁。

    清单 9–14。 服务器端注册后的感谢页面(/jsp/register-thanks.jsp)

    `


        
            

    Thank You


        


            

    Thanks for registering.  One FREE movie pass was just sent to:    
              


              
        

    `

    提交表单后需要注意的一个重要事项是,jQuery Mobile 管理浏览器地址栏中显示的 URL。例如,在服务器重定向到“/mvc/register/thanks之后,浏览器 URL 仍然显示我们动作的路径(/jqm-webapp/mvc/register)。如果您还没有为该路径实现 GET 请求处理程序,那么“感谢”页面上的“刷新”将导致 404,not found 错误。您有两种选择来处理这个问题:

    • 最简单的解决方案是在控制器上为动作路径实现一个 GET 请求处理程序。我们的RegisterController#thanks方法处理 GET 请求,并将简单地刷新感谢页面,重新显示会话中存储的电子邮件地址(参见清单 9–12)。此外,在网上提交表单时,建议先发布,然后重定向,以避免任何重复提交的问题。

    • Alternatively, you may manually set the data-url attribute on the page container. The value of the data-url attribute will be shown in the browser’s location bar. This also gives developers more flexibility when constructing semantic paths: data-url="/manually/set/url/path/”

      这种策略也可以用来隐藏文件名。例如,如果您转到“/my/movies/index.html”,您可以将页面的data-url属性更新为”/my/movies/”,这将隐藏 index.html 部分,使其不显示。

    使用 MVC 的服务器端数据访问

    在前面的例子中,我们看到了如何将表单数据发送到服务器。在这个例子中,我们将使用 GET 请求从服务器获取数据。这个例子将从服务器获取电影列表,并在 jQuery Mobile JSP 页面中显示结果(参见 Figure 9–7)。

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–7。 从服务器端 MVC 访问中获取的电影

    在服务器端,我们有一个 Spring MVC 控制器设置来处理以下 href 上的 GET 请求:

    <a href="**/jqm-webapp/mvc/movies**" data-role=”button”>Movies</a>

    当按钮被点击时,一个 GET 请求将被触发并发送给我们的 MoviesController。MoviesController 将检索我们的电影数据,并将响应转发给电影 JSP 页面(参见清单 9–15)。

    清单 9–15。【com.bmb.jqm.MoviesController.java】MVC 控制器获取电影数据

    `@Controller()
    public class MoviesController {

    **    @RequestMapping(method = RequestMethod.GET)**
        public String getMovies(ModelMap model) {
            model.addAttribute(“movies”, getMovieData());
            return “movies”;
        }
    }`

    响应将被转发到电影页面,JSP 将迭代电影列表,为每个结果显示一个单独的列表项(参见清单 9–16)。

    清单 9–16。 JSP 显示电影数据(/jsp/movies.jsp)

    `


        

    • **        <c:forEach var=“movie” items=" KaTeX parse error: Expected 'EOF', got '#' at position 49: …      <a href="#̲">             …{movie.image} " />
                      

      m o v i e . t i t l e ∗ ∗ < / h 3 >                  < p > R a t e d : ∗ ∗ {movie.title}**</h3>                 <p>Rated: ** movie.title</h3>                <p>Rated:{movie.rating}


                    

    Runtime: ${movie.runtime} min.


                
            
    **        </c:forEach>
         `

    这种服务器端解决方案的一个优点是页面标记的简单性。没有 JavaScript 的动态页面生成、字符串连接或 jQuery 选择器的动态字段绑定,我们在前面的客户端示例中已经看到了。

    服务器端与客户端

    决定实施哪种服务访问策略取决于几个因素。如果您现在已经在构建 Web 应用,那么您可能已经有了一个在 Web 上访问数据的既定模式。如果是这样,出于一致性目的,您可能希望继续使用这种策略。幸运的是,当正确实现时,jQuery Mobile 将与这两种策略很好地集成,最终您可以共同选择最适合您特定应用需求的模式。以下是每种策略的支持性注意事项:

    客户端集成:

    • Faster response times. Client-side integrations produce faster response times because they have fewer point-to-point server dependencies. For instance, we could have aggregated our Twitter data on the server-side but our response times would have decreased due to the additional server communication.

      **注意:**虽然客户端集成提供了更快的响应时间,但在与第三方 API 集成时要小心,因为在服务器端封装它们有利于更好地将您自己的页面与第三方修改隔离开来。例如,脸书的 RESTful API 在过去经常改变,现在它实际上被否决了。

    • 更快地实现。我们在客户端的 Twitter 例子是一个非常快速的实现,因为只有我们的客户端标记需要修改。在服务器端实现这项任务需要修改客户端和服务器端组件。

    服务器端集成:

    • 比较靠谱。服务器端解决方案比客户端解决方案更可靠,因为您不必担心客户端 JavaScript 的不兼容性。
    • 更安全。当实现客户端解决方案时,您必须小心暴露的 API 和数据类型。如果您正在与暴露个人身份信息(PII)、个人健康信息(PHI)或支付卡行业(PCI)信息的 API 集成,客户端解决方案将是不可取的。
    • 更清晰的页面标记。在比较使用服务器端和客户端访问策略实现的页面时,我们看到了这样的例子。我们的服务器端访问示例中使用的页面不依赖于定制的 JavaScript。
    • 更简单的组件单元测试。我相信服务器端单元测试仍然比客户端单元测试简单。然而,在对 jQuery Mobile 项目进行了几次 QUnit 测试之后,我开始相信客户端单元测试可以非常成功和可靠!

    谷歌地图整合

    在最近的一项移动 Web 调查中,近 75%的 Web 开发人员使用地理定位,使其成为最受欢迎的 HTML5 API。 13 在构建位置感知应用时,通常会有一个显示兴趣点或方向的地图视图。在网络上,地理定位 14 结合谷歌地图 15 为构建地图功能提供了非常有用的 API。在这一节中,我们将了解 jQuery Mobile 与地理定位和谷歌地图的集成情况。首先,我们将创建一个示例,在地图上标出您的当前位置(参见图 9–8)。


    13 见www . webdirections . org/somw 2011/

    14 见【http://dev.w3.org/geo/api/spec-source.html】的。

    15code . Google . com/APIs/maps/documentation/JavaScript/basics . html

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 9–8。 谷歌地图与 jQuery Mobile 整合

    页面中的标记很少,因为我们只需要为地图创建内容容器(参见清单 9–17)。

    清单 9–17。 用于谷歌地图集成的 jQuery Mobile 页面标记(ch9/maps.html)

    `

                Google Maps                ** ` `

    <div data-role=“content” id=“map-canvas”>
            
        

    `

    当与谷歌地图集成时,有几个附加功能是必需的:

    1. 首先,我们需要设置页面和地图容器的样式,使其全屏显示:**#map-page, #map-canvas { width: 100%; height: 100%; padding: 0; }**
    2. 接下来,我们导入定制的 JavaScript 来帮助确定用户的地理位置并绘制地图视图。我们很快就会看到这个文件的细节:**<script type="text/javascript" src="maps.js"></script>**
    3. 然后,我们导入 Google Maps API: **<script src="http://maps.google.com/maps/api/jssensor=false">**
    4. 最后,我们确定我们的地图容器。我们的地图将在这个元素内绘制:<div data-role="content" **id="map-canvas"**>

    帮助确定用户地理位置和绘制地图视图的定制 JavaScript 如清单 9–18 所示。

    清单 9–18。 用于谷歌地图集成的 JavaScript(ch9/Maps . js)

    `$( “#map-page” ).live( “pageinit”, function() {

    *   // Default to Hollywood, CA when no geolocation support*
        var defaultLatLng = new google.maps.LatLng(34.0983425**,** -118.3267434);

    if ( navigator.geolocation ) {
            function success(pos) {
     *           // Location found, show coordinates on map*
                drawMap(new google.maps.LatLng(
                   pos.coords.latitude, pos.coords.longitude));
            }

    function fail() {
                drawMap(defaultLatLng);  // Show default map
            }

    *       // Find users current position*
    **        navigator.geolocation.getCurrentPosition**(success, fail,
                {enableHighAccuracy:true, timeout: 6000, maximumAge: 500000});     } else {
            drawMap(defaultLatLng); // No geolocation support
        }

    function drawMap(latlng) {
            var myOptions = {
                zoom: 10,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

    var map = new google.maps.Map(
                document.getElementById(“map-canvas”), myOptions);

    *       // Add an overlay to the map of current lat/lng*
            var marker = new google.maps.Marker({
                position: latlng,
                map: map,
                title: “Greetings!”
            });
        }
    });`

    当地图页面处于“就绪”状态时,我们将执行以下步骤来绘制地图视图:

    1. 首先,我们确定浏览器是否支持地理定位:if ( **navigator.geolocation** ) {

    2. If the browser supports Geolocation we will attempt to retrieve the users current position: navigator.geolocation.getCurrentPosition(success, fail,

      { enablehigaccuracy:true,timeout: 6000,maximumAge:500000 });

      getCurrentPosition API 最多可以接受三个参数。第一个参数是成功回调。这是唯一必需的参数。下一个参数是错误回调,最后一个参数是我们的可配置选项。我们已经将地理位置查找配置为使用高精度。如果支持,这将尝试使用 GPS 定位。我们还将超时设置为 6 秒。如果我们在 6 秒后没有找到用户的位置,我们的错误回调将被调用。最后,我们已经配置了查找可以使用缓存的位置,如果它不到 5 分钟。

    3. 当找到一个成功的位置时,将调用成功回调。在这种情况下,我们将使用位置坐标:function **success**(pos) {     **drawMap**(new google.maps.LatLng(         pos.coords.latitude, pos.coords.longitude))     }来绘制地图

    4. 最后,drawMap方法将绘制一张 Google 地图,在地图中心被标识为您所在位置的位置显示一个覆盖图标。但是,如果不支持地理定位或者没有建立位置,加利福尼亚州好莱坞将显示为默认位置(参见清单 9–18)。

    总结

    在本章中,我们看到了如何将 jQuery Mobile 与客户端和服务器端的数据访问策略相集成。jQuery Mobile 很好地集成了这两种策略,允许您选择最适合您的应用需求的访问方法。虽然客户端策略提供了更好的性能,并且可以更快地实现,但它可能不如服务器端策略可靠、安全或可维护。

    最后,我们看到了一个如何将 jQuery Mobile 与地理定位和 Google Maps 集成的例子。有了这两个 mapping API,我们现在能够将地图视图添加到 jQuery Mobile 应用中。

    在第十章中,我们将看看如何利用现有的 jQuery Mobile 应用,并通过 PhoneGap 在本地发布它们。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16501.html
标签
VKDoc
评论
发布的文章

HTML5入门基础

2024-06-16 09:06:50

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!