简体   繁体   中英

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

I am able to get an element by Id like this in JavaFX.

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

How do I do the same given element's classname?

Thanks.

You can access any component by using: the lookUp method.

For Example:

Button has class: specialClazz and your mainPane is a StackPane: rootPane

So you just do:

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

For an ID:

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

I came across this and saw there wasn't much for answers. The way I found way to work with dom classes is not great but it gets the job done.

To add a class on a Node you obtained, use the setAttribute() method. Be careful to maintain any classes that might already exist on the 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);
}

Then, if you wish to search the DOM by class you can execute javascript to do so using the executeScript on the WebEngine . The return type depends on what you're asking the script to do.

Small note: disabling javascript via engine.setJavaScriptEnabled(false); does not prohibit use of the engine.executeScript() method.

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

However inefficient, I did this to determine what I would be getting back from executeScript() before writing any further code:

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

Like I said it isn't great, but you can write some wrapper functions to make it easier to work with. Hope this helps!

I'd use javax.xml.xpath . See XPath Tutorial - Example 6 : Values of attributes can be used as selection criteria.

Note also that there is not necessarily a (single) element's class name . id is unique in a Document whereas class is not. So it should rather read elements' class name . (Subtle, but important. :-) In other words: there is not necessarily just one Element returned when searching for a given class.

The above answer:

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

is bad. Because executeScript return's JSObject but not HTMLCollection; it cannot be casted.

The corrent is below java9 modular code sample (java14 has var): and you should add vm options to project:

--add-exports 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();
        }
}

If you are not using java9+ modular, these reflects can replace with HTMLButtonElementImpl,HTMLDocumentImpl.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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