
【示例】wap2app应用中302等二次跳转的地址匹配
场景一
页面A -> 点击跳转 -> 302等地址 -> 目标地址
302地址: http://m.example.com/redirect?redirect_url=http://m.example.com/detail.html
目标地址:http://m.example.com/detail.html
为了防止出现白屏或者重复打开窗口的情况,需要在 sitemap.json -> pages 中,将302地址与目标地址匹配到一起。
{
"webviewId": "detail",
"matchUrls": [
{
"pathname": "/redirect",
"search": "R:redirect_url=.*\\/detail.html"
}, {
"pathname": "/detail.html"
}
]
}
场景一
页面A -> 点击跳转 -> 302等地址 -> 目标地址
302地址: http://m.example.com/redirect?redirect_url=http://m.example.com/detail.html
目标地址:http://m.example.com/detail.html
为了防止出现白屏或者重复打开窗口的情况,需要在 sitemap.json -> pages 中,将302地址与目标地址匹配到一起。
{
"webviewId": "detail",
"matchUrls": [
{
"pathname": "/redirect",
"search": "R:redirect_url=.*\\/detail.html"
}, {
"pathname": "/detail.html"
}
]
}
收起阅读 »

【示例】wap2app应用在iOS平台下唤醒淘宝
wap2app 应用,在 iOS 环境下唤醒淘宝等应用,需要配置两处白名单。
第一处
manifest.json -> plus -> distribute -> apple 节点下,添加 urlschemewhitelist。对应的值为数组格式,如:
{
"plus": {
"distribute": {
"apple": {
"urlschemewhitelist": [
"mqq",
"taobao"
]
}
}
}
}
第二处
同样是 manifest.json 文件 plus 节点下,添加 schemeWhitelist 节点,其对应的值也是数组格式,如:
{
"plus": {
"schemeWhitelist": [
"mqq",
"taobao"
]
}
}
注意
urlschemewhitelist 和 schemeWhitelist 所在的节点不同,注意属性名的大小写,保持这两个属性对应的值相同。
wap2app 应用,在 iOS 环境下唤醒淘宝等应用,需要配置两处白名单。
第一处
manifest.json -> plus -> distribute -> apple 节点下,添加 urlschemewhitelist。对应的值为数组格式,如:
{
"plus": {
"distribute": {
"apple": {
"urlschemewhitelist": [
"mqq",
"taobao"
]
}
}
}
}
第二处
同样是 manifest.json 文件 plus 节点下,添加 schemeWhitelist 节点,其对应的值也是数组格式,如:
{
"plus": {
"schemeWhitelist": [
"mqq",
"taobao"
]
}
}
注意
urlschemewhitelist 和 schemeWhitelist 所在的节点不同,注意属性名的大小写,保持这两个属性对应的值相同。

