弹出窗口

本页描述了如何处理、显示或抑制弹出窗口。

概述

任何网页都可以使用以下方式之一显示弹出窗口:

  1. window.open() JavaScript 函数。 例如:

    window.open("https://www.google.com", "_blank", 
        "resizable=yes, top=500, left=500, width=400, height=400");
    
  2. 带有 target 属性的链接:

    <a href="https://www.google.com" target="_blank">Open Google</a>
    

默认情况下, IBrowser 实例的所有弹出窗口都会被抑制。 如果从没有自定义弹出窗口处理的 IBrowser 实例初始化了一个 IBrowserView 实例,则会注册默认弹出窗口处理程序。 弹出窗口显示在单独的窗口或表单中。

打开弹出窗口

要更改默认行为并控制弹出窗口的创建,请使用 CreatePopupHandlerOpenPopupHandler 处理程序。

当引擎想知道是否可以创建弹出窗口时,将调用 CreatePopupHandler 处理程序。 以下代码示例展示了如何允许创建弹出窗口:

browser.CreatePopupHandler =
    new Handler<CreatePopupParameters, CreatePopupResponse>(p =>
    {
        return CreatePopupResponse.Create();
    });
browser.CreatePopupHandler = 
    New Handler(Of CreatePopupParameters, CreatePopupResponse)(Function(p)
        Return CreatePopupResponse.Create()
    End Function)

如果 CreatePopupHandler 处理程序允许您创建弹出窗口,则会调用 OpenPopupHandler 处理程序。 在此处理程序中,您可以访问创建的弹出窗口并在必要时显示它。 请参阅以下代码示例:

browser.OpenPopupHandler = 
    new Handler<OpenPopupParameters>(p =>
    {
        // 访问已创建的弹出浏览器。
        IBrowser popup = p.PopupBrowser;
    });
browser.OpenPopupHandler = 
    New Handler(Of OpenPopupParameters)(Sub(p)
        ' 访问已创建的弹出浏览器。
        Dim popup As IBrowser = p.PopupBrowser
    End Sub)

在上述示例中,popup 实例在处理程序被调用时没有加载任何网页。 网页将稍后加载。 目前,您可以注册所有必要的事件监听器和处理程序,但无法访问 DOM 或 JavaScript,因为 popup 还没有 IFrame

抑制弹出窗口

要抑制弹出窗口,请使用以下方法:

browser.CreatePopupHandler =
    new Handler<CreatePopupParameters, CreatePopupResponse>(p =>
    {
        return CreatePopupResponse.Suppress();
    });
browser.CreatePopupHandler = 
    New Handler(Of CreatePopupParameters, CreatePopupResponse)(Function(p)
        Return CreatePopupResponse.Suppress()
    End Function)

将弹出窗口 URL 加载到主浏览器中

要禁止创建单独的弹出窗口并将弹出窗口 URL 加载到主浏览器中,请使用以下方法:

browser.CreatePopupHandler =
    new Handler<CreatePopupParameters, CreatePopupResponse>(p =>
    {
        browser.Navigation.LoadUrl(p.TargetUrl);
        return CreatePopupResponse.Suppress();
    });
browser.CreatePopupHandler = 
    New Handler(Of CreatePopupParameters, CreatePopupResponse)(Function(p)
        browser.Navigation.LoadUrl(p.TargetUrl)
        Return CreatePopupResponse.Suppress()
    End Function)

显示弹出窗口

当您初始化 WinForms 或 WPF BrowserView 时,它会使用 CreatePopupHandlerOpenPopupHandler 处理程序的默认实现自动配置给定的 IBrowser 实例。

CreatePopupHandler 的默认实现允许创建所有弹出窗口:

browser.CreatePopupHandler =
    new Handler<CreatePopupParameters, CreatePopupResponse>(p =>
    {
        return CreatePopupResponse.Create();
    });
browser.CreatePopupHandler = 
    New Handler(Of CreatePopupParameters, CreatePopupResponse)(Function(p)
        Return CreatePopupResponse.Create()
    End Function)

有关 WinForms 和 WPF 的 OpenPopupHandler 处理程序默认实现的详细信息,请参阅下文。

