MIP 事件绑定
事件绑定语法说明
MIP 提供了 on
属性来定义对组件的事件绑定与事件触发时的行为。
您已通过 MIP.scrollTo() 方法滚动到底部,请点击下方按钮返回原示例
单事件绑定语法
on
属性的语法格式如下所示:
<TAGNAME
on="eventName:targetId.actionName(args)"
>
</TAGNAME>
相关参数的说明如下表所示:
参数名 | 是否必须 | 描述 |
---|---|---|
eventName | 是 | 组件抛出的事件名 |
targetId | 是 | 要触发行为的组件元素 id,或者是特殊对象 MIP |
actionName | 是 | 对应组件元素或对象所暴露的行为方法 |
args | 否 | 行为方法的参数,参数为空时可以不写 |
下面的这些都是合法的 on
表达式:
<!-- 定义一个 id 为 header-element 的元素 -->
<div hidden></div>
<!-- 触发 header-element 的显示 -->
<div on="tap:header-element.show()">点我</div>
<!-- 当方法不存在参数时,也可以将括号省略不写 -->
<div on="tap:header-element.show">点我</div>
<!-- 调用 MIP 特殊对象上的方法 -->
<div on="tap:MIP.setData({ a: 1 + 2 })"></div>
<div on="tap:MIP.navigateTo({ url: 'https://www.baidu.com', target: '_blank' })">
多事件绑定与多行为触发
on
语法支持监听多个事件,以及触发多个行为。其中多个事件通过 ;
进行分隔,单个事件的多个行为之间通过 ,
分隔。例如:
<input
on="
tap:
input-element.scrollTo({ duration: 500, position: 'center' }),
MIP.setData({ clicked: clicked + 1 });
change:
MIP.setData({ value: event.value })
">
为了使得过长的 on 表达式更易于阅读,在分隔符前后允许存在换行符和空格进行表达式分段操作。
注意: 定义在同一个事件下面的多个行为当中,只允许存在 1 个 MIP.setData()
方法,以免造成数据执行顺序的混乱。
支持的事件
MIP 提供的事件包括两类:全局事件和组件事件。其中全局事件由 MIP 核心提供,比如点击、输入等通用事件;组件事件则是由 MIP 组件自身实现和触发的自定义事件,具体的组件事件需要到对应的组件文档当中阅读 事件
一栏。
抛出的事件可能会携带数据,这些数据信息可以通过 event.xxx
表达式获取,比如 <input>
input-throttled
事件,可以通过 event.value
获取当前输入框的输入信息:
<!-- 监听 input-throttled 事件,并将输入框结果写入 text -->
<input type="text" on="input-throttled:MIP.setData({ text: event.value })">
<!-- 将 text 绑定到 p 标签上将输入结果 -->
<!-- m-text 绑定语法更详细的说明将在数据绑定章节进行详细说明 -->
<p m-text="text"></p>
其效果如下所示:
全局事件
事件名 | 描述 | 元素 | 数据 |
---|---|---|---|
tap | 使用 touch 事件实现的点击触发事件。较原生 click 事件有更快的响应速度。 | 任何 HTML 元素(包括原生 HTML 和 MIP 组件) | 无 |
click | 原生点击触发。 由于 click 事件在 iOS 下存在明显延迟,因此移动 MIP 页请优先使用 tap 事件。 | 任何 HTML 元素(包括原生 HTML 和 MIP 组件) | 无 |
change | 元素 value 改变并提交时触发 | 表单元素,包括 input、textarea、select | event.value |
input-debounced | 输入防抖,元素 value 改变 300ms 后触发,300ms 内存在任何 value 的改变都将重新计时 | 表单元素,包括 input、textarea、select | event.value |
input-throttled | 输入截流,元素 value 改变时每 100ms 最多触发一次 | 表单元素,包括 input、textarea、select | event.value |
组件事件
组件事件是 MIP 组件自身实现和触发的自定义事件,是全局事件的扩展和补充。具体的事件可以阅读具体的 MIP 组件文档当中的 事件
小节。
在这里列举出个别比较有意思的组件事件供大家参考:
mip-date-countdown
倒计时组件,提供定时触发事件 timeout
:
<!-- 3000ms 后触发定时事件-->
<mip-date-countdown
timeleft-ms="3000"
when-ended="stop"
on="timeout:toast.hide"
>
<template type="mip-mustache">
<div>{{ss}} {{seconds}}</div>
</template>
</mip-date-countdown>
<!-- 3000ms 后触发 toast 的隐藏 -->
<span>欢迎欢迎热烈欢迎!</span>
mip-position-observer
位置监听组件,用于用户滑动屏幕过程中监听元素的位置信息,发出 enter
、exit
、scroll
事件。
<mip-position-observer
layout="nodisplay"
on="
enter:toast-element.show;
exit:toast-element.hide
"
></mip-position-observer>
<div>欢迎欢迎热烈欢迎!</div>
触发行为
在监听到事件的触发后所执行的方法就是行为,与事件类似,分为以下 3 类:
- 全局元素方法:任何元素(HTML 原生元素或 MIP 元素)都默认提供的方法,如
show
、hide
等等; - 特殊对象方法:
MIP.xxx
所提供的方法,如MIP.navigateTo
、MIP.setData
等等; - 组件自定义方法:需阅读 MIP 组件文档对应的
行为
或方法
模块;
提示: 这些方法根据各自的实现不同,对参数的要求和形式会存在一些差别,因此在开发的时候需要仔细阅读对应方法的文档说明。
全局元素方法
MIP 为所有元素(包括普通 HTML 和 MIP 元素)都提供了一些默认方法,这样开发者就能够在 on
表达式当中去执行他们。
行为 | 描述 |
---|---|
hide | 隐藏元素。 如: element-id.hide |
show | 显示元素。 如: element-id.show |
toggleVisibility | 切换显示和隐藏元素。 |
toggleClass({ class: STRING, force: BOOLEAN }) | 切换元素类名。 参数 force 可选,如果为 true,则只添加类名。如果为 false,则只移除类名。如: element-id.toggleClass({class: 'active'}) |
scrollTo({ duration: INTEGER, position: STRING }) | 视口滚动到元素所在位置。 参数 duration 可选,用于指定动画时间,单位 ms,默认是 0。参数 position 可选,只可取 top ,center 或者 bottom ,用于指定滚动后元素在视口的位置,默认是 top 。如: element-id.scrollTo({duration: 500, position: 'center'}) |
focus | 让元素获得焦点。 如: element-id.focus |
注意: 当 MIP 组件自定义方法与全局元素方法重名的情况下,比如 mip-toggle 具有自定义行为 show
和 hide
,此时优先触发组件的自定义方法。
提示: 在参数写法上,我们兼容了 AMP 的语法,因此也可以使用类似 AMP 的书写方式传入参数:element-id.toggleClass(class='active', force=false)
下面是全局元素方法的一些例子:
隐藏或显示元素
需要注意的是,show
只能显示被 hide
和 toggleVisibility
行为隐藏的元素,或者是使用 hidden
属性隐藏的元素。如果当前元素是通过 class 添加的 display: none
,请采用 toggleClass
移除节点相关 class。
<!-- 点击显示添加了 hidden 属性的元素-->
<button on="tap:text1.show">显示文字1</button>
<!-- 点击隐藏 -->
<button on="tap:text1.hide">隐藏文字1</button>
<!-- 点击切换元素的隐藏和显示 -->
<button on="tap:text1.toggleVisibility">切换文字1的隐藏和显示</button>
<p hidden>文字1</p>
效果如下所示:
文字1
添加或移除 class
<!-- 无法通过 text2.show 方法显示通过 display: none 定义样式的元素 -->
<button on="tap:text2.show">无法显示文字</button>
<!-- 通过 toggleClass 添加或移除 .hide 实现元素的隐藏或显示 -->
<button on="tap:text2.toggleClass({class: 'hide'})">添加/移除 hidden class</button>
<!-- .hide { display: none; } -->
<p class="hide">文字2</p>
效果如下所示:
文字2
滚动到具体元素
<!-- 点击滚动到页面底部 -->
<button on="tap:bootm-button.scrollTo({ duration: 500, position: 'center' })">点击滚动到底部</button>
效果如下所示:
获取焦点
<!-- 点击使 a 链获得焦点 -->
<button on="tap:a-link.focus">点击按钮,使下方 a 链获得焦点</button>
<a href="https://www.mipengine.org"><p>#a-link:focus p { color: red; } </p></a>
效果如下所示:
#a-link:focus p { color: red; }
特殊对象方法
前面提到 targetId 可以传入特殊对象 MIP。在 on
语法中,MIP 对象暴露了如下行为。
行为 | 描述 |
---|---|
setData({ [name]: Expression }) | 将数据合并到到全局状态树中,结合数据绑定,写入数据时允许写有限的计算表达式进行运算。 更多内容请参考数据绑定 如: MIP.setData({ a: 1 + 1, b: 'hello' }) |
navigateTo({ url: STRING, target: STRING, opener: BOOLEAN }) | 跳转到指定 url 页面。参数 url 为必填参数,要跳转到的目标页面 URL参数 target 为必填参数,只可取 _top 或 _blank 。opener 为可选参数,用于指定在 target=_blank 时新打开的页面能否访问到 window.opener 。如: MIP.navigateTo({ url: 'https://www.baidu.com', target: '_blank' }) |
closeOrNavigateTo({ url: STRING, target: STRING, opener: BOOLEAN }) | 关闭当前页面,如果失败则如 navigateTo 跳转。一般用作新打开页面的后退操作。参数说明与示例用法同上。 |
scrollTo({ id: STRING, duration: INTEGER, position: STRING }) | 视口滚动到 id 元素的位置,类似于全局元素方法 element-id.scrollTo 。参数 id 为必填参数,用于指定要滚动到的元素参数 duration 为可选参数参数 position 为可选参数。 |
goBack | 返回上一个页面,效果等同于 window.history.back() 如: MIP.goBack |
打开当前页面的打印对话框 如: MIP.print |
提示: 在参数写法上,我们兼容了 AMP 的语法,因此也可以使用类似 AMP 的书写方式传入参数:MIP.navigateTo(url='https://www.baidu.com', target='_blank')
下面是一些 MIP 方法的一些使用示例:
MIP.setData
这个例子演示了通过 setData 完成对按钮点击次数的记录:
<mip-data>
<script type="application/json">
{
"count": 0
}
</script>
</mip-data>
<button on="tap:MIP.setData({ count: count + 1 })">点击次数 + 1</button>
<p>当前按钮点击次数为:<span m-text="count"></span></p>
其效果如下所示:
{ "count": 0 }当前按钮点击次数为:
MIP.navigateTo 和 MIP.closeOrNavigateTo
需要说明的是,在通常情况下,应优先使用 <a href="xxx"></a>
的形式实现页面跳转,因为 a 链的形式更有利于搜索引擎的抓取和分析。
<button on="tap:MIP.navigateTo({ url: 'https://www.mipengine.org', target: '_blank', opener: true })">在新页面打开 mip 官网</button>
<button on="tap:MIP.closeOrNavigateTo({ url: 'https://www.mipengine.org', target: '_blank', opener: true })">关闭页面或者打开 mip 官网</button>
效果如下所示:
MIP.scrollTo
<button on="tap:MIP.scrollTo({ id: 'top-example', duration: 500, position: 'center' })">滚动到顶部 id 为 top-button 的按钮处</button>
效果如下所示:
MIP.goBack 和 mip.print
<button on="tap:MIP.goBack">返回上页</button>
<button on="tap:MIP.print">打印页面</button>
效果如下所示:
组件自定义方法
MIP 组件允许自定义方法,通过 this.addEventAction
进行自定义方法的注册。因此需要阅读对应 MIP 组件文档当中的 行为
或 方法
部分进行学习。
行为封装与前置判断
我们提供了 mip-action-macro 来进一步增强 MIP on 表达式的功能。
mip-action-macro 主要提供的功能包括:
- 将单个或多个行为封装起来,提高行为复用率
- 支持在执行方法前提供前置判断条件,只有当判断条件为真时才会执行方法
- 支持对全部全局元素方法和特殊对象方法的参数进行有限能力的计算
下面进行 mip-action-macro 的使用方法演示,更具体的组件说明,请点击链接查看 mip-action-macro 的组件文档。
<mip-data>
<script type="application/json">
{
"protocol": "https://",
"baidu": "www.baidu.com",
"mipengine": "www.mipengine.org"
}
</script>
</mip-data>
<mip-action-macro
condition="event.url === baidu"
on="execute:MIP.navigateTo({ url: protocol + event.url, target: '_blank' })"
></mip-action-macro>
<button on="tap:macro-id.execute({ url: baidu })">点击跳转至百度首页</button>
<button on="tap:macro-id.execute({ url: mipengine })">点击不会发生任何跳转</button>
效果如下所示:
{ "protocol": "https://", "baidu": "www.baidu.com", "mipengine": "ww.mipengine.org" }
您已通过 bottom-button.scrollTo() 方法滚动到底部,请点击下方按钮返回原示例