UWP - 加入 Windows Runtime Component 到 JavaScript context

在 WebView 里面让 Javascript 与 App 交互已经是很平常的事情了,为什么要特别写这篇。 因为发现除了 window.external.notify 允许从网页送入消息到 App 之外,还可以加入自定义的 component 到网页里让 Javascript 使用。 这篇将介绍怎么实践。


根据 WebView class 的介绍,在 Windows 10 开始允许利用 AddWebAllowedObject method 去引用建立好的 Windows Runtime component 到 WebView 的 Javascript context 之中,让 Javascript 有能力存取 native 的 properties, methods, events。

那我们来看要做些什么才能完成这样的功能。

1. 建立 Universal Windows Platform 与 Windows Runtime component ,再将 Component 的项目加入到 App 的参考之中; UWP - 加入 Windows Runtime Component 到 JavaScript context

2. 为 component 项目中的 class 加入 AllowForWeb 的 attribute;

Allow​For​Web​Attribute Class 允许让开发者公开 native 对象变成类似 global parameter 的内容放在 WebView 的 top-level。

由于声明 AllowForWeb 的类是受到保护的,所以需要是 sealed 的 class。 如下的程序:


[AllowForWeb]
public sealed class JavaScriptExternalObject
{
    /// 
    /// 提供给外部使用时收听的事件
    /// 
    public event EventHandler FromJavaScriptMessage;
        
    /// 
    /// 提供给 JavaScript 调用的方法
    /// 
    public void onOpenNativeShareDialog(string json)
    {
            FromJavaScriptMessage?.Invoke(null, json);
    }
}

3. 在 WebView 的 NavigationStarting 事件发生时为每个新进入的网页加入 JavaScriptExternalObject; 利用 AddWebAllowedObject 将 native Windows Runtime Component 声明的类加入到 Webview 之中,如下:


public sealed partial class MainPage : Page
{
    private JavaScriptExternalObject javascriptExternalObject;

    public MainPage()
    {
        javascriptExternalObject = new JavaScriptExternalObject();
        javascriptExternalObject.FromJavaScriptMessage += JavascriptExternalObject_FromJavaScriptMessage;
        this.InitializeComponent();
    }

    private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
    {
        // 定义公开的名称为: external
        // JavaScriptExternalObject: 为 Javascript 里面可以利用 external.{JavaScriptExternalObject 里面的内容}
        sender.AddWebAllowedObject("external", javascriptExternalObject);
    }

    private async void JavascriptExternalObject_FromJavaScriptMessage(object sender, string e)
    {
        // 接受来自 JavasScript 的消息
        await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            var dialog = new MessageDialog(e);
            await dialog.ShowAsync();
        });
    }
}

[注意]

如果注册 external 的话,WebView 会自动覆写原本 external 的 methods,所以 window.external.notify 也就无法使用了 (ScriptyNotify event 不会被触发)。

需要自行在加入 notify method 到自定义的 JavaScriptExternalObject class 里面才能使用哦

4. WebView 载入 html 内容,并且测试内容;

html 内文如下:




JavaScriptInvokeNativeSample
<body>
    

上一篇:UWP GridView切换数据时界面闪动


下一篇:初识 Uno Platform