【问题标题】:How to focus a <WebView> in react native?如何在本机反应中聚焦 <WebView>?
【发布时间】:2018-10-06 01:42:33
【问题描述】:

我正在寻找一种方法来自动聚焦输入/文本区域字段或触发 React Native 中 WebView 组件内的点击。自动对焦背后的目标是确保键盘立即弹出...

有人有什么想法吗?打开或关闭键盘的提示也很有用...

我也在这里提交了一个问题:https://github.com/facebook/react-native/issues/18965

【问题讨论】:

  • webview 是一个不受react-native 控制的沙盒容器。如果我记得,您将无权操作视图的 UI 控件。您要么必须在 react-native 中生成 UI,要么接受从 webview 获得的内容。如果有人知道不同,请随时纠正我。
  • 这个怎么样,我可以通过编程方式触发 WebView 上的“点击”,就好像我是用户点击 WebView 一样?
  • 是的。 web-view 本身是一个 react-native 对象。因此,它应该响应触摸事件。一旦焦点移动到 web 视图,它就超出了 RN 范围。
  • “所以,它应该响应触摸事件”如何在没有用户输入的情况下手动/以编程方式触发?
  • 我没有这样做的确切功能。但我认为它会类似于这个github.com/erikras/redux-form/issues/3065

标签: react-native


【解决方案1】:

https://facebook.github.io/react-native/docs/webview.html#injectedjavascript

您可以在 WebView 页面上执行任何 javascript

let injectScript = `document.querySelector('#myInput').focus();`;

<WebView
        injectedJavaScript={injectScript}
        source={{uri:"XXX"}}
        startInLoadingState
      />

【讨论】:

  • 抱歉回复慢。我不得不找时间来测试这个解决方案。根据原始问题“自动对焦背后的目标是确保键盘立即弹出”。但是这个解决方案不会这样做,因为注入的 JavaScript 不能为 WebView 本身请求焦点。
【解决方案2】:

更新:自从我发布此内容后,有人创建了这个具有“自动对焦”功能的模块:https://github.com/TryImpossible/react-native-enhance-webview (解决方案2)


在研究了一下之后我看到了 2 个解决方案。

  1. Fork React Native 并调整 WebView 组件。

需要将以下更改应用到https://github.com/facebook/react-native/blob/6e359c4589b0627de59332ce56fe28804425a609/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java#L545

    view.loadUrl(url, headerMap);
    view.requestFocus();
    return;

添加的 view.requestFocus(); 将焦点放在 WebView 上。之后,在 WebView 中,您需要在一些 HTML 元素上调用 .focus()

  1. 第二个解决方案是基于 WebView 编写一个自定义的原生组件,这是一个更简单的解决方案,因为分叉和重建 React Native 有点工作......

帮助解决此解决方案的最佳资源是遵循以下两篇文章:

https://lakshinkarunaratne.wordpress.com/2018/01/22/enhancing-the-react-native-webview-part-1-supporting-file-uploads-in-ios-android/

https://lakshinkarunaratne.wordpress.com/2018/03/11/enhancing-the-react-native-webview-part-2-supporting-file-downloads-in-android/

本机组件中最重要的文件是AdvancedWebviewManager.java。在那里,您可以覆盖或定义一个新的 source 方法,该方法将在加载 URL 后调用 .requestFocus()

package your.package.advancedwebview;

import android.webkit.WebView;

import javax.annotation.Nullable;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.webview.ReactWebViewManager;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Locale;

public class AdvancedWebviewManager extends ReactWebViewManager {
    public WebView webview = null;

    public static final String REACT_CLASS = "AdvancedWebview";

    private AdvancedWebviewPackage aPackage;
    public String getName() {
        return REACT_CLASS;
    }

    @ReactProp(name = "sourceFocus")
    public void setSource(WebView view, @Nullable ReadableMap source) {
        if (source != null) {
            if (source.hasKey("html")) {
                String html = source.getString("html");
                if (source.hasKey("baseUrl")) {
                    view.loadDataWithBaseURL(
                            source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
                } else {
                    view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING);
                }
                return;
            }
            if (source.hasKey("uri")) {
                String url = source.getString("uri");
                String focusKeyboard = source.getString("focusKeyboard");
                String previousUrl = view.getUrl();
                if (previousUrl != null && previousUrl.equals(url)) {
                    return;
                }
                if (source.hasKey("method")) {
                    String method = source.getString("method");
                    if (method.equals(HTTP_METHOD_POST)) {
                        byte[] postData = null;
                        if (source.hasKey("body")) {
                            String body = source.getString("body");
                            try {
                                postData = body.getBytes("UTF-8");
                            } catch (UnsupportedEncodingException e) {
                                postData = body.getBytes();
                            }
                        }
                        if (postData == null) {
                            postData = new byte[0];
                        }
                        view.postUrl(url, postData);
                        return;
                    }
                }
                HashMap<String, String> headerMap = new HashMap<>();
                if (source.hasKey("headers")) {
                    ReadableMap headers = source.getMap("headers");
                    ReadableMapKeySetIterator iter = headers.keySetIterator();
                    while (iter.hasNextKey()) {
                        String key = iter.nextKey();
                        if ("user-agent".equals(key.toLowerCase(Locale.ENGLISH))) {
                            if (view.getSettings() != null) {
                                view.getSettings().setUserAgentString(headers.getString(key));
                            }
                        } else {
                            headerMap.put(key, headers.getString(key));
                        }
                    }
                }
                view.loadUrl(url, headerMap);
                if (focusKeyboard.equals("focus")) {
                    view.requestFocus();
                }
                return;
            }
        }
        view.loadUrl(BLANK_URL);
    }


    public void setPackage(AdvancedWebviewPackage aPackage){
        this.aPackage = aPackage;
    }

    public AdvancedWebviewPackage getPackage(){
        return this.aPackage;
    }
}

这基本上是从https://github.com/facebook/react-native/blob/6e359c4589b0627de59332ce56fe28804425a609/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java#L545 复制和扩展ReactWebViewManager.java 文件

【讨论】:

    【解决方案3】:

    在最新版本的react-native-webview 中,WebView 得到了方法requestFocus()。它尚未记录,因此请谨慎使用。

    我也在寻找解决方案,它在 Android 上运行良好。

    https://github.com/react-native-community/react-native-webview/commit/6f053bad7be666d09b49e403931656d6b4fa410a#diff-bad447a30759e328812e9bae6798621cR21

    【讨论】:

      猜你喜欢
      • 2020-05-02
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多