HTML5技术

微信小程序开发日记——高仿知乎日报(中) - iyifei(2)

字号+ 作者:H5之家 来源:H5之家 2017-01-04 18:02 我要评论( )

可以看出模版中的内容展示部分用了蛮多的block加判断语句wx:if wx:elif wx:else。这些都是为了需要根据解析后的内容类型来判断需要展示什么标签和样式。解析后的内容大概格式是这样的: {body: [title: '标题',auth

可以看出模版中的内容展示部分用了蛮多的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 = transferSign(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() ) { //获取图片 img=img.replace("pic1","pic3"); img=img.replace("pic2","pic3"); 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( /&nbsp;/g, ' ' ) .replace( /&ldquo;/g, '"' ) .replace( /&rdquo;/g, '"' ).replace( /&middot;/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 } /** * 将转义字符转为实体 * @param data * @returns {*} */ function transferSign(data){ data=data.replace(/&ndash;/g,"–"); data=data.replace(/&mdash;/g,"—"); data=data.replace(/&hellip;/g,"…"); data=data.replace(/&bull;/g,""); data=data.replace(/&rsquo;/g,"’"); data=data.replace(/&ndash;/g,"–"); return data; }

代码的解析过程比较繁杂,大家可以根据返回的html结构和参照解析库的作者写的文章来解读。

底部工具栏

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 微信小程序的机会在于重新理解群组与二维码 - 腾讯攻城师lee

    微信小程序的机会在于重新理解群组与二维码 - 腾讯攻城师lee

    2017-01-04 18:03

  • 微信小程序开发日记——高仿知乎日报(上) - iyifei

    微信小程序开发日记——高仿知乎日报(上) - iyifei

    2017-01-04 08:02

  • 如何为你的微信小程序体积瘦身? - 腾讯攻城师lee

    如何为你的微信小程序体积瘦身? - 腾讯攻城师lee

    2017-01-03 13:00

  • 体验报告:微信小程序在安卓机和苹果机上的区别 - 腾讯攻城师lee

    体验报告:微信小程序在安卓机和苹果机上的区别 - 腾讯攻城师lee

    2017-01-01 11:02

网友点评