9

I want to handle the click/tap event on a WebView control

I've tried the GestureRecognizers but nothing happens, i think maybe the WebView has some sort of making the event handled "true".

<WebView>
   <WebView.GestureRecognizers>
      <TapGestureRecognizer
              Tapped="OnWebViewClick"
              NumberOfTapsRequired="1" />
   </WebView.GestureRecognizers>
</WebView>

And I've tried it using c# code behind too but no luck :/

Esam Sherif
  • 327
  • 2
  • 7
  • 12

6 Answers6

4

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.

Charles Roddie
  • 952
  • 5
  • 16
3

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.

Sharada Gururaj
  • 13,471
  • 1
  • 22
  • 50
2

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.

GeekyMonkey
  • 12,478
  • 6
  • 33
  • 39
1

I've found the simplest approach is to use a Grid with two controls, the WebView and a Button

<Grid>
    <WebView 
        Grid.Column="0"
        Grid.Row="0"
        HeightRequest="100"
        WidthRequest="1000" /> 
    <Button
        Grid.Column="0"
        Grid.Row="0"
        BackgroundColor="Transparent"
        HorizontalOptions="Fill"
        VerticalOptions="Fill"  
        Clicked="OnWebViewTapped"/>
</Grid>

The button covers the WebView and intercepts taps.

David Clarke
  • 12,888
  • 9
  • 86
  • 116
0

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.

Ratish
  • 57
  • 1
  • 1
  • 4
  • 1
    Thanks... i've checked it and it does help alot. but i want to know how to do it myself i was thinking something like this ( http://arteksoftware.com/gesture-recognizers-with-xamarin-forms/ ) but i had no luck – Esam Sherif Jun 22 '15 at 23:59
0

An easier workaround is to use the 'Focused' event on your webview. You can implement it as below:

var wb = new WebView
{
  HorizontalOptions = LayoutOptions.FillAndExpand,
  VerticalOptions = LayoutOptions.FillAndExpand,
  Source = "https://stackoverflow.com/questions/56320611/webview-gesturerecognition-not-working-in-xamarin-forms",
};

wb.Focused += (s, e) =>
{
   //Handle your logic here!
   wb.Unfocus(); 
};
Sparsha Bhattarai
  • 693
  • 11
  • 20