一个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('天行健, 君子以自强不息. ')
}
}
6 个评论
要回复文章请先登录或注册
NewsNing (作者)
赵梦欢
NewsNing (作者)
NewsNing (作者)
lhyh
小资电脑