react-native-webview 从 html 调用特定的 javascript 函数
react-native-webview Calling a specific javascript function from the html
以下是 web 视图,我正在使用内联 HTML。
<WebView
javaScriptEnabled={true}
domStorageEnabled={true}
allowFileAccess={true}
originWhitelist={['*']}
style={{height: deviceHeight, width: deviceWidth, margin: 10}}
// source={{ uri: 'https://www.google.com/'}}
source={{
html:
'<script> function invokeHello() { window.ReactNativeWebView.postMessage("Hello") } function fillQRCode() { window.alert("filling qrcode"); document.getElementById("qr_code").value = "QR Code"; } function scanQRCode() { let data = {"nativeItemToAccess": "camera", "operation": { "type": "CALLBACK", "fieldId": "qr_code", "callback": `${fillQRCode}` }}; window.ReactNativeWebView.postMessage(JSON.stringify(data)); }</script> <!-- <form method="get" enctype="application/x-www-form-urlencoded" action="/html/codes/html_form_handler.cfm" onSubmit="invokeHello()"> --> <p><label>Name<input type="text" name="customer_name" required></label> </p> <p><label>Phone <input type="tel" name="phone_number" id="phone_number"></label></p> <p><label>QR Code <input type="text" disabled name="qr_code" id="qr_code"></label><p></p><button onclick="scanQRCode()">Scan</button></p></p> <p><button>Submit Booking</button></p><!-- </form> -->',
}}
// injectedJavaScript={runFirst}
ref={r => (this.webref = r)}
onMessage={event => {
if (this.webref) {
let data = JSON.parse(event.nativeEvent.data);
console.log('1: data being received: ', data);
if(data) {
switch(data.nativeItemToAccess) {
case 'camera':
this.performOperation(data);
break;
case 'test':
alert('test is invoked');
break;
}
}
}
}}
/>
在下面找到相同的 html,它是内联的(张贴只是为了使其更具可读性),
<script>
function invokeHello() { window.ReactNativeWebView.postMessage("Hello") }
function fillQRCode() { window.alert("filling qrcode"); document.getElementById("qr_code").value = "QR Code"; }
function scanQRCode() {
let data = {"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": `${fillQRCode}`
}};
window.ReactNativeWebView.postMessage(JSON.stringify(data));
}
</script>
<!-- <form method="get" enctype="application/x-www-form-urlencoded" action="/html/codes/html_form_handler.cfm" onSubmit="invokeHello()"> -->
<p><label>Name<input type="text" name="customer_name" required></label> </p>
<p><label>Phone <input type="tel" name="phone_number" id="phone_number"></label></p>
<p><label>QR Code <input type="text" disabled name="qr_code" id="qr_code"></label><p></p><button onclick="scanQRCode()">Scan</button></p></p>
<p><button>Submit Booking</button></p>
<!-- </form> -->
当我点击扫描按钮时,onMessage
被调用并且正确接收到传递的数据。我将根据收到的数据调用不同的函数。
下面是相机调用的函数,
performOperation = data => {
switch (data.operation.type) {
case 'FIELD_UPDATE':
this.updateField(data.operation.fieldId);
break;
case 'CALLBACK':
this.performCallback(data.operation.callback);
break;
}
};
performCallback = callback => {
console.log('2: callback: ', callback);
this.webref.injectJavaScript(`
try {
var fn = window[${callback}];
if (typeof fn === "function") {
fn();
} else {
window.alert('this is not a function '+ typeof fn);
}
true;
} catch (e) {
window.alert('unable to call the function: '+ e);
}
`);
};
updateField = fieldId => {
this.webref.injectJavaScript(`
document.getElementById("${fieldId}").value = "QR Code";
`);
};
performOperation
函数处理回调 javascript 方法,或者它只会填充一个文本框,具体取决于 data.operation.type
。所以现在 data.operation.type
是 CALLBACK
所以 performCallback
被调用,但我无法调用作为对象输入接收的函数。对象如下,
{"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": ${fillQRCode}
}};
fillQRCode
是 html 的 <script>
标签中的函数。
接收到的函数是字符串形式,如何转换为函数调用
我修改了传递函数的方式,
{"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": "fillQRCode"
}};
也就是说,我没有传递整个函数(我现在觉得这是错误的做法),而是只传递函数名称并按如下方式调用函数,
performCallback = callback => {
console.log('2: callback: ', callback);
var qrCode = 'zdjkcnsjkdnsdkfjnjk';
this.webref.injectJavaScript(`
try {
${callback}("${qrCode}")
true;
} catch (e) {
window.alert('unable to call the function: '+ e);
}
`);
};
以下是 web 视图,我正在使用内联 HTML。
<WebView
javaScriptEnabled={true}
domStorageEnabled={true}
allowFileAccess={true}
originWhitelist={['*']}
style={{height: deviceHeight, width: deviceWidth, margin: 10}}
// source={{ uri: 'https://www.google.com/'}}
source={{
html:
'<script> function invokeHello() { window.ReactNativeWebView.postMessage("Hello") } function fillQRCode() { window.alert("filling qrcode"); document.getElementById("qr_code").value = "QR Code"; } function scanQRCode() { let data = {"nativeItemToAccess": "camera", "operation": { "type": "CALLBACK", "fieldId": "qr_code", "callback": `${fillQRCode}` }}; window.ReactNativeWebView.postMessage(JSON.stringify(data)); }</script> <!-- <form method="get" enctype="application/x-www-form-urlencoded" action="/html/codes/html_form_handler.cfm" onSubmit="invokeHello()"> --> <p><label>Name<input type="text" name="customer_name" required></label> </p> <p><label>Phone <input type="tel" name="phone_number" id="phone_number"></label></p> <p><label>QR Code <input type="text" disabled name="qr_code" id="qr_code"></label><p></p><button onclick="scanQRCode()">Scan</button></p></p> <p><button>Submit Booking</button></p><!-- </form> -->',
}}
// injectedJavaScript={runFirst}
ref={r => (this.webref = r)}
onMessage={event => {
if (this.webref) {
let data = JSON.parse(event.nativeEvent.data);
console.log('1: data being received: ', data);
if(data) {
switch(data.nativeItemToAccess) {
case 'camera':
this.performOperation(data);
break;
case 'test':
alert('test is invoked');
break;
}
}
}
}}
/>
在下面找到相同的 html,它是内联的(张贴只是为了使其更具可读性),
<script>
function invokeHello() { window.ReactNativeWebView.postMessage("Hello") }
function fillQRCode() { window.alert("filling qrcode"); document.getElementById("qr_code").value = "QR Code"; }
function scanQRCode() {
let data = {"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": `${fillQRCode}`
}};
window.ReactNativeWebView.postMessage(JSON.stringify(data));
}
</script>
<!-- <form method="get" enctype="application/x-www-form-urlencoded" action="/html/codes/html_form_handler.cfm" onSubmit="invokeHello()"> -->
<p><label>Name<input type="text" name="customer_name" required></label> </p>
<p><label>Phone <input type="tel" name="phone_number" id="phone_number"></label></p>
<p><label>QR Code <input type="text" disabled name="qr_code" id="qr_code"></label><p></p><button onclick="scanQRCode()">Scan</button></p></p>
<p><button>Submit Booking</button></p>
<!-- </form> -->
当我点击扫描按钮时,onMessage
被调用并且正确接收到传递的数据。我将根据收到的数据调用不同的函数。
下面是相机调用的函数,
performOperation = data => {
switch (data.operation.type) {
case 'FIELD_UPDATE':
this.updateField(data.operation.fieldId);
break;
case 'CALLBACK':
this.performCallback(data.operation.callback);
break;
}
};
performCallback = callback => {
console.log('2: callback: ', callback);
this.webref.injectJavaScript(`
try {
var fn = window[${callback}];
if (typeof fn === "function") {
fn();
} else {
window.alert('this is not a function '+ typeof fn);
}
true;
} catch (e) {
window.alert('unable to call the function: '+ e);
}
`);
};
updateField = fieldId => {
this.webref.injectJavaScript(`
document.getElementById("${fieldId}").value = "QR Code";
`);
};
performOperation
函数处理回调 javascript 方法,或者它只会填充一个文本框,具体取决于 data.operation.type
。所以现在 data.operation.type
是 CALLBACK
所以 performCallback
被调用,但我无法调用作为对象输入接收的函数。对象如下,
{"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": ${fillQRCode}
}};
fillQRCode
是 html 的 <script>
标签中的函数。
接收到的函数是字符串形式,如何转换为函数调用
我修改了传递函数的方式,
{"nativeItemToAccess": "camera", "operation": {
"type": "CALLBACK",
"fieldId": "qr_code",
"callback": "fillQRCode"
}};
也就是说,我没有传递整个函数(我现在觉得这是错误的做法),而是只传递函数名称并按如下方式调用函数,
performCallback = callback => {
console.log('2: callback: ', callback);
var qrCode = 'zdjkcnsjkdnsdkfjnjk';
this.webref.injectJavaScript(`
try {
${callback}("${qrCode}")
true;
} catch (e) {
window.alert('unable to call the function: '+ e);
}
`);
};