【WP8.1】WebView笔记

之前在WP8的时候做过WebBrowser相关的笔记,在WP8.1的WebView和WebBrowser有些不一样,在这里做一些笔记

下面分为几个部分

  1、禁止缩放

  2、JS通知后台C#代码(notify)

  3、C#调用JS方法

    动态加载JS文件,动态注册事件方法(eval)

  4、WebView导航

  5、手势(WinJS)

  6、常见问题

1、禁用缩放  

body {
    /* Block area from manipulation actions (zoom, pan) */
    touch-action: pan-y;
}

  这个值可以禁用掉缩放和横向手势

  关于touch-action参见:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh767313.aspx?f=255&MSPPError=-2147217396

2、JS通知后台C#代码(notify) 

window.external.notify(msg);

注意:这里的方法名是小写的,在WP8上后面的Notify方法的首字母是大小写都可以

3、C#调用JS方法(InvokeScriptAsync)

  通过后台代码动态加载css,js,动态绑定事件和方法

  3.1、先定义传输的数据格式

/// <summary>
/// JS消息格式
/// </summary>
public class JsInvokeModel
{
    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("content1")]
    public string Content1 { get; set; }

    [JsonProperty("content2")]
    public string Content2 { get; set; }

    [JsonProperty("content3")]
    public string Content3 { get; set; }
}

  3.2、XAML

<WebView x:Name="WebView" DOMContentLoaded="WebView_OnDOMContentLoaded" ScriptNotify="WebView_OnScriptNotify" />

  3.3、下面是事件方法

