微信小程序之天涯论坛早报

碎片化时代的生意发展

1.定义立异:共享经济&新零售

共享经济:共享单车,共享充电宝,还有种种“花式共享“:K电视,健身仓,雨伞,吸猫,卫生巾…不一而足

新零售:从线上线下充裕融合,到无人便利店,再到无人货架大发生,盒马鲜生,缤果盒子,果小美,猩便利等….

关键词:小,近,快

二零一七年并未大革新大翻新,更加多是商业格局立异,在切割更碎片的现象里,和更碎片的命宫里,以更快更便利的艺术来诱惑用户,满意碎片化的要求

“口红效应”的怀想:当经济衰退时,
“廉价的非要求之物”会蓬勃发展,3块,5块的小闲钱,用以“安慰”强烈的开销欲望。

2.个体IP崛起:知识付费&网红经济

知识付费:得到,在行,分答,喜玛拉雅fm,腾讯网live等…

文化网红们地产红利期多买了套房就从头讲投资,网媒红利期做了个博主就初叶讲个人IP,微商红利期赚钱了就开讲朋友圈营销。大多也讲不出去个之所以然,只可以把难题抛给付费者们:要早起打卡,要读书打卡,要写作打卡,一起听课打鸡血,不仅获得了二手知识,还抚平了担忧,30,50块就有近便的小路逆转马云(英文名:中国首富马云),不要太赚。

网红经济:从映客,快手的直播热;再到抖音,秒拍,短摄像的爆火;打赏只需1块,2块,尽显劳动人民的庄严和光荣

网红们一方面找不到工作,一方面又特它么缺钱,借着道奇创业,万众创新的西风,以“短,频,快”的艺术把温馨做成了事情,后延性的成功了“打工是不能够打工的”的私家自由。

3.大文娱:王者荣耀,战狼2,鹿晗(英文名:lù hán),中国有嘻哈

娱乐市场:王者农药略有疲软,绝地求生立马坚挺,开启了用“全民农药”杀时间到“全民吃鸡”式杀时间。

影视市场:战狼2以近60亿再破票房神话,并问鼎2017全球票房榜单,羞羞的铁拳也以20亿的票房直追战狼,是中华影片市场的一剂强心针。

玩耍市场:鹿晗(英文名:lù hán)谈个恋爱人民躁动,中国有嘻哈打call不断,薛之谦先生人设一崩再崩。经济不紧气时,大文娱会乘势腾飞,就像是日本经济泡沫开头,av产业空前繁荣。

假定现实生活好玩,哪个人会在“王者”里找刺激?什么人会追星找幻觉?哪个人会寄情于游戏影视?既然无法逾越阶层。不如娱乐至死。

在那几个碎片化时代,商业世界以越切越碎的规律进化,用“短(小),频(近),快”的章程来知足个人的即时需求。用豁达短信息,短视频,碎片知识,小零食用以填满碎片化的时间。让用户时时酸爽,刻刻满意。

晚报详情页

二〇一七年度商业热点

野史早报

http://news.at.zhihu.com/api/4/news/before/{date}

参数 说明
date 年月日格式时间yyyyMMdd,例如:20150903、20161202

其一接口也是用与首页列表的早报显示,可是差距的是此接口要求传一个日期参数,如20150804格式。获取最新晚报接口只可以获得当天的日报列表,倘使急需获得前几日要么更久往日的日报,则要求那一个接口单独赢得。

​再见2017!你让咱们在成吨的负能量里“云焦虑”,你让大家排山倒海的热点里“佛系”,盘点好二零一七年的崎岖,好让大家搭上2018复兴号的烈车!

本次示例的源码地址:

大混沌时代的动感焦虑

1.逃不掉的“中年危害”

陪伴着经济条件的剧变,竞争时局也发出剧变,先有HTC清理34岁以上老员工,后有HUAWEI42岁工程师被劝退跳楼身亡。

曾受过高等教育,靠能力打拼的职场白领们,却一瞬顷间沦为吃青春饭的娼妇,一旦年龄大了即将被扫地出门。前日还对四伯偶爸迷之狂热,前些天却对油腻中年男人人喊打,油腻秃顶、盘手串儿,保温杯泡枸杞都招人厌。

世易时移,年轻人进步神速,中年人入土为安。还没来得及站稳装逼,一夜间被鄙视嫌弃,“人到中年不如狗”话虽凶横,但也真正。

2.“全民焦虑”的挣扎

前有“瓜亚基尔保姆纵火,预章书院”,后有“幼儿园虐童,江歌被杀”,再加上“12w/平的学区房,大兴火灾”让人一丧到底,身处“一半海水,一半火花”的社会风气让二〇一七年刺激卓绝。

这一个社会化大系统里,阶层固化,社会冷漠,早就追寻的归依尤如川剧变脸,曾经信认为真的都被推翻。在实际中把梦想摔碎,掉进绝望唯有一步之遥,在那些大混沌时代,没人能摸清脉搏,没人能立于不败,唯一不变的就是愈演愈烈,生命安全感的缺失,让百姓陷入受害者的忧患中。

大家的中产阶级们,唯一精通的学识和技巧依附于大开支,蹒跚前行但会天天掉队,本质上也是无产阶级。从心里充满了对收缩的恐惧,和对失控将来的无力感。2017华夏引领了满世界化焦虑化的进度。

3.亚文化:“丧”,“佛系”

 丧文化:

“独丧丧,不如众丧丧” 拆穿野心勃勃也难成功的真相,撕破苍白生活背后的没指望,认清再加把劲也无力买房;喝下Be
Real的毒鸡汤,不再人云亦云地鸡血前行,不如在费力的人生里丧中带乐

拜生活的高压所赐,他们用丧文化来表述自己的根本,颓唐,颓败,负能量和春风得意。必竞生活不断眼前的枸杞,还有海外的绿帽;因为吃得,心里会更

