List icon Contents

DOM

This guide describes how to access a DOM document, find elements, modify a DOM structure, simulate user input, etc.

Overview

Each web page loaded in a Browser has a main Frame . The Frame itself may have child frames. For example, when a web page has IFRAMEs, please use the Frame class to access DOM and JavaScript.

Accessing document

Every Frame has a DOM Document. To access the Document please use the Frame.document() method:

Java
Kotlin
frame.document().ifPresent(document -> {});
val document = frame.document
document?.let {
}

Finding elements

You can find HTML elements inside an element by different conditions. The following example demonstrates how to find all DIV elements inside the document element:

Java
Kotlin
document.documentElement().ifPresent(documentElement ->
        documentElement.findElementsByTagName("div").forEach(element -> {}));
val divs = document.documentElement!!.findElementsByTagName("div")
divs.forEach { element -> }

If you need to find only the first HTML element use the following approach:

Java
Kotlin
documentElement.findElementByTagName("div").ifPresent(element -> {});
val div = documentElement.findByTagName("div")
div?.let {
}

Here are the examples of searching for HTML elements by different conditions:

Java
Kotlin
documentElement.findElementsById("<id>");
documentElement.findElementsByName("<attr-name>");
documentElement.findElementsByTagName("<tag-name>");
documentElement.findElementsByClassName("<attr-class>");
documentElement.findElementsById("<id>")
documentElement.findElementsByName("<attr-name>")
documentElement.findElementsByTagName("<tag-name>")
documentElement.findElementsByClassName("<attr-class>")

XPath

JxBrowser DOM API allows evaluating XPath expressions using Node.evaluate(String expression). You can evaluate an XPath expression in scope of a specified Node using the following code:

Java
Kotlin
try {
    var result = node.evaluate("count(//div)");
} catch (XPathException e) {
    // Failed to evaluate the given expression.
}
val queryNumberOfDivs = XPathExpression("count(//div)")
try {
    val result: XPathResult = node.evaluate(queryNumberOfDivs)
} catch (e: XPathException) {
    // Failed to evaluate the given expression.
}

The method throws XPathException when the library failed to evaluate the given expression.

The evaluation result is stored in the XPathResult object. Please make sure that the result contains the expected value type, e.g. Number, Boolean, String, Node, and extracts the value itself:

Java
Kotlin
if (result.isNumber()) {
    double number = result.asNumber();
}
if (result.isNumber) {
    val number: Double = result.asNumber()
}

Query selector

To find the elements that match a specified selector, e.g. #root, please use the following code:

Java
Kotlin
var elements = element.findElementsByCssSelector("#root");
val elements = element.findElementsByCssSelector("#root")

Node at point

To find the Node at a specific point, e.g. 100x150, on the web page please use the following approach:

Java
Kotlin
var inspection = frame.inspect(Point.of(100, 150));
inspection.node().ifPresent(node -> {});
val inspection: PointInspection = frame.inspect(Point(100, 150))
val node: Node? = inspection.node

Working with elements

Element bounds

You can get bounds of the Element with the position relative to the top-left of the viewport of the current Document as follows:

Java
Kotlin
var rect = element.boundingClientRect();
val rect = element.boundingClientRect()

This method returns an empty Rect when the element has a hidden attribute or the CSS style of the element contains display: none; statement.

Element attributes

The Element class provides methods that allow you to get, add, remove, or modify the HTML element attributes. The following example demonstrates how to get all the attributes of the element and print their names and values:

Java
Kotlin
element.attributes().asMap().forEach((name, value) ->
        System.out.println(name + ": " + value));
element.attributes.asMap().forEach { (name, value) ->
    println("$name: $value")
}

The following example demonstrates how to add/modify an element attribute:

Java
Kotlin
element.attributes().put("attrName", "attrValue");
element.attributes["attrName"] = "attrValue"

Creating elements

The DOM API allows modifying the document DOM structure. The following example demonstrates how to create and insert <p> element with some text:

Java
Kotlin
// Create a new paragraph element.
var paragraph = document.createElement("p");
// Create a text node with the given text.
var text = document.createTextNode("Text");
// Insert the text node into the paragraph element.
if (paragraph.appendChild(text)) {
    // Insert the paragraph element into the required element.
    boolean success = element.appendChild(paragraph);
}
// Create a new paragraph element.
val paragraph = document.createElement("p")
// Create a text node with the given text.
val text = document.createTextNode("Text")
// Insert the text node into the paragraph element.
if (paragraph.appendChild(text)) {
    // Insert the paragraph element into the required element.
    val success = element.appendChild(paragraph)
}

Closing nodes

DOM objects that have a Node counterpart are not subjects to Blink garbage collection. By default, we keep these objects in memory until the page is unloaded.

To optimize the memory usage, you can enable garbage collection on the per-object basis:

Java
Kotlin
node.close();
node.close()

Closing Node marks the corresponding Blink object as collectable, but it does not release the object immediately. After calling the close() method, the attempts to use Node will lead to ObjectClosedException.

DOM events

Each Node implements the EventTarget interface that provides methods for registering DOM events. You can register DOM listener to receive DOM events such as click, mousedown, mouseup, keydown, load, error etc.

The following example demonstrates how to register a click event listener for a document HTML element:

Java
Kotlin
document.documentElement().ifPresent(element ->
        element.addEventListener(EventType.CLICK, event -> {
            // Mouse click event has been received.
            if (event instanceof MouseEvent) {
                var mouseEvent = (MouseEvent) event;
                var clickCount = mouseEvent.clickCount();
            }
        }, false));
val listener = Observer<Event> { event ->
    // Mouse click event has been received.
    if (event is MouseEvent) {
        val clickCount = event.clickCount()
    }
}
val useCapture = false
document.documentElement?.addEventListener(
    EventType.CLICK,
    listener,
    useCapture
)

Also, JxBrowser allows you to listen to the custom DOM events and access their payload:

Java
Kotlin
// Create a custom DOM event type.
var eventType = EventType.of("MyEvent");
// Listen to the events of the given event type.
element.addEventListener(eventType, event -> {
    // The MyEvent event has been received.
    if (event instanceof CustomEvent) {
        var customEvent = (CustomEvent) event;
        var payload = customEvent.detail();
    }
}, false);
// Create a custom DOM event type.
val eventType = EventType.of("MyEvent")
val listener = Observer<Event> { event ->
    // The MyEvent event has been received.
    if (event is CustomEvent) {
        val payload = event.detail<JsObject>()
    }
}
val useCapture = false
// Listen to the events of the given event type.
element.addEventListener(eventType, listener, useCapture)

Automation

JxBrowser DOM API provides everything you need to automate the web form filling. This section describes how to update the text in the text fields, select a checkbox or a radio button, select one or multiple options in a drop-down list, simulate a click, etc.

To work with web form controls please use the FormControlElement interface. This interface allows to check whether the control is enabled, and to modify its value. All the form controls such as INPUT, SELECT, TEXTAREA, and others inherit this interface.

Input

To work with INPUT elements please use the InputElement interface. It provides all the required methods to check the input type and set its value.

Text, email, password

To replace the default value of a text, email, or password field with a new value, please use the InputElement.value(String) method.

For example, if your web form contains the <input> elements with the following types:

<input type="text" id="firstname" placeholder="First Name">
<input type="email" id="email" placeholder="Email Address">
<input type="password" id="password" placeholder="Password">

you can set their value using the following approach:

Java
Kotlin
documentElement.findElementById("firstname").ifPresent(element ->
        ((InputElement) element).value("John"));

documentElement.findElementById("email").ifPresent(element ->
        ((InputElement) element).value("me@company.com"));

documentElement.findElementById("password").ifPresent(element ->
        ((InputElement) element).value("Jkdl12!"));
val firstname = documentElement.findById("firstname") as InputElement
firstname.value = "John"

val email = documentElement.findById("email") as InputElement
email.value = "me@company.com"

