weui

先说一下weui是一个什么项目:

WeUI 为微信 Web 服务量身设计的h5框架

WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知更加统一。包含button、cell、dialog、 progress、 toast、article、icon等各式元素。

严格的讲它是一个css库。算一个精简的库

它是使用less编写,最终编译成css,压缩成weui.min.css的,当然这里面还使用了一下比较好的开发实践

入门

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <title>WeUI</title>
        <link rel="stylesheet" href="path/to/weui/dist/style/weui.min.css"/>
    </head>
    <body>

    </body>
</html>

但它的demo里提供了不少好东西

打开weui/examples/index.html就可以演示效果

  • 模板是加载,替换了常规的ajax(页面少的时候是个好办法)
  • 实现了container里的显示隐藏效果
  • pushstate改变url

结构

  • container
    • page1
    • page2

看一下代码结构

helloworld

copy

<div class="container js_container">
  ...
</div>

预览一下效果,看到图片都未展示,于是把example里的images放到public/images下

此时预览,发现图片特别大,这肯定是css没有加载,于是把example.css放到public/demo下 改名为myweui.css

在html里引入即可

<link rel="stylesheet" href="./myweui.css" />

此时预览就可以了。此例用于测试样式是足够的,是为helloworld1

可是我如何点击,进入下一页呢

多页操作

把之前例子的

    <script type="text/html" id="tpl_button">
        <div class="page">
            <div class="hd">
                <h1 class="page_title">Button</h1>
            </div>
            <div class="bd spacing">
                <a href="javascript:;" class="weui_btn weui_btn_primary">按钮</a>
                <a href="javascript:;" class="weui_btn weui_btn_disabled weui_btn_primary">按钮</a>
                <a href="javascript:;" class="weui_btn weui_btn_warn">确认</a>
                <a href="javascript:;" class="weui_btn weui_btn_disabled weui_btn_warn">确认</a>
                <a href="javascript:;" class="weui_btn weui_btn_default">按钮</a>
                <a href="javascript:;" class="weui_btn weui_btn_disabled weui_btn_default">按钮</a>
                <div class="button_sp_area">
                    <a href="javascript:;" class="weui_btn weui_btn_plain_default">按钮</a>
                    <a href="javascript:;" class="weui_btn weui_btn_plain_primary">按钮</a>

                    <a href="javascript:;" class="weui_btn weui_btn_mini weui_btn_primary">按钮</a>
                    <a href="javascript:;" class="weui_btn weui_btn_mini weui_btn_default">按钮</a>
                </div>
            </div>
        </div>
    </script>

放到.container下面,这样就定义了模板

此时点击button按钮是不会有显示的。

那么我再找找例子里,是不是少什么东西?

把example.js放到public/demo下,改名为myweui.js

引入

    <script src="./myweui.js"></script>

此时刷新就好了。

也就是说所有的东西都在这个js里,我们之前说的pushstate、各种效果等都在这里

看一下按钮是如何定义和响应的

<a class="weui_cell js_cell" href="javascript:;" data-id="button">
    <span class="weui_cell_hd">
      <img src="/images/icon_nav_button.png" class="icon_nav" alt=""></span>
    <div class="weui_cell_bd weui_cell_primary">
        <p>Button</p>
    </div>
    <div class="weui_cell_ft">
    </div>
</a>
  • class="weui_cell js_cell"
  • data-id="button"

这样就行了?

我们看一下myweui.js