WinForms

WinForms BrowserView 的默认实现如下:

using System;
using System.Windows.Forms;
using DotNetBrowser.Browser;
using DotNetBrowser.Browser.Events;
using DotNetBrowser.Browser.Handlers;
using DotNetBrowser.Geometry;
using DotNetBrowser.Handlers;
using DotNetBrowser.WinForms;

namespace Popups.WinForms
{
    public class OpenPopupHandler : IHandler<OpenPopupParameters>
    {
        private readonly Control parent;

        public OpenPopupHandler(Control parent)
        {
            this.parent = parent;
        }

        public void Handle(OpenPopupParameters parameters)
        {
            Action showPopupAction = () =>
            {
                ShowPopup(parameters.PopupBrowser,
                          parameters.Rectangle);
            };
            parent.BeginInvoke(showPopupAction);
        }

        private void ShowPopup(IBrowser popupBrowser, Rectangle rectangle)
        {
            BrowserView browserView = new BrowserView
            {
                Dock = DockStyle.Fill
            };

            browserView.InitializeFrom(popupBrowser);
            // 为弹出浏览器本身设置相同的弹出处理程序。
            popupBrowser.OpenPopupHandler = new OpenPopupHandler(browserView);

            Form form = new Form();

            if(!rectangle.IsEmpty)
            {
                form.StartPosition = FormStartPosition.Manual;

                form.Location = new System.Drawing.Point(rectangle.Origin.X,
                                                         rectangle.Origin.Y);

                form.ClientSize = new System.Drawing.Size((int)rectangle.Size.Width,
                                                          (int)rectangle.Size.Height);

                browserView.Width = (int)rectangle.Size.Width;
                browserView.Height = (int)rectangle.Size.Height;
            }
            else
            {
                form.Width = 800;
                form.Height = 600;
            }

            form.Closed += delegate
            {
                form.Controls.Clear();

                if(!popupBrowser.IsDisposed)
                {
                    popupBrowser.Dispose();
                }
            };

            popupBrowser.TitleChanged += delegate (object sender, TitleChangedEventArgs e)
            {
                form.BeginInvoke((Action)(() => { form.Text = e.Title; }));
            };

            popupBrowser.Disposed += delegate
            {
                Action formCloseAction = () =>
                {
                    form.Controls.Clear();
                    form.Hide();
                    form.Close();
                    form.Dispose();
                };
                form.BeginInvoke(formCloseAction);
            };

            form.Controls.Add(browserView);
            form.Show();
        }
    }
}
Imports DotNetBrowser.Browser
Imports DotNetBrowser.Browser.Handlers
Imports DotNetBrowser.Geometry
Imports DotNetBrowser.Handlers
Imports DotNetBrowser.WinForms

Public Class OpenPopupHandler
    Implements IHandler(Of OpenPopupParameters)

    Private ReadOnly parent As Control

    Public Sub New(parent As Control)
        Me.parent = parent
    End Sub

    Public Sub Handle(p As OpenPopupParameters) _
        Implements IHandler(Of OpenPopupParameters).Handle
        Dim showPopupAction As Action = Sub()
            ShowPopup(p.PopupBrowser, p.Rectangle)
        End Sub
        parent.BeginInvoke(showPopupAction)
    End Sub

    Private Sub ShowPopup(popupBrowser As IBrowser, rectangle As Rectangle)
        Dim browserView As New BrowserView With {.Dock = DockStyle.Fill}

        browserView.InitializeFrom(popupBrowser)
        ' 为弹出浏览器本身设置相同的弹出处理程序。
        popupBrowser.OpenPopupHandler = New OpenPopupHandler(browserView)

        Dim form As New Form()

        If Not rectangle.IsEmpty Then
            form.StartPosition = FormStartPosition.Manual

            form.Location =
                New Drawing.Point(rectangle.Origin.X, rectangle.Origin.Y)

            form.ClientSize =
                New Drawing.Size(rectangle.Size.Width, rectangle.Size.Height)

            browserView.Width = CInt(rectangle.Size.Width)
            browserView.Height = CInt(rectangle.Size.Height)
        Else
            form.Width = 800
            form.Height = 600
        End If

        AddHandler form.Closed, Sub()
            form.Controls.Clear()

            If Not popupBrowser.IsDisposed Then
                popupBrowser.Dispose()
            End If
        End Sub

        AddHandler popupBrowser.TitleChanged, Sub(sender, e)
            form.BeginInvoke(CType(Sub()
                form.Text = e.Title
            End Sub, Action))
        End Sub

        AddHandler popupBrowser.Disposed, Sub()
            Dim formCloseAction As Action = Sub()
                form.Controls.Clear()
                form.Hide()
                form.Close()
                form.Dispose()
            End Sub
            form.BeginInvoke(formCloseAction)
        End Sub

        form.Controls.Add(browserView)
        form.Show()
    End Sub