60年间西方的嬉皮士运动、70年份英帝国爵士乐音乐、以及东瀛已经风靡的“宅文化”,都与风行的“丧文化”世代相承。那波“丧文化”很好的诠释了俺们那代人“富贵岂由人,我就缺运气!”的粗暴现实。

佛系90后:

不幸还未散去,佛系又一夜刷屏,当焦虑戾气横行的社会,90后们也未能幸免,很快便赴了
80后中危的后尘, 登时沦为00后眼里的中年母亲,中年秃头。

90后曾是大棚里倍受呵护的花朵,却被社会的狂飙打得遂不及防,在这些“失落“满满的时代,“佛系”是四遍次失望后的安静,与其恐怖的比拼,不如在佛系的湍流里杜门谢客,任其自流;脱离了“丧”气,过上了无欲无求,不悲不喜的佛门生活。

秃着头出家,是为着截至白令海的郁闷;不求输赢,是因为根本赢不了;不悲不喜,是因为简单过就是最大的欢呼雀跃;无欲无求,是因为无法得啊。

内容

日报的始末也是最难做的,因为接口重返的内容是html…,天呀,是html!小程序肯本就不辅助,解析html的进度格外优伤,因为我的正则表明式只是几乎为0,解析方案的追寻进程很虐心,经典的jQuery是用持续了,又从未dom,无法用传统的章程解析html。尝试了正则学习,可是也是无法在长期内精晓,寻找了无数解析库,大多是着重浏览器api。但是,上天是不会忽视有心人的,哈哈,依旧被我找到了化解方案。幸运的本人意识了一个用正则编写的和接近与语法分析方法的xml解析库。那一个库是一个very
good的网友封装的html解析库。详情点击
用Javascript解析html

是因为晚报详情内容的html部分结构太大,那里只列出了大致的结构,那个布局是通用的(不过不保障虎扑会改变社团,若是变动了,从前的解析可能就没用了…心累)

