You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止MAUI中WebView在鼠标中键点击时打开新标签页

解决MAUI WebView鼠标中键/Shift点击链接弹出新窗口的问题

以下是几种可靠的解决方案,针对你尝试过的方法做优化补充:

方法1:注入全覆盖的JS脚本拦截事件

如果之前的JS没覆盖动态加载链接或事件冒泡,试试全局监听的脚本,确保拦截所有触发场景:

document.addEventListener('mousedown', function(e) {
    // 检测鼠标中键点击 或 Shift+左键点击
    if (e.button === 2 || (e.shiftKey && e.button === 0)) {
        const target = e.target.closest('a');
        if (target && target.href) {
            e.preventDefault();
            e.stopPropagation();
            // 向MAUI传递点击的URL
            window.chrome.webview.postMessage({ type: 'CustomLinkClick', url: target.href });
        }
    }
});
// 额外拦截中键触发的右键菜单(可选)
document.addEventListener('contextmenu', function(e) {
    const target = e.target.closest('a');
    if (target && e.button === 2) {
        e.preventDefault();
    }
});

在MAUI中,WebView加载完成后注入脚本,并订阅消息接收事件:

// 页面加载完成后注入JS
webView.Navigated += async (s, e) =>
{
    await webView.EvaluateJavaScriptAsync(@"
        document.addEventListener('mousedown', function(e) {
            if (e.button === 2 || (e.shiftKey && e.button === 0)) {
                const target = e.target.closest('a');
                if (target && target.href) {
                    e.preventDefault();
                    e.stopPropagation();
                    window.chrome.webview.postMessage({ type: 'CustomLinkClick', url: target.href });
                }
            }
        });
        document.addEventListener('contextmenu', function(e) {
            const target = e.target.closest('a');
            if (target && e.button === 2) {
                e.preventDefault();
            }
        });
    ");
};

// 接收JS传递的消息,执行自定义操作
webView.WebMessageReceived += (s, e) =>
{
    var message = System.Text.Json.JsonSerializer.Deserialize<CustomLinkMessage>(e.Data);
    if (message?.Type == "CustomLinkClick")
    {
        // 示例:在当前WebView打开目标链接
        webView.Source = new UrlWebViewSource { Url = message.Url };
    }
};

// 自定义消息模型
public class CustomLinkMessage
{
    public string Type { get; set; }
    public string Url { get; set; }
}

方法2:正确使用OnWindowCreated事件拦截

如果JS拦截有遗漏,直接在MAUI层面拦截窗口创建请求:

webView.OnWindowCreated += (s, e) =>
{
    // 取消默认新窗口创建
    e.Cancel = true;
    // 获取目标URL并执行自定义操作
    if (e.Uri != null)
    {
        webView.Source = new UrlWebViewSource { Url = e.Uri.ToString() };
    }
};

注意:不同平台触发时机有差异,Windows平台下该事件响应更稳定,Android/iOS需额外配置WebView的窗口支持选项。

方法3:Windows平台直接操作WebView2底层

针对Windows平台,通过Handler获取WebView2实例,注册底层事件拦截所有新窗口请求:

#if WINDOWS
webView.HandlerChanged += (s, e) =>
{
    if (webView.Handler?.PlatformView is Microsoft.UI.Xaml.Controls.WebView2 webView2)
    {
        webView2.CoreWebView2.NewWindowRequested += (sender, args) =>
        {
            // 标记请求已处理,阻止默认新窗口
            args.Handled = true;
            // 执行自定义操作
            if (!string.IsNullOrEmpty(args.Uri))
            {
                webView.Source = new UrlWebViewSource { Url = args.Uri };
            }
        };
    }
};
#endif

这个方法能拦截所有新窗口触发场景,包括中键点击、Shift点击、JS的window.open等。


内容的提问来源于stack exchange,提问作者Igor Markiv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:21:14