End Class

WPF

WPF BrowserView 的默认实现如下:

using System;
using System.Windows;
using System.Windows.Threading;
using DotNetBrowser.Browser;
using DotNetBrowser.Browser.Handlers;
using DotNetBrowser.Geometry;
using DotNetBrowser.Handlers;
using DotNetBrowser.Wpf;

namespace Popups.Wpf
{
    public class OpenPopupHandler : IHandler<OpenPopupParameters>
    {
        private readonly FrameworkElement parent;

        private Dispatcher Dispatcher => parent?.Dispatcher
                                         ?? Application.Current.Dispatcher;

        public OpenPopupHandler(FrameworkElement parentElement)
        {
            parent = parentElement;
        }

        public void Handle(OpenPopupParameters parameters)
        {
            Action showPopupAction = () =>
            {
                ShowPopup(parameters.PopupBrowser,
                          parameters.Rectangle);
            };
            Dispatcher.BeginInvoke(showPopupAction);
        }

        private void ShowPopup(IBrowser popupBrowser, Rectangle rectangle)
        {
            BrowserView browserView = new BrowserView();
            browserView.InitializeFrom(popupBrowser);
            // 为弹出浏览器本身设置相同的弹出处理程序。
            popupBrowser.OpenPopupHandler = new OpenPopupHandler(browserView);

            Window window = new Window {Owner = Window.GetWindow(parent)};

            if (!rectangle.IsEmpty)
            {
                window.Top = rectangle.Origin.Y;
                window.Left = rectangle.Origin.X;
                window.SizeToContent = SizeToContent.WidthAndHeight;

                browserView.Width = rectangle.Size.Width;
                browserView.Height = rectangle.Size.Height;
            }
            else
            {
                window.Width = 800;
                window.Height = 600;
            }

            window.Closed += (sender, args) =>
            {
                window.Content = null;
                if (!popupBrowser.IsDisposed)
                {
                    popupBrowser.Dispose();
                }
            };

            popupBrowser.TitleChanged += (sender, e) =>
            {
                Dispatcher?.BeginInvoke((Action) (() => window.Title = e.Title));
            };

            popupBrowser.Disposed += delegate
            {
                Dispatcher?.Invoke(() =>
                {
                    window.Content = null;
                    window.Hide();
                    window.Close();
                });
            };

            window.Content = browserView;
            window.Show();
        }
    }
}
Imports System.Windows.Threading
Imports DotNetBrowser.Browser
Imports DotNetBrowser.Browser.Handlers
Imports DotNetBrowser.Geometry
Imports DotNetBrowser.Handlers
Imports DotNetBrowser.Wpf

