【问题标题】:Is there really no way to implement confirm() and prompt() in a UWP WebView?真的没有办法在 UWP WebView 中实现 confirm() 和 prompt() 吗?
【发布时间】:2021-03-25 22:08:21
【问题描述】:

有没有人获得了最基本的 Javascript API,如 prompt() 和 confirm() 在 UWP WebView 中工作?没有实现它们并不奇怪,但真的没有办法在应用程序中支持它们吗?如果是真的,那太疯狂了……

在您问之前,我们已经有太多的 HTML/Javascript 可以重写,只是为了一个新的 Windows 应用程序。无论如何,认为我们应该这样做是愚蠢的。

最大的问题是在我们等待用户阅读对话框时无法暂停 Javascript 线程。以下是我尝试过的一些事情:

  • ScriptNotify:这适用于 alert(),但我们不能像 confirm() 那样返回结果。
  • AddWebAllowedObject:我尝试实现一个本机对象,它更接近。 Javascript调用了我的本机警报函数并等待,但在本机函数返回结果之前我无法显示对话框。 UI 只是挂起。 :(
  • WebViewExecutionMode.SeparateThread:我终于尝试在不同的线程上运行 WebView。这样,对话框实际上出现了,但随后一切都冻结了,直到本机函数再次返回结果。多线程的噩梦……

如果这真的不可能,微软是否计划在近期内添加它? Android、macOS 和 iOS Web 视图都支持这些基本 API;小菜一碟。

【问题讨论】:

    标签: uwp


    【解决方案1】:

    真的没有办法在UWP WebView中实现confirm()和prompt()吗?

    如果您需要在应用代码中接收从 WebView 托管脚本发送的通知和数据,则需要处理 ScriptNotify 事件。

    ScriptNotify:这适用于 alert(),但我们不能像 confirm() 那样返回结果。

    如您所知,confirm() 方法可能效果不佳。但是您可以在 UWP 应用程序中使用 MessageDialog 作为解决方法来获得相同的效果。例如:

    HTML

    <button id="btnConfirm" onclick="confirmBox('sure to delete?')">click me to confirm</button> 
    <script type="text/javascript">
        function confirmBox(message) { 
            window.external.notify('typeConfirm:' + message); 
        }
    </script>
    

    背后的C#代码

    private async void WebView_ScriptNotify(object sender, NotifyEventArgs e)
    {
        Windows.UI.Popups.MessageDialog dialog;
        string[] messageArray = e.Value.Split(':');
        string message;
        string type;
        if (messageArray.Length > 1)
        {
            message = messageArray[1];
            type = messageArray[0];
        }
        else
        {
            message = e.Value;
            type = "typeAlert";
        }
        dialog = new Windows.UI.Popups.MessageDialog(message);
        Debug.WriteLine("type=" + type + " ,message=" + message);
    
        if (type.Equals("typeConfirm"))
        {
            dialog.Commands.Add(new UICommand("Yes"));
            dialog.Commands.Add(new UICommand("Cancel"));
            dialog.DefaultCommandIndex = 0;
            dialog.CancelCommandIndex = 1;
        }
        var result = await dialog.ShowAsync();
        if (result.Label.Equals("Yes"))
        {
            // do something you want, maybe invoke a script
            //await webView1.InvokeScriptAsync("eval", new string[] { functionString });
        }
        else
        {
            // do something you want, maybe invoke a script
            //await webView1.InvokeScriptAsync("eval", new string[] { functionString });
        }
    }
    

    在你问之前,我们已经有太多的 HTML/Javascript 来重写它只是为了一个新的 Windows 应用程序

    如果您担心使用上述解决方法,恐怕没有其他方法。

    如果这真的不可能,微软是否计划很快添加它?

    很抱歉,我们无法确定将来是否可以实现某个功能,但您可以尝试将您的功能发布到user voice。无论如何,似乎不推荐使用托管在WebView 中的confirm()。如果有条件,您可以考虑其他方式将您的 HTML/JavaScript 传输到 UWP 应用程序中。查看此similar thread 了解更多详情。

    【讨论】:

    • 那么Edge浏览器是如何支持的呢?不是用同一个EdgeHTML引擎吗?
    • 微软的决定真的很奇怪
    【解决方案2】:

    Javascript / Typescript 的解决方案。 将在 UWP 应用中工作,而不是在 Edge/IE 中。

         async function confirm(title: string, message: string | null): Promise<boolean> {
    
            const UI = window['Windows'].UI;
    
            const dialog = new UI.Popups.MessageDialog(message, title);
    
            const yes = new UI.Popups.UICommand("Yes");
            yes.id = 0;
            const no = new UI.Popups.UICommand("No");
            yes.id = 1;
            dialog.commands.push(yes);
            dialog.commands.push(no);
            dialog.defaultCommandIndex = 0;
            dialog.cancelCommandIndex = 1;
            const result = await dialog.showAsync();
            return result.id === yes.id;
        }
    

    【讨论】:

    • 我也尝试过这种方法,但它仍然不能替代标准确认功能,因为它是异步的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    相关资源
    最近更新 更多