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

简介: 原文:重新想象 Windows 8 Store Apps (8) - 控件之 WebView[源码下载] 重新想象 Windows 8 Store Apps (8) - 控件之 WebView 作者:webabcd介绍重新想象 Windows 8 Store Apps 之 WebView ...
原文: 重新想象 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
[源码下载]

目录
相关文章
|
6月前
|
测试技术 UED Python
App自动化测试:高级控件交互技巧
Appium 的 Actions 类支持在移动应用自动化测试中模拟用户手势,如滑动、长按等,增强交互性测试。ActionChains 是 Selenium 的概念,用于网页交互,而 Actions 专注于移动端。在Python中,通过ActionChains和W3C Actions可以定义手势路径,例如在手势解锁场景中,先点击设置,然后定义触点移动路径执行滑动解锁,最后验证解锁后的元素状态。此功能对于确保应用在复杂交互下的稳定性至关重要。
128 5
|
6月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
222 3
|
6月前
|
iOS开发 开发者
一键制作 iOS 上架 App Store 描述文件教程
一键制作 iOS 上架 App Store 描述文件教程
|
6月前
|
iOS开发 UED
解决提交到App Store时的ITMS-90478和ITMS-90062错误
解决提交到App Store时的ITMS-90478和ITMS-90062错误
82 0
|
6月前
|
iOS开发 开发者
苹果iOS App Store上架操作流程详解:从开发者账号到应用发布
很多开发者在开发完iOS APP、进行内测后,下一步就面临上架App Store,不过也有很多同学对APP上架App Store的流程不太了解,下面我们来说一下iOS APP上架App Store的具体流程,如有未涉及到的部分,大家可以及时咨询,共同探讨。
|
6月前
|
安全 开发工具 数据安全/隐私保护
如何将应用程序发布到 App Store
如何将应用程序发布到 App Store
|
6月前
|
安全 开发工具 数据安全/隐私保护
如何将应用程序发布到 App Store
如何将应用程序发布到 App Store
|
3月前
|
Windows
Windows——如何提取Microsoft Store的应用
Windows——如何提取Microsoft Store的应用
32 0
|
5月前
|
网络虚拟化 Windows
Windows 10 Windows1011出现0x80190001错误解决方案! Windows微软账户无法登录问题 Microsoft Store商店用不了
Windows 10 Windows1011出现0x80190001错误解决方案! Windows微软账户无法登录问题 Microsoft Store商店用不了
110 1
|
6月前
|
存储 数据安全/隐私保护 iOS开发
应用在App Store上被拒重新提交审核流程指南
该文本是关于iOS应用发布的步骤说明
83 2