<div class="question">
    <h2 class="question-title">日本的六大财阀现在怎么样了?</h2>
    <div class="answer">
        <div class="meta">
            ![](//upload-images.jianshu.io/upload_images/2192094-454caed2ef752b34.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
            leon,data analyst
        </div>
        <div class="content">
            <p>“财阀”在战后统称为 Group(集团),是以银行和传统工业企业为核心的松散集合体,由于历史渊源而有相互持股。</p>
            <p>Group 对于当今日本企业的意义在于:</p>
            <p><strong>MUFG:三菱集团、三和集团(みどり会)</strong></p>
            <p><img class="content-image" src="http://pic1.zhimg.com/70/90c319ac7a7b2723e5b511de954f45bc_b.jpg" alt="资讯 1"
                /></p>
        </div>
    </div>
    <div class="view-more"><a href="http://www.zhihu.com/question/23907827">查看知乎讨论</a></div>
</div>

外层的.question是晚报中问题答案的体现单位,可能有三个,由此要求循环显示。.question-title是题材的标题,.meta中是作者的音讯,img.avatar是用户的头像,span.author是用户的名目,span.bio想必使用户的签字吗。最难解析的是.content中的内容,相比多。不过有个规律就是都是以<p>标签包裹着,获取了.content中的所有p就足以得到所有的段落。之后再分析出段落中的图片。

以下是详情页的始末浮现模版

<view style="padding-bottom: 150rpx;">
    <block wx:for="{{news.body}}">
        <view class="article">
            <view class="title" wx:if="{{item.title && item.title != ''}}">
                <text>{{item.title}}</text>
            </view>
            <view class="author-info" wx:if="{{(item.avatar && item.avatar != '') || (item.author && item.author != '') || (item.bio && item.bio != '')}}">
                <image wx:if="{{item.avatar && item.avatar != ''}}" class="avatar" src="{{item.avatar}}"></image>
                <text wx:if="{{item.author && item.author != ''}}" class="author-name">{{item.author}}</text>
                <text wx:if="{{item.bio && item.bio != ''}}" class="author-mark">,{{item.bio}}</text>
            </view>
            <view class="content" wx:if="{{item.content && item.content.length > 0}}">
                <block wx:for="{{item.content}}" wx:for-item="it">
                    <block wx:if="{{it.type == 'p'}}">
                        <text>{{it.value}}</text>
                    </block>
                    <block wx:elif="{{it.type == 'img'}}">
                        <image mode="aspectFill" src="{{it.value}}" data-src="{{it.value}}" bindtap="previewImgEvent" />
                    </block>
                    <block wx:elif="{{it.type == 'pstrong'}}">
                        <text class="strong">{{it.value}}</text>
                    </block>
                    <block wx:elif="{{it.type == 'pem'}}">
                        <text class="em">{{it.value}}</text>
                    </block>
                    <block wx:elif="{{it.type == 'blockquote'}}">
                        <text class="qoute">{{it.value}}</text>
                    </block>
                    <block wx:else>
                        <text>{{it.value}}</text>
                    </block>
                </block>

            </view>

            <view  class="discuss" wx:if="{{item.more && item.more != ''}}">
                <navigator url="{{item.more}}">查看知乎讨论</navigator>
            </view>
        </view>
    </block>
</view>

可以看出模版中的内容展现部分用了蛮多的block加判断语句wx:if wx:elif wx:else。这几个都是为了索要按照分析后的情节类型来判断必要出示如何标签和体制。解析后的始末大约格式是如此的:

{
    body: [
       title: '标题',
       author: '作者', 
       bio: '签名', 
       avatar: '头像', 
       more: '更多地址',
       content: [   //内容
            {
                type: 'p',
                value: '普通段落内容'
            },
            {
                type: 'img',
                value: 'http://xxx.xx.xx/1.jpg'
            },
            {
                type: 'pem',
                value: '...'
            },
            ...
       ]
    ],
    ...
}

内需留意的一些是主旨早报有时候回来的html内容是因而unicode编码的不可以一向显示,里边全是相近&#xxxx;的字符,那必要单独为主旨晚报的日报详情解析编码。

再点击大旨晚报中的列表项是,传递一个符号是宗旨晚报的参数theme

//跳转到日报详情页
toDetailPage: function( e ) {
    var id = e.currentTarget.dataset.id;
    wx.navigateTo( {
      url: '../detail/detail?theme=1&id=' + id
    });
},    

然后在Detail.js的onLoad事件中收受参数

//获取列表残过来的参数 id:日报id, theme:是否是主题日报内容(因为主题日报的内容有些需要单独解析)
onLoad: function( options ) {
    var id = options.id;
    var isTheme = options[ 'theme' ];
    this.setData( { id: id, isTheme: isTheme });
},

从此将来初步请求接口获取早报详情,并基于是或不是是主题早报举办个性化解析

//加载页面相关数据
function loadData() {
  var _this = this;
  var id = this.data.id;
  var isTheme = this.data.isTheme;
  //获取日报详情内容
  _this.setData( { loading: true });
  requests.getNewsDetail( id, ( data ) => {
    data.body = utils.parseStory( data.body, isTheme );
    _this.setData( { news: data, pageShow: 'block' });
    wx.setNavigationBarTitle( { title: data.title }); //设置标题
  }, null, () => {
    _this.setData( { loading: false });
  });
}

上述传入一个isTheme参数进入解析方法,解析方法依据此参数判断是还是不是须求展开独立的编码解析。

内容分析的库代码比较多,就不贴出了,可以到git上查看。那里给出解析的包装。

var HtmlParser = require( 'htmlParseUtil.js' );

String.prototype.trim = function() {
  return this.replace( /(^\s*)|(\s*$)/g, '' );
}

String.prototype.isEmpty = function() {
  return this.trim() == '';
}

/**
 * 快捷方法 获取HtmlParser对象
 * @param {string} html html文本
 * @return {object} HtmlParser
 */
function $( html ) {
  return new HtmlParser( html );
}

/**
 * 解析story对象的body部分
 * @param {string} html body的html文本
 * @param {boolean} isDecode 是否需要unicode解析
 * @return {object} 解析后的对象
 */
function parseStory( html, isDecode ) {
  var questionArr = $( html ).tag( 'div' ).attr( 'class', 'question' ).match();
  var stories = [];
  var $story;
  if( questionArr ) {
    for( var i = 0, len = questionArr.length;i < len;i++ ) {
      $story = $( questionArr[ i ] );
      stories.push( {
        title: getArrayContent( $story.tag( 'h2' ).attr( 'class', 'question-title' ).match() ),
        avatar: getArrayContent( getArrayContent( $story.tag( 'div' ).attr( 'class', 'meta' ).match() ).jhe_ma( 'img', 'src' ) ),
        author: getArrayContent( $story.tag( 'span' ).attr( 'class', 'author' ).match() ),
        bio: getArrayContent( $story.tag( 'span' ).attr( 'class', 'bio' ).match() ),
        content: parseStoryContent( $story, isDecode ),
        more: getArrayContent( getArrayContent( $( html ).tag( 'div' ).attr( 'class', 'view-more' ).match() ).jhe_ma( 'a', 'href' ) )
      });
    }
  }
  return stories;
}

/**
 * 解析文章内容
 * @param {string} $story htmlparser对象
 * @param {boolean} isDecode 是否需要unicode解析
 * @returb {object} 文章内容对象
 */
function parseStoryContent( $story, isDecode ) {
  var content = [];
  var ps = $story.tag( 'p' ).match();
  var p, strong, img, blockquote, em;
  if( ps ) {
    for( var i = 0, len = ps.length;i < len;i++ ) {
      p = ps[ i ]; //获取<p>的内容
      if( !p || p.isEmpty() )
        continue;

      img = getArrayContent(( p.jhe_ma( 'img', 'src' ) ) );
      strong = getArrayContent( p.jhe_om( 'strong' ) );
      em = getArrayContent( p.jhe_om( 'em' ) );
      blockquote = getArrayContent( p.jhe_om( 'blockquote' ) );

      if( !img.isEmpty() ) { //获取图片
        content.push( { type: 'img', value: img });
      }
      else if( isOnly( p, strong ) ) { //获取加粗段落<p><strong>...</strong></p>
        strong = decodeHtml( strong, isDecode );
        if( !strong.isEmpty() )
          content.push( { type: 'pstrong', value: strong });
      }
      else if( isOnly( p, em ) ) { //获取强调段落 <p><em>...</em></p>
        em = decodeHtml( em, isDecode );
        if( !em.isEmpty() )
          content.push( { type: 'pem', value: em });
      }
      else if( isOnly( p, blockquote ) ) { //获取引用块 <p><blockquote>...</blockquote></p>
        blockquote = decodeHtml( blockquote, isDecode );
        if( !blockquote.isEmpty() )
          content.push( { type: 'blockquote', value: blockquote });
      }
      else { //其他类型 归类为普通段落 ....太累了 不想解析了T_T
        p = decodeHtml( p, isDecode );
        if( !p.isEmpty() )
          content.push( { type: 'p', value: p });
      }
    }
  }
  return content;
}

/**
 * 取出多余或者难以解析的html并且替换转义符号
 */
function decodeHtml( value, isDecode ) {
  if( !value ) return '';
  value = value.replace( /<[^>]+>/g, '' )
    .replace( / /g, ' ' )
    .replace( /“/g, '"' )
    .replace( /”/g, '"' ).replace( /·/g, '·' );
  if( isDecode )
    return decodeUnicode( value.replace( /&#/g, '\\u' ) );
  return value;

}

/**
 * 解析段落的unicode字符,主题日报中的内容又很多是编码过的
 */
function decodeUnicode( str ) {
  var ret = '';
  var splits = str.split( ';' );
  for( let i = 0;i < splits.length;i++ ) {
    ret += spliteDecode( splits[ i ] );
  }
  return ret;
};

/**
 * 解析单个unidecode字符
 */
function spliteDecode( value ) {
  var target = value.match( /\\u\d+/g );
  if( target && target.length > 0 ) { //解析类似  "7.1 \u20998" 参杂其他字符
    target = target[ 0 ];
    var temp = value.replace( target, '{{@}}' );
    target = target.replace( '\\u', '' );
    target = String.fromCharCode( parseInt( target ) );
    return temp.replace( "{{@}}", target );
  } else {
    // value = value.replace( '\\u', '' );
    // return String.fromCharCode( parseInt( value, '10' ) )
    return value;
  }
}

/**
 * 获取数组中的内容(一般为第一个元素)
 * @param {array} arr 内容数组
 * @return {string} 内容
 */
function getArrayContent( arr ) {
  if( !arr || arr.length == 0 ) return '';
  return arr[ 0 ];
}

function isOnly( src, target ) {
  return src.trim() == target;
}

module.exports = {
  parseStory: parseStory
}

代码的分析进度比较散乱,我们可以根据重临的html结构和参照解析库的作者写的稿子来解读。

资讯 2

资讯 3

二零一七年度刷屏热词

上一遍的《微信小程序之小豆瓣图书》制作了一个书籍的询问成效,只是简短地动用到了互联网请求,其余超过半数小程序应该的文化。而此次的演示是知乎日报,成效点相比多,页面也比上次错综复杂了诸多。在我编写那个DEMO以前,网上早就有不少网友弄出了同等的DEMO,也是充足正确的,毕竟这些案例很经典,有比较完好的API,很值得模仿学习。本次个人的DEMO也算是五遍小小的磨练吧。

丧文化时代的心思共鸣

负能量:人艰不拆式扎心共鸣

1.“看见音乐的能力”(虎扑云音乐)

“扎心了老铁”文案:

“哭着吃过饭的人,是可以走下去的”

“最怕你毕生一世无所作为,还说平凡难能可贵”

“手机上存满了分手的歌,好像自己谈过恋爱似的”

“你那么擅长安慰旁人,一定度过了广大协调安慰自己的日子吧”

2. “干了那杯小确丧”(饿了么&新浪资讯)

彻底系丧文案:

“毫无作为黑茶”“混吃等死奶绿”

“假诺广告没有了,那信箱除了帐单就不会有其他东西了”

“好东西就活该跟好朋友分享,我忘了上下一心从未对象”

3.“年纪越大,越没人原谅你的穷”(蚂蚁财富)

人艰不拆式海报:

“对负有大牌化妆品如数家珍,但您绝不会揭穿自己用的都是小样”

“了然父母催你存钱的好意,但更领悟自己光是活下来就用尽全力”

正能量:尚存的中和和爱

1. “有人私下爱着你”走心系刷屏(999头疼灵)

“那世界没那么好,也没那么不好”—你以为自己不被优待、没人在意,甚至是人家眼中的调侃,可事实上“那么些世界,总有人背后爱着你”

不少时候咱们看不到生活的小寒,以为唯有团结一身的赶路,其实在您看不到的地点,有人正悄悄爱着你。即使只是一个善心的眼神、一句关怀的语言…

2.“世界再大,大但是一盘番茄炒蛋”戳中泪点式刷屏(招商银行)

“为何远涉重洋?

因为走出去

才驾驭怎么着是社会风气,什么是当真的钟爱

没成想

番茄炒蛋成了开拓世界的首先道问题。“

一道显明的菜,一段时间差,一段浓浓母子情,刹那间戳中人心。

不幸横行的时代里,当你在世界里攀爬的时候,亲情一贯与您相伴。在您有难处的时候给你接济,在你无助的时候给您力量,用母爱治愈了您的孤单无助。

“世界再大用也能用爱填满”感人至深。

3.“小朋友画廊”1元公益(腾讯公益)

告别千篇一律卖惨式公益营销,用画作本身的艺术感染力,感受一个个遗憾个体热腾腾的魂魄,让他俩原有的肥力绽放,一笔笔勾勒出更绚丽更美好的世界。

用艺术唤醒对美的求偶,和对生命的期待和爱,让每一个人都拿走康复。1元达到慈善的好心,激发出性格中的大爱与爱心,没有道德绑架,同时公布人人对美好世界的想望。

但“丧”文化并不“丧”,除了扎心式的共鸣,性格深处都梦想收获认同,得到爱,被世界接到的底层愿望,所以尚存的一丝柔和,关怀与爱,或美的营销都能在丧的主旋律里召唤回每个人的心与魂。

“你的内心藏着团火,路过的人只看到烟”

2018愿你“”出自由欲望

”出生命火光

宜人如你,左手分享右手转发〜

扭转按钮

因为小程序中并未侧栏组件,不可能做到侧滑手势展现侧栏(本人发现touchstart事件和tap事件有争论,无法兑现下手势侧滑判断,所以没有用侧滑手势,可能是本人精晓太浅了,没有意识解决形式,嘿嘿…),浮动按钮的样式参照了Android中的FloatAction经典按钮。可以生成在界面上,仍是可以滑动到任意地方,背景为多少透明。

<view class="float-action" bindtap="ballClickEvent" style="opacity: {{ballOpacity}};bottom:{{ballBottom}}px;right:{{ballRight}}px;" bindtouchmove="ballMoveEvent"> 
</view>

.float-action {
  position: absolute;
  bottom: 20px;
  right: 30px;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  box-shadow: 2px 2px 10px #AAA;
  background: #1891D4;
  z-index: 100;
}

按钮的样式随便弄了弹指间,宽高用了px是因为背后的活动判断要求得到显示器的宽高音讯,那些音讯的单位是px。wxml绑定了点击事件和活动事件,点击事件是决定侧栏弹出,滑动事件是按钮移动。

//浮动球移动事件
ballMoveEvent: function( e ) {
    var touchs = e.touches[ 0 ];
    var pageX = touchs.pageX;
    var pageY = touchs.pageY;
    if( pageX < 25 ) return;
    if( pageX > this.data.screenWidth - 25 ) return;
    if( this.data.screenHeight - pageY <= 25 ) return;
    if( pageY <= 25 ) return;
    var x = this.data.screenWidth - pageX - 25;
    var y = this.data.screenHeight - pageY - 25;
    this.setData( {
        ballBottom: y,
        ballRight: x
    });
}

touchmove事件中的会传递一个event参数,通过那么些参数可以博获得当出手势滑动到的现实性坐标信息e.touches[ 0 ]

2017刷屏级营销

问题

  • 蛮多图片彰显不出来,不知到是为啥,src路径正常,从前的小豆瓣图书也是有图片列表,可是尚未出现那种状态。
  • 代码结构相比较烂,很多地方都尚未优化处理,复用率较低,待重构。
  • 页面布局有些不创建,尺寸控制的不够好。
  • 有的wxml没有用模板作用代替重复的渲染工作,达不到复用效果。

底层工具栏

一般资讯APP的详情页都有一个平底的工具栏用于操作分享、收藏、评论和点赞等等。为了更好地陶冶下手能力,自己也做了一个平底工具栏,就算合法的APP并没有那么些事物。前面介绍到的获得额外音信API在那里就被利用了。本来自己是想把引进人数和评价数突显在尾部的图片右上角,但是由于我的安插难点,底部的字号已经是很小了,突显数量的地方的字号又不能够再小了,那样看起来数字突显的地方和图标的深浅大概如出一辙,十分不对,所以就不具体数字了。那块如故有广大待完善的职能的,比较收藏功用和是不是有评说提醒作用等。

<view class="toolbar">
    <view class="inner">
        <view class="item" bindtap="showModalEvent"><image src="../..share.png" /></view>
        <view class="item" bindtap="reloadEvent"><image src="../..refresh.png" /></view>
        <view class="item"><image src="../..vorite.png" /></view>
        <view class="item" data-id="{{id}}" bindtap="toCommentPage"><image src="../..insert_comment.png" />
            <view class="tip"></view>
        </view>
        <view class="item">
            <image src="../..thumb_up_active.png" />
        </view>
    </view>
</view>

底层有分享、收藏、评论和点赞按钮,分享肯定是做不了啦,哈哈,可是效果仍然须求有些,就一个modal弹窗,显示各个社交应用的图标就行啊。

<modal class="modal" confirm-text="取消" no-cancel hidden="{{modalHidden}}" bindconfirm="hideModalEvent">
    <view class="share-list">
        <view class="item"><image src="../..share_qq.png" /></view>
        <view class="item"><image src="../..share_pengyouquan.png" /></view>
        <view class="item"><image src="../..share_qzone.png" /></view>
    </view>
    <view class="share-list" style="margin-top: 20rpx">
        <view class="item"><image src="../..share_weibo.png" /></view>
        <view class="item"><image src="../..share_alipay.png" /></view>
        <view class="item"><image src="../..share_plus.png" /></view>
    </view>
</modal>

model的潜伏和出示都是经过hidden特性来支配。

底层工具栏中还有一个按钮是刷新,其实就是一个再度调用接口请求数据的进程而已。

//重新加载数据
reloadEvent: function() {
    loadData.call( this );
},

资讯 4

取得最新晚报

http://news-at.zhihu.com/api/4/news/latest

归来的数量用于晚报的首页列表,首页的结构有前后部分,上有些是图表滑动模块,用于浮现热门早报,下局地是首页晚报列表,以上接口重返的多少有叫座晚报和首页日报

大旨晚报栏目列表

http://news-at.zhihu.com/api/4/themes

主页的侧面栏展现有大旨晚报的列表,须求通过这些接口获取大旨晚报栏目列表

一些图纸体现不断的难题已收获修复,感谢热心网友pull request

要是我们欣赏,给个star振奋一下本人,将来会有更好的著述与大家大饱眼福:)

晚报列表

列表的布局开封小异,然则那里的列表涉及到分页,我们得以一挥而就地行使scroll-view组件,它的scrolltolower是格外好用的,当组件滚动到底层就会接触这些事件。上次的小豆瓣图书也是运用了那个组件分页。但是本次的分页动画跟上次不一样等,而是用一个附带旋转动画的基础代谢图标,使用官方的卡通片api来贯彻旋转。

<view class="refresh-block" wx:if="{{loadingMore}}">
    <image animation="{{refreshAnimation}}" src="../..refresh.png"></image>
</view>

代码中有一个眼看的animation属性,这些特性就是用来控制动画的。

/**
 * 旋转上拉加载图标
 */
function updateRefreshIcon() {
  var deg = 360;
  var _this = this;

  var animation = wx.createAnimation( {
    duration: 1000
  });

  var timer = setInterval( function() {
    if( !_this.data.loadingMore )
      clearInterval( timer );
    animation.rotateZ( deg ).step();
    deg += 360;
    _this.setData( {
      refreshAnimation: animation.export()
    })
  }, 1000 );
}

当列表加载数据时,给动画设置一个时长duration,然后按Z轴旋转,即垂直方向旋转rotateZ,每趟旋转360度,周期是1000飞秒。

资讯,列表的布局跟上次的小豆瓣图书的布局基本上,用到了循环结构wx:for和判断语句wx:if
wx:else来控制差其余显示方向。

<view class="common-list">
    <block wx:for="{{pageData}}">
        <view class="list-item {{item.images[0] ? 'has-img': ''}}" wx:if="{{item.type != 3}}" data-id="{{item.id}}" bindtap="toDetailPage">
            <view class="content">
                <text>{{item.title}}</text>
            </view>
            <image wx:if="{{item.images[0]}}" src="{{item.images[0]}}" class="cover"></image>
        </view>
        <view class="list-spliter" wx:else>
            <text>{{item.title}}</text>
        </view>
    </block>
</view>

class="list-spliter"那块是用来浮现日期,列表中的早报只要不是当天的记录,就在中等插入一条日期显示块。在列表项中有一个安慕希运算判断输出具体的class{{item.images[0] ? 'has-img': ''}},是因为列表中或者没有图片,由此要求判定当前有没有图表,没有图片就不添加class为has-img来控制带有图片列表项的布局。

首页

早报短评

http://news-at.zhihu.com/api/4/story/{id}/short-comments

参数 说明
id 日报id

晚报的评论页面展现段评用到的接口(没有找到分页参数,分页没有做)

https://github.com/oopsguy/WechatSmallApps

代码编写

启动页

用作一个仿制博客园早报的伪APP,高大上的起步封面是必须的,哈哈。启动页面很粗略,请求一个使用启动封面接口,获取封面路径和版权音信。当进入页面,在onLoad事件中获取显示屏的宽和高来呼吁适合尺寸的图形,在onReady中呼吁加载图片,在伸手成果之后,延迟2s进入首页,幸免页面一闪而过。

onLoad: function( options ) {
    var _this = this;
    wx.getSystemInfo( {
      success: function( res ) {
        _this.setData( {
          screenHeight: res.windowHeight,
          screenWidth: res.windowWidth,
        });
      }
    });
},

onReady: function() {
    var _this = this;
    var size = this.data.screenWidth + '*' + this.data.screenHeight;
    requests.getSplashCover( size, ( data ) => {
      _this.setData( { splash: data });
    }, null, () => {
      toIndexPage.call(_this);
    });
}

/**
 * 跳转到首页
 */
function toIndexPage() {
  setTimeout( function() {
    wx.redirectTo( {
      url: '../index/index'
    });
  }, 2000 );
}

资讯 5

轮播图

首页顶部需求动用轮播图来展现热门晚报,小程序中的Swipe零件可以兑现。

<swiper class="index-swiper" indicator-dots="true" interval="10000">
    <block wx:for="{{sliderData}}">
        <swiper-item data-id="{{item.id}}" bindtap="toDetailPage">
            <image mode="aspectFill" src="{{item.image}}" style="width:100%" />
            <view class="mask"></view>
            <view class="desc"><text>{{item.title}}</text></view>
        </swiper-item>
    </block>
</swiper>

装有的始末都无法不要在swiper-item标签中,因为大家的图形不止有一张,而是有多少个热门晚报音信,须要用循环来突显数据。那里须要指定的是image里的习性mode设置为aspectFill是为了适应组件的大幅度,那必要捐躯他的可观,即有可能裁剪,但那是最好的来得效果。toDetailPage是点击事件,触发跳转到晚报详情页。在跳转到早报详情页要求附带早报的id千古,大家在循环列表的时候把当下日报的id存到标签的data中,用data-id标识,那有点类似与html5中的data-*API。当在那么些标签上发出点击事件的时候,我们得以通过Event.currentTarget.dataset.id来获取data-id的值。

资讯 6

主旨晚报

主旨早报的体裁跟首页大概千篇一律,我是拷贝过来修改了一点点(懒)。却别在多了一行主编区域。但是那几个主编区域并未已毕怎么着效益,本来是点击主编的头像跳转到主编的私房首页简介,没有时间布置就不做了,那也是亟需解析html的(累)。

主题晚报列表要求经受一个切实可行的宗旨晚报id,依照这些id来呼吁接口获取大旨早报的早报列表。

//接受主页传递过来的主题日报id
onLoad: function( options ) {
    this.setData( { id: options.themeId });
}

宗旨早报的央求列表格局和主页的列表格局大多,由于没有察觉分页参数,宗旨早报的晚报列表那有些也绝非分页请求。大旨早报的晚报详情如故跳转到早报详情页面的。

资讯 7

是因为新浪早报是一个资讯类的App,UI的布局首即使以新闻列表页、资讯详情页和评论页为主,当然本次也顺手了利用设置页,可是当下效应尚未编写,过段时间会更新补充,继续周密。

拿到早报详细

http://news-at.zhihu.com/api/4/news/{id}

参数 说明
id 日报id

在点击晚报列表也的晚报项时,需求跳转到早报详情页浮现日报的切切实实新闻,那么些接口用来博取晚报的彰显封面和具体内容。

API分析

本次应用使用了新浪晚报的API,比较上次豆瓣图书的数额相比多了,可是有的仍旧有限定,而且自己从没找到评论接口的分页参数,所以评论那块没有做多少的分页。

以下是拔取到的切实API,越发详实参数和重临结构可参看网上网友享受的
和讯日报-API-分析
,在此就不做重新分析了。

早报长评

http://news-at.zhihu.com/api/4/story/{id}/long-comments

参数 说明
id 日报id

晚报的评说页面显示长评用到的接口(没有找到分页参数,分页没有做)

安装页面

当然想做设置页面里列出的功用,不过工作相比忙,仍旧归属到末端的无所不包布置吗,现阶段只做了简约的页面布局。

唯独依旧讲一下投机的思绪

  • 夜间情势就是改变使用的来得样式,利用到了css,大家得以在page中放置一个顶层的view来概括起拥有的wxml元素,当切换大旨时给页面顶层元素一个大旨控制类。


    ….


那怎么落到实处换肤即刻生效呢?一个页面刚启动是会由此onLoad、onShow等,当第二次进入的时候页面的onLoad事件就不会在次接触,而是触发onShow事件,我们可以透过onShow事件来赢得存在全局缓存中的宗旨设置。

onShow: function() {
    var app = getApp();
    this.setData({theme: app.globalData.theme});
}

<view class="{{theme}}">
    ...
</view>
  • 免除缓存功能,当然是把临时文件和localStorage中的数据清空。

    clearDataEvent: function() {

    wx.clearStorage(); //清除应用数据
    

    }

  • 利用的无图浏览格局跟大旨的笔触差不离,就是判定应用缓存中的设置是不是是无图方式,如若是就在内容体现的时候加一个断定,根据那些值来判断是不是出示图片类型的内容。

    onLoad: function() {

    var app = getApp();
    this.setData({imageMode: app.getImageMode()});
    

    }







资讯 8

评说页面

评说页面蛮不难的,就是显得评论列表,不过要显示两有些,一部分是长评,另一有些是短评。长评跟短评的布局都是通用的。进入到评论页面时,若是长评有多少,则先加载长评,短评需要用户点击短评标题才加载,否则就从来加载短评。那亟需上一个端详页面中传送晚报的额外新闻过来(即长评数量和短评数量)。

事先早已在晚报详情页面中,顺便加载了附加的消息

//请求日报额外信息(主要是评论数和推荐人数)
requests.getStoryExtraInfo( id, ( data ) => {
    _this.setData( { extraInfo: data });
});

在跳转到评论页面的时候顺便传递评论数量,那样咱们就不用在评价页面在呼吁三遍额外音信了。

//跳转到评论页面
toCommentPage: function( e ) {
    var storyId = e.currentTarget.dataset.id;
    var longCommentCount = this.data.extraInfo ? this.data.extraInfo.long_comments : 0; //长评数目
    var shortCommentCount = this.data.extraInfo ? this.data.extraInfo.short_comments : 0; //短评数目
    //跳转到评论页面,并传递评论数目信息
    wx.navigateTo( {
      url: '../comment/comment?lcount=' + longCommentCount + '&scount=' + shortCommentCount + '&id=' + storyId
    });
}

讲评页面接受参数

//获取传递过来的日报id 和 评论数目
onLoad: function( options ) {
    var storyId = options[ 'id' ];
    var longCommentCount = parseInt( options[ 'lcount' ] );
    var shortCommentCount = parseInt( options[ 'scount' ] );
    this.setData( { storyId: storyId, longCommentCount: longCommentCount, shortCommentCount: shortCommentCount });
},

跻身页面立时加载数据

//加载长评列表
onReady: function() {
    var storyId = this.data.storyId;
    var _this = this;
    this.setData( { loading: true, toastHidden: true });

    //如果长评数量大于0,则加载长评,否则加载短评
    if( this.data.longCommentCount > 0 ) {
      requests.getStoryLongComments( storyId, ( data ) => {
        console.log( data );
        _this.setData( { longCommentData: data.comments });
      }, () => {
        _this.setData( { toastHidden: false, toastMsg: '请求失败' });
      }, () => {
        _this.setData( { loading: false });
      });
    } else {
      loadShortComments.call( this );
    }
}


/**
 * 加载短评列表
 */
function loadShortComments() {
  var storyId = this.data.storyId;
  var _this = this;
  this.setData( { loading: true, toastHidden: true });
  requests.getStoryShortComments( storyId, ( data ) => {
    _this.setData( { shortCommentData: data.comments });
  }, () => {
    _this.setData( { toastHidden: false, toastMsg: '请求失败' });
  }, () => {
    _this.setData( { loading: false });
  });
}

讲评页面的突显也是特其余简短,一下给出长评模版,短评也是千篇一律的,里面的点赞按钮成效木有达成啊。

<view class="headline">
    <text>{{longCommentCount}}条长评</text>
</view>

<view class="common-list">
    <block wx:for="{{longCommentData}}">
        <view class="list-item has-img" data-id="{{item.id}}">
            <view class="content">
                <view class="header">
                    <text class="title">{{item.author}}</text>
                    <image class="vote" src="../..thumb_up.png" />
                </view>
                <text class="body">{{item.content}}</text>
                <text class="bottom">{{item.time}}</text>
            </view>
            <image src="{{item.avatar}}" class="cover" />
        </view>  
    </block>
</view>

资讯 9

侧滑菜单

侧滑菜单是一个经文APP布局方案,小程序中从不提供这些组件,甚是遗憾。不过完毕起来也不是很难,可是总感觉有点别扭…

侧滑菜单的样式采纳了固定定位的布局position: fixed,默许隐藏与左边,当点击浮动按钮时弹出,点击遮罩或者侧栏上面的倒闭按钮时收回。侧栏的弹出和收回动画选用小程序提供的动画API。

<view class="slide-mask" style="display:{{maskDisplay}}" bindtap="slideCloseEvent"></view>
<view class="slide-menu" style="right: {{slideRight}}px;width: {{slideWidth}}px;height:{{slideHeight}}px;" animation="{{slideAnimation}}">
  <icon type="cancel" size="30" class="close-btn" color="#FFF" bindtap="slideCloseEvent" />
  <scroll-view scroll-y="true" style="height:100%;width:100%">
    <view class="header">
      <view class="userinfo">
        <image src="../..vatar.png" class="avatar"></image>
        <text>Oopsguy</text>
      </view>
      <view class="toolbar">
        <view class="item">
          <image src="../..v.png"></image>
          <text>收藏</text>
        </view>
        <view class="item" bindtap="toSettingPage">
          <image src="../..setting.png"></image>
          <text>设置</text>
        </view>
      </view>
    </view>
    <view class="menu-item home">
      <text>首页</text>
    </view>
    <view class="slide-inner">
      <block wx:for="{{themeData}}">
        <view class="menu-item" data-id="{{item.id}}" bindtap="toThemePage">
          <text>{{item.name}}</text>
          <image src="../..plus.png"></image>
        </view>
      </block>
    </view>    
  </scroll-view>
</view>

/*slide-menu*/
.slide-mask {
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
  bottom: 0;
  background: rgba(0, 0, 0, .3);
  z-index: 800;
}
.slide-menu {
  position: fixed;
  top: 0;
  background: #FFF;
  z-index: 900;
}
/*.slide-menu .slide-inner {
  padding: 40rpx;
}*/
.slide-menu .header {
  background: #019DD6;
  height: 200rpx;
  color: #FFF;
  padding: 20rpx 40rpx 0 40rpx;
}

.userinfo {
  height: 80rpx;
  line-height: 80rpx;
  overflow: hidden;
}
.userinfo .avatar {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  margin-right: 40rpx;
  float: left;
}
.userinfo text {
  float: left;
  font-size: 35rpx;
}
.toolbar {
  height: 100rpx;
  padding-top: 25rpx;
  line-height: 75rpx;
}
.toolbar .item {
  width: 50%;
  display: inline-block;
  overflow: hidden;
  text-align: center
}
.toolbar .item text {
  display: inline-block;
  font-size: 30rpx
}
.toolbar .item image {
  display: inline-block;
  position: relative;
  top: 10rpx;
  margin-right: 10rpx;
  height: 50rpx;
  width: 50rpx;
}

.slide-menu .menu-item {
  position: relative;
  height: 100rpx;
  line-height: 100rpx;
  padding: 0 40rpx;
  font-size: 35rpx;
}
.slide-menu .menu-item:active {
  background: #FAFAFA;
}
.slide-menu .menu-item image {
  position: absolute;
  top: 25rpx;
  right: 40rpx;
  width: 50rpx;
  height: 50rpx;
}
.slide-menu .home {
  color: #019DD6
}

.slide-menu .close-btn {
  position: absolute;
  top: 20rpx;
  right: 40rpx;
  z-index: 1000
}

上述是侧栏的一个简便的布局和体裁,包涵了侧栏中的用户音信块和宗旨晚报列表。当然那一个信息是索要通过js的中网络请求来博取的。侧栏结构上方有一个class为slide-mask的view,那是一个遮罩元素,当侧栏弹出的时候,侧栏后面就有一层轻微透明的黑色遮罩。侧栏的冲天和宽度起首是不定的,需求在进入页面的时候,立时获得装备音讯来取得屏幕的中度小幅调整侧栏样式。

//获取设备信息,屏幕的高度宽度
onLoad: function() {
    var _this = this;
    wx.getSystemInfo( {
      success: function( res ) {
        _this.setData( {
          screenHeight: res.windowHeight,
          screenWidth: res.windowWidth,
          slideHeight: res.windowHeight,
          slideRight: res.windowWidth,
          slideWidth: res.windowWidth * 0.7
        });
      }
    });
}

涨幅我取了屏幕宽度的70%,中度一致。侧栏的弹出收回动画使用内置动画API

//侧栏展开
function slideUp() {
  var animation = wx.createAnimation( {
    duration: 600
  });
  this.setData( { maskDisplay: 'block' });
  animation.translateX( '100%' ).step();
  this.setData( {
    slideAnimation: animation.export()
  });
}

//侧栏关闭
function slideDown() {
  var animation = wx.createAnimation( {
    duration: 800
  });
  animation.translateX( '-100%' ).step();
  this.setData( {
    slideAnimation: animation.export()
  });
  this.setData( { maskDisplay: 'none' });
}

侧栏弹出的时候,遮罩的css属性display设置为block显示,侧栏通过css动画transform来想左边移动了100%的升幅translateX(100%),侧栏收回时,动画恰好与弹出的反倒,其实那么些动画片最后都会翻译为css3动画属性,这一个API只是css3卡通的卷入。为了点击遮罩收回侧栏,遮罩的tap事件也要绑定slideCloseEvent

//浮动球点击 侧栏展开
ballClickEvent: function() {
    slideUp.call( this );
},

//遮罩点击  侧栏关闭
slideCloseEvent: function() {
    slideDown.call( this );
}

资讯 10

主题早报具体内容列表

http://news-at.zhihu.com/api/4/theme/{themeId}

参数 说明
themeId 主题日报栏目id

在主页侧栏点击宗旨日报进入正题晚报的内容页,需求出示此主题日报下的早报列表。

晚报额外音讯

http://news-at.zhihu.com/api/4/story-extra/{id}

参数 说明
id 日报id

在日报详情页面中,不仅要显得晚报的内容,好内需相当获取此晚报的评价数目和推进士数等额外音讯。

开行界面图片

http://news-at.zhihu.com/api/4/start-image/{size}

参数 说明
size 图片尺寸,格式:宽*高。例如: 768*1024

得到刚进来应用时的体现封面,可以根据传递的尺码参数来获取适配用户屏幕的封皮。

http://git.oschina.net/oopsguy/WechatSmallApps

闲语

此次编写的小程序用到了蛮多知识点,就算开支了过多岁月,不过一切都是极度的值得。编写的历程中遇见最大的坚苦就是解析html内容,可以说是狼狈周章,哈哈,智商不足啦。很愿意能有网友能进献出更好的缓解办法。那一个小例子做的可比简陋,很多效果没有完全落到实处,跟人家的Android和React仿客户端相比较,小巫见大巫啦。还得抽空已毕后续的更多效益。

到近年来停止,小程序已经更新了四遍,辅助了ES5/ES6更换、下拉刷新事件、上传文件等功效,但是还有众多API还无法在模仿条件下显得效果。自己觉得一贯做类似于豆瓣图书和微博日报等除外网络请求之外没什么尤其的地点的行使也倒霉,需求尝试新的API来伸张自己的视野,后续打算往未选用到的API举办案例制作。不知不觉已经踏出校园准备有五个月了,很挂念从前的上学生活,做过很多案例,可是都尚未写日记和保存的习惯。本次写的篇幅蛮多的,可累死我了。很幸运自己初入工作圈就能冲击小程序沙台风,期待它正式公测!

眼前相比较完整的效益动态图

资讯 11

总结

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注