React Native中Android设备WebView的InjectionJavascript中的分派操作不起作用

时间:2018-11-15 09:11:44

标签: react-native webview android-webview

我有1个html,我需要获取图像标签的所有src属性。一切运行正常(iOS,Android虚拟机,iOS设备),但是只有Android Device,我无法获得src属性!请帮我!谢谢!

  

我的WebView

render() {
    const { source, style, ...otherProps } = this.props;
    const { realContentHeight } = this.state;
    const html = source.html;
    const number = this.addHeight(html);
    const addHeightMore = number * 220;

    return (
        <View style={{ flex: 1 }}>
            <View 
                style={{

                    paddingHorizontal: 5,
                }}
            >
                <WebView
                    {...otherProps}
                    source={{ 
                        html:`
                             <head></head>
                             <body style="font-size: ${sizeText}; text-align: left; padding: 5">
                                  ${templates[this.props.template](html)}
                             </body>
                            `
                    }}
                    onLoad={this.onLoad.bind(this)}
                    injectedJavaScript={this.injectedJavaScript()}
                    mixedContentMode={'compatibility'}
                    onMessage={this.onMessage.bind(this)}
                    scrollEnabled={false}
                    style={[{ height: Platform.OS === 'ios' ? realContentHeight : realContentHeight < screenHeight ? screenHeight : realContentHeight + addHeightMore}, style]}
                    javaScriptEnabled
                />
            </View>
        </View>
    )
}
  

injectedJavascript()

injectedJavaScript() {

    return ` 
        ${this.hackBefore()}

        function dispatchAction(action, params) {
            window.postMessage(JSON.stringify({
                action,
                params,
            }));
        };

        var imgs = [];

        document.querySelectorAll('img:not(.emoji):not(.embedded-img):not(.embedded-btn)').forEach(function (img, index) {
            var src = img.getAttribute('src');
            imgs.push(src);

            img.addEventListener('click', function (event) {
                dispatchAction('openGallery', {
                    index: index,
                });
            });
        });

        dispatchAction('addImages', {
            imgs: imgs,
        });

        ${this.hackAfter()}
    `
}
  

hackBefore

hackBefore(){         返回Platform.OS ==='ios'吗?          (function(){ var originalPostMessage = window.postMessage; var patchedPostMessage = function(message, targetOrigin, transfer) { originalPostMessage(message, targetOrigin, transfer); }; patchedPostMessage.toString = function() { return String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage'); }; window.postMessage = patchedPostMessage;         :          if (window.postMessage.length !== 1) { window.postMessage = function(msg) { setTimeout(function () { console.log('window.postMessage not ready'); window.postMessage(msg); }, 500); } }     }

  

hackAfter()

hackAfter() {
    return Platform.OS === 'ios' ? '})();' : ''
}
  

onMessage()

onMessage(event) {
    const { action, params } = JSON.parse(event.nativeEvent.data)

    switch (action) {
    case 'heightCaculated': {
        return this.setState({
        realContentHeight: params.height,
        isRendering: false,
        })
    }
    case 'addImages': {
        this.props.resetImages()
        // Prefetch image
        params.imgs.map(img => Image.prefetch(img))
        return this.props.addImages(params.imgs)
    }

    case 'openGallery':
        return navigator.navigate('Gallery', {
            index: params.index,
        })


    default:
        return null
    }
}
  

redux

   export default connect(null, {
    addImages,
    resetImages,
})(WebViewAutoHeight)

1 个答案:

答案 0 :(得分:0)

在生产中的Android设备上运行应用程序时,必须将HTML文件构建到Android资产目录-android/app/src/main/assets/index.html

然后,您的WebView源应指向该文件file:///android_asset/index.html。但仅在某些条件下

如果您使用的是Android,并且正在生产中运行,则源应为file:///android_asset/index.html。否则,将源指向本地HTML文件。

这是一个例子,我不确定您的项目的结构如何,但是您可以挑选所需的内容。

import React from 'react';
import { Platform, WebView } from 'react-native';

import localFile from '../index.html';

const MyWebView extends React.Component {
  isAndroid = () => Platform.OS === "android"
  isDev = () => __DEV__
  getSource = () => {
    if(this.isAndroid() && !this.isDev()) {
      return { uri: 'file:///android_asset/index.html' };
    }
    return localFile
  }
  render() {
    <WebView
      source={this.getSource()}
    />
  }
}