我有一个已升级的 React Native 应用程序。回到旧时代,如果您访问一篇新闻文章,该文章有超链接,并且您单击了超链接,它会将您重定向到手机浏览器并打开那里的链接,但它不再这样做,因为我们必须升级react-native-autoheight-webview
库,所以为 0.6.1 版本所做的补丁现在已经消失了。该补丁允许超链接在单独的浏览器中打开。
我一直在尝试重复这个过程,以便我们能够得到相同的行为。所以我将此代码添加到 node_modules/react-native-autoheight-webview/AutoHeightWebView/index.js
文件:
const _onLoadStart = event => {
if (event.nativeEvent.url.startsWith("http")) {
this.stopLoading();
Linking.openURL(event.nativeEvent.url).catch(err => console.log('An error occurred', err));
} else {
const {onLoadStart} = this.props;
onLoadStart && onLoadStart(event);
}
}
const { currentSource, script } = reduceData(props);
const { width, height } = size;
useEffect(
() =>
onSizeUpdated &&
onSizeUpdated({
height,
width
}),
[width, height, onSizeUpdated]
);
return (
<WebView
{...props}
ref={webView}
onMessage={handleMessage}
onLoadStart={_onLoadStart}
style={[
styles.webView,
{
width,
height
},
style
]}
injectedJavaScript={script}
source={currentSource}
/>
);
}),
(prevProps, nextProps) => !shouldUpdate({ prevProps, nextProps })
);
但这没有任何作用。
我也在同一个文件中尝试过这个:
const uri = `${media}/1.0/articles`;
return (
<WebView
{...props}
ref={webView}
onMessage={handleMessage}
source={{uri}}
onNavigationStateChange={(event) => {
if (event.url !== uri) {
this.webview.stopLoading();
Linking.openURL(event.url);
}
}}
style={[
styles.webView,
{
width,
height
},
style
]}
injectedJavaScript={script}
source={currentSource}
/>
);
什么也没有。
我无法返回<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c9bbaca8aabde4a7a8bda0bface4a8bcbda6a1aca0aea1bde4beacabbfa0acbe89f9e7ffe7f8" rel="noreferrer noopener nofollow">[email protected]</a>
并制作另一个补丁包,因为该版本与React Native 60s版本控制不兼容,即我们不再使用index.ios.js/index.android.js
而是 index.js
。
最早的包裹react-native-autoheight-webview
将是 1.0.0 并且该版本没有实际意义,因为 WebView
和Linking
模块不再位于 react-native
中图书馆,但在 react-native-webview
内库,它看起来并不支持相同的属性来让用户在单独的浏览器中打开超链接,而不是在应用程序的 Web View 中打开超链接。至少我的尝试没有成功。
我还尝试了免费套餐react-native-webview-bridge
来救援,但该包开始使我的应用程序在 iOS 和 Android 端崩溃,所以这不是一个可行的解决方案。以下是此方法失败的几个示例:
Undefined symbols for architecture arm64:
"_RCTJSNavigationScheme", referenced from:
-[RCTWebViewBridgeManager constantsToExport] in libReact-Native-Webview-Bridge.a(RCTWebViewBridgeManager.o)
-[RCTWebViewBridge webView:shouldStartLoadWithRequest:navigationType:] in libReact-Native-Webview-Bridge.a(RCTWebViewBridge.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
在 iOS 端,在 Android 端我收到此错误:
2019-10-17 13:01:14.292 15725-15839/com.nfibengage.dv E/AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
Process: com.nfibengage.dv, PID: 15725
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/facebook/react/views/webv
我想最终,我如何成功地指示我的应用程序通过从 DOM 与 React Native 通信来在外部浏览器中打开外部链接?
我在 `node_modules/react-native-autoheight-webview/AutoHeightWebView/index.js 中尝试了此配置:
jsCode = () => {
const attachEvent = function(elem, event, callback) {
event = event.replace(/^on/g, '');
if ('addEventListener' in window) {
elem.addEventListener(event, callback, false);
} else if ('attachEvent' in window) {
elem.attachEvent('on' + event, callback);
} else {
const registered = elem['on' + event];
elem['on' + event] = registered ? function(e) {
registered(e);
callback(e);
} : callback;
}
return elem;
}
const all_links = document.querySelectorAll('a[href]');
if (all_links) {
for (var i in all_links) {
if (all_links.hasOwnProperty(i)) {
attachEvent(all_links[i], 'onclick', function(e) {
if (!new RegExp('^https?:\/\/' + location.host, 'gi').test(this.href)) {
// handle external URL
e.preventDefault();
window.postMessage(JSON.stringify({
external_url_open: this.href
}));
}
});
}
}
}
}
render() {
const { height, width } = this.state;
const { style, originWhitelist } = this.props;
const { source, script } = this.getUpdatedState(this.props, getBaseScript);
return (
<WebView
{...this.props}
originWhitelist={originWhitelist || ['*']}
ref={this.webView}
onMessage={this.onMessage}
style={[
styles.webView,
{
width,
height
},
style
]}
injectedJavaScript={this.jsCode}
source={source}
/>
);
}
}
使用本文档作为指南: https://medium.com/@elhardoum/opening-external-links-in-browser-in-react-native-webview-18fe6a66312a
它对我没有任何帮助。
接下来我尝试添加 onNavigationStateChange
属性(property)归我ActionAlertFeedCard
:
import React from "react";
import {
Text,
StyleSheet,
View,
TouchableOpacity,
Platform
} from "react-native";
import { WebView } from "react-native-webview";
import { TextButton } from "react-native-material-buttons";
import PropTypes from "prop-types";
import format from "date-fns/format";
import { Card, Divider } from "common-components";
import { v2Colors, feedContentStyles, v2ButtonStyles } from "theme";
import { moderateScale } from "react-native-size-matters";
//prettier-ignore
const getHtml = content => `<body style="font-family: -apple-system, Roboto, sans-serif; font-size: ${moderateScale(32, 0.2)}px;">${content}</body>`;
const ActionAlertFeedCard = ({
completed,
content,
datePosted,
mainActionButtonPress,
secondaryActionButtonPress,
style,
title
}) => (
<Card style={style}>
<View style={feedContentStyles.header}>
<Text style={feedContentStyles.title}>{"ACTION ALERT"}</Text>
<Text style={feedContentStyles.postDate}>
{`${completed ? "Completed" : "Posted"} ${format(
datePosted,
"MMM D, YYYY"
)}`}
</Text>
</View>
<Divider />
<View style={feedContentStyles.content}>
<Text style={feedContentStyles.contentTitle}>{title}</Text>
<WebView
useWebKit={true}
scrollEnabled={false}
style={styles.webview}
source={{
html: getHtml(content)
}}
onNavigationStateChange={event => {
console.log("url of webpage" + event.url);
}}
// scalesPageToFit={Platform.OS !== "ios"}
/>
新闻文章从未完成加载。
最佳答案
如果您希望所有超链接在外部浏览器中打开,那么您尝试过的此方法应该有效:
onNavigationStateChange={(event) => {
console.log("url of webpage: "+ event.url);
if (event.url !== uri) {
this.webview.stopLoading();
Linking.openURL(event.url);
}
}}
其中 uri 是您最初加载的文章的 URL。 如果它不起作用,请尝试保留控制台日志并检查该事件是否被触发。
无需应用任何补丁或其他东西,您可以简单地将react-native-autoheight-webview与react-native-webview一起使用。
webview 库页面上有关于此的指南:https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#controlling-navigation-state-changes
关于reactjs - 重构 AutoHeightWebView 库以获取在单独的浏览器中打开的超链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58400606/