在为 Growth 添加一个 WebView 的时候,由于 JavaScript 代码比较多,发现自己写的 onMessage 根本收不到任何消息:
handleMessage = (event: Object) => {
const message = JSON.parse(event.nativeEvent.data);
console.log(message);
}
对应的 WebView 代码:
$(function() {
window.postMessage(JSON.stringify({ status: 'ready' }));
document.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
if (data.action === 'algorithm') {
window.algorithm = data.algorithm;
$(window).trigger('bridge.run', window.algorithm);
} else if (data.action === 'run') {
$('#btn_run').trigger('click');
} else if (data.action === 'run') {
$('#btn_pause').trigger('click');
}
});
})
发现这样写也是不行的。探索了好几天,才想到这个问题一定是一个 issue,然后找到了:react native html postMessage can not reach to WebView #11594
发现了同样的问题,对于这个问题的解决办法就是写一个 awaitPostMessage
方法:
function awaitPostMessage() {
var isReactNativePostMessageReady = !!window.originalPostMessage;
var queue = [];
var currentPostMessageFn = function store(message) {
if (queue.length > 100) queue.shift();
queue.push(message);
};
if (!isReactNativePostMessageReady) {
var originalPostMessage = window.postMessage;
Object.defineProperty(window, 'postMessage', {
configurable: true,
enumerable: true,
get: function () {
return currentPostMessageFn;
},
set: function (fn) {
currentPostMessageFn = fn;
isReactNativePostMessageReady = true;
setTimeout(sendQueue, 0);
}
});
window.postMessage.toString = function () {
return String(originalPostMessage);
};
}
function sendQueue() {
while (queue.length > 0) window.postMessage(queue.shift());
}
}
然后再执行我们的 postMessage 方法,如下所示:
$(function() {
function awaitPostMessage() {
var isReactNativePostMessageReady = !!window.originalPostMessage;
var queue = [];
var currentPostMessageFn = function store(message) {
if (queue.length > 100) queue.shift();
queue.push(message);
};
if (!isReactNativePostMessageReady) {
var originalPostMessage = window.postMessage;
Object.defineProperty(window, 'postMessage', {
configurable: true,
enumerable: true,
get: function () {
return currentPostMessageFn;
},
set: function (fn) {
currentPostMessageFn = fn;
isReactNativePostMessageReady = true;
setTimeout(sendQueue, 0);
}
});
window.postMessage.toString = function () {
return String(originalPostMessage);
};
}
function sendQueue() {
while (queue.length > 0) window.postMessage(queue.shift());
}
};
awaitPostMessage(); // Call this only once in your Web Code.
window.postMessage(JSON.stringify({ status: 'ready' }));
document.addEventListener('message', function (event) {
var data = JSON.parse(event.data);
if (data.action === 'algorithm') {
window.algorithm = data.algorithm;
$(window).trigger('bridge.run', window.algorithm);
} else if (data.action === 'run') {
$('#btn_run').trigger('click');
} else if (data.action === 'run') {
$('#btn_pause').trigger('click');
}
});
})
或许您还需要下面的文章: