xamarin.forms Handle Clicked event on WebView

Solution 1:

You can use the HybridWebView from XLabs, and use javascript injection to invoke and handle clicks in your Xamarin control. The injected javascript code can add a click-event listener at capture stage. When a click is detected it uses Native callback to send information back to C# code.

For example - you can define a custom control like this:

public class ClickEventArgs : EventArgs
{
    public string Element { get; set; }
}

public class ClickableWebView : XLabs.Forms.Controls.HybridWebView
{
    public event EventHandler<ClickEventArgs> Clicked;

    public static readonly BindableProperty ClickCommandProperty =
        BindableProperty.Create("ClickCommand", typeof(ICommand), typeof(ClickableWebView), null);

    public ICommand ClickCommand
    {
        get { return (ICommand)GetValue(ClickCommandProperty); }
        set { SetValue(ClickCommandProperty, value); }
    }

    public ClickableWebView()
    {
        LoadFinished += (sender, e) => 
            InjectJavaScript(@"
            document.body.addEventListener('click', function(e) {
                e = e || window.event;
                var target = e.target || e.srcElement;
                Native('invokeClick', 'tag='+target.tagName+' id='+target.id+' name='+target.name);
            }, true /* to ensure we capture it first*/);
        ");

        this.RegisterCallback("invokeClick", (string el) => {
            var args = new ClickEventArgs { Element = el };

            Clicked?.Invoke(this, args); 
            ClickCommand?.Execute(args);
        });
    }
}

Sample XAML usage

<local:ClickableWebView 
    Uri="https://google.com" 
    Clicked="Handle_Clicked"
/>

and sample code-behind

void Handle_Clicked(object sender, CustomWebView.ClickEventArgs e)
{
    Xamarin.Forms.Application.Current.MainPage.DisplayAlert("WebView Clicked", e.Element, "Dismiss");
}

** Output **

sample output

Alternatively, you can also bind ClickCommand property to implement this using MVVM pattern.

Solution 2:

I am using this hack: put the WebView in a Grid and insert a BoxView in the same cell. Then put a handler on the BoxView.

Solution 3:

Another option is to handle the click in html and do a navigation that doesn't go anywhere. You can put something like this in your html

<div onclick="window.location.href='#click#'">...</div>

So a click anywhere inside there would cause a navigation. If you only have a button, you could just use

<a href='#click'>...</a>

Then in your WebView control wire up the Navigating event, and check if the new url contains "#click". If so, do your click handling code and call e.Cancel=true in the event to prevent the browser from completing the navigation.

Note that onclick handlers don't work on body or document elements in Xamarin Webview. At least not on iOS.

Solution 4:

Gesture recognizer doesn't work with WebView. You can try using MR.Gestures

To get all the features you will have to purchase a license.

If you forget to configure the license key properly or the key does not match your app name, then all the events will still be raised, but the properties of the EventArgs will be empty. That may be enough for the tap and long press events, but not for the more complicated ones.