Open yanyue404 opened 1 year ago
H5 调 APP
const getUserInfo = (callback) => { let timestamp = +new Date(); //时间戳 // 回调函数 JSBridge.callback__userInfo.push({ callback, timestamp, }); JSBridge.postMessage({ action: "userInfo", timestamp: +new Date(), }); }; /** * 向app发送指令,当app处理完指令后一般会回调全局的 fromApp()方法。通过这种形式与app进行交互 * @param msg 指令(json对象) */ const postMessage = (msg) => { console.log("action:", JSON.stringify(msg)); if (!this.isInApp()) { console.warn("异常提示:请在 App 内使用!"); return; //为防止在非app环境下调用,如果发现不是app环境,则结束代码 } try { let plat = window.navigator.platform.toLowerCase() || window.navigator.platform; if (plat == "iphone" || plat == "iPhone") { window.webkit.messageHandlers.iphone.postMessage(msg); } else { window.android.postMessage(msg); } } catch (err) { console.log(err); } };
APP 调 H5
在 H5 这边实现要在全局 window 上定义好 APP 要回调的方法
function fromApp(action, msg) { let res = null; // msg转换后的json对象 switch (action) { case "userInfo": res = eval("(" + msg + ")"); //转化为json对象 JSBridge.userInfo = res; for (let i = 0; i < JSBridge.callback__userInfo.length; i++) { const task = JSBridge.callback__userInfo[i]; if (task.callback && task.timestamp === res.reqTime) { task.callback(res); JSBridge.callback__userInfo.splice(i, 1); //将该位置上的元素移除 } } break; } }
通过 HTTP POST 请求,将少量数据使用异步的方式,发送到服务端。
function reportEvent() { const url = "http://api.wangxiaokai.vip/test"; const data = JSON.stringify({ time: performance.now(), }); navigator.sendBeacon(url, data); } document.addEventListener("visibilitychange", function () { if (document.visiblityState === "hidden") { reportEvent(); } });
发送的时机
浏览器端自动判断合适的时机进行发送
是否会产生阻塞或影响页面性能
不会产生阻塞,影响当前页面的卸载。 不影响下个新页面的加载,不存在性能问题。 另外,数据传输可靠。
语法
navigator.sendBeacon(url, data);
参数解析
返回值
当浏览器将数据成功加入传输队列时,sendBeacon 方法会返回 true,否则返回 false。
注意返回值的时机:成功加入传输队列,而不是服务端的处理成功后的返回。
缺点
创建一个函数的底层方法,支持函数体的数据格式是字符串,在模板引擎类似场景下有不可替代的作用,异常强大。
<body> <template id="template"> <h2>${title}</h2> ${data.map(function (obj, index) { return ` <p>文章:${obj.article}</p> <p>作者:${obj.author}</p> `; }).join('')} </template> </body> <script> String.prototype.interpolate = function (params) { console.log("innerHTML 内容:", this); const names = Object.keys(params); const vals = Object.values(params); return new Function(...names, `return \`${this}\`;`)(...vals); }; const html = template.innerHTML.interpolate({ data: [ { article: "文章标题1", author: "张鑫旭", }, { article: "文章标题2", author: "CSS新世界", }, ], title: "例子演示", }); console.log(html); </script>
输出结果:
/* <h2>例子演示</h2> <p>文章:文章标题1</p> <p>作者:张鑫旭</p> <p>文章:文章标题2</p> <p>作者:CSS新世界</p> */
/** * 缓存静态方法的value * @param {*} fn fn 的参数中不能使用 引用类型 */ function cacheStaticFn(fn) { const cacheMap = new Map() return (...args) => { let cacheKey = args.join('-') if (!cacheMap.has(cacheKey)) { cacheMap.set(cacheKey, fn(...args)) } return cacheMap.get(cacheKey) } } let isIos = cacheStaticFn(() => { let browserRule = /^.*((iPhone)|(iPad)|(Safari))+.*$/ return browserRule.test(navigator.userAgent) }) // 当ios后退刷新时 async function whenIosBack(callback) { if (isIos()) { window.onpageshow = (event) => { if (event.persisted) { callback() } } return true } return false } function handleRefresh(callback) { if (!whenIosBack(callback)) { document.addEventListener('visibilitychange', () => { if (!document.hidden && !document.webkitHidden && !document.mozHidden) { callback() } }) } }
postMessage:H5 与 App 交互
H5 调 APP
APP 调 H5
在 H5 这边实现要在全局 window 上定义好 APP 要回调的方法
navigator.sendBeacon: 页面关闭时,前端上传监控数据
通过 HTTP POST 请求,将少量数据使用异步的方式,发送到服务端。
发送的时机
浏览器端自动判断合适的时机进行发送
是否会产生阻塞或影响页面性能
不会产生阻塞,影响当前页面的卸载。 不影响下个新页面的加载,不存在性能问题。 另外,数据传输可靠。
语法
参数解析
返回值
当浏览器将数据成功加入传输队列时,sendBeacon 方法会返回 true,否则返回 false。
缺点
JS new Function 语法
创建一个函数的底层方法,支持函数体的数据格式是字符串,在模板引擎类似场景下有不可替代的作用,异常强大。
输出结果:
IOS 返回不刷新
参考链接