【汇总】wap2app常见问题
常见问题
302之类的二次跳转如何匹配防止白屏
http://ask.dcloud.net.cn/article/13074
相同规则的地址间跳转会反复打开新窗口么?
当前 webview 中跳转一个相同规则的 url,直接在当前 webview 中加载,不会重复打开新的 webview。
可以本地打包或嵌入其它应用内么?
不支持本地打包,只能通过云端打包成相应的apk/ipa。同时,也不能嵌入到其它应用中。
http://ask.dcloud.net.cn/question/48290
如何移除原生导航栏
原则上不建议移除原生导航栏,原生导航栏也是优化的比较重要的一部分。
http://ask.dcloud.net.cn/question/50018
网站引用了 mui 导致返回键操作异常
mui.js 在 5+ 环境下会处理 backbutton,wap2app 同样也会处理,因此会造成冲突。
mui 提供了关闭监听的配置,详细参考文档说明:关闭页面
mui.init({
keyEventBind: {
backbutton: false //关闭back按键监听
}
});
wap2app如何让一个链接是在同一个webview中跳转,而不是打开另外一个webview。
将目标 url 配置到一个 page 的 matchUrls。
wap2app如何返回上一页并刷新
获取目标 webview 对象,并执行刷新逻辑。
http://ask.dcloud.net.cn/question/49546
wap2app应用iOS如何唤起淘宝等第三方应用
需要配置两处白名单
http://ask.dcloud.net.cn/article/13073
wap2app原生下拉pullToRefresh怎么更新list的DOM而不是刷新网页
可以执行自定义的下拉刷新逻辑
http://ask.dcloud.net.cn/question/48490
wap2app中使用Native.js
远程的 HTML 不能使用 Native.js
http://ask.dcloud.net.cn/question/48540
退出时候的反馈如何去掉
调整首页 easyConfig -> quit 的配置即可
http://ask.dcloud.net.cn/article/12750
http://ask.dcloud.net.cn/article/13069
自定义插件以及其它第三方SDK的集成
不支持扩展
首页titleNview配置的按钮怎么添加监听事件
http://ask.dcloud.net.cn/article/12622
云打包时如何加密
云端打包时,选择“启用js原生混淆”。如果有需要,可以使用第三方,如360等提供的加固方案,进行加固。
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题
常见问题
302之类的二次跳转如何匹配防止白屏
http://ask.dcloud.net.cn/article/13074
相同规则的地址间跳转会反复打开新窗口么?
当前 webview 中跳转一个相同规则的 url,直接在当前 webview 中加载,不会重复打开新的 webview。
可以本地打包或嵌入其它应用内么?
不支持本地打包,只能通过云端打包成相应的apk/ipa。同时,也不能嵌入到其它应用中。
http://ask.dcloud.net.cn/question/48290
如何移除原生导航栏
原则上不建议移除原生导航栏,原生导航栏也是优化的比较重要的一部分。
http://ask.dcloud.net.cn/question/50018
网站引用了 mui 导致返回键操作异常
mui.js 在 5+ 环境下会处理 backbutton,wap2app 同样也会处理,因此会造成冲突。
mui 提供了关闭监听的配置,详细参考文档说明:关闭页面
mui.init({
keyEventBind: {
backbutton: false //关闭back按键监听
}
});
wap2app如何让一个链接是在同一个webview中跳转,而不是打开另外一个webview。
将目标 url 配置到一个 page 的 matchUrls。
wap2app如何返回上一页并刷新
获取目标 webview 对象,并执行刷新逻辑。
http://ask.dcloud.net.cn/question/49546
wap2app应用iOS如何唤起淘宝等第三方应用
需要配置两处白名单
http://ask.dcloud.net.cn/article/13073
wap2app原生下拉pullToRefresh怎么更新list的DOM而不是刷新网页
可以执行自定义的下拉刷新逻辑
http://ask.dcloud.net.cn/question/48490
wap2app中使用Native.js
远程的 HTML 不能使用 Native.js
http://ask.dcloud.net.cn/question/48540
退出时候的反馈如何去掉
调整首页 easyConfig -> quit 的配置即可
http://ask.dcloud.net.cn/article/12750
http://ask.dcloud.net.cn/article/13069
自定义插件以及其它第三方SDK的集成
不支持扩展
首页titleNview配置的按钮怎么添加监听事件
http://ask.dcloud.net.cn/article/12622
云打包时如何加密
云端打包时,选择“启用js原生混淆”。如果有需要,可以使用第三方,如360等提供的加固方案,进行加固。
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题

