具有 contenteditable 的 Webview 无法以编程方式聚焦 [英] Webview with contenteditable cannot be focused programmatically

查看:14
本文介绍了具有 contenteditable 的 Webview 无法以编程方式聚焦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用户第一次点击控件之前,尝试在 WebView 上执行 requestFocus() 不起作用.

Trying to do a requestFocus() on the WebView does not work until the user has first clicked on the control.

我知道这一定是可能的,因为 htmlEditor 可以通过这种方式聚焦(我怀疑它是基于可编辑的 WebView).

I know this must be possible as htmlEditor can be focused this way (and I suspect it is based on a contenteditable WebView).

我正在使用带有contenteditable"的 webview 编写我自己的专用 htmlEditor,我真的希望能够像使用标准 htmlEditor 一样聚焦它.

I am coding my own specialized htmlEditor using a webview with "contenteditable" and I would really like to be able to focus it like I can do with the standard htmlEditor.

我相信这一定是 Javafx 的一个问题,我已经将它提交给了 Jira,但我想知道是否有人能想到解决这个问题的方法.

I believe this must be an issue with Javafx and I have already submitted it to Jira, but I wonder if anyone can think of a work-around for this.

更新:jira 中的问题编号:RT-21695

UPDATE: Issue number in jira: RT-21695

简短的演示代码:

/* Demo webview */

public class WebViewConteneditableDemo extends Application {


String initialEditview = "<html><head>"
        + "</head><body contenteditable='true'>"
        +"</body></html>";

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Webview focus demo");


    final WebView editor = new WebView();

    Button btn = new Button();
    btn.setText("Test Webview focus");
    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
           editor.requestFocus();
        }
    });

    BorderPane root = new BorderPane();
    root.setTop(btn);

    root.setCenter(editor);
    editor.getEngine().loadContent(initialEditview);

    primaryStage.setScene(new Scene(root, 500, 450));
    primaryStage.show();
}

}

推荐答案

requestFocus api 只是请求焦点,不保证焦点.

The requestFocus api is just a request for focus, it does not guarantee focus.

有时其他 JavaFX 控件的内部实现在您请求焦点之前或之后请求焦点,这最终在您的 requestFocus 调用中没有任何效果.

Sometimes the internal implementation of other JavaFX controls request focus before or after you have requested focus which ends up in your requestFocus call not having any effect.

通常,您可以通过将它包装在 Platform.runLater 或使用 时间线 带有 KeyFrame 在延迟后调用 requestFocus.

Often you can make the requestFocus call take effect by either wrapping it in a Platform.runLater or using a Timeline with a KeyFrame which invokes requestFocus after a delay.

如果这些都不起作用,那么 WebView 的 requestFocus 处理中可能存在错误,JavaFX 团队可以在您提交的 jira 上下文中解决该错误.

If neither of those work, then there is likely a bug in the requestFocus processing for WebView which the JavaFX team can address in the context of the jira you filed.

更新

问题中示例代码的具体问题是,虽然 WebView 获得了焦点,但 WebView 中的可编辑内容元素没有获得焦点.

The specific issue in the sample code in the question was that, although the WebView was focused, the editable content element in the WebView was not focused.

我尝试只加载示例代码中的 html 进入 firefox,它的行为与 JavaFX WebView 完全相同(即可编辑的内容元素在被点击之前不会被聚焦).所以我不认为这是 WebView 的问题.

I tried loading just the html from the sample code <html><head></head><body contenteditable='true'></body></html> into firefox and it behaved exactly the same as the JavaFX WebView (i.e. the editable content element was not focused until it was clicked on). So I don't believe this is an issue with WebView.

要获得可编辑元素的焦点,您需要在需要焦点时执行一些脚本,例如在 javascript onload hook <body onLoad='document.body.focus();'contenteditable='true'/>

To get the editable element focused, you need to execute some script when you want it focused, for example in the javascript onload hook <body onLoad='document.body.focus();' contenteditable='true'/>

这是一个可执行的示例应用程序,它演示了 JavaFX WebView 中 contenteditable 元素的焦点行为的编程控制:

Here is an executable sample application which demonstrates programmatic control of focus behaviour of contenteditable elements in a JavaFX WebView:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewEditable extends Application {
  String content = "<body bgcolor='cornsilk' onLoad='document.body.focus();' contenteditable='true'/>";
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) {
    final WebView editor = new WebView();
    editor.getEngine().loadContent(content);

    Button webviewFocusButton = new Button("Focus on WebView");
    webviewFocusButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        editor.getEngine().executeScript("document.body.focus()");
        editor.requestFocus();
      }
    });
    Button selfFocusButton = new Button("Focus on this Button");

    Label focusLabel = new Label();
    focusLabel.textProperty().bind(Bindings
      .when(editor.focusedProperty())
        .then("WebView has the focus.")
        .otherwise("WebView does not have the focus.")
    );
    focusLabel.setMaxWidth(Double.MAX_VALUE);
    focusLabel.setStyle("-fx-background-color: coral; -fx-padding: 5;");

    BorderPane layout = new BorderPane();
    layout.setTop(HBoxBuilder.create().spacing(10).children(webviewFocusButton, selfFocusButton).style("-fx-padding: 10; -fx-background-color: palegreen").build());
    layout.setCenter(editor);
    layout.setBottom(focusLabel);
    stage.setScene(new Scene(layout));
    stage.show();
  }
}

这篇关于具有 contenteditable 的 Webview 无法以编程方式聚焦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