我如何通过JavaFX WebEngine的CSS类名获得HTML元素

How do I get an HTML Element By CSS class name via a JavaFX WebEngine?

本文关键字:HTML 元素 CSS 何通过 JavaFX WebEngine      更新时间:2023-09-26

我可以在JavaFX中通过Id获得一个元素。

Element nameField = engine.getDocument().getElementById( "name" );

我如何做相同的给定元素的类名?

谢谢。

我偶然发现了这个问题,并没有太多的答案。我发现使用dom类的方法不是很好,但它完成了工作。

在获取的节点上添加类,使用setAttribute()方法。注意维护Node上可能已经存在的任何类。

Document doc = engine.getDocument();
if (doc != null){
    Element elem = doc.getElementById('someID'); 
    String classNames = elem.getAttribute("class");
    classNames += " someClass"; //note the whitespace!
    elem.setAttribute("class", classNames);
}

然后,如果您希望通过类搜索DOM,您可以在WebEngine上使用executeScript执行javascript。返回类型取决于您要求脚本执行的操作。

小提示:通过engine.setJavaScriptEnabled(false);禁用javascript并不会禁止使用engine.executeScript()方法。

HTMLCollection result =  (HTMLCollection)engine.executeScript("document.getElementsByClassName('someClass')");

无论效率有多低,在编写任何进一步的代码之前,我这样做是为了确定我将从executeScript()得到什么:

Object result =  engine.executeScript("document.getElementsByClassName('someClass')");
System.out.println(result.getClass().getName());

就像我说的,它不是很好,但您可以编写一些包装器函数使其更容易使用。希望这对你有帮助!

您可以使用:lookUp方法访问任何组件。

例如:

按钮有类:specialClazz和你的mainPane是一个StackPane: rootPane

所以你只需要:

rootPane.lookUp(".specialClazz"); // .-selector!

对于ID:

rootPane.lookUp("#specialID"); // #-selector!

我会用javax.xml.xpath。参见XPath教程-示例6:属性的值可以用作选择标准。

还需要注意的是,元素的类名不一定是id在文档中是唯一的,而class则不是。所以它应该读取元素的类名。(微妙,但很重要。:-)换句话说:当搜索给定的类时,不一定只返回一个Element。

以上答案:

"HTMLCollection result =  (HTMLCollection)engine.executeScript("document.getElementsByClassName('someClass')");"

是坏的。因为executeScript返回的是JSObject而不是HTMLCollection;它不能被强制转换

当前如下java9模块化代码示例(java14有var):你应该在项目中添加vm选项:

——添加导出javafx.web/com.sun.webkit.dom = atools

var doc = webEngine.getDocument();
if (doc instanceof HTMLDocument htmlDocument) { //actually htmlDoc is HTMLDocumentImpl but java9 have to reflect
  try {
            Method method = null;
            var clazz = htmlDocument.getClass();
            method = clazz.getSuperclass().getMethod("getElementsByClassName", String.class);
            HTMLCollection collection = (HTMLCollection) method.invoke(htmlDocument,"button");
            //if collection not only 1
            //you should special the document more deeply
            for (int i = 0; i < collection.getLength(); i++) {
                var btn = collection.item(i);
                //actual is HTMLButtonElementImpl
                //HTMLButtonElement htmlButtonElement = (HTMLButtonElement) btn;
                var method1 = btn.getClass().getMethod("click");
                method1.invoke(btn);
                Log.d("");
                break;
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
}

如果您不使用java9+模块化,这些反映可以替换为HTMLButtonElementImpl, htmldocumententimpl。