C#开发微信门户及应用(44)--微信H5页面开发的经验总结

811 查看

在我们开发微信页面的时候,需要大量用到了各种呈现的效果,一般可以使用Boostrap的效果来设计不同的页面,不过微信团队也提供很多这方面的资源,包括JSSDK的接口,以及Weui的页面样式和相关功能页面,给我们提供了很大的便利,本文是在自己做的一些H5微信应用页面上做了一些功能总结,希望能够给大家提供一定的帮助。

1、微信网页开发

1) JSSDK
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
目前JSSDK支持的接口分类包括下面几类:基础接口、分享接口、图像接口、音频接口、智能接口、设备信息、地理位置、摇一摇周边、界面操作、微信扫一扫、微信小店、微信卡券、微信支付,随着微信功能的全部整合,估计更多的接口会陆续开放出来。
2)WeUI和Jquery WeUI
WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页开发量身设计,可以令用户的使用感知更加统一。在微信网页开发中使用 WeUI,有如下优势:
同微信客户端一致的视觉效果,令所有微信用户都能更容易地使用你的网站
便捷获取快速使用,降低开发和设计成本
微信设计团队精心打造,清晰明确,简洁大方

该样式库目前包含 button、cell、dialog、progress、toast、article、icon 等各式元素,已经在 GitHub上开源。访问 http://weui.github.io/weui/ 或微信扫码即可预览。
jQuery WeUI 中使用的是官方 WeUI 的 CSS 代码,并提供了 jQuery/Zepto 版本的 API 实现。JQuery WeUI相对于在官方WeUI的基础上做了一些功能扩展,已丰富界面设计和相关功能,因此我们可以考虑直接基于JQuery WeUI的基础上进行页面开发即可。
在我前面的一些案例中,都利用了We UI样式来进行很多微信H5页面的功能设计,包括微信支付页面、签到页面等等。
如微信支付页面如下所示:





以及签到页面效果如下所示。




当然我们可以根据业务需要,增加很多这样和微信色调样式一致的页面,这个就是利用WeUI样式带来的界面体验一致性的好处。
本篇主要介绍微信H5页面开发的经验总结,上面提到了利用JSSDK和WeUI来对微信应用的H5页面进行开发,因此下面的相关效果也就是利用这些技术进行处理的。

2、判断微信浏览器

有些情况下,我们可能需要用户只能在微信浏览器上打开,不能用其他浏览器去打开连接,还有就是基于一些用户身份信息的获取,也是需要通过微信浏览器才能重定向获取的,否则使用其他浏览器会出错,因此判断是否为微信浏览器有时候也是一个常规的做法。
判断是否为微信浏览器有两种方式可以达到目的,一个是在前端使用JS脚本去处理,一个是采用后台C#代码进行判断处理,两种均可以达到目的。
使用JS代码实现代码和效果如下所示。

//判断是否在微信中打开
function isWeiXin() {
    var ua = window.navigator.userAgent.toLowerCase();
    if (ua.match(/MicroMessenger/i) == 'micromessenger') {
        return true;
    } else {
        return false;
    }
}

在页面输出处理如下所示。

$(function () {
    var isWeixin = isWeiXin();
    if (isWeixin) {
        $("#weixin").html(window.navigator.userAgent);   //请在微信中打开该页面         
    }
    var display = "是否在微信浏览器中打开:";
    display += isWeixin ? "是" : "否";
    $("#isWeixin").html(display);
});


如果是正常使用微信跳转的页面链接,那么上会提示为:是。
刚才提到了,使用C#后台代码也可以判断是否在浏览器内,一般情况下,我们可以 判断用户的浏览器后做重定向,如果用户确实是微信浏览器的,则继续后面处理,否则重定向到提示页面给用户。

/// <summary>
/// 检查是否微信中打开,否则重定向
/// </summary>
/// <returns></returns>
protected string CheckBrowser()
{
    bool passed = false;
    string userAgent = Request.UserAgent;

    passed = userAgent.ToLower().Contains("micromessenger");
    if (!passed)
    {
        var type = "warn";
        var message = "请在微信中打开该页面";
        var url = string.Format("{0}/H5/info?type={1}&message={2}", ConfigData.WebsiteDomain, type, message);
        return url;
    }
    return null;
}

我们就可以在函数开始部分进行判断即可。