$(function () {

这很明显是zeptojs写法

// page stack
var stack = [];
var $container = $('.js_container');
$container.on('click', '.js_cell[data-id]', function () {
    var id = $(this).data('id');
    go(id);
});

头几行,定义了一个stack,我们想一下那个推进来的效果,

  • 默认显示,为栈的第一个元素
  • 如果push进来就,stack里push一个,设置为当前显示的
  • 如果点击返回呢,stack里pop出去最后一个,设置上一个为显示的
  • 如果返回了栈顶,点返回就没效果了

这里的click事件,它的事件是.js_cell[data-id]

也就是class=js_cell,并且有data-id属性。

对比一下button的按钮

<a class="weui_cell js_cell" href="javascript:;" data-id="button">

如此,大概你就该明白了。

那么事件里面是

var id = $(this).data('id');
go(id);

就用button这个例子讲,这个id应该是data-id="button"里的button,对吧?

然后go就跳转了,也就是push的效果应该是它弄的

function go(id){
    var $tpl = $($('#tpl_' + id).html()).addClass('slideIn').addClass(id);
    $container.append($tpl);
    stack.push($tpl);
    // why not use `history.pushState`, https://github.com/weui/weui/issues/26
    //history.pushState({id: id}, '', '#' + id);
    location.hash = '#' + id;

    $($tpl).on('webkitAnimationEnd', function (){
        $(this).removeClass('slideIn');
    }).on('animationend', function (){
        $(this).removeClass('slideIn');
    });
    // tooltips
    if (id == 'cell') {
        $('.js_tooltips').show();
        setTimeout(function (){
            $('.js_tooltips').hide();
        }, 3000);
    }
}

看一下源码

  • $container.append($tpl);是dom元素插入
  • stack.push($tpl); 视图栈压入最新的
  • location.hash = '#' + id;是pushstate更改url地址
  • 其他就是动画或者根据id干点坏事了

稍微注意一下:我们push的页面从哪里来的?

var $tpl = $($('#tpl_' + id).html()).addClass('slideIn').addClass(id);
$container.append($tpl);

我们知道id是data-id="button"里的button,也就是说我们要根据id=“tpl_button”来找模板里的html。

想想我们之前是不是拷贝了一个这样的模板?

ok,只要是class=js_cell,并且有data-id属性的就会触发点击时间,根据tpl_button里的内容显示(push)。

这是push,那么返回pop呢?

// location.hash = '#hash1' 和点击后退都会触发`hashchange`,这个demo页面只关心后退
$(window).on('hashchange', function (e) {
    if (/#.+/gi.test(e.newURL)) {
        return;
    }
    var $top = stack.pop();
    if (!$top) {
        return;
    }
    $top.addClass('slideOut').on('animationend', function () {
        $top.remove();
    }).on('webkitAnimationEnd', function () {
        $top.remove();
    });
});

location.hash变了

  • var $top = stack.pop();很明显出栈了
  • if (!$top) {return;} 是如果栈顶,不做操作
  • 然后处理$top,然后出栈的视图移除掉

最外面的视图移除了,很明显就是上一个视图显示了。

so,原理就是这么简单

时间有限,视图和其他点击事件控件的演示就不讲了

weui的缺点

weui的优点

  • 它很好的解决推入和返回的问题
  • 它有微信一样的ui界面
  • 它还提供了基本的ui组件(弹出框,actionsheet等)

那么它的缺点呢?页面内容过长的时候,滑动不流畅,以为它就没解决这个问题呢

这不正是iscroll解决的问题么?

如果weui加上iscroll的特性,是不是就很棒了?

让weui和iscroll结婚

以weui2为蓝本

观察一下它的dom

    <div class="container js_container">
        <div class="page">
            <div class="hd">
                <h1 class="page_title">WeUI</h1>
                <p class="page_desc">为微信Web服务量身设计</p>
            </div>
            <div class="bd">

            </div>
        </div>
    </div>

结合我们之前讲的移动端特点

  • header
  • content(#wrapper)
  • footer

也就是说我们可以这样做

<div class="container js_container">
    <div class="page">
        <div class="hd header">
            <h1 class="page_title">WeUI</h1>
        </div>
        <div class="bd" id="wrapper">

        </div>

        <div class="hd footer">
            <h1 class="page_title">WeUI</h1>
        </div>
    </div>
</div>

我们先把helloiscroll里的内容放进去

<h1 class="page_title">WeUI</h1>

去掉 class="page_title"

不能滑动,添加js就好了

  <script type="text/javascript">
    $(function(){
      // alert('dom ready');
      loaded () ;
    });

    var myScroll;

    function loaded () {
        myScroll = new IScroll('#wrapper', { mouseWheel: true });
    }

    document.addEventListener('touchmove', function (e) { 
      e.preventDefault(); 
    }, false);

  </script>

修改iscroll2.css

  #header {/*add*/
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    width: 100%;
    height: 45px;
    line-height: 45px;
    background: #CD235C;
    padding: 0;
    color: #eee;
    font-size: 20px;
    text-align: center;
    font-weight: bold;
  }
  #wrapper {
    position: absolute;
    z-index: 1;
    top: 48px;/*m*/
    bottom: 0px; /*m*/
    left: 0;
    width: 100%;
    background: #ccc;
    overflow: hidden;
  }

同时放到cell的高度

  #scroller li {
    padding: 0 10px;
    height: 100px; /*m from 44 to 100*/
    line-height: 40px;
    border-bottom: 1px solid #ccc;
    border-top: 1px solid #fff;
    background-color: #fafafa;
    font-size: 14px;
  }