【文档】wap2app之app.js
该文章意在汇总整理 app.js 的配置,方便日常开发中查阅。
详细教程请参考 app.js - wap2app教程
App
App(appConfig);
参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
options | Object | 全局参数配置 | * | |
onLaunch | Function | 生命周期函数,监听 wap2app 应用初始化。 | wap2app 应用初始化完成时触发,全局只触发一次。 | |
onShow | Function | 生命周期函数,监听 wap2app 应用显示。 | 当 wap2app 应用从后台进入前台显示时触发。 | |
onHide | Function | 生命周期函数,监听 wap2app 应用隐藏。 | 当 wap2app 应用从前台进入后台时触发。 |
Tips
当用户按了设备 Home 键,wap2app 应用并不会立即被销毁,而是进入了后台运行。当再次打开 wap2app 应用时,会从后台进入前台。
appConfig -> options 参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
debug | Boolean | 是否输出日志,默认为 false。 | 通过 HBuilder 真机运行调试时,如果设置为 true,则在控制台输出日志信息。 |
Page
Page(id, pageConfig);
参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
id | String | webview 的 id | 该值取自 sitemap.json 中配置 page 对应的 webviewId | |
pageConfig | Object | 页面参数配置 | * |
pageConfig 参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
onShow | Function | 生命周期函数,监听 webview 的显示。 | 对应的 webview 显示时触发 | |
onClose | Function | 生命周期函数,监听 webview 的关闭。 | 对应的 webview 关闭时触发 |
运行环境
需要注意的是,以上函数中的 JavaScript 的代码,并不是在首页或者某个 webviewe 中执行。
所以当 JavaScript 代码中涉及到最某个特定 webview 中的内容进行操作时,需要获取 webview 通过 evalJS 方法来执行。
例如,从详情页返回时,希望刷新列表页。在 app.js 中,注册 detail 页面的配置。
Page('detail', {
onClose: function() {
// 刷新列表
var listWebview = plus.webview.getWebviewById('list');
if(listWebview) {
listWebview.evalJS('refresh()'); //refresh() 方法是目标窗口中全局的函数,用于刷新页面;
// 或者简单点,直接用 webview 的刷新方法;
// listWebview.reload(true);
}
}
});
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题
该文章意在汇总整理 app.js 的配置,方便日常开发中查阅。
详细教程请参考 app.js - wap2app教程
App
App(appConfig);
参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
options | Object | 全局参数配置 | * | |
onLaunch | Function | 生命周期函数,监听 wap2app 应用初始化。 | wap2app 应用初始化完成时触发,全局只触发一次。 | |
onShow | Function | 生命周期函数,监听 wap2app 应用显示。 | 当 wap2app 应用从后台进入前台显示时触发。 | |
onHide | Function | 生命周期函数,监听 wap2app 应用隐藏。 | 当 wap2app 应用从前台进入后台时触发。 |
Tips
当用户按了设备 Home 键,wap2app 应用并不会立即被销毁,而是进入了后台运行。当再次打开 wap2app 应用时,会从后台进入前台。
appConfig -> options 参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
debug | Boolean | 是否输出日志,默认为 false。 | 通过 HBuilder 真机运行调试时,如果设置为 true,则在控制台输出日志信息。 |
Page
Page(id, pageConfig);
参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
id | String | webview 的 id | 该值取自 sitemap.json 中配置 page 对应的 webviewId | |
pageConfig | Object | 页面参数配置 | * |
pageConfig 参数说明 | 参数 | 类型 | 说明 | 更多 |
---|---|---|---|---|
onShow | Function | 生命周期函数,监听 webview 的显示。 | 对应的 webview 显示时触发 | |
onClose | Function | 生命周期函数,监听 webview 的关闭。 | 对应的 webview 关闭时触发 |
运行环境
需要注意的是,以上函数中的 JavaScript 的代码,并不是在首页或者某个 webviewe 中执行。
所以当 JavaScript 代码中涉及到最某个特定 webview 中的内容进行操作时,需要获取 webview 通过 evalJS 方法来执行。
例如,从详情页返回时,希望刷新列表页。在 app.js 中,注册 detail 页面的配置。
Page('detail', {
onClose: function() {
// 刷新列表
var listWebview = plus.webview.getWebviewById('list');
if(listWebview) {
listWebview.evalJS('refresh()'); //refresh() 方法是目标窗口中全局的函数,用于刷新页面;
// 或者简单点,直接用 webview 的刷新方法;
// listWebview.reload(true);
}
}
});
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题