//如果不是微信浏览器,则返回错误页面
var checkUrl = CheckBrowser();
if (!string.IsNullOrEmpty(checkUrl)) return Redirect(checkUrl);

如果非微信浏览器打开页面链接,重定向的页面效果如下所示。


3、字典数据的绑定

和常规网页功能一样,我们在设计微信页面应用的时候,很多数据也是来源字典数据的,而且需要把它们动态绑定在页面上,微信页面的JQuery WeUI提供了一些列表字典数据的展示效果如下所示。



这个常规的数据绑定如下所示,如下JS代码所示。

$("#job").select({
    title: "选择职业",
    items: ["法官", "医生", "猎人", "学生", "记者", "其他"],
    onChange: function(d) {
      console.log(this, d);
    },
    onClose: function() {
      console.log("close");
    },
    onOpen: function() {
      console.log("open");
    },
  });

也可以使用集合对象进行赋值处理,如下JS代码所示。

$("#in").select({
    title: "您的爱好",
    multi: true,
    min: 2,
    max: 3,
    items: [
      {
        title: "画画",
        value: 1,
        description: "额外的数据1"
      },
      {
        title: "打球",
        value: 2,
        description: "额外的数据2"
      }
    ],
    beforeClose: function(values, titles) {
      if(values.indexOf("6") !== -1) {
        $.toast("不能选打球", "cancel");
        return false;
      }
      return true;
    },
    onChange: function(d) {
      console.log(this, d);
    }
  });

基于上面的JS脚本,我们选择后者,使用Ajax技术来填充数据,这样可以动态获取后台的字典数据,并进行页面的绑定操作。

为了方便,我们可以设计一个公共函数,用于数据字典的绑定处理,如下所示。

//绑定字典内容到指定的控件
function BindDictItem(ctrlName, dictTypeName, onChange, onClose, onOpen) {
    var url = '/h5/GetDictJson?dictTypeName=' + encodeURI(dictTypeName);

    //获取Ajax的内容,并放到items集合
    var control = $('#' + ctrlName);
    var items = [];
    $.ajax({
        type: 'GET',
        url: url,
        //async: false, //同步
        dataType: 'json',
        success: function (data) {
            control.empty();//清空下拉框
            //把JSON集合加到数组里面
            $.each(data, function (i, item) {
                items.push({
                    title: item.Text, value: item.Value
                });
            });

            //设置显示列表
            control.select({
                title: "选择" + dictTypeName,
                items: items,
                onChange: onChange,
                onClose: onClose,
                onOpen: onOpen
            });
        },
        error: function (xhr, status, error) {
            $.toast("操作失败" + xhr.responseText); //xhr.responseText
        }
    });
}

那么我们绑定字典数据,就只需要调用这个函数就可以很简单实现数据字典的绑定操作了。

$(function () {
    BindDictItem("Status", "设备状态");
    BindDictItem("Dept", "科室");
    BindDictItem("Building", "建筑物");
    BindDictItem("Floor", "楼层");
    BindDictItem("Special", "特殊情况");
});

我们看具体在微信中打开对应连接,字典绑定的效果如下所示。



我们则可以在微信后台对数据字典进行维护即可进行实时的数据更新。


4、微信图片的预览功能

在很多页面里面,我们需要展示丰富的图片,我们需要结合微信的图片预览功能接口,我们才能把图片打开后方便进行缩放处理操作,那么该如何利用微信JSSDK的图片预览接口呢?
首先我们需要引入Jquery WeUI的样式类库,以及JSSDK所需的JS文件,如下所示。

<script src="~/Content/wechat/jquery-weui/lib/jquery-2.1.4.js"></script>
<script src="~/Content/wechat/jquery-weui/js/jquery-weui.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

然后在页面初始化JSSDK的API脚本,如下代码所示。

var appid = '@ViewBag.appid';
var noncestr = '@ViewBag.noncestr';
var signature = '@ViewBag.signature';
var timestamp = '@ViewBag.timestamp';

wx.config({
    debug: false,
    appId: appid, // 必填,公众号的唯一标识
    timestamp: timestamp, // 必填,生成签名的时间戳
    nonceStr: noncestr, // 必填,生成签名的随机串
    signature: signature, // 必填,签名,见附录1
    jsApiList: [
       'checkJsApi',
       'chooseImage',
       'previewImage',
       'uploadImage',
       'downloadImage'
    ]
});

