繁体   English   中英

JavaFX WebView中的Javascript

[英]Javascript in JavaFX WebView

我是Java和JavaFX的新手,我只是想知道JavaFX的webview是否可以自己运行javascript,除了它与java代码的通信。 例如,我可以在窗口加载时在webview中运行javascript警告语句,并在webview中实际获得警报,就像在普通浏览器中一样。 我知道我可以用我的java代码捕获这个警报事件

webEngine.setOnAlert

但我实际上希望javascript事件发生在webview窗口本身,就像在普通浏览器中一样。

我问这个简单问题的原因是因为我正在使用带有textarea的webview,我想启用拼写检查。 我有一个javascript拼写检查程序,在普通浏览器中完美运行,当我输入错误时我得到红色下划线,但我也想让它在JavaFX webview中工作。

我很感谢能得到任何帮助!

WebView JavaScript回调处理程序示例

以下是一些基于JavaScript触发器命令显示JavaFX对话框的示例代码 示例代码用于JavaScript确认处理程序,但警报处理程序的代码功能类似。

在示例屏幕截图中,左侧的黄色条将显示一个JavaFX标签,该标签基于由WebView调用的JavaScript函数触发的确认对话框的结果,该函数覆盖屏幕的其余部分。

确认对话框在WebView顶部的JavaFX中呈现,在显示对话框时阻止与WebView的交互。 确认对话框的样式只是一个示例,它可以使用css以任何方式设置样式,并且布局也可以在代码中更改(或者如果您愿意,可以在FXML标记中定义对话框布局)。

webviewconfirm

WebViewConfirm.java

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.BoxBlur;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.*;
import javafx.util.Callback;

/**
 * Demonstrates a modal WebView confirm box in JavaFX.
 * Dialog is rendered upon a blurred background.
 * Dialog is translucent.
 * Requires JavaFX 2.2
 * To test, run the program, then click the "Try it" button in the Result textarea.
 */
public class WebViewConfirm extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(final Stage primaryStage) {
    // initialize the stage
    primaryStage.setTitle("Modal Confirm Example");
    final WebView webView = new WebView();
    webView.getEngine().load("http://www.w3schools.com/js/tryit.asp?filename=tryjs_confirm");

    // layout the stage - a vbox to show confirmation results and a webview to generate confirmations.
    final VBox confirmationResults = new VBox();
    confirmationResults.getStyleClass().add("confirmation-results");
    confirmationResults.setMinWidth(150);
    HBox layout = new HBox();
    layout.getChildren().addAll(confirmationResults, webView);
    primaryStage.setScene(new Scene(layout));
    primaryStage.show();
    primaryStage.getScene().getStylesheets().add(getClass().getResource("modal-dialog.css").toExternalForm());

