Introdução
Instalação
Guias
- Engine
- Profile
- Browser
- BrowserView
- Navegação
- Conteúdo
- DOM
- JavaScript
- Pop-ups
- Diálogos
- Downloads
- Extensões
- Rede
- Cache
- Cookies
- Proxy
- Autenticação
- Plugins
- Impressão
- Senhas
- Perfis de dados do Usuário
- Cartões de Crédito
- Mídia
- Área de transferência
- Zoom
- Corretor Ortográfico
- Implantação
- Chromium
Resolução de Problemas
DOM
Este guia descreve como acessar a um documento DOM, encontrar elementos, modificar uma estrutura DOM, simular a entrada do usuário, etc.
Visão geral
Cada página Web carregada em
um Browser
tem um Frame
principal
. O próprio Frame
pode ter frames filhos. Por exemplo, quando uma página web tem IFRAME
s, utilize
a classe Frame
para acessar o DOM e o JavaScript.
Acessando o documento
Cada Frame
tem
um Document
DOM. Para acessar o Documento
utilize o método Frame.document()
:
frame.document().ifPresent(document -> {});
val document = frame.document
document?.let {
}
Encontrando elementos
Você pode encontrar elementos HTML dentro de um elemento através de diferentes condições. O exemplo a seguir demonstra como encontrar
todos os elementos DIV
dentro do elemento document:
document.documentElement().ifPresent(documentElement ->
documentElement.findElementsByTagName("div").forEach(element -> {}));
val divs = document.documentElement!!.findElementsByTagName("div")
divs.forEach { element -> }
Se você precisar encontrar apenas o primeiro elemento HTML, utilize a seguinte abordagem:
documentElement.findElementByTagName("div").ifPresent(element -> {});
val div = documentElement.findByTagName("div")
div?.let {
}
Aqui estão os exemplos de pesquisa de elementos HTML por diferentes condições:
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
A API DOM do JxBrowser permite a avaliação de expressões XPath utilizando Node.evaluate(String expression)
. É possível avaliar uma expressão XPath
no âmbito de um Node
especificado utilizando o seguinte código:
try {
var result = node.evaluate("count(//div)");
} catch (XPathException e) {
// Falha ao avaliar a expressão fornecida.
}
val queryNumberOfDivs = XPathExpression("count(//div)")
try {
val result: XPathResult = node.evaluate(queryNumberOfDivs)
} catch (e: XPathException) {
// Falha ao avaliar a expressão fornecida.
}
O método lança XPathException
quando a biblioteca não consegue avaliar a expressão fornecida.
O resultado da avaliação é armazenado no objeto XPathResult
. Certifique-se de que o resultado contém o tipo de valor esperado em, por exemplo, Number
, Boolean
, String
, Node
, e extrai o próprio valor:
if (result.isNumber()) {
double number = result.asNumber();
}
if (result.isNumber) {
val number: Double = result.asNumber()
}
Seletor de Query
Para encontrar os elementos que correspondem a um seletor especificado, por exemplo, #root
, utilize o seguinte código:
var elements = element.findElementsByCssSelector("#root");
val elements = element.findElementsByCssSelector("#root")
Node no Ponto
Para encontrar o Node
num ponto específico, por exemplo, 100x150, na página Web, utilize a seguinte abordagem:
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
Trabalhando com elementos
Limites de elementos
Você pode obter os limites do Element
com a posição relativa ao topo esquerdo da janela de visualização do Document
atual
da seguinte forma:
var rect = element.boundingClientRect();
val rect = element.boundingClientRect()
Este método devolve um Rect
vazio quando o elemento tem um atributo hidden
ou o estilo CSS do elemento contém a declaração display: none;
.
Atributos do elemento
A classe Element
fornece métodos que permitem obter, adicionar, remover ou modificar os atributos de elementos HTML. O
seguinte exemplo demonstra como obter todos os atributos do elemento e imprimir os seus nomes e valores:
element.attributes().asMap().forEach((name, value) ->
System.out.println(name + ": " + value));
element.attributes.asMap().forEach { (name, value) ->
println("$name: $value")
}
O exemplo seguinte demonstra como adicionar/modificar um atributo de elemento:
element.attributes().put("attrName", "attrValue");
element.attributes["attrName"] = "attrValue"
Criação de elementos
A API DOM permite modificar a estrutura DOM do documento. O exemplo seguinte demonstra como criar e
inserir o elemento <p>
com algum texto:
// Cria um novo elemento de parágrafo.
var paragraph = document.createElement("p");
// Criar um nó de texto com o texto fornecido.
var text = document.createTextNode("Text");
// Inserir o nó de texto no elemento de parágrafo.
if (paragraph.appendChild(text)) {
// Inserir o elemento de parágrafo no elemento necessário.
boolean success = element.appendChild(paragraph);
}
// Cria um novo elemento de parágrafo.
val paragraph = document.createElement("p")
// Criar um nó de texto com o texto fornecido.
val text = document.createTextNode("Text")
// Inserir o nó de texto no elemento de parágrafo.
if (paragraph.appendChild(text)) {
// Inserir o elemento de parágrafo no elemento necessário.
val success = element.appendChild(paragraph)
}
Fechando Nodes
Objetos DOM que possuem uma contraparte Node
não estão sujeitos à coleta de lixo do Blink. Por padrão, mantemos estes objetos
na memória até a página ser descarregada.
Para otimizar a utilização da memória, pode ativar a recolha de lixo por objeto:
node.close();
node.close()
Fechar o Node
marca o objeto Blink correspondente como coletável, mas não libera o objeto imediatamente.
Depois de chamar o método close()
, as tentativas de usar Node
levarão a ObjectClosedException
.
Eventos DOM
Cada Node
implementa a interface EventTarget
que fornece métodos para registar eventos DOM. Você pode registrar
DOM listener para receber eventos DOM como click
, mousedown
, mouseup
, keydown
, load
, error
etc.
O exemplo a seguir demonstra como registrar um ouvinte de evento click
para um elemento HTML de documento:
document.documentElement().ifPresent(element ->
element.addEventListener(EventType.CLICK, event -> {
// O evento de clique do mouse foi recebido.
if (event instanceof MouseEvent) {
var mouseEvent = (MouseEvent) event;
var clickCount = mouseEvent.clickCount();
}
}, false));
val listener = Observer<Event> { event ->
// O evento de clique do mouse foi recebido.
if (event is MouseEvent) {
val clickCount = event.clickCount()
}
}
val useCapture = false
document.documentElement?.addEventListener(
EventType.CLICK,
listener,
useCapture
)
Além disso, o JxBrowser permite que você ouça os eventos DOM personalizados e acessar sua carga útil:
// Criar um tipo de evento DOM personalizado.
var eventType = EventType.of("MyEvent");
// Escuta os eventos do tipo de evento fornecido.
element.addEventListener(eventType, event -> {
// O evento MyEvent foi recebido.
if (event instanceof CustomEvent) {
var customEvent = (CustomEvent) event;
var payload = customEvent.detail();
}
}, false);
// Criа um tipo de evento DOM personalizado.
val eventType = EventType.of("MyEvent")
val listener = Observer<Event> { event ->
// O evento MyEvent foi recebido.
if (event is CustomEvent) {
val payload = event.detail<JsObject>()
}
}
val useCapture = false
// Escuta os eventos do tipo de evento fornecido.
element.addEventListener(eventType, listener, useCapture)
Automatização
A API DOM do JxBrowser fornece tudo o que é necessário para automatizar o preenchimento de formulários Web. Esta seção descreve como atualizar o texto nos campos de texto, selecionar uma caixa de verificação ou um botão radio, selecionar uma ou várias opções numa lista drop-down, simular um clique, etc.
Para trabalhar com controles de formulários Web, utilize a interface FormControlElement
. Esta interface permite verificar se o controle
está ativado e modificar o seu valor. Todos os controles de formulário, tais como INPUT
, SELECT
, TEXTAREA
, e outros
herdam esta interface.
Entrada
Para trabalhar com elementos INPUT
utilize a interface InputElement
. Fornece todos os métodos necessários para verificar o tipo de entrada
e definir o seu valor.
Texto, E-mail, Senha
Para substituir o valor padrão de um campo de texto, e-mail ou senha por um novo valor, utilize
o método InputElement.value(String)
.
Por exemplo, se o seu formulário Web contiver os elementos <input>
com os seguintes tipos:
<input type="text" id="firstname" placeholder="First Name">
<input type="email" id="email" placeholder="Email Address">
<input type="password" id="password" placeholder="Password">
você pode definir o seu valor utilizando a seguinte abordagem:
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
Para verificar um botão radio ou uma checkbox, utilize o método InputElement.check()
.
Por exemplo, se o seu formulário Web contiver os elementos <input>
com os seguintes tipos:
<input type="checkbox" id="checkbox" value="Remember me">
<input type="radio" id="radio" checked>
você pode selecionar/desmarcar utilizando a seguinte abordagem:
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()
Arquivo
Os elementos <input>
com type=file
permitem ao usuário escolher um ou mais arquivos do seu dispositivo de armazenamento. JxBrowser
lhe permite selecionar programaticamente um arquivo e atualizar o valor dos <input type=file>
elementos.
Por exemplo, se o seu formulário web contiver um elemento <input>
como:
<input type="file" id="avatar" accept="image/png, image/jpeg" multiple>
você pode selecionar o(s) arquivo(s) necessário(s) programaticamente utilizando a seguinte abordagem:
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")
Área de texto
Para definir o texto num elemento <textarea>
como:
<textarea id="details"></textarea>
utilize a seguinte abordagem:
documentElement.findElementById("details").ifPresent(element ->
((TextAreaElement) element).value("Some text..."));
val details = documentElement.getById("details") as TextAreaElement
details.value = "Some text..."
Select & Option
Para selecionar todas as opções num controle SELECT
como:
<select id="fruits" multiple>
<option>Maçã</option>
<option>Laranja</option>
<option>Abacaxi</option>
<option>Banana</option>
</select>
utilize a seguinte abordagem:
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()
}
Com esta abordagem, você pode selecionar apenas uma opção necessária.
Simulação de clique
Para simular um clique do mouse num elemento, utilize o seguinte método:
element.click();
element.click()
Quando click()
é utilizado com os elementos suportados (como um <input>
), ele dispara o evento de clique do elemento. Este evento
é então transmitido para os elementos mais elevados na árvore do documento e ativa os respectivos eventos de clique.
Envio de eventos
É possível enviar um Event
para o EventTarget
especificado utilizando o método EventTarget.dispatch(Event)
.
O exemplo a seguir demonstra como enviar um evento click
padrão para o elemento especificado:
// Localização do cliente e da tela.
var location = Point.of(10, 10);
// Criar MouseEvent com as opções necessárias.
var mouseClickEvent = document.createMouseEvent(EventType.CLICK,
MouseEventParams.newBuilder()
// O botão principal pressionado.
.button(MouseEvent.Button.MAIN)
.clientLocation(location)
.screenLocation(location)
.uiEventModifierParams(
UiEventModifierParams.newBuilder()
.eventParams(EventParams.newBuilder()
.bubbles(true)
.cancelable(true)
.build())
.build())
.build());
// Gera um evento de clique no elemento de destino.
element.dispatch(mouseClickEvent);
// Localização do cliente e da tela.
val location = Point(10, 10)
// Criar MouseEvent com as opções necessárias.
val eventParams = EventParams(bubbles = true, cancelable = true)
val uiEventModifiers = UiEventModifierParams(eventParams)
val mouseEventParams = MouseEventParams(
button = MouseEvent.Button.MAIN, // O botão principal pressionado.
location = location,
locationOnScreen = location,
uiEventModifierParams = uiEventModifiers
)
val mouseClickEvent = document.createMouseEvent(
EventType.CLICK,
mouseEventParams
)
// Gera um evento de clique no elemento de destino.
element.dispatch(mouseClickEvent)
Utilizando esta abordagem, você pode criar e enviar vários eventos DOM. Tais eventos são normalmente designados por eventos sintéticos, por oposição aos eventos disparados pelo
Browser
propriamente dito.