无意中接到了一个小的工作任务:配合手机app端的分享功能做一个wap站,简言之:将手机app端分享的文章id传过来,利用此id再进行一系列的操作,由于文章分为纯文本,图文以及图集的三种类型的文章,因此在做这个wap站的时候,就出现了一些小插曲,为了提醒自己以后不再犯类似的错,特地记录下来,警示自己也算是给小伙伴们分享一些经验吧……
前言:其实业务逻辑并不是那么的复杂,只是在这次工作中恰好就是遇到了自己最薄弱的知识点:正则表达式。由于自己之前就害怕手写正则表达式,再加上这里频繁的使用正则匹配数据库中拿到的数据,导致自己的工作进度延缓了好多;其次就是没有搞清楚优酷的视频代码在app端播放的时候,浏览器执行的js顺序,从而使今天一中午的时间都放在了寻找这个问题的答案上;最后遇到的便是在套用swiper.js插件进行图集文章展示时,没法使后台传过来的数据利用template模板渲染到前台页面,也就无法很好的使用swiper.js了。下面便是对这三个问题的详细描述,以及最终自己是如何处理这些疑难杂症的。
问题一:使用正则匹配数据
使用nodejs,利用传来的id值,一条sql语句便在数据库查出了此id下的文章的所有信息(用data来表示根据id查出来的所有信息吧),
let id = this.get().id; let data = await this.model('article').where({id: id, state: 1}).find();//state=1为正常显示的文章
其他的数据展示起来都是直接利用模板引擎直接渲染到页面之上的,而唯独只有content字段中存的数据千奇百怪,要想合理正确的将其展示到页面上,就必须对此字段中的数据进行处理,于是就出现了各种正则表达式匹配content中的内容。
1.纯文本文章:
content字段中只有p标签,这样的数据不进行任何处理,直接将数据{{data.content}}渲染到内容所要展示的位置即可,app端也可以正常显示;
2.图文结合的文章:
content字段中不仅有p标签,还有img标签,而问题就在于这个img标签了。一般非网络图片,即本地上传并存到数据库的图片,我们默认给它存进数据库的结构都是'image/20161201123'这样的形式,但是在页面展示时,想要正确让它显示就必须在这路径之前加上图片显示的域名,比如'http://www.baidu.com',而这个显示的域名最开始是写在config文件中的,于是最终只是需要this.config('imgSiteUrl')便可以获取到这个域名,但问题关键就在于我要找出数据库content字段中所有的的img标签,并将每一个img标签中的src属性值全都替换为其前加上图片显示域名,就是这个如何匹配所有的img标签,困惑了自己足够长的时间。在网上搜罗到了很多相关的文章,但是基本都是治标不治本的套路,对于自己来说根本就用不到那些东西,而需要自己手写正则,却又是那么的困难,直到经过DX大神的指导,才发现匹配img标签原来是so easy ,
let reg = new RegExp("<img.+?src="(.+?)".*/>", "");//匹配是否含有img标签
let reg = new RegExp("<img.+?src="(.+?)".*/>", "");//匹配是否含有img标签 let flag = reg.test(str); if (flag) {//含有img标签 str = str.replace(/<img[s]*src="image/g, "<img src="" + this.config('imgSiteUrl') + "image"); data.content = str; }
总而言之就是自己想太多,反而把一件简单的事情做的那么复杂,到最终也都是没有做出来……
套用DX大神的说法:他写的正则表达式,完全属于耍流氓的写法,而他一直则坚信:今天的工作想方设法都要完成,绝不拖拉,即使使用的技术是多么的‘无耻下流’,总之实现效果就可以按时回家睡觉了,至于他的这种超简单但是行之有效的正则写法,他说如果我们的大boss看见,绝对会损他,但是我依旧很佩服他那种信手拈来的魄力。
这样匹配到img标签,并成功的将img标签中的src属性值替换成了前面加上图片显示域名的地址,这样再把{{data.content}}渲染出来,便可出现正确的图文展示形式。
实现思路:用正则匹配出content字段中所有的含有src属性的img标签,并利用.replace('正则表达式','替换后的值'),然后在进行渲染页面。
3.播放优酷视频:
这是一种属于普通文章的一类文章,其中也有p标签,img标签,但是多了一段js代码,也就是多了几个script标签。所要完成的工作就是将img标签中的src属性前面加上图片显示域名,并将那段优酷的js视频代码处理一下,使其正确显示在页面之上。对于这个问题,从中午十点多一直到12点午饭,MB大神和我找了这么长时间,最终居然只写了一句代码,就是将优酷的视频代码中的一个script在页面加载完毕之后仔重新执行以便即可。
let scriptArr = str.match(/<script type="text/javascript">.*</script>/g); if (scriptArr && scriptArr.length > 0) { data['scripts'] = scriptArr[0]//将播放优酷视频的js代码取出来然后在页面中再执行一次 }
而对于这个js执行问题,自己之前也是一知半解,只知道有这么一回事,但是也从来没有仔细研究过,于是今天就把自己给坑了,对于这个教训,以后就该铭记了!
4.图集文章:
类似于网易,腾讯新闻经常看到了图片+文字描述的那类文章。其实在套用swiper.js插件的时候,只要将数据循环正确,页面便会自动将N多张图片显示到页面上,并附带上左右滑动的效果,但是不巧的是,我们数据是一张图附一个描述,在用户进行图片左右切换的时候,图片+文字都得对应改变,而在页面上套用的模板却是将文章的标题和描述放在一起(--------------------------这里写html代码,,明天去了再写),而开始的时候,自己想的是将data.content循环一遍,取出它的value.desc,然后赋值给显示描述的这个p标签,但是不妙的是,我要是这样循环的话,页面中就会出现N多个p标签,而这些描述信息就会全部填满整个页面,在左右滑动图片的时候,相对应的描述也不会随着图片变换而显示。于是在参考之前CZ大神用device写app时候的思路,就一门心思的盯着swiper插件找各种方法,于是就找到了onInit以及onSlideChangeEnd两个方法,通过它本身自带的这种方法,成功的获得了每张图片滑动过去的index,这样跟显示描述的角标刚好是同一个值,本以为这样就可以完美的显示每张图片相对应的描述了,只是最后还是出现了一个‘灵异事件’——从后台怎么也不能把data.content的值渲染出出来,而之前屡试不爽的{{data.content}}这次也一直获取到的是空的值,----------------------这个问题,到现在我也不知道是因为什么,而最终在老大的指导下,是重新将data.content赋值给另外一个变量,这样便成功的在页面上渲染出了此content值。---------------自己研究的结果:
昨天的那个在javascript标签中不显示的原因是:在art-template模板引擎中,可以将对象数组直接渲染到html页面(遍历取值就行),但是不支持直接渲染到<script></script>标签中,script中只接受string类型的数据,昨天的contentTemp在后台的时候,被JSON.parse()了,变成了object,这样子模板引擎就不支持了。。。。。。。。。
实现思路:利用swiper插件本身的方法,获取到相对应图片的index值,再将content.desc[index]取出来塞到content显示的那个位置即可成功实现图片+相对应文字随意切换的效果。
想起来很简单的wap站,居然被自己用了两天时间做完,而且还是在那么多大神同事的指点下完成的,瞬间有点感觉对不住大家,其实回头想来这些都不难,只是自己不足的地方实在太多,而这份小工作恰好就把这些问题全集中在了一起,希望自己以后遇见类似的问题,知道怎么处理,尽量少打扰大神同事们~~~
做一个阳光的叶叶!