    // show the confirmation dialog each time a new page is loaded and
    // record the confirmation result.
    webView.getEngine().setConfirmHandler(new Callback<String, Boolean>() {
      @Override public Boolean call(String msg) {
        Boolean confirmed = confirm(primaryStage, msg);
        confirmationResults.getChildren().add(new Label("Confirmed? " + confirmed));
        return confirmed;
      }
    });
  }

  private Boolean confirm(final Stage parent, String msg) {
    final BooleanProperty confirmationResult = new SimpleBooleanProperty();
    // initialize the confirmation dialog
    final Stage dialog = new Stage(StageStyle.TRANSPARENT);
    dialog.initOwner(parent);
    dialog.initModality(Modality.WINDOW_MODAL);
    dialog.setScene(
      new Scene(
        HBoxBuilder.create().styleClass("modal-dialog").children(
          LabelBuilder.create().text(msg).build(),
          ButtonBuilder.create().text("OK").defaultButton(true).onAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              // take action and close the dialog.
              confirmationResult.set(true);
              parent.getScene().getRoot().setEffect(null);
              dialog.close();
            }
          }).build(),
          ButtonBuilder.create().text("Cancel").cancelButton(true).onAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
              // abort action and close the dialog.
              confirmationResult.set(false);
              parent.getScene().getRoot().setEffect(null);
              dialog.close();
            }
          }).build()
        ).build()
        , Color.TRANSPARENT
      )
    );

    // allow the dialog to be dragged around.
    final Node root = dialog.getScene().getRoot();
    final Delta dragDelta = new Delta();
    root.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        // record a delta distance for the drag and drop operation.
        dragDelta.x = dialog.getX() - mouseEvent.getScreenX();
        dragDelta.y = dialog.getY() - mouseEvent.getScreenY();
      }
    });
    root.setOnMouseDragged(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        dialog.setX(mouseEvent.getScreenX() + dragDelta.x);
        dialog.setY(mouseEvent.getScreenY() + dragDelta.y);
      }
    });

    // style and show the dialog.
    dialog.getScene().getStylesheets().add(getClass().getResource("modal-dialog.css").toExternalForm());
    parent.getScene().getRoot().setEffect(new BoxBlur());
    dialog.showAndWait();

    return confirmationResult.get();
  }

  // records relative x and y co-ordinates.
  class Delta { double x, y; }
}

莫代尔,dialog.css

/**
 * modal-dialog.css
 * place in same directory as WebViewConfirm.java
 * ensure your build system copies the file to your build output directory
 */

.root {
  -fx-glass-color: rgba(95, 158, 160, 0.9);
}

.modal-dialog {
  -fx-padding: 20;
  -fx-spacing: 10;
  -fx-alignment: center;
  -fx-font-size: 20;
  -fx-background-color: linear-gradient(to bottom, derive(-fx-glass-color, 20%), -fx-glass-color);
  -fx-border-color: derive(-fx-glass-color, -20%);
  -fx-border-width: 5;
  -fx-background-insets: 12;
  -fx-border-insets: 10;
  -fx-border-radius: 6;
  -fx-background-radius: 6;
}

.modal-dialog:pressed {
  -fx-cursor: move;
}

.modal-dialog .button:pressed {
  -fx-cursor: default;
}

.confirmation-results {
  -fx-background-color: cornsilk;
  -fx-padding: 5;
}

你问题的可能答案

您的问题对我来说并不是很清楚,但我认为如果弹出一个ControlsFX对话框,您将实现您想要的效果。 您可以使用标准Dialog(其功能类似于Internet Explorer的JavaScript警报对话框)或轻量级对话框(其功能类似于Firefox的JavaScript警报对话框) - 有关详细信息,请参阅ControlsFX功能页面

ControlsFX是基于Java 8的,但是对于JavaFX 2.2,StackOverflow上有很多关于在JavaFX中显示对话框的主题(例如: 如何在JavaFX 2.0中创建和显示常见对话框(错误,警告,确认)? )。 上面的示例代码是JavaFX 2.2中对话框用法的示例

对您提问中提出的其他观点的评论

如果JavaFX的webview本身可以运行javascript,除了它与java代码的通信

是的,WebView可以处理JavaScript。

例如,我可以在窗口加载时在webview中运行javascript警告语句,并在webview中实际获得警报,就像在普通浏览器中一样。

是的,如果您为WebView设置了警报处理程序,使其功能类似于“普通浏览器”,则会弹出一个关于接收JavaScript警报命令的对话框。 请注意,“普通浏览器”不会基于JavaScript警报功能修改网页文档对象模型,而是弹出本机对话框 - 该对话框实际上不是网页的一部分。

我实际上希望javascript事件发生在webview窗口本身,就像在普通浏览器中一样。

“普通”浏览器根据其UI模型处理不同的警报。 例如,在Firefox中,警报对话框将显示在当前浏览器选项卡窗口中,在Internet Explorer中,警报对话框将显示在Internet Explorer窗口上方。 JavaFX警报处理程序非常灵活,您可以随意处理警报。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM