The answer above works ok. I just like to add some information that I think is very important...
Get DOM Element's position, and simulate a Mouse Click (and Move):
// get button's position
string jsonString = null;
var jsReponse = await chromiumWebBrowser1.EvaluateScriptAsync(
@"(function () {
var bnt = document.getElementById('pnnext');
bnt.focus();
var bntRect = bnt.getBoundingClientRect();
return JSON.stringify({ x: bntRect.left, y: bntRect.top });
})();"
);
if (jsReponse.Success && jsReponse.Result != null)
jsonString = (string)jsReponse.Result;
// send mouse click event
if (jsonString != null)
{
var jsonObject = JObject.Parse(jsonString);
var xPosition = (int)jsonObject["x"] + 1; // add +1 pixel to the click position
var yPosition = (int)jsonObject["y"] + 1; // add +1 pixel to the click position
var host = chromiumWebBrowser1.GetBrowser().GetHost();
host.SendMouseMoveEvent(xPosition, yPosition, false, CefEventFlags.None);
Thread.Sleep(50);
host.SendMouseClickEvent(xPosition, yPosition, MouseButtonType.Left, false, 1, CefEventFlags.None);
Thread.Sleep(50);
host.SendMouseClickEvent(xPosition, yPosition, MouseButtonType.Left, true, 1, CefEventFlags.None);
}
1 - The best way to get a DOM element's position on CefSharp, up to the present moment, is executing a custom JavaScript, and parse the result back. That's the purpose of the first segment of the code above. It gets an element by its ID (as defined on the HTML structure of the loaded web page), then gets its position relative to the viewport, and then returns it back to the C# code.
Back on C#, we parse it using Newtonsoft's JObject.Parse
method.
2 - The clicking occurs at the specified x
and y
coordinates, but is very important to know that this coordinates are relative to the browser component window (viewport). So if your web browser component is only 100px
tall and you send a clicking command to y
coordinate as 150px
the clicking will occur but outside the web browser, hence, not in the web page.
3 - One trick to see if the click is really being executed, and where exactly, is change it from MouseButtonType.Left
to MouseButtonType.Right
. Doing it, if there is no restrictions on the web page, you will be able to see the "mouse right button menu". If you are clicking outside, chances are that you'll see a "mouse right button menu" on the OS (Windows here, and I was able to see that I was clicking outside my component with this trick) .
4 - Sometimes (specially with anti-crawler environments) it's necessary to also mimic the mouse movement. I do it using the method SendMouseMoveEvent
as shown in the first line.
5 - If you have a very tall page loaded in your component, and you need to click on a button really outside the boundaries of the component, you need to scroll the web page. You can do it execution some JavaScript as on the example code above, or You can do it with code below:
Simulate a Mouse Scroll (Mouse Wheel Event):
// send scroll command
// (mouse position X, mouse position Y, how much to scroll X, how much to scroll Y, events)
chromiumWebBrowser1.GetBrowser().GetHost().SendMouseWheelEvent(10, 10, 0, -100, CefEventFlags.None);
Thread.Sleep(300);
The biggest part of the parameters are self-explanatory, but the most important part here is the 3rd and 4th parameters, which are respectively "how much to scroll X" and "how much to scroll Y". To scroll down, just use negative values, and to scroll up, positive ones. In the code above, it scrolls nothing (zero pixels) horizontally (x
axis) and 100px down vertically (y
axis).
You can use this code inside a loop
to scroll how much you need. I use it in conjunction with a JavaScript code to retrieve the position of a button, to detect if it's on the viewport, or if i need to send a scroll event again.
BrSettings.WebSecurity = CefState.Disabled;
on browser start – Zamudio