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>&mdash; 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>&mdash; 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 当前网页?

脚本在 WebView 中不适用于 react-native

可以在 React Native 的 WebView 中访问 Cookies 吗?