React Native集成OpenLayers时,通过WebView调用JS函数失败的问题求助
React Native集成OpenLayers时,通过WebView调用JS函数失败的问题求助
各位好,我现在在开发一个React Native结合OpenLayers的应用,遇到了一个卡住的问题:我有两个项目,一个是写了OpenLayers地图的JS项目,里面定义了showMiddlemarker()和hideMiddlemarker()两个函数;另一个是React Native项目,我想通过WebView组件调用这两个函数,但用injectJavaScript方法完全没效果,想请大家帮忙排查下原因!
我的实现逻辑
- 在React Native中加载本地的
index.html(对应OpenLayers的地图页面) - 用一个
swch状态来控制调用显示/隐藏中间标记的函数,状态变化时会触发injectJavaScript的执行 - 已经确认
swch状态在正确变化(console.log能输出对应的值),但WebView里的函数就是没被触发 - 另外我测试了
onMessage方法是能正常工作的,只有injectJavaScript调用函数这里出问题
React Native端代码
import { useAssets } from "expo-asset"; import { useContext, useEffect, useRef, useState } from "react"; import { useWindowDimensions } from "react-native"; import WebView from "react-native-webview"; import { Context } from "../App"; const Page = () => { const [assets] = useAssets([require("../assets/index.html")]); const [htmlString, setHtmlString] = useState<string>(); const pageDimensions = useWindowDimensions(); const webViewRef = useRef<WebView | null>(null); const [add, setAdd, swch] = useContext(Context); useEffect(() => { if (assets) { fetch(assets[0].localUri || "") .then((res) => res.text()) .then((html) => setHtmlString(html)); } }, [assets]); useEffect(() => { if (webViewRef.current) { console.log(swch) const functionToCall = swch ? "showMiddlemarker();" : "hideMiddlemarker();"; webViewRef.current.injectJavaScript(`${functionToCall}; true;`); } }, [swch]); if (!htmlString) { return null; } return ( <WebView ref={(r) => (webViewRef.current = r)} javaScriptEnabled source={{ html: htmlString, }} style={{ width: pageDimensions.width, height: pageDimensions.height, }} scrollEnabled={false} overScrollMode="never" showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} scalesPageToFit={false} containerStyle={{ flex: 1 }} onLoad={() => { webViewRef.current?.injectJavaScript(` function showMiddlemarker() { console.log("Showing marker"); markerElement.style.display = "block"; } function hideMiddlemarker() { console.log("Hiding marker"); markerElement.style.display = "none"; } true; `); }} /> ); }; export default Page;
OpenLayers端JS代码
import "./style.css" import Feature from 'ol/Feature.js'; import Map from 'ol/Map.js'; import Overlay from 'ol/Overlay.js'; import Point from 'ol/geom/Point.js'; import View from 'ol/View.js'; import {Icon, Style} from 'ol/style.js'; import {OGCMapTile, OSM, Vector as VectorSource} from 'ol/source.js'; import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js'; import { fromLonLat } from 'ol/proj'; const coords = fromLonLat([25.91667,47.85]) const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM(), }), ], view: new View({ center: coords, zoom: 13, }), }); const marker = new VectorLayer({ source: new VectorSource({ features:[ new Feature({ geometry: new Point( coords ) }) ] }), style: new Style({ image: new Icon({ src:"https://i.imgur.com/oOGwJW8.png", scale:0.07 }) }) }) const markerElement = document.createElement("div"); markerElement.className = "marker"; markerElement.style.width = "32px"; markerElement.style.height = "32px"; markerElement.style.backgroundImage = "url('https://i.imgur.com/oOGwJW8.png')"; markerElement.style.backgroundSize = "contain"; markerElement.style.position = "absolute"; markerElement.style.transform = "translate(-50%, -50%)"; markerElement.style.display = "block" const markerOverlay = new Overlay({ element: markerElement, positioning: "center-center", stopEvent: false, }); map.addOverlay(markerOverlay); map.getView().on("change:center", () => { const center = map.getView().getCenter(); markerOverlay.setPosition(center); }); markerOverlay.setPosition(coords); //map.addLayer(marker) function hideMiddlemarker() { markerElement.style.display = "none"; } function showMiddlemarker() { markerElement.style.display = "block"; }
当前效果截图
目前地图能正常加载显示,中间标记也能正常显示,就是没法通过React Native的状态切换来控制它的显示隐藏:
备注:内容来源于stack exchange,提问作者Tecleanu Ionut
相关产品推荐
相关产品推荐