val password = documentElement.findById("password") as InputElement
password.value = "Jkd12!"

Check box, radio button

To check a radio button or a checkbox please use the InputElement.check() method.

For example, if your web form contains the <input> elements with the following types:

<input type="checkbox" id="checkbox" value="Remember me">
<input type="radio" id="radio" checked>

you can select/unselect them using the following approach:

Java
Kotlin
documentElement.findElementById("checkbox").ifPresent(element ->
        ((InputElement) element).check());

documentElement.findElementById("radio").ifPresent(element ->
        ((InputElement) element).uncheck());
val checkbox = documentElement.getById("checkbox") as InputElement
checkbox.check()

val radio = documentElement.getById("radio") as InputElement
radio.uncheck()

File

The <input> elements with type=file let the user choose one or more files from their device storage. JxBrowser allows you to programmatically select a file and update the value of the <input type=file> elements.

For example, if your web form contains an <input> element like:

<input type="file" id="avatar" accept="image/png, image/jpeg" multiple>

you can select the required file/files programmatically using the following approach:

Java
Kotlin
documentElement.findElementById("avatar").ifPresent(element ->
        ((InputElement) element).file("file1.png", "file2.jpeg"));
val avatar = documentElement.getById("avatar") as InputElement
avatar.file("file1.png", "file2.png")

Text area

To set the text in a <textarea> element like:

<textarea id="details"></textarea>

please use the following approach:

Java
Kotlin
documentElement.findElementById("details").ifPresent(element ->
        ((TextAreaElement) element).value("Some text..."));
val details = documentElement.getById("details") as TextAreaElement
details.value = "Some text..."

Select & option

To select all options in a SELECT control like:

<select id="fruits" multiple>
    <option>Apple</option>
    <option>Orange</option>
    <option>Pineapple</option>
    <option>Banana</option>
</select>

please use the following approach:

Java
Kotlin
documentElement.findElementById("fruits").ifPresent(element -> {
    var selectElement = (SelectElement) element;
    selectElement.options().forEach(optionElement ->
            optionElement.select());
});
val fruits = documentElement.getById("fruits") as SelectElement
fruits.options.forEach {
    it.select()
}

Using this approach you can select only one required option.

Simulating click

To simulate a mouse click on an element please use the following method:

Java
Kotlin
element.click();
element.click()

When click() is used with the supported elements (such as an <input>), it fires the element’s click event. This event then bubbles up to the elements higher in the document tree and fires their click events.

Dispatching events

You can dispatch an Event at the specified EventTarget using the EventTarget.dispatch(Event) method.

The following example demonstrates how to dispatch a standard click event at the specified element:

Java
Kotlin
// Client and screen location.
var location = Point.of(10, 10);
// Create MouseEvent with the required options.
var mouseClickEvent = document.createMouseEvent(EventType.CLICK,
        MouseEventParams.newBuilder()
                // The main button pressed.
                .button(MouseEvent.Button.MAIN)
                .clientLocation(location)
                .screenLocation(location)
                .uiEventModifierParams(
                        UiEventModifierParams.newBuilder()
                                .eventParams(EventParams.newBuilder()
                                        .bubbles(true)
                                        .cancelable(true)
                                        .build())
                                .build())
                .build());
// Generate a click event on the target element.
element.dispatch(mouseClickEvent);
// Client and screen location.
val location = Point(10, 10)
// Create MouseEvent with the required options.
val eventParams = EventParams(bubbles = true, cancelable = true)
val uiEventModifiers = UiEventModifierParams(eventParams)
val mouseEventParams = MouseEventParams(
    button = MouseEvent.Button.MAIN, // The main button pressed.
    location = location,
    locationOnScreen = location,
    uiEventModifierParams = uiEventModifiers
)
val mouseClickEvent = document.createMouseEvent(
    EventType.CLICK,
    mouseEventParams
)
// Generate a click event on the target element.
element.dispatch(mouseClickEvent)

Using this approach you can create and dispatch various DOM events. Such events are commonly called synthetic events , as opposed to the events fired by the Browser itself.