Public Class OpenPopupHandler
    Implements IHandler(Of OpenPopupParameters)

    Private ReadOnly parent As FrameworkElement

    Private ReadOnly Property Dispatcher As Dispatcher
        Get
            Return If(parent?.Dispatcher, Application.Current.Dispatcher)
        End Get
    End Property

    Public Sub New(parentElement As FrameworkElement)
        parent = parentElement
    End Sub

    Public Sub Handle(p As OpenPopupParameters) _
        Implements IHandler(Of OpenPopupParameters).Handle
        Dim showPopupAction As Action =
                Sub()
                    ShowPopup(p.PopupBrowser, p.Rectangle)
                End Sub
        Dispatcher.BeginInvoke(showPopupAction)
    End Sub

    Private Sub ShowPopup(popupBrowser As IBrowser, rectangle As Rectangle)
        Dim browserView As New BrowserView()
        browserView.InitializeFrom(popupBrowser)
        ' 为弹出浏览器本身设置相同的弹出处理程序。
        popupBrowser.OpenPopupHandler = New OpenPopupHandler(browserView)

        Dim window As New Window With {.Owner = Window.GetWindow(parent)}

        If Not rectangle.IsEmpty Then
            window.Top = rectangle.Origin.Y
            window.Left = rectangle.Origin.X
            window.SizeToContent = SizeToContent.WidthAndHeight

            browserView.Width = rectangle.Size.Width
            browserView.Height = rectangle.Size.Height
        Else
            window.Width = 800
            window.Height = 600
        End If

        AddHandler window.Closed, Sub(sender, args)
            window.Content = Nothing
            If Not popupBrowser.IsDisposed Then
                popupBrowser.Dispose()
            End If
        End Sub

        AddHandler popupBrowser.TitleChanged, Sub(sender, e)
            Dispatcher?.BeginInvoke(CType(Sub() window.Title = e.Title, Action))
        End Sub

        AddHandler popupBrowser.Disposed, Sub()
            Dispatcher?.Invoke(Sub()
                window.Content = Nothing
                window.Hide()
                window.Close()
            End Sub)
        End Sub

        window.Content = browserView
        window.Show()
    End Sub
End Class

Avalonia UI

Avalonia BrowserView 的默认实现如下:

using Avalonia;
using Avalonia.Controls;
using Avalonia.Threading;
using DotNetBrowser.AvaloniaUi;
using DotNetBrowser.Browser;
using DotNetBrowser.Browser.Handlers;
using DotNetBrowser.Geometry;
using DotNetBrowser.Handlers;

namespace Popups
{
    public class OpenPopupHandler : IHandler<OpenPopupParameters>
    {
        public void Handle(OpenPopupParameters parameters)
        {
            Dispatcher.UIThread.InvokeAsync(() =>
            {
                ShowPopup(parameters.PopupBrowser,
                          parameters.Rectangle);
            });
        }

        private void ShowPopup(IBrowser popupBrowser, Rectangle rectangle)
        {
            BrowserView browserView = new BrowserView();
            browserView.InitializeFrom(popupBrowser);
            // 为弹出浏览器本身设置相同的弹出处理程序。
            popupBrowser.OpenPopupHandler = new OpenPopupHandler();

            Window window = new Window();

            if (!rectangle.IsEmpty)
            {
                window.Position = new PixelPoint(rectangle.Origin.X, rectangle.Origin.Y);
                window.SizeToContent = SizeToContent.WidthAndHeight;
                browserView.Width = rectangle.Size.Width;
                browserView.Height = rectangle.Size.Height;
            }
            else
            {
                window.Width = 800;
                window.Height = 600;
            }

            window.Closed += (sender, args) =>
            {
                window.Content = null;
                if (!popupBrowser.IsDisposed)
                {
                    popupBrowser.Dispose();
                }
            };

            popupBrowser.TitleChanged += (sender, e) =>
            {
                Dispatcher.UIThread.InvokeAsync(() => window.Title = e.Title);
            };

            popupBrowser.Disposed += delegate
            {
                Dispatcher.UIThread.InvokeAsync(() =>
                {
                    window.Content = null;
                    window.Hide();
                    window.Close();
                });
            };

            window.Content = browserView;
            window.Show();
        }
    }
}

关闭弹出窗口

打开的弹出窗口可以使用 IBrowser.Dispose() 方法或 JavaScript 中的 window.close() 来关闭。 在这两种情况下,Disposed 事件都会被触发。

我们建议您始终注册 Disposed 事件监听器,以便在弹出窗口关闭时获得通知。 如果显示了弹出窗口,则可以通过此功能将其隐藏。

popupBrowser.Disposed += delegate
{
    // 隐藏弹出窗口。
};
AddHandler popupBrowser.Disposed, Sub()
    ' 隐藏弹出窗口。
End Sub
Go Top