下面开始集成点击进入按钮页面

看一下按钮是如何定义和响应的

<a class="weui_cell js_cell" href="javascript:;" data-id="button">
    <span class="weui_cell_hd">
      <img src="/images/icon_nav_button.png" class="icon_nav" alt=""></span>
    <div class="weui_cell_bd weui_cell_primary">
        <p>Button</p>
    </div>
    <div class="weui_cell_ft">
    </div>
</a>

放到第一个li里

此时不能点击,nnd,这是怎么回事儿呢?

各位想想之前讲iscroll的时候,是不是有点注意事项啊?

比如你在#wrapper内部放a标签或button的click事件是绑定补上的。需要配置

myScroll = new IScroll('#wrapper', { 
  mouseWheel: true,
  click: true
});

翻查一下代码,确实没加click(其实是为了演示故意的)

加上,再次预览

很明显是z-index问题,翻查iscroll2.css里发现#wrapper是z-index:1

而.page没有设置,简单改一下即可

<style>
  .page{
    z-index: 2;
  }
</style>

是时候去加上weui其他效果了

  • li上增加按钮
  • 把对应模板引入

helloworld-weui2+iscroll2.html

gulp

  • web server
  • livereload
  • watch实时监控
  • less:css预处理器
  • minify 压缩
  • sourcemap 生成

下面我们来扒光它

准备工作

首先看目录结构

  • 有package.json,说明它是一个node模块或者说它依赖了node模块
  • 有gulpfile.js,说明它是使用gulp作为构建工具的。

还有src和dist目录,一般src是源码,dist是构建后生成的目录,至此,我们似乎明白了点什么

首先clone代码

git clone https://github.com/weui/weui.git

上面说了,有package.json,此时需要安装依赖模块

npm install

至此就准备完了,下面看一下gulpfile.js

看一下它有哪些tasks

看一下它有哪些tasks,查看命令是gulp -T

  weui git:(master)  gulp -T
[14:04:18] Using gulpfile ~/workspace/github/weui/gulpfile.js
[14:04:18] Tasks for ~/workspace/github/weui/gulpfile.js
[14:04:18] ├── source
[14:04:18] ├─┬ styles
[14:04:18]  └── source
[14:04:18] ├─┬ release
[14:04:18]  └── styles
[14:04:18] ├── watch
[14:04:18] ├── server
[14:04:18] └── default

看这个的目的,其实就为了了解当前gulpfile里tasks,以便让大家有一个概况了解

大概有7个task,其中styles和release是有依赖作业的。

也就是说,整个项目目前的task比较少,比较适合讲解,而且是腾讯公司的项目,大家应该会比较认可一些

ok,下面我们分别看一下每个task

上面讲过,所有的task定义在gulpfile.js里,那么我们就结合源码,看一下gulpfile.js的task是如何定义,以及如何应用的

default

// 参数说明
//  -w: 实时监听
//  -s: 启动服务器
//  -p: 服务器启动端口,默认8080
gulp.task('default', function () {
    if (yargs.s) {
        gulp.start('server');
    }
    if (yargs.w) {
        gulp.start('release');
        gulp.start('watch');
    } else {
        gulp.start('release');
    }
});

这是默认作业,也就是在根目录,执行

gulp

相当于

gulp default

其实make,rake,ant等都有类似约定。

这里面值得说明的是

  • 1) 这是最简单的task定义,无任何依赖作业
  • 2) 作业里面使用nodejs写的yargs模块,用户处理cli参数

比如此时可以执行gulp -s后者gulp default -s

  weui git:(master)  gulp -s
[14:14:09] Using gulpfile ~/workspace/github/weui/gulpfile.js
[14:14:09] Starting 'default'...
[14:14:09] Starting 'server'...
[14:14:09] Finished 'server' after 44 ms
[14:14:09] Starting 'source'...
[14:14:09] Finished 'source' after 9.24 ms
[14:14:09] Starting 'styles'...
[14:14:09] Finished 'styles' after 14 ms
[14:14:09] Starting 'release'...
[14:14:09] Finished 'release' after 4.62 μs
[14:14:09] Finished 'default' after 71 ms
[BS] 1 file changed (example.css)
[BS] 1 file changed (weui.min.css)

然后它就会打开网页,跳转到http://localhost:8080/example/

从task定义里可知

    if (yargs.s) {
        gulp.start('server');
    }

说明server是一个task,这里的start就相当于call或者invoke某个task的方法。

