我无法在ReactNative上获取Webview以在物理Android设备上执行注入的JavaScript。在过去的两天里,我尽可能地搜索网络,但仍未找到解决方案。测试结果如下:
我的Webview定义如下:
<WebView
style={styles.webView}
source={{
html: html,
baseUrl: 'web/'
}}
injectedJavaScript={'render(' + JSON.stringify(this.state.data) + ');'}
javaScriptEnabledAndroid={true}
scrollEnabled={false}
bounces={false}
renderLoading={() => <LoadingIndicator />}
/>
我也尝试过指定javaScriptEnabled
,但无济于事。我还尝试使用较小的脚本来对页面上的元素进行着色或使用window.postMessage
将消息发回给应用程序,但没有任何反应。我需要将数据注入HTML,这将根据提供的数据为我呈现图形。我最后的办法是手动构建HTML,并附加数据作为提供给Webview的标记的一部分,但我真的很想保持简单,只需按照工作方式< /强>
我使用的是最新版本的ReactNative(0.41),手机正在运行Android 6 +。
答案 0 :(得分:6)
我刚刚发现Android WebView似乎将任何JS注入单行,即使它包含换行符。这意味着丢失的分号肯定会导致问题,或者在我的情况下,由//
分隔的注释。使用/*
和*/
进行评论后,我的注入JavaScript再次运行。
答案 1 :(得分:4)
好吧,在将这个问题暂时搁置一段时间并找到(不那么优雅)问题的解决方案之后,我决定分享我最终做的事情:
const html = '<html>...<script>...[INJECTEDSCRIPT]</script></html>';
componentDidMount()
事件中检索了数据,并使用this.setState({ data: retrievedData });
injectedJavaScript
属性以我想要的方式工作(如问题中所述),我求助于替换{{1带有序列化数据的HTML常量中的值。我知道,这不是最优雅的解决方案,但它是唯一一个可以在多种设备和仿真器配置中可靠工作的解决方案。示例,为简洁起见编辑,如下:
[INJECTEDSCRIPT]
答案 2 :(得分:0)
我一直在努力使Javascript(预嵌入和注入)也能执行。到目前为止,一个简单而更好的解决方案是使用WebViewBridge。之后,一切都按预期进行。这里是软件包的链接:cnpmjs.org/package/react-native-webview-bridge。
这里有一个演示:
import React, {
Component
} from 'react';
import PropTypes from 'prop-types';
import {
Platform,
WebView,
ActivityIndicator,
} from 'react-native';
import WevViewBridge from 'react-native-webview-bridge';
// TODO: Keep in mind that you should ALWAYS edit
// two separate file and keep them matched.
const IOS_WEB_PAGE_SOURCE = './webPage/wordBody.html';
const ANDROID_WEB_PAGE_SOURCE = 'file:///android_asset/webPage/wordBody.html';
export default class WordBody extends Component {
static propTypes = {
data: PropTypes.object.isRequired,
}
_injectedScript = `
(function(){
let data = ${JSON.stringify(this.props.data)};
refresh(data);
})();
`;
render() {
/*
* We are using Platform.select here for two reasons:
* 0. Everythig work fine for IOS using `WebView` from RN
* 1. Android doesn't load web ressource with `require`
* 2. On Android, `WebView` from react-native doesn't
* execute JavaScript so we use `WebViewBridge`.
*/
return Platform.select({
ios: (<WebView
style = {{backgroundColor: 'rgba(0, 0, 0, 0)', flex:1,}}
scalesPageToFit
source = {require(IOS_WEB_PAGE_SOURCE)}
javaScriptEnabled={true}
originWhitelist={['*']}
injectedJavaScript = {this._injectedScript}
renderLoading={() => <ActivityIndicator/>}
/>),
android: (<WevViewBridge
style = {{backgroundColor: 'rgba(0, 0, 0, 0)', flex:1,}}
scalesPageToFit
source = {{uri:ANDROID_WEB_PAGE_SOURCE}}
javaScriptEnabled={true}
// originWhitelist={['*']}
injectedJavaScript = {this._injectedScript}
renderLoading={() => <ActivityIndicator/>}
/>)
});
};
}