【问题标题】:How to fix styling of server-rendered html inside react-native-webview?如何修复 react-native-webview 中服务器渲染的 html 样式?
【发布时间】:2020-11-21 00:10:15
【问题描述】:

这真是令人头疼。我有一个服务器,它使用快速车把模板将 html/css/js 呈现给我的 react-native-webview。它需要以这种方式发生,我无法呈现静态站点/文件。

问题是页面加载时总是缩小。

在 android 上,有一个时间点可以很好地加载,但它会在一秒钟后改变,并离开屏幕。好像是在 JS 执行之后才发生的,但很难说。

此更改似乎与此服务器日志相关:

2020-11-20T23:46:09.276261+00:00 heroku[路由器]: at=info method=GET path="/favicon.ico" 主机=app.herokuapp.com request_id=7a59f27b-7f1d-4ca2-a649-96fedd5072c1 fwd="184.56.205.17" dyno=web.1 连接=1ms 服务=3ms 状态=404 字节=481 协议=https

在 iOS 上,它总是加载超级缩小。

在浏览器中测试它看起来一直很好。一旦从移动设备上查看,它就会一团糟。我怎样才能缓解这个问题,让它像在浏览器上加载一样加载?

这里是 react-native 方面:

<Modal
  visible={this.state.paymentMethodModal}
  transparent={true}
  animationType={'slide'}
  onRequestClose={() => this.setState({ paymentMethodModal: !this.state.paymentMethodModal })}
  style={{ backgroundColor: Colors.PRIMARY_DARK }} >
  <View style={{ borderTopLeftRadius: 15, borderTopRightRadius: 15, backgroundColor: Colors.PRIMARY_DARK, paddingTop: Platform.OS == 'ios' ? 50 : 15, width: width, height: height }}>
    <TouchableOpacity style={{ borderRadius: 20, backgroundColor: Colors.PRIMARY_WHITE, alignSelf: 'flex-start', marginLeft: 10, marginBottom: 5, paddingVertical: 8, paddingHorizontal: 15 }} onPress={() => { this.setState({ paymentMethodModal: !this.state.paymentMethodModal }) }}><Text>Close</Text></TouchableOpacity>
      <WebView
        style={{ height: height, width: width, backgroundColor: Colors.PRIMARY_DARK }}
        ref={(ref) => (this.webview = ref)}
        source={{ uri: this.API_ENDPOINT }}
        renderError={(error) => <View style={{ flex: 1 }}><Text>{error}</Text></View>}
        onError={syntheticEvent => {
          const { nativeEvent } = syntheticEvent;
          console.warn('WebView error: ', nativeEvent);
        }}
        startInLoadingState={true}
        renderLoading={() => <ActivityIndicator animating={true} size={"large"} style={{ alignSelf: 'center', position: 'absolute', top: '45%', left: '47%' }} color={Colors.PRIMARY_GREEN} />}
        scalesPageToFit={false}
        injectedJavaScript={`const meta = document.createElement('meta'); meta.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, user-scalable=0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta); `}
        />
    </View>
</Modal>

当到达终点时,渲染条带卡钱包的服务器:

res.render('card-wallet', {
  client_secret: setupIntent.client_secret,
  type: 'edit',
  customer: req.query.customer,
  style: 'card-wallet.css',
  javascript: 'card-wallet.js'
});

车把模板:

<div class="wrapper">
  <div class="content">
    <p class="bold text-lg primary-white">Payment Setup</p>
      <form action="/charge" method="post" id="payment-form" data-secret="{{ client_secret }}"
      data-payment_method_id="{{ payment_method_id }}" data-type="{{ type }}" data-customer="{{ customer }}">
        <div class="form-row">
          <input id="cardholder-name" type="text" name="cardholder-name" placeholder="Cardholder Name"></input>
          <div id="card-element">
            <!-- A Stripe Element will be inserted here. -->
          </div>
          <div id="status-wrapper" class="mt-10">
            <p id="status-msg" class="primary-alert text-md"></p>
          </div>
        </div>
        <button id="save-button">Save Card</button>
      </form>
      <div id="spinner" class="spinner-grow text-light"></div>
        <div id="success-wrapper">
          <p id="success-msg" class="text-md primary-white italic"></p>
      </div>
      <div class="auth-wrapper">
        <p id="agreement" class="text-sm primary-white italic">Clicking 'Save Card' means you authorize this app to send payment instructions to your card issuer in accordance with our application policies. </p>
      </div>
   </div>
</div>

将 card-wallet.css 和 card-wallet.js 放入一个 pastebin 以保持这篇文章的简短。

card-wallet.css:https://pastebin.com/q4ZuYnTN

card-wallet.js:https://pastebin.com/LqykSwvK

在浏览器上:

在 iPhone 上:

当它看起来像我想要的方式时(在班次之前)在 android 上显示:

轮班后的android:

我想要的只是让所有这些体验完全相同。我该如何处理(比如在浏览器上)?

更新:我设法让它在没有缩小的情况下渲染,仅在 iPhone 上。我只需将&lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt; 添加到主车把模板。但转移问题在 android 上仍然存在

【问题讨论】:

    标签: react-native react-native-android react-native-ios express-handlebars react-native-webview


    【解决方案1】:

    最终解决了与元标记相关的问题。

     <meta name="viewport" content="width=device-width, initial-scale=1" />
    

    我不得不:

    1. 将该标签移动到服务器呈现的 html 中(已解决 iOS)

    2. 删除 webview 上的注入 JavaScript 属性,该属性用于设置元标记(这解决了 android shift)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2015-06-02
      • 2019-01-05
      • 1970-01-01
      • 2015-05-30
      • 2015-03-09
      • 2021-10-16
      相关资源
      最近更新 更多