注:yargs是一个nodejs模块,目前最好的解析cli参数的库

当然,如果这样,是不是太简单了呢?而且亲,你还有2个参数没说呢

是的

  • -w: 实时监听
  • -p: 服务器启动端口,默认8080

这里要说的就是一个开发惯例,

-p很好理解,就是httpserver的短口port,如果指定是7070那就是7070,如果没指定就是8080 给程序员自己定制的空间,谁还没有个端口自定义权利呢?

-w比较特殊,这里的w是watch的意思,就是监控某个文件或目录,只要有变化就触发xx动作,一般用于编译,比如coffee,typescript,less,sass等

看一下定义

    if (yargs.w) {
        gulp.start('release');
        gulp.start('watch');

这里的意思的如果有w参数,就先调release task,然后watch作业。

这里牵连出3个task,有server,watch,release,容我慢慢道来

btw:这里的if (yargs.w) {怎么看逻辑都怪怪的,既然有无w都执行release task,这样写法还是有待商榷的。

server

server task一看就知道是启动服务器,一般前端开发,都是起一个服务器在浏览器里测试

所以还是比较容易理解

看代码

gulp.task('server', function () {
    browserSync.init({
        server: {
            baseDir: "./dist"
        },
        ui: {
            port: 8081,
            weinre: {
                port: 9090
            }
        },
        port: 8080,
        startPath: '/example'
    });
});

代码里的几个关键词

  • browserSync
  • server
  • port
  • startPath
  • weinre

browserSync是一个nodejs模块,专门做的是livereload的事儿,也就是说,我们在编辑器里写代码,保存了,文件就会变动,文件变动了就会触发操作系统的监控事件,这时让浏览器刷新

于是,代码变了,不用刷新浏览器就能看到效果。。。

这其实就是传说中得livereload...

又可以偷懒了,祭奠f5吧!!!

其他(server,port,startPath)是browserSync的配置项,有兴趣自己扒文件吧

这里稍稍提一下weinre,因为weui这个项目是移动端h5页面,所以才会用到weinre调试的,是远程调试h5的利器

http://people.apache.org/~pmuellr/weinre-docs/latest/

总结一下

整个server就是browserSync提供的3个功能

  • 1)起了一个server
  • 2)支持livereload
  • 3) 自动打开网页

还不错吧,下面看一下更实用的一个task: watch监控

watch

gulp.task('watch', function () {
    gulp.watch('src/**/*.less', ['styles']);
    gulp.watch('src/example/**/*.{html,js}', ['source'], function () {
        browserSync.reload();
    });
});

watch其实就干了2件事儿

  • 1)如果'src/*/.less'变动,执行styles task
  • 2)如果'src/example/*/.{html,js}'变动,先执行'source' task,然后livereload通知浏览器

大家伙只要了解文件变动能干坏事即可,其他可自由发挥

如果gulp内置的watch无法满足,你还可以使用gulp-watch这个单独模块,哈哈,如果有兴趣还可以研究一下操作系统底层监控文件变动接口,有点意思

release

release是发布最终css的task

gulp.task('release', ['styles']);

release只是依赖styles task,相当于styles的别名。

值得说明的是,weui是less写的,需要编译成css,然后最终发布的是css文件

那么,

  • 如果js是用coffeescript,typescript写的呢?
  • 如果css是用less,sass,stylus写的呢?

其实都是一样的思路,编译成js或css,然后发布

这些预处理器,让开发方便,高效的同时,也增加了前端的复杂度,真是老子那句话

福兮祸所伏,祸兮福所倚...

阿门。。。 阿弥托佛。。。

source

下面一个source task

上面的都比较简单,只是作业定义和作业依赖定义而已,下面看一下真实的流式处理

gulp.task('source', function(){
    gulp.src('src/example/**/*.!(less)', option)
        .pipe(gulp.dest(dist))
        .pipe(browserSync.reload({stream: true}));
});

回故一下,上面讲的流式内容

  • src是输入
  • dest是输出
  • pipe是管道的意思,也是stream里核心概念,也就是说上一个的输出,是下一个的输入。

这代码里的src里的,所有不是less的文件,都丢到dist目录

    gulp.src('src/example/**/*.!(less)', option)
        .pipe(gulp.dest(dist))

然后,它又pipe一个,仅仅是为了表示顺序,无上下文传递关系(偷懒做法而已,不可取)

这样写起来是不是非常简单?

我知道你会回答是,下面我们来

讲个不简单的

styles

下面是关于样式处理的task

