首页 > 解决方案 > 如何让 Android 中的 React Native 知道 Highcharts 图表中工具提示中的点击事件?

问题描述

我有一个用 Expo 构建的 React Native 应用程序。关于如何在将在移动浏览器上打开的 Highcharts 工具提示中添加链接?我能够将 URL 传递给 Highcharts,以便在单击工具提示时打开该 URL:

return(
    <View style={styles.container}>
        <ChartView
            onMessage={m => this.onMessage(m)}
            config={config}
        />
    </View>

这会触发此方法打开 URL:

onMessage = (m) => {
    let data = JSON.parse(m.nativeEvent.data);
    Linking.openURL(data.url)
};

并且 URL 通过全局变量填充window.myURL并发送消息postMessage()

render() {
    let Highcharts = "Highcharts";
    let config ={
        ...
        plotOptions: {
            series: {
                stickyTracking: false,
                point: {
                    events: {
                        click: function(e) {
                            window.postMessage(JSON.stringify({'url': window.myUrl}));
                        }
                    }
                }
            },
        },
        tooltip: {
            useHTML: true,
            formatter: function () {
                window.myUrl = extras.url;
                return `<div class="text">some text</div>`;
            }
    };

这在 iOS(物理和仿真器)上运行良好,但在 Android 上不起作用(物理和仿真器都不是)。

我经历了不同的 Github 问题,例如onMessage 未在本机代码中调用,即使从 webview(android)发送并且反应原生 html postMessage 无法到达 WebView,他们倾向于建议在window.postMessage(). 但是,我发现即使这样也行不通:

plotOptions: {
    series: {
        point: {
            events: {
                click: function(e) {
                    setTimeout(function() {
                        console.log('bla');
                        window.postMessage(JSON.stringify({'url': window.myUrl}));
                    }, 200);
                }
            }
        }
    },
},

由于 evenconsole.log()不起作用,在我看来,该click事件似乎没有被 Android 捕获。

如何让 Android 知道此事件,以便我可以浏览消息然后打开 URL?

标签: react-nativehighchartsreact-native-androidreact-highcharts

解决方案


"click"活动很好。问题是,RN 核心的<WebView>Android 实现在 polyfilling 方面存在缺陷window.postMessage()。这个问题已经在这个 github issue中得到了很好的讨论。

所以看起来问题的本质,是 RNwindow.postMessage出于某种原因必须对原生进行 polyfill,但是覆盖没有及时发生,导致window.postMessage仍然对原生进行调用。

该 github issue 中提出的一种解决方案(适用于 Android)是简单地停止使用 native window.postMessage,并直接使用内部接口,这是实际的 polyfill 函数。

// in place of `window.postMessage(data)`, use:
window.__REACT_WEB_VIEW_BRIDGE.postMessage(String(data))

不过请注意,此 API 不是公开的,将来可能会发生变化。


推荐阅读