React Native 中 WebView 内的 Twitter 小部件
Posted
技术标签:
【中文标题】React Native 中 WebView 内的 Twitter 小部件【英文标题】:Twitter widget inside WebView in React Native 【发布时间】:2016-12-01 07:33:26 【问题描述】:我正在尝试在我的 React Native 应用程序的 WebView
中加载 Twitter 小部件,但我注入的 javascript 似乎由于某种原因无法正常工作。
我正在做的是异步加载 Twitter 脚本(函数采用 from here),然后在加载脚本时执行 twttr.widgets.load()
函数以绘制小部件。
有可能做到吗,还是我尝试使用默认的Webview
组件来实现不可能?
这是我的代码:
render()
let utils = ' \
function loadScript(src, callback) \
var s, r, t; \
r = false; \
s = document.createElement("script"); \
s.type = "text/javascript"; \
s.src = src; \
s.onload = s.onreadystatechange = function() \
if ( !r && (!this.readyState || this.readyState == "complete") ) \
r = true; \
callback(); \
\
; \
t = document.getElementsByTagName("script")[0]; \
t.parentNode.insertBefore(s, t); \
\
';
let twitter = ' \
loadScript("//platform.twitter.com/widgets.js", function () \
twttr.widgets.load(); \
); \
';
let JS = utils + twitter;
let source = '<blockquote class="twitter-tweet" data-lang="es"><p lang="en" dir="ltr">8 TED Talks to inspire projects with kids: <a href="https://twitter.com/TEDTalks/status/758116657638309896">https://twitter.com/TEDTalks/status/758116657638309896</a> <a href="https://twitter.com/TEDTalks/status/758116657638309896">pic.twitter.com/HMmYAeP7Km</a></p>— TED Talks (@TEDTalks) <a href="https://twitter.com/TEDTalks/status/758116657638309896">27 de julio de 2016</a></blockquote>';
return (
<WebView
source=html: source
javaScriptEnabled=true
injectedJavascript= JS
/>
);
【问题讨论】:
【参考方案1】:似乎在 WebView 中加载脚本不起作用(我不知道为什么)。因此,为了让它工作,我需要使用 script 标签加载 Twitter 的脚本并将其连接到我的 HTML 代码。
render()
let JS = '<script type="text/javascript" src="https://platform.twitter.com/widgets.js"></script>';
let source = JS + '<blockquote class="twitter-tweet" data-lang="es"><p lang="en" dir="ltr">8 TED Talks to inspire projects with kids: <a href="https://twitter.com/TEDTalks/status/758116657638309896">https://twitter.com/TEDTalks/status/758116657638309896</a> <a href="https://twitter.com/TEDTalks/status/758116657638309896">pic.twitter.com/HMmYAeP7Km</a></p>— TED Talks (@TEDTalks) <a href="https://twitter.com/TEDTalks/status/758116657638309896">27 de julio de 2016</a></blockquote>';
return (
<WebView
source=html: source
javaScriptEnabled=true
/>
);
【讨论】:
这个答案来自 2016 年。自那以后,React 生态系统发生了变化。 您能否分享一下发生了什么变化以及最新的方法是什么?谢谢。【参考方案2】:我像这样把它拼凑在一起,它大部分都可以工作,尽管高度不是可变的,这并不理想:
import React from "react"
import ReactNative from "react-native"
const View, WebView, StyleSheet, ActivityIndicator = ReactNative
export default class EmbeddedTweet extends React.Component
constructor(props)
super(props)
this.state =
loading: true,
embedHtml: null,
componentDidMount()
this.setupEmbed()
setupEmbed()
let tweetUrl =
"https://publish.twitter.com/oembed?url=" + encodeURIComponent(this.props.url)
fetch(tweetUrl, method: "GET", headers: Accepts: "application/json" ).then(
resp =>
resp.json().then(json =>
let html = json.html
this.setState(
loading: false,
embedHtml: html,
)
)
)
renderLoading()
if (this.state.loading)
return (
<View style=styles.loadingWrap>
<ActivityIndicator />
</View>
)
renderEmbed()
if (this.state.embedHtml)
let html = `<!DOCTYPE html>\
<html>\
<head>\
<meta charset="utf-8">\
<meta name="viewport" content="width=device-width, initial-scale=1.0">\
</head>\
<body>\
$this.state.embedHtml\
</body>\
</html>`
return (
<View style=styles.webviewWrap>
<WebView source= html: html style=styles.webview />
</View>
)
render()
return (
<View
style=[styles.container, height: this.props.height || 300 , this.props.style]
>
this.renderLoading()
this.renderEmbed()
</View>
)
const styles = StyleSheet.create(
container:
flex: 1,
,
loadingWrap:
flex: 1,
backgroundColor: "#999",
justifyContent: "center",
alignItems: "center",
,
webviewWrap:
flex: 1,
borderWidth: 1,
borderRadius: 4,
borderColor: "#999",
,
webview:
flex: 1,
,
)
【讨论】:
以上是关于React Native 中 WebView 内的 Twitter 小部件的主要内容,如果未能解决你的问题,请参考以下文章
WebView(react-native-webview)在 Expo SDK36 中获取错误代码 -1
React Native 问题:WebView 已从 React Native 中移除
有啥方法可以在 react-native-webview 中禁用 hapticFeedback
React-native:如何自动保存 webview 当前网页?