一個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('天行健, 君子以自強不息. ') } }