• 重新想象 Windows 8 Store Apps (8) 控件之 WebView


    [源码下载]


    重新想象 Windows 8 Store Apps (8) - 控件之 WebView



    作者:webabcd


    介绍
    重新想象 Windows 8 Store Apps 之 WebView

    • 演示 WebView 的基本应用
    • 演示 WebView 如何与 JavaScript 交互
    • 通过 Share Contract 分享 WebView 中的内容
    • 如何全屏 WebView



    示例
    1、WebView 的基本应用
    WebView/Demo.xaml

    <Page
        x:Class="XamlDemo.Controls.WebView.Demo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Controls.WebView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <Button Name="btnNavigateUrl" Content="导航到指定的 url" Click="btnNavigateUrl_Click_1" />
                
                <Button Name="btnShowHtml" Content="解析指定的 html 字符串" Click="btnShowHtml_Click_1" Margin="0 10 0 0" />
    
                <Button Name="btnFullScreen" Content="演示当 WebView 全屏时如何操作当前页(WebView 会遮挡所有元素)" Click="btnFullScreen_Click_1" Margin="0 10 0 0" />
    
                <WebView Name="webView" Width="400" Height="300" HorizontalAlignment="Left" Margin="0 10 0 0" />
                
            </StackPanel>
        </Grid>
    </Page>

    WebView/Demo.xaml.cs

    /*
     * WebView - 内嵌浏览器
     *     Source - 导航到指定的 url
     *     Navigate() - 导航到指定的 url
     *     NavigateToString() - 解析指定的 html 字符串
     *     LoadCompleted - 在 DOM 加载完成后所触发的事件
     *     NavigationFailed - 导航发生错误时触发的事件(事件参数:WebViewNavigationFailedEventArgs)
     *     
     * WebViewNavigationFailedEventArgs
     *     Uri - 尝试导航到的 Uri
     *     WebErrorStatus - 错误状态(Windows.Web.WebErrorStatus 枚举)
     */
    
    using System;
    using Windows.UI.Popups;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace XamlDemo.Controls.WebView
    {
        public sealed partial class Demo : Page
        {
            public Demo()
            {
                this.InitializeComponent();
            }
    
            private void btnNavigateUrl_Click_1(object sender, RoutedEventArgs e)
            {
                // 导航到指定的 url
                webView.Navigate(new Uri("http://webabcd.cnblogs.com/", UriKind.Absolute));
                // webView.Source = new Uri("http://webabcd.cnblogs.com/", UriKind.Absolute);
    
                // 导航失败时
                webView.NavigationFailed += webView_NavigationFailed;
            }
    
            async void webView_NavigationFailed(object sender, WebViewNavigationFailedEventArgs e)
            {
                await new MessageDialog(e.WebErrorStatus.ToString()).ShowAsync();
            }
    
            private void btnShowHtml_Click_1(object sender, RoutedEventArgs e)
            {
                // 解析指定的 html 字符串
                webView.NavigateToString("<html><body>I am webabcd</body></html>");
            }
    
            private void btnFullScreen_Click_1(object sender, RoutedEventArgs e)
            {
                var root = Window.Current.Content as Windows.UI.Xaml.Controls.Frame;
                root.Navigate(typeof(XamlDemo.Controls.WebView.FullScreen));
            }
        }
    }


    2、WebView 如何与 JavaScript 交互
    WebView/Interact.xaml

    <Page
        x:Class="XamlDemo.Controls.WebView.Interact"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Controls.WebView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <Button Name="btnInvokeJavaScript" Content="app 调用 WebView 加载内容中的 JavaScript 脚本" Click="btnInvokeJavaScript_Click_1" />
    
                <Button Name="btnAccessDOM" Content="通过 eval 访问 DOM" Click="btnAccessDOM_Click_1" Margin="0 10 0 0" />
    
                <WebView Name="webView" Width="400" Height="300" Source="http://localhost:39629/WebViewInteract.html" HorizontalAlignment="Left" Margin="0 10 0 0" />
    
            </StackPanel>
        </Grid>
    </Page>

    WebView/Interact.xaml.cs

    /*
     * 演示 app 如何与 WebView 中的 JavaScript 进行交互
     * 
     * WebView - 内嵌浏览器
     *     InvokeScript() - 调用 JavaScript 中的指定函数,并返回执行结果
     *     ScriptNotify - 当接收到从 JavaScript 发过来的数据时所触发的事件(事件参数:NotifyEventArgs)
     *     AllowedScriptNotifyUris - 允许触发 ScriptNotify 事件的 uri 列表
     *     
     * NotifyEventArgs
     *     Value - js 传递给 app 的数据
     * 
     *     
     * 注:本例通过加载 WebServer 项目下的 WebViewInteract.html 来演示 app 与 js 的交互
     */
    
    using System;
    using System.Collections.Generic;
    using Windows.UI.Popups;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Controls.WebView
    {
        public sealed partial class Interact : Page
        {
            public Interact()
            {
                this.InitializeComponent();
    
                // 指定允许触发 ScriptNotify 事件的 uri 列表(如果 uri 是目录而不是文件,则此目录下所有文件都可以触发 ScriptNotify 事件)
                List<Uri> allowedUris = new List<Uri>();
                allowedUris.Add(new Uri("http://localhost:39629/"));
                webView.AllowedScriptNotifyUris = allowedUris;
    
                webView.ScriptNotify += webView_ScriptNotify;
            }
    
            async void webView_ScriptNotify(object sender, NotifyEventArgs e)
            {
                // 获取 js 传递过来的数据(js 端通向 app 传递数据的方法:window.external.notify('js to app');)
                await new MessageDialog(e.Value).ShowAsync();
            }
    
            // app 调用 js
            private async void btnInvokeJavaScript_Click_1(object sender, RoutedEventArgs e)
            {
                string[] arguments = { "webabcd" };
                // 调用 js 方法:sayHelloToJs('webabcd'); 并返回结果
                string result = webView.InvokeScript("sayHelloToJs", arguments);
    
                await new MessageDialog(result).ShowAsync();
            }
    
            // 通过 eval 方式访问 DOM
            private async void btnAccessDOM_Click_1(object sender, RoutedEventArgs e)
            {
                // 获取 document.title 的值
                string[] arguments = { "document.title" };
                string result = webView.InvokeScript("eval", arguments);
    
                await new MessageDialog(result).ShowAsync();
            }
        }
    }


    3、通过 Share Contract 分享 WebView 中的内容
    WebView/Share.xaml

    <Page
        x:Class="XamlDemo.Controls.WebView.Share"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Controls.WebView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="120 0 0 0">
    
                <Button Name="btnShare" Content="通过 Share Contract 分享 WebView 中的被选中的文本内容" Click="btnShare_Click_1" />
                
                <WebView Name="webView" Width="400" Height="300" Source="http://webabcd.cnblogs.com/" HorizontalAlignment="Left" Margin="0 10 0 0" />
                
            </StackPanel>
        </Grid>
    </Page>

    WebView/Share.xaml.cs

    /*
     * 演示如何通过 Share Contract 分享 WebView 中的内容(复制到剪切板也是同理)
     * 
     * WebView - 内嵌浏览器
     *     DataTransferPackage - 返回 DataPackage 对象
     */
    
    using Windows.ApplicationModel.DataTransfer;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace XamlDemo.Controls.WebView
    {
        public sealed partial class Share : Page
        {
            private DataTransferManager _dataTransferManager;
    
            public Share()
            {
                this.InitializeComponent();
            }
            
            private void btnShare_Click_1(object sender, RoutedEventArgs e)
            {
                _dataTransferManager = DataTransferManager.GetForCurrentView();
                _dataTransferManager.DataRequested += _dataTransferManager_DataRequested;
    
                DataTransferManager.ShowShareUI();
            }
    
            // 分享 WebView 中的被选中的文本内容
            void _dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
            {
                DataRequest request = args.Request;
                DataPackage dataPackage = webView.DataTransferPackage;
                DataPackageView dataPackageView = dataPackage.GetView();
    
                // 如果用户选择了一段内容,则通过 WebView.DataTransferPackage 获取到的数据里就会有 StandardDataFormats.Text 格式的内容,此内容就是用户所选中的内容
                if (dataPackageView.Contains(StandardDataFormats.Text)) 
                {
                    dataPackage.Properties.Title = "Title";
                    dataPackage.Properties.Description = "Description";
    
                    request.Data = dataPackage;
                }
                else
                {
                    request.FailWithDisplayText("没有选中任何内容");
                }
    
                _dataTransferManager.DataRequested -= _dataTransferManager_DataRequested;
            }
        }
    }


    4、全屏 WebView 时需要注意哪些
    WebView/FullScreen.xaml

    <Page
        x:Class="XamlDemo.Controls.WebView.FullScreen"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:XamlDemo.Controls.WebView"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <Storyboard x:Name="sbOpenAppBar">
                <DoubleAnimation x:Name="aniTranslateYOpen" Storyboard.TargetName="webView" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Duration="00:00:00.367">
                    <DoubleAnimation.EasingFunction>
                        <ExponentialEase EasingMode="EaseOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
            <Storyboard x:Name="sbCloseAppBar">
                <DoubleAnimation x:Name="aniTranslateYClose" Storyboard.TargetName="webView" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Duration="00:00:00.367">
                    <DoubleAnimation.EasingFunction>
                        <ExponentialEase EasingMode="EaseOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </Page.Resources>
        
        <Page.BottomAppBar>
            <AppBar x:Name="appBar">
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="btnHome" Style="{StaticResource HomeAppBarButtonStyle}" Click="btnHome_Click_1" />
                </StackPanel>
            </AppBar>
        </Page.BottomAppBar>
    
        <Grid Background="Transparent">
            <WebView Name="webView" Source="http://webabcd.cnblogs.com/">
                <WebView.RenderTransform>
                    <CompositeTransform/>
                </WebView.RenderTransform>
            </WebView>
        </Grid>
    </Page>

    WebView/FullScreen.xaml.cs

    /*
     * 由于 WebView 控件上不允许显示其他任何元素,那么当 WebView 全屏时如何操作当前页呢?
     * 可以考虑通过 AppBar 操作当前页面,但是 AppBar 也会被 WebView 挡住,所以我们要做的是当 AppBar 显示后,减小 WebView 的高度
     * 
     * 注:WebViewBrush 上是可以显示其他元素的
     */
    
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace XamlDemo.Controls.WebView
    {
        public sealed partial class FullScreen : Page
        {
            public FullScreen()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                appBar.Opened += appBar_Opened;
                appBar.Closed += appBar_Closed;
            }
    
            protected override void OnNavigatedFrom(NavigationEventArgs e)
            {
                appBar.Opened -= appBar_Opened;
                appBar.Closed -= appBar_Closed;
            }
    
            // 显示 BottomAppBar,减小 WebView 的高度,使其不会遮挡 BottomAppBar
            void appBar_Opened(object sender, object e)
            {
                // 强制更新布局,这样可以获取到 WebView 和 BottomAppBar 的最新的真实高度
                this.UpdateLayout();
    
                double appBarHeight = appBar.ActualHeight;
                webView.Height = webView.ActualHeight - appBarHeight;
    
                // WebView 的高度减小后会居中显示,此方法用于将 WebView 的顶端和屏幕的顶端对齐,同时来个动画效果
                aniTranslateYOpen.To = -appBarHeight / 2.0;
                sbOpenAppBar.Begin();
            }
    
            // appBar_Opened 的逆运算,不解释
            void appBar_Closed(object sender, object e)
            {
                this.UpdateLayout();
    
                double appBarHeight = appBar.ActualHeight;
                webView.Height = webView.ActualHeight + appBarHeight;
    
                aniTranslateYOpen.To = appBarHeight / 2.0;
                sbCloseAppBar.Begin();
            }
    
            // 导航到首页
            private void btnHome_Click_1(object sender, RoutedEventArgs e)
            {
                var root = Window.Current.Content as Windows.UI.Xaml.Controls.Frame;
                root.Navigate(typeof(XamlDemo.MainPage));
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    Linux/Unix中的#!和!#
    包含min函数的栈
    顺时针打印矩阵
    二叉树镜像
    数的子结构
    合并两个排序的链表
    反转链表
    链表中倒数第K个结点
    调整数组顺序使奇数位于偶数前面
    在O(1)时间删除链表结点
  • 原文地址:https://www.cnblogs.com/webabcd/p/2942242.html
Copyright © 2020-2023  润新知