gulp.task('styles', ['source'], function () {
    gulp.src('src/example/example.less', option)
        .pipe(less().on('error', function (e){
            console.error(e.message);
            this.emit('end');
        }))
        .pipe(gulp.dest(dist))
        .pipe(browserSync.reload({stream: true}));

    gulp.src('src/style/weui.less', option)
        .pipe(sourcemaps.init())
        .pipe(less().on('error', function (e) {
            console.error(e.message);
            this.emit('end');
        }))
        .pipe(sourcemaps.write())
        .pipe(autoprefixer())
        .pipe(gulp.dest(dist))
        .pipe(minify())
        .pipe(rename(function (path) {
            path.basename += '.min';
        }))
        .pipe(gulp.dest(dist))
        .pipe(browserSync.reload({stream: true}));
});

这是整个gulpfile里最长的一个task

下面拆成2部分分析一下

  • 依赖source,执行完source,然后编译less
  • 编译的less有例子和具体要发布的weui.css

part1

    gulp.src('src/example/example.less', option)
        .pipe(less().on('error', function (e){
            console.error(e.message);
            this.emit('end');
        }))
        .pipe(gulp.dest(dist))
        .pipe(browserSync.reload({stream: true}));
  • less()来编译less文件,src和dest大家要看清楚
  • 最后pipe了一个livereload触发

和上面的source task类似,只有less编译不一样,这里就不详细讲解了

下面看一下part2

    gulp.src('src/style/weui.less', option)
        .pipe(sourcemaps.init())
        .pipe(less().on('error', function (e) {
            console.error(e.message);
            this.emit('end');
        }))
        .pipe(sourcemaps.write())
        .pipe(autoprefixer())
        .pipe(gulp.dest(dist))
        .pipe(minify())
        .pipe(rename(function (path) {
            path.basename += '.min';
        }))
        .pipe(gulp.dest(dist))
        .pipe(browserSync.reload({stream: true}));
  • src是src/style/weui.less
  • sourcemaps.init()是初始化sourcemap
  • less编译
  • .pipe(sourcemaps.write())是写入sourcemap
  • .pipe(autoprefixer())自动增加前缀
  • .pipe(gulp.dest(dist)) 输出到dist目录
  • .pipe(minify()) 是压缩
  • .pipe(rename(function (path) 重命名,因为文件后面要加min
  • .pipe(gulp.dest(dist)) 压缩后的文件进行保存
  • .pipe(browserSync.reload({stream: true}));是livereload触发

整体是分了3个阶段

  • 1)编译less和生成sourcemap
  • 2)压缩minify
  • 3)触发livereload

实战总结

至此,我们就讲完了所有gulpfile里的内容,以及每个task的细节

结论是:这是一个比较典型的gulp项目,还不错

当然它也不是非常完美,比如作业依赖可以优化、代码校验检测、release没有reversion处理等

下面简单看一下package.json

package.json

这里有2个地方需要注意

  "devDependencies": {
    "browser-sync": "^2.9.11",
    "gulp": "^3.8.10",
    "gulp-autoprefixer": "^2.3.1",
    "gulp-less": "^3.0.2",
    "gulp-minify-css": "^0.4.4",
    "gulp-rename": "^1.2.2",
    "gulp-replace": "^0.5.2",
    "gulp-sourcemaps": "^1.6.0",
    "yargs": "^1.3.3"
  }

是gulpfile里引用的模块

  "scripts": {
    "test": "gulp release"
  },

执行npm test即可发布最终css。

关于push state

最早一版本的代码 https://github.com/weui/weui/blob/489ddfbc1a9e0cc1f39803aa7ca9609a94ebde75/src/example/example.js

/**
 * Created by jfengjiang on 2015/9/11.
 */

