1. 引言
jQuery Mobile 是一套基于 HTML5 的移动端 UI 框架,它最大的特点之一就是采用「页面(Page)」作为组织内容的基本单位。在单页应用中,多个页面通过 Ajax 加载和切换,而这一过程伴随着一系列生命周期事件。理解这些页面事件,是掌握 jQuery Mobile 页面导航、数据初始化和动态内容加载的关键。
本文将系统梳理 jQuery Mobile 的页面事件体系,包括页面初始化事件、页面切换事件、页面容器事件,并结合丰富的代码实例演示每个事件的触发时机和典型用法。
2. 页面事件概览
jQuery Mobile 的页面事件主要分为三大类:
- 页面初始化事件:
pagebeforecreate、pagecreate、pageinit,在页面首次创建时依次触发。 - 页面切换事件:
pagebeforeshow、pageshow、pagebeforehide、pagehide,在页面显示和隐藏时触发。 - 页面容器事件:
pagecontainerbeforetransition、pagecontainerchange等,作用于整个页面容器。
下面这张表汇总了常用页面事件及其触发时机:
| 事件名称 | 触发时机 | 典型用途 |
|---|---|---|
| pagebeforecreate | 页面即将创建、尚未初始化组件时 | 在框架增强前修改页面 DOM |
| pagecreate | 页面已创建,组件增强完成前 | 绑定自定义事件、初始化第三方插件 |
| pageinit | 页面初始化完成,组件增强结束后 | 执行页面级初始化逻辑 |
| pagebeforeshow | 页面即将显示(切换动画开始前) | 动态更新页面数据 |
| pageshow | 页面显示完成(切换动画结束后) | 统计曝光、启动轮播等 |
| pagebeforehide | 当前页面即将隐藏时 | 暂停视频、保存表单状态 |
| pagehide | 当前页面隐藏完成后 | 清理定时器、释放资源 |
3. 页面初始化事件
页面初始化事件在页面第一次被创建时触发,是绑定页面级逻辑的最佳时机。下面通过一个完整示例演示三个初始化事件的触发顺序。
3.1 基础示例:观察初始化顺序
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>页面初始化事件演示</title> <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> </head> <body> <div><div><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>页面切换事件演示</title> <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> </head> <body> <!-- 页面 A --> <div>pagebeforehide: 页面 A 即将隐藏 pagebeforeshow: 页面 B 即将显示 pageshow: 页面 B 显示完成 pagehide: 页面 A 已隐藏4.2 在 pagebeforeshow 中动态加载数据
pagebeforeshow是动态更新页面内容的推荐位置,因为此时页面尚未显示,用户不会看到数据刷新的过程。
<div><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>页面容器事件演示</title> <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> </head> <body> <div><div><script> // 推荐:事件委托 $(document).on("pageinit", "#dynamicPage", function () { console.log("动态页面初始化完成"); }); // 不推荐:直接绑定,动态加载的页面可能无法触发 // $("#dynamicPage").on("pageinit", function () { // console.log("可能不会触发"); // }); </script>6.2 区分 pageinit 与 pageshow
pageinit只在页面首次创建时触发一次,而pageshow每次页面显示时都会触发。如果需要在每次进入页面时刷新数据,应使用pageshow或pagebeforeshow。
<script> var initCount = 0; var showCount = 0; $(document).on("pageinit", "#counterPage", function () { initCount++; console.log("pageinit 触发次数:" + initCount); }); $(document).on("pageshow", "#counterPage", function () { showCount++; console.log("pageshow 触发次数:" + showCount); }); </script>6.3 避免重复绑定
当页面被反复访问时,如果事件绑定代码在pageshow中执行,会导致事件重复绑定。应将一次性绑定逻辑放在pageinit或pagecreate中。
<script> $(document).on("pageinit", "#repeatPage", function () { // 只绑定一次,避免重复 $("#refreshBtn").off("click").on("click", function () { loadData(); }); }); </script>7. 综合实战:待办事项应用
下面结合本文介绍的所有知识点,实现一个完整的待办事项应用,包含页面初始化、页面切换和动态数据加载。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>待办事项应用</title> <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> </head> <body> <!-- 列表页 --> <div data-role="page" id="listPage"> <div data-role="header"> <h1>待办事项</h1> </div> <div data-role="content"> <ul id="todoList" data-role="listview" data-inset="true"></ul> <a href="#addPage" class="ui-btn ui-btn-icon-left ui-icon-plus">新增待办</a> </div> </div> <!-- 新增页 --> <div data-role="page" id="addPage"> <div data-role="header"> <h1>新增待办</h1> </div> <div data-role="content"> <form id="addForm"> <label for="todoTitle">事项内容:</label> <input type="text" id="todoTitle" placeholder="请输入待办事项"> <button type="submit" class="ui-btn">保存</button> </form> </div> </div> <script> var todos = []; // 列表页初始化:绑定事件 $(document).on("pageinit", "#listPage", function () { $("#addForm").on("submit", function (e) { e.preventDefault(); var title = $("#todoTitle").val().trim(); if (title) { todos.push(title); $("#todoTitle").val(""); $.mobile.pageContainer.pagecontainer("change", "#listPage", { transition: "slide", reverse: true }); } }); }); // 列表页每次显示时刷新数据 $(document).on("pagebeforeshow", "#listPage", function () { var list = $("#todoList").empty(); if (todos.length === 0) { list.append("<li>暂无待办事项</li>"); } else { $.each(todos, function (index, item) { list.append("<li>" + item + "</li>"); }); } list.listview("refresh"); }); // 新增页显示时清空输入框 $(document).on("pagebeforeshow", "#addPage", function () { $("#todoTitle").val(""); }); // 全局页面切换日志 $(document).on("pagecontainerchange", function (event, ui) { console.log("当前页面:" + ui.toPage[0].id); }); </script> </body> </html>8. 总结
jQuery Mobile 的页面事件体系围绕页面生命周期展开,掌握它们能够帮助开发者更好地控制页面初始化、数据加载和资源释放。以下是本文的核心要点:
- 初始化事件:
pagebeforecreate、pagecreate、pageinit依次触发,适合完成页面级初始化逻辑。 - 切换事件:
pagebeforeshow、pageshow、pagebeforehide、pagehide在页面显示和隐藏时触发,适合动态更新数据和清理资源。 - 容器事件:
pagecontainerbeforetransition、pagecontainerchange作用于全局页面切换过程。 - 绑定方式:推荐使用事件委托,将事件绑定在
document上,避免动态加载页面无法触发事件。 - 触发次数:
pageinit只触发一次,pageshow每次显示都会触发,根据需求选择合适的事件。
在实际项目中,建议将页面初始化逻辑放在pageinit中,将每次进入页面需要刷新的数据放在pagebeforeshow中,将资源清理逻辑放在pagehide中,这样既能保证性能,又能确保页面状态始终正确。