mobilebone
Version:
Bone main for mobile web APP with a sigle page mode by using HTML5 history API router.
161 lines (140 loc) • 10 kB
HTML
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<meta name="description" content="Mobilebone.js 使用教程-中文版-事件" />
<meta name="keywords" content="Mobilebone.js, Mobilebone, 路由, javascript, 使用教程, 事件" />
<meta name="author" content="张鑫旭, zhangxinxu" />
<link rel="icon" href="../assets/favicon.ico">
<title>Mobilebone.js使用教程-事件</title>
<link rel="stylesheet" href="../../src/mobilebone.css">
<link rel="stylesheet" href="../assets/docs.css">
</head>
<body>
<header id="header"></header>
<aside id="aside"></aside>
<div class="page out">
<div class="content">
<h2>事件</h2>
<p>先了解 Mobilebone 中与页面生命周期相关的事件。</p>
<h3>生命周期</h3>
<p>Mobilebone 中,页面从进入到离开为一个完整的生命周期。</p>
<p>整个生命周期过程如下图所示,Mobilebone 在生命周期的各个阶段都暴露了接口可以让开发者自定义事件。</p>
<p style="background-color: #fff; padding:20px; text-align:center;">
<img src="../assets/mobilebone-lifecircle.svg" width="641" height="1160" alt="Mobilebone生命周期中的事件">
</p>
<p>其中:</p>
<ul>
<li><code>preventdefault</code> 事件在进入和离开之前都会执行;</li>
<li><code>onpagefirstinto</code> 事件只会在第1次进入的时候执行;</li>
<li><code>callback</code> 事件每次页面进入的时候执行;</li>
<li><code>fallback</code> 事件每次页面离开的时候执行;</li>
<li><code>animationstart</code> 事件在进入和离开动画执行前都会执行;</li>
<li><code>onpagefirstinto</code> 事件在进入和离开动画执行后都会执行。</li>
</ul>
<h3>设置</h3>
<p>Mobilebone 中生命周期事件分全局事件和局部事件。</p>
<ul>
<li><p>全局事件使用 Mobilebone 对象直接指定,例如希望所有页面进入的时候都执行,可以这样设置:</p>
<pre>Mobilebone.callback = function () {
console.log('每次页面进入都执行');
};</pre></li>
<li><p>局部事件则通过 <code>data-*</code> 的语法在页面容器元素上设置,例如:</p>
<pre><div class="page out" data-callback="someFuncName">
<p>页面内容</p>
</div></pre>
<p>表示该页面进入的时候会执行函数名为<code>someFuncName</code>的方法。</p></li>
</ul>
<p>默认状态下,对于局部事件,Mobilebone 会在 <code>window</code> 对象中寻找对应名称的函数并执行。例如,<code>data-callback="someFuncName"</code> 设置后 Mobilebone 会执行 <code>window.someFuncName()</code>。</p>
<p>然而,在 JavaScript 中,全局对象是容易产生冲突的,因此显然,函数挂载到 <code>window</code> 对象中并不适合复杂的项目,Mobilebone 是支持指定事件函数挂载的对象的,同样也分全局设置和局部设置。</p>
<ul>
<li>
<p>全局设置通过 <a href="../api/#&Mobilebone.rootTransition.html" class="link" target="_blank" data-ajax="false">Mobilebone.rootTransition</a> 属性进行设置。</p>
<p>例如有个 Vue 实例对象 <code>myVue</code>:</p>
<pre>var myVue = new Vue({
methods: {
someFuncName () {}
}
});</pre>
<p>则下面的设置就可以让 Mobilebone 调用 Vue 实例对象中的方法:</p>
<pre>Mobilebone.rootTransition = myVue;</pre>
</li>
<li>
<p>局部设置通过 <code>data-root</code> 属性进行设置,例如:</p>
<pre><div class="page out" data-root="$" data-callback="callback"></div></pre>
<p>则当前页面的 <code>callback</code> 方法会在 <code>window.$</code> 中寻找并执行,此设置不会影响其他页面。</p>
</li>
</ul>
<h3>事件中的参数</h3>
<p>每个生命周期事件都暴露了若干参数,例如:</p>
<ul>
<li>onpagefirstinto(pageInto, pageOut, options)</li>
<li>callback(pageInto, pageOut, options)</li>
<li>fallback(pageInto, pageOut, options)</li>
<li>animationstart(page, intoOrOut, options)</li>
<li>animationend(page, intoOrOut, options)</li>
<li>preventdefault(pageInto, pageOut, options)</li>
</ul>
<p>这些参数的作用是让开发者知道当前移入移出的页面是哪个,以及页面间传递的参数是什么(通过 <code>options.query</code> 获取)。</p>
<p>至于各个参数的含义和作用可以参考对应的 API 文档:<a href="../api/#&data-callbackKeys.html" class="link" target="_blank" data-ajax="false">data-callbackKeys.html</a></p>
<h3>内置的事件</h3>
<p>Mobilebone 对页面中所有的 <code><a></code> 元素默认的 <code>'click'</code>事件行为 和 <code><form></code> 元素的默认的 <code>'submit'</code> 事件行为进行了劫持。</p>
<p>例如:</p>
<ul>
<li>点击 <code><a href="#targetPage"></code> 不再是锚点跳转,而是显示页面中 <code>id</code> 属性值是 <code>'targetPage'</code> 的页面元素。</li>
<li>点击 <code><a href="target.html"></code> 不再是跳转到 <code>target.html</code> 页面,而是自动拉取 <code>target.html</code> 页面内容并作为一个内嵌的页面显示。</li>
<li>提交 <code><form action="/someUrl"></code> 不再是传统的带刷新的表单提交,而是会把当前表单请求返回的内容作为一个内嵌的页面显示。</li>
</ul>
<p>如果希望 <code><a></code> 元素和 <code><form></code> 元素保留默认的行为,可以在这些元素上设置 <code>data-ajax="false"</code>,例如:</p>
<pre><a href="target.html" data-ajax="false">传统的页面跳转</a></pre>
<p>如果希望<code><a></code> 元素或者 <code><form></code> 元素在执行无刷新过场之前进行其他的逻辑判断处理,则可以使用 <code>data-preventdefault</code> 进行处理,代码示意:</p>
<pre><a href="login.html" data-preventdefault="isDialogLogin">登录</a></pre>
<pre>let isDialogLogin = function () {
<span class="comment">// 大屏下使用弹框执行登录</span>
if (screen.width > 800) {
<span class="comment">// 登录弹框显示</span>
loginDialog.show();
<span class="comment">// 返回 true 表示阻止 Mobilebone 的事件处理行为</span>
return true;
}
};</pre>
<p>相关API详见这里:<a href="../api/#&data-ajax.html" class="link" target="_api" data-ajax="false">data-ajax</a>、<a href="../api/#&data-preventDefault.html" class="link" target="_blank" data-ajax="false">data-preventdefault</a>。</p>
<h3>页面代码的执行</h3>
<p>在 Mobilebone 项目中,入口页面的事件就和普通的网页一样执行的,无论是内联 JavaScript 代码,还是 <code>src</code> 地址外链的 JavaScript 代码。</p>
<p>但是,如果是通过 Ajax 请求拉取的请求页,则这些页面中的 JavaScript 代码默认是不执行的,原因在于避免冗余执行。</p>
<p>例如,列表页有20个详情页链接,如果每次请求一个详情页,里面的 JavaScript 代码都全部执行一遍,则会产生大量的重复的 JavaScript 代码执行,这是没有必要的。</p>
<p>在Mobilebone 项目中,更推荐所有页面共用一个主 JavaScript 文件代码,也就是在这个 JavaScript 文件中处理所有的逻辑关系。如果项目比较复杂,可以分页面或模块开发,然后发布的时候合并成一个独立的 JavaScript 文件作为主文件即可。</p>
<p>当然,Mobilebone 提供了执行请求的页面中的 JavaScript 代码的能力,设置 <a href="../api/#&Mobilebone.evalScript.html" class="link" target="_api" data-ajax="false">Mobilebone.evalScript</a> 的值为 <code>true</code>就可以了。</p>
<pre>Mobilebone.evalScript = true;</pre>
<p>但是需要注意的是,设置 <code>Mobilebone.evalScript</code> 为 <code>true</code> 只会执行内联的 <code><script></code> 脚本,例如下面的代码会执行:</p>
<pre><script>console.log('script excuted!');</script></pre>
<p>但是下面的 <code>1.js</code> 就不会执行:</p>
<pre><script src="1.js"></script></pre>
<hr>
<p>发现错误?想参与编辑?在 <a href="https://github.com/zhangxinxu/mobilebone/blob/master/docs/guide/install.html" class="link" target="_github" rel="nooppener">GitHub 上编辑此页</a>!</p>
</div>
</div>
<script src="nav.js"></script>
<script src="../../src/mobilebone.js"></script>
<script>
Mobilebone.captureLink = false;
window.navKey = "install";
</script>
<script src="../assets/docs.js"></script>
<!-- ga统计 -->
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-11205167-1']);
_gaq.push(['_trackPageview']);
(function() {
if (location.host == 'www.zhangxinxu.com') {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
}
})();
</script>
</body>
</html>