【文档】wap2app之sitemap.json
该文章意在汇总整理 sitemap.json 的配置,方便日常开发中查阅。
详细教程请参考 sitemap.json概述 - wap2app教程
根节点
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
global | Object | App 全局配置 | sitemap.json概述 |
pages | Array | M 站所有需要增强的页面配置 | sitemap.json概述 |
global
App 全局配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
webviewParameter | Object | webview 相关配置 | webviewParameter配置 |
easyConfig | Object | 为提升用户体验而提供的简化实现 | easyConfig配置 |
pages
页面组配置
page
sitemap.json -> pages 集合的单个页面配置对象
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
webviewId | String | 当前页面所属 webview 的 id | * |
matchUrls | Array | 页面 url 匹配规则 | matchUrls配置 |
webviewParameter | Object | webview 相关配置 | webviewParameter配置 |
easyConfig | Object | 为提升用户体验而提供的简化实现 | easyConfig配置 |
matchUrl
page -> matchUrls 集合的单个匹配规则对象
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
href | String/RegExp/Wildcard | 页面完整 url | * |
hostname | String/RegExp/Wildcard | 域名信息 | * |
pathname | String/RegExp/Wildcard | 路径信息 | * |
search | String/RegExp/Wildcard | 查询字符串信息 | * |
hash | String/RegExp/Wildcard | 锚点信息 | * |
webviewParameter
webview 相关配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
titleNView | Object | 原生标题栏样式配置 | titleNView配置 |
statusbar | Object | 系统状态栏样式配置 | * |
appendCss | String | 向服务端页面插入的 css 代码 | * |
appendJs | String | 向服务端页面插入的 JavaScript 代码 | * |
pullToRefresh | Object | 下拉刷新配置 | * |
tabBar | Object | 选项卡切换效果优化,目前仅支持首页底部选项卡 | 选项卡切换优化 |
subNViews | String | NView模板配置 | NView模板 |
statusbar
系统状态栏样式配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
style | String | 状态栏前景色(文字颜色) | * |
background | String | 状态栏背景色,默认应当与原生导航条背景色保持一致 | * |
pullToRefresh
下拉刷新配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
support | Boolean | 是否启用原生下拉刷新,默认为 false | * |
easyConfig
为提升用户体验而提供的简化实现
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
back | Object | wap2app 后退逻辑 | * |
open | Object | 打开新窗口的优化 | * |
quit | Object | wap2app 退出逻辑 | 仅支持首页 |
back
wap2app 后退逻辑
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
before | Array | 后退前的优化 | * |
history | Boolean | 是否执行 history.back() | * |
back -> before 集合的单个配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
popupSelector | String | 弹出层选择器 | * | |
closeSelector | String | 取消按钮选择器或遮罩层选择器 | * | |
eventType | String | 事件类型,默认为 click | * |
open
打开新窗口的优化
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
animation | Object | 窗口动画配置 | * |
open -> animation 的配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
type | String | 窗口动画类型 | 窗口显示动画效果 | |
duration | Number | 窗口动画执行时间,单位为 ms,默认 300ms | * |
quit
wap2app 退出逻辑,仅支持在首页配置。
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
toast | Object | toast 消息框配置 | * |
quit -> toast 配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
showFeedback | Boolean | 是否显示 toast,默认为 true | * |
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题
该文章意在汇总整理 sitemap.json 的配置,方便日常开发中查阅。
详细教程请参考 sitemap.json概述 - wap2app教程
根节点
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
global | Object | App 全局配置 | sitemap.json概述 |
pages | Array | M 站所有需要增强的页面配置 | sitemap.json概述 |
global
App 全局配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
webviewParameter | Object | webview 相关配置 | webviewParameter配置 |
easyConfig | Object | 为提升用户体验而提供的简化实现 | easyConfig配置 |
pages
页面组配置
page
sitemap.json -> pages 集合的单个页面配置对象
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
webviewId | String | 当前页面所属 webview 的 id | * |
matchUrls | Array | 页面 url 匹配规则 | matchUrls配置 |
webviewParameter | Object | webview 相关配置 | webviewParameter配置 |
easyConfig | Object | 为提升用户体验而提供的简化实现 | easyConfig配置 |
matchUrl
page -> matchUrls 集合的单个匹配规则对象
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
href | String/RegExp/Wildcard | 页面完整 url | * |
hostname | String/RegExp/Wildcard | 域名信息 | * |
pathname | String/RegExp/Wildcard | 路径信息 | * |
search | String/RegExp/Wildcard | 查询字符串信息 | * |
hash | String/RegExp/Wildcard | 锚点信息 | * |
webviewParameter
webview 相关配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
titleNView | Object | 原生标题栏样式配置 | titleNView配置 |
statusbar | Object | 系统状态栏样式配置 | * |
appendCss | String | 向服务端页面插入的 css 代码 | * |
appendJs | String | 向服务端页面插入的 JavaScript 代码 | * |
pullToRefresh | Object | 下拉刷新配置 | * |
tabBar | Object | 选项卡切换效果优化,目前仅支持首页底部选项卡 | 选项卡切换优化 |
subNViews | String | NView模板配置 | NView模板 |
statusbar
系统状态栏样式配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
style | String | 状态栏前景色(文字颜色) | * |
background | String | 状态栏背景色,默认应当与原生导航条背景色保持一致 | * |
pullToRefresh
下拉刷新配置
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
support | Boolean | 是否启用原生下拉刷新,默认为 false | * |
easyConfig
为提升用户体验而提供的简化实现
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
back | Object | wap2app 后退逻辑 | * |
open | Object | 打开新窗口的优化 | * |
quit | Object | wap2app 退出逻辑 | 仅支持首页 |
back
wap2app 后退逻辑
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
before | Array | 后退前的优化 | * |
history | Boolean | 是否执行 history.back() | * |
back -> before 集合的单个配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
popupSelector | String | 弹出层选择器 | * | |
closeSelector | String | 取消按钮选择器或遮罩层选择器 | * | |
eventType | String | 事件类型,默认为 click | * |
open
打开新窗口的优化
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
animation | Object | 窗口动画配置 | * |
open -> animation 的配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
type | String | 窗口动画类型 | 窗口显示动画效果 | |
duration | Number | 窗口动画执行时间,单位为 ms,默认 300ms | * |
quit
wap2app 退出逻辑,仅支持在首页配置。
属性 | 类型 | 说明 | 更多 |
---|---|---|---|
toast | Object | toast 消息框配置 | * |
quit -> toast 配置 | 属性 | 类型 | 说明 | 更多 |
---|---|---|---|---|
showFeedback | Boolean | 是否显示 toast,默认为 true | * |
扩展阅读
wap2app概述(入门必读)
sitemap.json文档
app.js文档
wap2app应用强化
wap2app常见问题