$(function () {
    // 页面栈
    var stack = [];
    var $container = $('.js_container');
    $container.on('click', '.js_cell[data-id]', function () {
        var id = $(this).data('id');
        var $tpl = $($('#tpl_' + id).html()).addClass('slideIn').addClass(id);
        $container.append($tpl);
        stack.push($tpl);
        history.pushState({id: id}, '', '#' + id);

        $($tpl).on('webkitAnimationEnd', function (){
            $(this).removeClass('slideIn');
        }).on('animationend', function (){
            $(this).removeClass('slideIn');
        });
        // tooltips
        if (id == 'cell') {
            $('.js_tooltips').show();
            setTimeout(function (){
                $('.js_tooltips').hide();
            }, 3000);
        }

    });

    // webkit will fired popstate on page loaded
    $(window).on('popstate', function () {
        var $top = stack.pop();
        if (!$top) {
            return;
        }
        $top.addClass('slideOut').on('animationend', function () {
            $top.remove();
        }).on('webkitAnimationEnd', function () {
            $top.remove();
        });
    });

    // toast
    $container.on('click', '#showToast', function () {
        $('#toast').show();
        setTimeout(function () {
            $('#toast').hide();
        }, 5000);
    });
    $container.on('click', '#showLoadingToast', function () {
        $('#loadingToast').show();
        setTimeout(function () {
            $('#loadingToast').hide();
        }, 5000);
    });

    $container.on('click', '#showDialog1', function () {
        $('#dialog1').show();
        $('#dialog1').find('.weui_btn_dialog').on('click', function () {
            $('#dialog1').hide();
        });
    });
    $container.on('click', '#showDialog2', function () {
        $('#dialog2').show();
        $('#dialog2').find('.weui_btn_dialog').on('click', function () {
            $('#dialog2').hide();
        });
    })
});

11.18日的代码

/**
 * Created by jfengjiang on 2015/9/11.
 */

$(function () {
    // page stack
    var stack = [];
    var $container = $('.js_container');
    $container.on('click', '.js_cell[data-id]', function () {
        var id = $(this).data('id');
        go(id);
    });

    // location.hash = '#hash1' 和点击后退都会触发`hashchange`,这个demo页面只关心后退
    $(window).on('hashchange', function (e) {
        if (/#.+/gi.test(e.newURL)) {
            return;
        }
        var $top = stack.pop();
        if (!$top) {
            return;
        }
        $top.addClass('slideOut').on('animationend', function () {
            $top.remove();
        }).on('webkitAnimationEnd', function () {
            $top.remove();
        });
    });

    function go(id){
        var $tpl = $($('#tpl_' + id).html()).addClass('slideIn').addClass(id);
        $container.append($tpl);
        stack.push($tpl);
        // why not use `history.pushState`, https://github.com/weui/weui/issues/26
        //history.pushState({id: id}, '', '#' + id);
        location.hash = '#' + id;

        $($tpl).on('webkitAnimationEnd', function (){
            $(this).removeClass('slideIn');
        }).on('animationend', function (){
            $(this).removeClass('slideIn');
        });
        // tooltips
        if (id == 'cell') {
            $('.js_tooltips').show();
            setTimeout(function (){
                $('.js_tooltips').hide();
            }, 3000);
        }
    }

    if (/#.*/gi.test(location.href)) {
        go(location.hash.slice(1));
    }

    // toast
    $container.on('click', '#showToast', function () {
        $('#toast').show();
        setTimeout(function () {
            $('#toast').hide();
        }, 5000);
    });
    $container.on('click', '#showLoadingToast', function () {
        $('#loadingToast').show();
        setTimeout(function () {
            $('#loadingToast').hide();
        }, 5000);
    });

    $container.on('click', '#showDialog1', function () {
        $('#dialog1').show();
        $('#dialog1').find('.weui_btn_dialog').on('click', function () {
            $('#dialog1').hide();
        });
    });
    $container.on('click', '#showDialog2', function () {
        $('#dialog2').show();
        $('#dialog2').find('.weui_btn_dialog').on('click', function () {
            $('#dialog2').hide();
        });
    });

    function hideActionSheet(weuiActionsheet, mask) {
        weuiActionsheet.removeClass('weui_actionsheet_toggle');
        mask.removeClass('weui_fade_toggle');
        weuiActionsheet.on('transitionend', function () {
            mask.hide();
        }).on('webkitTransitionEnd', function () {
            mask.hide();
        })
    }
    $container.on('click','#showActionSheet', function () {
        var mask = $('#mask');
        var weuiActionsheet = $('#weui_actionsheet');
        weuiActionsheet.addClass('weui_actionsheet_toggle');
        mask.show().addClass('weui_fade_toggle').click(function () {
            hideActionSheet(weuiActionsheet, mask);
        });
        $('#actionsheet_cancel').click(function () {
            hideActionSheet(weuiActionsheet, mask);
        });
        weuiActionsheet.unbind('transitionend').unbind('webkitTransitionEnd');
    });
});

issues

修复pushState导致微信从左边缘向右滑动无法返回上一页,而是直接关闭WebView的bug

https://github.com/weui/weui/commit/e547d9d8ef02e2318ce9d173169056e36987abcd

FAQ

全文完

欢迎关注我的公众号【node全栈】

node全栈.png