xamarin.forms 处理 WebView 上的 Clicked 事件

xamarin.forms Handle Clicked event on WebView

我想处理 WebView 控件上的 click/tap 事件

我试过 GestureRecognizers 但没有任何反应,我想也许 WebView 有某种处理事件的方法 "true"。

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

而且我也使用 c# 代码进行了尝试,但没有成功:/

手势识别器不适用于 WebView。您可以尝试使用 MR.Gestures

要获得所有功能,您必须购买许可证。

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.

您可以使用 XLabs 中的 HybridWebView,并使用 javascript 注入来调用和处理 Xamarin 控件中的点击。注入的 javascript 代码可以在 capture 阶段添加一个点击事件监听器。当检测到点击时,它使用 Native 回调将信息发送回 C# 代码。

例如 - 您可以像这样定义自定义控件:

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);
        });
    }
}

示例XAML用法

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

和示例代码隐藏

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

** 输出 **

或者,您也可以绑定 ClickCommand 属性 以使用 MVVM 模式实现。

我正在使用这个 hack:将 WebView 放在 Grid 中,然后在同一个单元格中插入 BoxView。然后在 BoxView 上放置一个处理程序。

另一种选择是处理 html 中的点击并执行不会去任何地方的导航。你可以把这样的东西放在你的 html

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

所以点击里面的任何地方都会导致导航。如果你只有一个按钮,你可以使用

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

然后在您的 WebView 控件中连接 Navigating 事件,并检查新的 url 是否包含“#click”。如果是这样,请执行您的点击处理代码并在事件中调用 e.Cancel=true 以防止浏览器完成导航。

请注意,onclick 处理程序不适用于 Xamarin Webview 中的正文或文档元素。至少在 iOS.

上没有

一个更简单的解决方法是在您的网络视图上使用 'Focused' 事件。您可以按如下方式实现它:

var wb = new WebView
{
  HorizontalOptions = LayoutOptions.FillAndExpand,
  VerticalOptions = LayoutOptions.FillAndExpand,
  Source = "",
};

wb.Focused += (s, e) =>
{
   //Handle your logic here!
   wb.Unfocus(); 
};

我发现最简单的方法是使用带有两个控件的 GridWebViewButton

<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>

按钮覆盖 WebView 并拦截点击。