打包的ipa在APP Store审核过程中因定位被退回的解决方法
iOS应用如果需要用到定位,正常情况下
plus.geolocation.getCurrentPosition((data)=>{},(error)=>{})
即可,这时会弹出提示框给用户选择是否允许使用定位功能。
但关键的地方就是,现在审核标准需要在APP里面说明为什么要获取定位,
因此就要在manifest.json里面的代码视图添加相关代码:
"plus": {
"distribute": {
"apple": {
"plistcmds": [
"Set :NSLocationAlwaysUsageDescription 我是经常要使用定位的原因描述",
"Set :NSLocationWhenInUseUsageDescription 我是需要使用定位的原因描述"
]
}
}
}
iOS应用如果需要用到定位,正常情况下
plus.geolocation.getCurrentPosition((data)=>{},(error)=>{})
即可,这时会弹出提示框给用户选择是否允许使用定位功能。
但关键的地方就是,现在审核标准需要在APP里面说明为什么要获取定位,
因此就要在manifest.json里面的代码视图添加相关代码:
"plus": {
"distribute": {
"apple": {
"plistcmds": [
"Set :NSLocationAlwaysUsageDescription 我是经常要使用定位的原因描述",
"Set :NSLocationWhenInUseUsageDescription 我是需要使用定位的原因描述"
]
}
}
}
收起阅读 »

