一个App,其中大部分是要对页面之间的数据进行交互。javascript
碧如:A打开B页面,B页面执行一些代码,再通知回A页面。html
这多是h5+er们遇到最多见的一个场景了。java
ok,咱们将问题实例化:web
A页面有个选择地区的按钮,须要打开B页面选择一个地区,而后获取到选取结果返回给A页面并展现。segmentfault
咱们看看用mui.fire怎么来实现这个功能app
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。ui
可是!我我的仍是建议脱离mui.js来实现这个功能this
能够借用我们以前文章里面的讲过的,利用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('天行健, 君子以自强不息. ') } }