//所有准备好后
wx.ready(function () {
});

加入我们页面里面包含有两部分的图片,一个是设备铭牌图片,一个是其他附属图片,我们分别展示,如下HTML代码所示。

<div class="weui_cells_title"><h3>铭牌图片</h3></div>
<div class="weui_cells">
    <div class="weui_cell">
        <div id="previewImage">
            @for (var i = 0; i < ViewBag.mainList.Count; i++)
            {
                <img id='mainPic_@i' src='@ViewBag.mainList[i]' alt="铭牌图片" style="height:auto;width:100%" />
            }
        </div>
    </div>
</div>

<div class="weui_cells_title"><h3>其他图片</h3></div>
<div class="weui_cells">
    <div class="weui_cell">
        <div id="previewImage2">
            <div class="weui-row">
                @for (var i = 0; i < ViewBag.otherList.Count; i++)
                {
                    <div class="weui-col-50">
                        <img id='otherPic_@i' src='@ViewBag.otherList[i]' alt="其他图片" style="height:auto;width:100%" />
                    </div>
                }
            </div>
        </div>
    </div>
</div>

这些代码构建了很多个图片控件,也就是原始的HTML图片控件,如果仅仅这样做,那么只能利用网页的效果,而无法利用微信浏览器预览图片,可以放大缩小的丰富功能。

为了实现我们说需要的功能,需要进行一定的处理,简单的方法,可以设计一个JS函数,然后通过JS函数来实现微信预览图片功能,代码如下所示。

function BindClick(selector) {
    document.querySelector(selector).onclick = function (event) {
       var imgArray = [];
        var curImageSrc = $(this).attr('src');
        var oParent = $(this).parent();
        if (curImageSrc && !oParent.attr('href')) {
            $(selector).each(function (index, el) {
                var itemSrc = $(this).attr('src');
                imgArray.push(itemSrc);
            });

            wx.previewImage({
                current: curImageSrc,
                urls: imgArray
            });
        }
    }
}


BindClick('#previewImage img');
BindClick('#previewImage2 img');

这个函数的做法,是参考网上一个大牛的做法,不过这样做存在一个问题,图片如果有多张的话,那么需要点击第一张图片才能开始预览,不能点击其他几张开始。

为了改进这个缺点,我们可以可以利用Razor的模板实现我们需要的代码生成,如下所示集合了Razor模板生成JS代码,实现了我们所需要JS代码的生成。

    var urls = [];
    @foreach (var url in ViewBag.mainList)
{
    <text>urls.push('@url');</text>
}
    @for (var i = 0; i < ViewBag.mainList.Count; i++)
{
    <text>
    document.querySelector('#mainPic_@i').onclick = function () {
        wx.previewImage({
            current: $(this).attr("src"),//urls[@i],
            urls: urls
        });
    };
    </text>
}

    var urlsOther = [];
    @foreach (var url in ViewBag.otherList)
{
    <text>urlsOther.push('@url');</text>
}
    @for (var i = 0; i < ViewBag.otherList.Count; i++)
{
    <text>
    document.querySelector('#otherPic_@i').onclick = function () {
        wx.previewImage({
            current: $(this).attr("src"),//urls[@i],
            urls: urlsOther
        });
    };
    </text>
}

JS代码的生成后的代码如下所示.

var urls = [];
urls.push('http://www.iqidi.com/UploadFiles/设备铭牌图片/TIzMZl04X1iqkHMP44hXFHjQ-yyvrxS-tgwgzMGfwe9AUMTxKohcVC6w6O.jpg');

document.querySelector('#mainPic_0').onclick = function () {
    wx.previewImage({
        current: $(this).attr("src"),//urls[0],
        urls: urls
    });
};


var urlsOther = [];
urlsOther.push('http://www.iqidi.com/UploadFiles/设备铭牌图片/lJk_LNwxTGfL5SNpmJwWyfyBONa2JRO7uzu3PJV3aGsrilPPHY2r-ymU00.jpg');

document.querySelector('#otherPic_0').onclick = function () {
    wx.previewImage({
        current: $(this).attr("src"),//urls[0],
        urls: urlsOther
    });
};

这样最终就可以实现我们所需要的效果了,当然多张图片也不会有任何的问题。