【分享】5+App的中View
5+App 中的 View 大概可以分为:
- DOM 也就是 HTML 的内容
- Webview 做为 HTML 的容器
- NView 原生 View
- Map、Video 等原生的控件
- NativeUI 系统原生界面
层级关系
默认的层级关系 DOM < Map = Webview < NView < NativeUI
- DOM 的层级是最低的,因此经常出现某些 HTML 的内容被其它更高层级 View 遮挡的情况。
- Map = Webview 其实不够严谨。原生控件创建后,会与当前 Webview 建立关联关系,可以简单理解为层级一致。
- Webview < NView 是默认的情况,如果 NView 被 append 到 Webview 的话,NView 的层级则会跟随父 Webview。
- NativeUI 系统原生界面的层级是最高的
下面通过一些示例,来验证一下这些层级关系。
示例
这里要先提一句,一个新的 Webview 创建并且显示,默认都会置于栈顶,也就是说会在当前所有 Webview 的最上层。
地图
- NativeUI 弹出框在 Webview 与 Map 上层
- 新的Webview 新开一个 Webview 会遮挡包含 Map 的 Webview。
NView
- NView 默认情况下,层级是高于所有 Webview 的。
- 不append 此时点击“新开窗口”或“返回”,会一直看到 NView 的存在。
- append 此时 NView 作为 Webview 的一部分存在,层级与父 Webview 一致,点击“新开窗口”或“返回”不会再看到 NView 的存在。
- NativeUI 弹出框始终会在 NView 上层
源码
示例的具体代码,见附件。
5+App 中的 View 大概可以分为:
- DOM 也就是 HTML 的内容
- Webview 做为 HTML 的容器
- NView 原生 View
- Map、Video 等原生的控件
- NativeUI 系统原生界面
层级关系
默认的层级关系 DOM < Map = Webview < NView < NativeUI
- DOM 的层级是最低的,因此经常出现某些 HTML 的内容被其它更高层级 View 遮挡的情况。
- Map = Webview 其实不够严谨。原生控件创建后,会与当前 Webview 建立关联关系,可以简单理解为层级一致。
- Webview < NView 是默认的情况,如果 NView 被 append 到 Webview 的话,NView 的层级则会跟随父 Webview。
- NativeUI 系统原生界面的层级是最高的
下面通过一些示例,来验证一下这些层级关系。
示例
这里要先提一句,一个新的 Webview 创建并且显示,默认都会置于栈顶,也就是说会在当前所有 Webview 的最上层。
地图
- NativeUI 弹出框在 Webview 与 Map 上层
- 新的Webview 新开一个 Webview 会遮挡包含 Map 的 Webview。
NView
- NView 默认情况下,层级是高于所有 Webview 的。
- 不append 此时点击“新开窗口”或“返回”,会一直看到 NView 的存在。
- append 此时 NView 作为 Webview 的一部分存在,层级与父 Webview 一致,点击“新开窗口”或“返回”不会再看到 NView 的存在。
- NativeUI 弹出框始终会在 NView 上层
源码
示例的具体代码,见附件。
收起阅读 »
【5+】Webview页面之间的数据交流
一个App,其中大部分是要对页面之间的数据进行交互。
碧如:A打开B页面,B页面执行一些代码,再通知回A页面。
这可能是h5+er们遇到最常见的一个场景了。
ok,我们将问题实例化:
A页面有个选择地区的按钮,需要打开B页面选择一个地区,然后获取到选取结果返回给A页面并展示。
我们看看用mui.fire怎么来实现这个功能
A页面
<header class="mui-bar mui-bar-nav">
<h1 class="mui-title">A</h1>
</header>
<div class="mui-content">
<input type="text" readonly placeholder="未选择">
<button type="button" class="mui-btn mui-btn-blue">选取地区</button>
</div>
<script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
// 自定义监听select事件
document.addEventListener('select', function(e){
var text = e.detail.text;
document.querySelector("input").value = text;
});
// 按钮点击事件
document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
// 打开B页面,选取一个结果
mui.openWindow('B.html');
});
</script>
B页面
<header class="mui-bar mui-bar-nav">
<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
<h1 class="mui-title">B</h1>
</header>
<div class="mui-content">
<ul class="mui-table-view">
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
上海
</a>
</li>
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
深圳
</a>
</li>
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
北京
</a>
</li>
</ul>
</div>
<script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui('ul').on('tap', 'li', function() {
// 获取当前选择的内容
var text = this.innerText;
// 通知上个页面
var w = plus.webview.currentWebview();
var opener = w.opener();
mui.fire(opener, "select",{
text: text
});
// 关闭本页面
w.close();
});
真机调试一下,o98k。
但是!我个人还是建议脱离mui.js来实现这个功能
可以借用咱们之前文章里面的讲过的,利用webview对象的evalJS方法
【5+】跨webview多页面 触发事件(一)
【5+】跨webview多页面 触发事件(一)
感觉用Broadcast.js有点小题大做
那咱们就写一个类似Android中的onActivityResult和setResult方法
新建一个app.js,作为一个自己的插件,里面实现两个方法 onActivityResult 和 setResult
(function(app){
/**
* 打开一个页面
* @param {String} url 页面路径
* @param {String} id 页面id
* @param {Object} ex 参数
* @param {Function} callback
*/
app.onActivityResult = function(url, id, ex, callback){
};
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data){
};
}(window.app || (window.app = {})));
我们一步步来,先看看setResult如何触发上个页面的函数
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data){
// 获取当前webview
var indexW = plus.webview.currentWebview();
// 获取创建者的webview
var opener = indexW.opener();
// 执行js字符串
opener.evalJS();// ??????
};
卧槽,那么,问题来了,evalJS该执行什么呢?
如果我在A页面的window对象下定一个函数
window.test = function(data){
alert(JSON.stringify(data));
}
那么,我们在evalJS里面就该这么写
// 执行js字符串
var jsstr = "window.test && window.test(" + JSON.stringify(data) + ")";
opener.evalJS(jsstr);
好吧,考虑到一个页面可能通过这个方式打开多个页面,那么我们这个test函数就得改一个不重复唯一的名称,并且定义放到onActivityResult方法里面
var _id = 0,
_tempName = '',
ow,cw;
/**
* 打开一个页面
* @param {String} url 页面路径
* @param {String} id 页面id
* @param {Object} ex 参数
* @param {Function} callback
*/
app.onActivityResult = function(url, id, ex, callback) {
// 生成唯一回调函数名称
_tempName = 'APP_RESULT_FUN_' + _id++;
// 定义函数
window[_tempName] = function(data){
// 执行自定义回调
callback(data);
};
// 传递函数名称到目标页面
ex.callbackName = _tempName;
// 显示菊花
cw = plus.nativeUI.showWaiting();
// 创建目标页面
ow = plus.webview.create(url, id, {
render: "always"
}, ex);
// title更新时显示 页面
ow.addEventListener('titleUpdate', function(){
// 关闭菊花
cw && (cw.close(),cw = null);
// 显示页面
ow.show('pop-in');
});
// 页面关闭时,注销window下此次事件
ow.addEventListener('close', function(){
setTimeout(function(){
window[_tempName] = null;
});
});
};
生成特殊一个函数,并把函数名通过extras的方式传参到目标页面,
相应的,setResult方法也需要少许更改
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data) {
// 获取当前webview
var indexW = plus.webview.currentWebview();
// js字符串
var jsstr = "";
// 如果存在自定义回调函数名
if(indexW.callbackName){
// 拼接js字符串
jsstr = "window." + indexW.callbackName;
jsstr = jsstr + "&&" + jsstr + "(" + JSON.stringify(data) + ")";
// 执行
indexW.opener().evalJS(jsstr);
}
// 返回当前页面
return indexW;
};
试试引用后在AB页面测试一下
// A页面 按钮点击事件
document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
// 打开B页面,选取一个结果
app.onActivityResult('B.html', 'B', {}, function(data){
// 修改内容
document.querySelector("input").value = data.text;
});
});
// B页面 选项点击事件
mui('ul').on('tap', 'li', function() {
// 获取当前选择的内容
var text = this.innerText;
// 通知上个页面 并关闭本页面
app.setResult({
text: text
}).close();
});
卧槽666。
class Man{
constructor(){
this.name = 'newsning'
}
say(){
console.log('天行健, 君子以自强不息. ')
}
}
一个App,其中大部分是要对页面之间的数据进行交互。
碧如:A打开B页面,B页面执行一些代码,再通知回A页面。
这可能是h5+er们遇到最常见的一个场景了。
ok,我们将问题实例化:
A页面有个选择地区的按钮,需要打开B页面选择一个地区,然后获取到选取结果返回给A页面并展示。
我们看看用mui.fire怎么来实现这个功能
A页面
<header class="mui-bar mui-bar-nav">
<h1 class="mui-title">A</h1>
</header>
<div class="mui-content">
<input type="text" readonly placeholder="未选择">
<button type="button" class="mui-btn mui-btn-blue">选取地区</button>
</div>
<script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
// 自定义监听select事件
document.addEventListener('select', function(e){
var text = e.detail.text;
document.querySelector("input").value = text;
});
// 按钮点击事件
document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
// 打开B页面,选取一个结果
mui.openWindow('B.html');
});
</script>
B页面
<header class="mui-bar mui-bar-nav">
<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
<h1 class="mui-title">B</h1>
</header>
<div class="mui-content">
<ul class="mui-table-view">
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
上海
</a>
</li>
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
深圳
</a>
</li>
<li class="mui-table-view-cell">
<a class="mui-navigate-right">
北京
</a>
</li>
</ul>
</div>
<script src="js/mui.min.js"></script>
<script type="text/javascript">
mui.init();
mui('ul').on('tap', 'li', function() {
// 获取当前选择的内容
var text = this.innerText;
// 通知上个页面
var w = plus.webview.currentWebview();
var opener = w.opener();
mui.fire(opener, "select",{
text: text
});
// 关闭本页面
w.close();
});
真机调试一下,o98k。
但是!我个人还是建议脱离mui.js来实现这个功能
可以借用咱们之前文章里面的讲过的,利用webview对象的evalJS方法
【5+】跨webview多页面 触发事件(一)
【5+】跨webview多页面 触发事件(一)
感觉用Broadcast.js有点小题大做
那咱们就写一个类似Android中的onActivityResult和setResult方法
新建一个app.js,作为一个自己的插件,里面实现两个方法 onActivityResult 和 setResult
(function(app){
/**
* 打开一个页面
* @param {String} url 页面路径
* @param {String} id 页面id
* @param {Object} ex 参数
* @param {Function} callback
*/
app.onActivityResult = function(url, id, ex, callback){
};
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data){
};
}(window.app || (window.app = {})));
我们一步步来,先看看setResult如何触发上个页面的函数
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data){
// 获取当前webview
var indexW = plus.webview.currentWebview();
// 获取创建者的webview
var opener = indexW.opener();
// 执行js字符串
opener.evalJS();// ??????
};
卧槽,那么,问题来了,evalJS该执行什么呢?
如果我在A页面的window对象下定一个函数
window.test = function(data){
alert(JSON.stringify(data));
}
那么,我们在evalJS里面就该这么写
// 执行js字符串
var jsstr = "window.test && window.test(" + JSON.stringify(data) + ")";
opener.evalJS(jsstr);
好吧,考虑到一个页面可能通过这个方式打开多个页面,那么我们这个test函数就得改一个不重复唯一的名称,并且定义放到onActivityResult方法里面
var _id = 0,
_tempName = '',
ow,cw;
/**
* 打开一个页面
* @param {String} url 页面路径
* @param {String} id 页面id
* @param {Object} ex 参数
* @param {Function} callback
*/
app.onActivityResult = function(url, id, ex, callback) {
// 生成唯一回调函数名称
_tempName = 'APP_RESULT_FUN_' + _id++;
// 定义函数
window[_tempName] = function(data){
// 执行自定义回调
callback(data);
};
// 传递函数名称到目标页面
ex.callbackName = _tempName;
// 显示菊花
cw = plus.nativeUI.showWaiting();
// 创建目标页面
ow = plus.webview.create(url, id, {
render: "always"
}, ex);
// title更新时显示 页面
ow.addEventListener('titleUpdate', function(){
// 关闭菊花
cw && (cw.close(),cw = null);
// 显示页面
ow.show('pop-in');
});
// 页面关闭时,注销window下此次事件
ow.addEventListener('close', function(){
setTimeout(function(){
window[_tempName] = null;
});
});
};
生成特殊一个函数,并把函数名通过extras的方式传参到目标页面,
相应的,setResult方法也需要少许更改
/**
* 返回创建者页面数据
* @param {Object} data 需要返回的数据
* @return {Webview} w 当前webview
*/
app.setResult = function(data) {
// 获取当前webview
var indexW = plus.webview.currentWebview();
// js字符串
var jsstr = "";
// 如果存在自定义回调函数名
if(indexW.callbackName){
// 拼接js字符串
jsstr = "window." + indexW.callbackName;
jsstr = jsstr + "&&" + jsstr + "(" + JSON.stringify(data) + ")";
// 执行
indexW.opener().evalJS(jsstr);
}
// 返回当前页面
return indexW;
};
试试引用后在AB页面测试一下
// A页面 按钮点击事件
document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
// 打开B页面,选取一个结果
app.onActivityResult('B.html', 'B', {}, function(data){
// 修改内容
document.querySelector("input").value = data.text;
});
});
// B页面 选项点击事件
mui('ul').on('tap', 'li', function() {
// 获取当前选择的内容
var text = this.innerText;
// 通知上个页面 并关闭本页面
app.setResult({
text: text
}).close();
});
卧槽666。
class Man{
constructor(){
this.name = 'newsning'
}
say(){
console.log('天行健, 君子以自强不息. ')
}
}
收起阅读 »