//DOM树加载完成后执行
private async void WebView_OnDOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
    //1、动态加载css
    var js = @"var myCss = document.createElement(""link"");
        myCss.rel = ""stylesheet"";
        myCss.type = ""text/css"";
        myCss.href = ""ms-appx-web:///Assets/Html/css/default.css"";
        document.body.appendChild(myCss);";
    await sender.InvokeScriptAsync("eval", new[] { js });

    //2、动态加载js库(json2)
    js = @"var myScript = document.createElement(""script"");
        myScript.type = ""text/javascript"";
        myScript.src = ""ms-appx-web:///Scripts/json2.min.js"";
        document.body.appendChild(myScript);";
    await sender.InvokeScriptAsync("eval", new[] {js});

    //3、调用js执行自定义代码(为图片添加点击事件,并通知)
    js = @"var imgs = document.getElementsByTagName(""img"");
           for (var i = 0, len = imgs.length; i < len; i++) {
               imgs[i].onclick = function (e) {
                   var jsonObj = { type: ‘image‘, content1: this.src };
                   window.external.notify(JSON.stringify(jsonObj));
               };
           }";
    await sender.InvokeScriptAsync("eval", new[] {js});

    //4、动态加载手势
    js = @"var myScript = document.createElement(""script"");
        myScript.type = ""text/javascript"";
        myScript.src = ""ms-appx-web:///Assets/Html/js/gesture.js"";
        document.body.appendChild(myScript);
        window.external.notify(myScript.src+"""");";
    await sender.InvokeScriptAsync("eval", new[] { js });

    //5、为body添加手势监听
    js = @"var target = document.getElementsByTagName(""body"")[0];
           prepareTarget(target, eventListener);";
    await sender.InvokeScriptAsync("eval", new[] { js });
}

  3.4、Notify监听

private void WebView_OnScriptNotify(object sender, NotifyEventArgs e)
{
    //这个事件函数可以监听到JS通知的消息,消息类型为文本
    //这里统一消息格式为:JsInvokeModel
    var model = JsonConvert.DeserializeObject<JsInvokeModel>(e.Value);
    switch (model.Type)
    {
        case "image":
            Info.Text = e.Value;
            break;
        case "swiperight":
            //右滑
            Info.Text = e.Value;
            break;
        case "swipeleft":
            //左滑
            Info.Text = e.Value;
            break;
        case "text":
            Info.Text = e.Value;
            break;
    }
}

  WebView虽然提供了同步方法InvokeScript,但是在WP8.1没有实现

   通过InvokeScriptAsync,可以做更多操作,例如,相信对于更换颜色(夜间模式),修改字体大小等

4、WebView导航

两种方式
//后退
    //WebView.GoBack();
    await WebView.InvokeScriptAsync("eval", new []{"history.go(-1)"});

    //刷新
    //WebView.Refresh();
    await WebView.InvokeScriptAsync("eval", new[] { "history.go()" });        

    //前进
    //WebView.GoForward();
    await WebView.InvokeScriptAsync("eval", new[] { "history.go(1)" });

5、手势

  由于WebView的内部结构与WebBrowser不同,WebView无法监听到Manipulation事件

  场景:当我们需要在PivotItem中放置WebView的时候,左右滑动无法切换PivotItem,下面通过JS手势监听WebView上面的手势操作,然后传到后台代码进行处理,这里没有做实时处理,只是监听了手势离开时的速度判断左右滑动

  5.1、定义手势监听事件方法

var gesture;
//记录手势操作开始位置
var gestureStartX;

//触发Id,防止重复触发,触发Id与手势Id
var gestureId = 1;
var lastGestureId = 0;

//速度触发
var gestureVector = 1.5;

//注册手势事件
function prepareTarget(target, eventListener) {
    //var target = document.getElementById(targetId);
    target.addEventListener("MSGestureStart", eventListener, false);
    target.addEventListener("MSGestureEnd", eventListener, false);
    target.addEventListener("MSGestureChange", eventListener, false);
    target.addEventListener("MSInertiaStart", eventListener, false);
    //target.addEventListener("MSGestureTap", eventListener, false);
    //target.addEventListener("MSGestureHold", eventListener, false);
    target.addEventListener("pointerdown", onPointDown, false);
    target.addEventListener("pointerup", onPointUp, false);

    gesture = new MSGesture();
    gesture.target = target;
}

function onPointUp(e) {
    //把触发时间参数传到gesture
    gesture.addPointer(e.pointerId);
}

function onPointDown(e) {
    //把触发时间参数传到gesture
    gesture.addPointer(e.pointerId);
}

//手势事件
//具体的属性参见:https://msdn.microsoft.com/zh-cn/library/ie/hh772076%28v=vs.85%29.aspx
function eventListener(evt) {
    var myGesture = evt.gestureObject;
    if (evt.type == "MSGestureStart") {
        //开始触发,记录初始位置
        gestureStartX = evt.clientX;
    }
    else if (evt.type == "MSInertiaStart") {
        if (lastGestureId == gestureId || evt.velocityX == "undefined") {
            return;
        } else {
            //释放时触发惯性事件,判断手势释放时的速度
            if (evt.velocityX > gestureVector) {
                var jsonObj = { type: "swiperight" };
                window.external.notify(JSON.stringify(jsonObj));
                lastGestureId = gestureId;
            } else if (evt.velocityX < -gestureVector) {
                jsonObj = { type: "swipeleft" };
                window.external.notify(JSON.stringify(jsonObj));
                lastGestureId = gestureId;
            }
        }
    }
    else if (evt.type == "MSGestureChange") {
        //if (lastGestureId == gestureId) {
        //    return;
        //} else {
        //    var change = evt.clientX - gestureStartX;
        //    window.external.notify("clientX:" + change);
        //}
    } else if (evt.type == "MSGestureEnd") {
        //手势结束,Id+1
        gestureId = gestureId + 1;
        myGesture.reset();
    }
}

gesture.js

  5.2、在WebView加载完成后,动态加载改JS文件,获取body标签,然后监听事件(参见3.3)

  5.3、当事件触发的时候改变Pivot.SelectedIndex,这样就能实现在WebView上滑动切换PivotItem

private void WebView_OnScriptNotify(object sender, NotifyEventArgs e)
{
    //这个事件函数可以监听到JS通知的消息,消息类型为文本
    //这里统一消息格式为:JsInvokeModel
    var model = JsonConvert.DeserializeObject<JsInvokeModel>(e.Value);
    switch (model.Type)
    {
        case "image":
            Info.Text = e.Value;
            break;
        case "swiperight":
            Info.Text = e.Value;
            if (pivot.Items != null)
            {
                if (pivot.SelectedIndex > 0)
                {
                    pivot.SelectedIndex--;
                }
                else
                {
                    pivot.SelectedIndex = pivot.Items.Count - 1;
                }
            }
            break;
        case "swipeleft":
            Info.Text = e.Value;
            if (pivot.Items != null)
            {
                if (pivot.SelectedIndex < pivot.Items.Count - 1)
                {
                    pivot.SelectedIndex++;
                }
                else
                {
                    pivot.SelectedIndex = 0;
                }
            }
            break;
        case "text":
            Info.Text = e.Value;
            break;
    }
}

6、常见问题

  6.1、alert和prompt方法在WebView失效,如果需要,可以使用 window.external.notify(‘message‘);然后再后台代码进行处理

7、Demo

  http://files.cnblogs.com/files/bomo/WebViewDemo.zip

8、参考链接

  手势事件参数说明:https://msdn.microsoft.com/zh-cn/library/ie/hh772076%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

  WinJS手势:https://msdn.microsoft.com/zh-cn/library/ie/hh968249(v=vs.85).aspx

关于WP8的WebBrowser,请移步:http://www.cnblogs.com/bomo/p/3949994.html

个人能力有限,如果上文有误或者您有更好的实现,可以给我留言

转载请注明出处:http://www.cnblogs.com/bomo/p/4320077.html

时间: 2024-11-07 06:22:27

【WP8.1】WebView笔记的相关文章

WP8.1开发笔记一:JSON数据处理

一:创建一个普通的WP8.1应用 二:在解决方案选中项目,右击 “添加NuGet应用”,添加 json.net 三:把抓包的JSON地址,处理一下 JSON格式在线校对:http://www.bejson.com/go.html?u=http://www.bejson.com/jsonviewernew/ JSON生成C#类:http://tools.wx6.org/json2csharp/ 四:输入相关的代码并且和前台页面绑定在一块: 后台页面的代码: using System; using

&lt;WP8开发学习笔记&gt;获取手机的常用型号(如Lumia920,而非RM-822)

之前WP7时代可以用API获得WP手机的型号如lumia510,但是到了WP8后用APi只能获得硬件版本号了如RM-822,这种型号可以让我们更详细的了解具体的硬件版本,比如国行和港行,设备版本号不一样(但是我不记得了╮(╯-╰)╭),一个支持4G,一个不支持,但是型号都是Lumia920,这或许是微软的考量吧. 但是当我们只想要手机常用的型号时,发现没有这个Api了,真的是很麻烦. 我在GitHub上找到了一个手机型号转换器,PhoneNameResolver,地址 https://githu

&lt;WP8开发学习笔记&gt;修改panorama全景控件的标题的大小

panorama(全景)控件非常具有WinPhone特色,但是那个巨大的标题许多时候会让人觉得违和.怎么修改它呢? 最开始想到的是加一个FontSize,结果毫无影响.╮(╯-╰)╭ <phone:Panorama Title="我的应用程序" FontSize="30"> <phone:Panorama.Background> <ImageBrush ImageSource="/PanoramaApp3;component/

1. WP8.1学习笔记

数据绑定 含义:将对象绑定到控件上 2.基本名词 控件:绑定目标 对象:绑定源(数据源) 控件与对象属性的联系:路径 如何绑定 创建对象,设置控件 在控件需要数据绑定的地方使用拓展语法 <Button Content="按钮"/> <Button content="{Binding Path=属性名}"/> 在后台为控件的DataContext赋值 this.Context=对象; 设置绑定类型: content="{Binding

&lt;WP8开发学习笔记&gt;ApplicationBar(任务栏)的切换以及“黑条问题”

ApplicationBar(以下简称AppBar)是WP应用相当常见的控件,也很方便.常见的做法是pivot或者panorama的页面切换的时候,AppBar跟随切换对应的按钮或者不显示按钮,如下图. 这个方法比较简单,网上很容易找到资料,不过我还是简要的说一下. 首先要在页面资源里添加需要的AppBar,我这里添加了两个银色的AppBar.一个默认模式,一个最小化模式. <phone:PhoneApplicationPage.Resources> <shell:Application

WP8.1学习笔记

应用程序生命周期: 运行: 在程序NotRunning状态下点击图标,应用将处于Running状态,这会触发一个Actived事件 挂起: 在程序Running状态下, 点击返回键或win键会触发一个Suspending事件,应用进入Suspended状态 停止: 内存不足,设备关机,用户手动关闭会使应用进入NotRunning状态 所以只能在挂起的时候保存数据 在注册了SusupensinManager的应用中 挂起的时候会调用OnSuspending.onNavigateFrom和SaveS

安卓开发复习笔记——WebView组件

我们专业方向本是JAVA Web,这学期突然来了个手机App开发的课设,对于安卓这块,之前自学过一段时间,有些东西太久没用已经淡忘了 准备随笔记录些复习笔记,也当做温故知新吧~ 1.什么是WebView? WebView(网络视图)能加载显示网页,可以将其视为一个浏览器,它使用了WebKit渲染引擎加载显示网页. 废话不多说,直接上代码 1.需要在xml布局文件中声明WebView组件 1 <WebView 2 android:id="@+id/webview" 3 androi

转 Android开发学习笔记:浅谈WebView

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 WebView(网络视图)能加载显示网页,可以将其视为一个浏览器.它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法: 第一种方法的步骤: 1.在要Activity中实例化WebView组件:WebView webView = new WebView(this); 2

Android分享笔记(4) Android的webview加载本地html、本apk内html和远程URL

//打开本包内asset目录下的index.html文件 webView.loadUrl(" file:///android_asset/index.html "); //打开本地sd卡内的index.html文件 wView.loadUrl("content://com.android.htmlfileprovider/sdcard/index.html"); //打开指定URL的html文件 wView.loadUrl(" http://m.oschi