点击li跳转时总跳转至第一个li的页面。而alert显示的是正确的innertext
var obj_lis = document.getElementById("my_list_movie").getElementsByTagName("li");
for(i = 0; i < obj_lis.length; i++) {
obj_lis[i].onclick = function() {
if(this.innerHTML.indexOf("电影票订单")) {
window.location.href = "ticket_order.html";
alert(this.innerHTML);
} else if(this.innerHTML.indexOf("代金优惠卷")) {
window.location.href = "coupons.html";
alert(this.innerHTML);
} else if(this.innerHTML.indexOf("收藏的电影")) {
window.location.href = "favorite_movie.html";
alert(this.innerHTML);
}
}
}
var obj_lis = document.getElementById("my_list_movie").getElementsByTagName("li");
for(i = 0; i < obj_lis.length; i++) {
obj_lis[i].onclick = function() {
if(this.innerHTML.indexOf("电影票订单")) {
window.location.href = "ticket_order.html";
alert(this.innerHTML);
} else if(this.innerHTML.indexOf("代金优惠卷")) {
window.location.href = "coupons.html";
alert(this.innerHTML);
} else if(this.innerHTML.indexOf("收藏的电影")) {
window.location.href = "favorite_movie.html";
alert(this.innerHTML);
}
}
}
收起阅读 »

vue2.x引入mui的开源项目源码+案例公开,没有过多的业务逻辑,刚写的项目,希望有好的commit提交过来整理好项目
项目地址:https://github.com/wuhou123/mui-vue2
下载app可以查看我的-我的足迹用到h5+和原生定位功能
也有关于mui常见问题文档
如果有问题提issues吧
项目地址:https://github.com/wuhou123/mui-vue2
下载app可以查看我的-我的足迹用到h5+和原生定位功能
也有关于mui常见问题文档
如果有问题提issues吧