我的第一个上线H5页面

Posted huyuzhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的第一个上线H5页面相关的知识,希望对你有一定的参考价值。

我的第一个任务是做一个h5的拉新页面

设计稿

技术分享图片

功能说明

在贝贝的贝壳任务新增"听儿歌赢奖励",期望能拿到更多拉新资源;

  • 奖励1,播放儿歌赢奖励
  • 每天抓取昨日播放量最高的前6个专辑;
  • 用户默认访问时展示前3个,点击换一换更换后3个;
  • 点击后直接进入播放器,播放内容是专辑的第一个内容;
  • 点击页面上专辑位置,认为用户进行了1次播放,后端加1贝壳;
  • 每个用户每天最多加3个;
  • 奖励2,下载早教宝送30贝壳
  • 点击按钮,跳转下载地址,安卓直接下载,ios跳转到Appstore下载,下载成功+30贝壳;
  • 奖励3,展示早教宝内的内容
  • 展示内容,点击跳转下载地址。

如果这只是一个屋限制的单张页面,其实写起来很容易的,用我以前所学的只是,不到半天的时间就可以写出这样一张页面。但在公司就没有这么简单。一个公司代码量庞大,公司内部自己封装了许多经常用的函数,而且app用户量庞大,我们必须考虑到个方面的性能问题。

下面开始讲代码的问题

编辑器

公司开发大都用vscode编辑器,它和sublime很相似,但是它有更强大的功能

代码结构

公司内部封装好了,当需要新建一个页面时,运行

npm run newpage party/activity

会自动给你生成一个文件夹,文件夹下面包括四个文件

技术分享图片

xtpl:是xtemplate的缩写,它是一种模板语言,和ejs类似。很多电商网站,如淘宝都使用这个模板语言。我们可以把列表渲染等拼接字符串丢到xtemplate里面,这样可以使我们的代码看起来简洁美观。

less:less的好用之处在于让我们的css和html一样具有层级关系,让我们的代码给具有可读性和可修改性。但要注意的是,层级嵌套不要太深,最多三级。因为浏览器读取的时候是从最里层向外找得。比如最里层是p,那就会找到页面中所有的p在找它的父级,很明显这样耗时。而我们又希望达到向html一样的层级关系,我们可以用&。下面是代码示例

.activity {
  width: 100%;
  letter-spacing: 2/@bs;
  font-size: 26/@bs;

  img {
    display: block;
    width: 100%;
  }
  &_music {
    margin-top: -10/@bs;
    padding: 6/@bs 40/@bs;
    height: 345/@bs;
    background-image: url(http://h0.hucdn.com/open/201804/5036d34bc97103eb_750x333.png);
    background-size: 100% 100%;
  }
}
    

最终“&_music”会被解析为“.activity_music”而不再是“.activity .music”

HTML

我们应该把html中需要和后端交互的一部分放在xtemplate中,然后通过js去将它添加到某个节点下

CSS

图片小缝隙问题

因为我写的是一张h5的拉新页面,页面的复用性不强,所以不需要点击的部分都是直接通过截图来实现的。

    <div class="reward1">
            <img src="http://h0.hucdn.com/open/201804/a092bae6fe513b30_750x335.png">
            <div class="activity_music">

            </div>
        </div>
        <div class="reward2">
            <img src="http://h0.hucdn.com/open/201804/269bd63c6bf51ee2_749x87.jpg">
            <img src="http://h0.hucdn.com/open/201804/76ad4d5de5f7aa8d_749x454.jpg" class="download" data-text=‘奖励二‘>
        </div>
        <div class="reward3">
            <img src="http://h0.hucdn.com/open/201804/e832a8c05b217e81_750x102.jpg">
            <img class="download" src="http://h0.hucdn.com/open/201804/7439e89b1ef75c84_749x910.jpg" data-text=‘奖励三‘>
        </div>
        <div class="reward4">
            <img src="http://h0.hucdn.com/open/201804/704e66e11bd5863f_750x494.png">
        </div>
    </div>

这样会造成每个img后面都有一个小缝隙。这个小缝隙是怎么产生的呢,可以参看张鑫旭的CSS深入理解vertical-align和line-height的基友关系

简单的说,我把img放在div里面

<div class="mask">
    <img src="http://h0.hucdn.com/open/201804/70999dd4e4598fe4_100x100.png">
</div>

在img后面会有一个很小的方块以这样的方式跟在它后面

技术分享图片

要解决这个问题有这样几种方案

  • 最简单的方法是将div和img之间的所有空格都去掉,向这样写

    <div class="mask"><img src="http://h0.hucdn.com/open/201804/70999dd4e4598fe4_100x100.png"></div>
    你可以这样理解,行内元素将自己包裹起来,同一行内允许其他元素存在,所以我们在书写html时div和img之间留了空隙,网页上自然就也有缝隙。但是这种方法不推荐使用,因为这样书写不美观,而且有的编辑器会自动为你添加缩进。
  • 将img的display设为block。因为这个原因是由img的display默认为inline-block造成的,所以我们将img的dispaly设为block让它变成块级元素就可以了。块级元素自占整个一行,将img设为block就没有元素可以和它共享这一行的位置了。
  • 将父级的font-size设置为0。一个空格相当与一个字,将font-size设为0了之后,这个字将不再占用空间。但使用这个方法的时候要注意,一定要在它的子集里面重设font-size,不然真正的文字也变得看不见了。
  • 给img设置float:left。这样做也不好,还需要去清除浮动。
  • 将vel-align设为bottom。这样改变img与小方块的对其方式其实小白块还是存在,只是在纵向就看不出来了。

    div大小固定问题

我在做一个列表展示的时候,使用了flex让它自适应为3块,于是就没有给它设置宽高了。但是我没有考虑到的是有可能它的标题很长,这样的话它就会自动将文字放到下面一排,这样效果就很丑了。所以我需要设置它的宽高,并且overflow:hidden这样即使它溢出也不会改变样式了。

box-sizing

我在写一段代码的时候,背景是切的一个图片,而我在width等于图片大小后,有对div设置了padding。这样我其实拉伸了背景图片,虽然效果影响不大,但是代码还是欠严谨。毕竟这几px的距离,可能是UI构思了很久的结果

js

整体思路

  • 先引入一些插件
  • 新建一个xtemplate模板
  • Promise.polyfill()如果游览器不支持,帮你自动修补
  • 拿数据
  • 定义一些共用的函数
  • 建一个class
  • constructor中放一些共用的变量和需要执行的函数
  • 定义一些只有在class里面在会用到的函数
  • 启动页面
    ```
    ‘use strict‘

import ‘./index.less‘
/eslint-disable no-unused-vars/
import sentry from ‘@base/sentry/zaojiaobao_m
import Promise from ‘es6-promise‘
import Xtemplate from ‘xtemplate/lib/runtime‘
import tmpl from ‘./index.xtpl‘
import { ajax, authenticationHandle } from ‘commons/js/tools.js‘
import Hybrid from ‘@base/simple_hybrid
import { sendLog, pageStart } from ‘libs/log/log2.js‘

const tpl = new Xtemplate(tmpl)

Promise.polyfill()
const getData = () => {
return ajax({
method: ‘GET‘,
query: {
method: ‘beibei.education.weal.reward.list‘
}
})
}

class Page {
constructor() {
Hybrid(‘customNavBarRightBtn‘).customNavBarRightBtn({
//默认隐藏右上角分享按钮
hidden: true
})

}

}
pageStart()
new Page()

### 需要编写的函数
#### 将音乐渲染到页面中
因为音乐有多首,所以我采用xtemplate去渲染它们
    {{#each(albums)}}
  • 技术分享图片 技术分享图片

    {{title}}

  • {{/each}}
今天已收听 {{listen_count}}首,获得 {{get_shell_count}}个贝壳
这里需要注意的是,我用到了data-id和data-target这些属性,这是为了在js中我更方便去取到需要的数据
js部分

getData()
.then(res => {
this.res = res
this.albums = [res.albums.slice(0, 3), res.albums.slice(3, 6)]
this.res.albums = this.albums[0]
this.$music.html(tpl.render(this.res))
})
.catch(err => {
popup.note(err.message || err.err_msg || JSON.stringify(err))
})

这段函数放到class的constructor里面。这里用到了promise的异步请求,将请求成功的操作放在then里面,报错放在catch里面。catch几种报错是为了记录报错的设备。

因为一共有六条数据,但是页面只显示三条数据,如果我将六条数据全交给模板,会造成样式混乱。而且因为换一换需要的是前三条数据和后三条数据的切换,所以我将数据切好放在一个数组中,为换一换做好准备
#### 点击换一换切换音乐

let _this = this
this.$music.on(‘click‘, ‘.changMusic‘, function() {
sendLog({
type: ‘click‘,
params: {
block_name: ‘点击换一换‘
}
})
if (_this.res.albums === _this.albums[0]) {
_this.res.albums = _this.albums[1]
} else {
_this.res.albums = _this.albums[0]
}
_this.$music.html(tpl.render(_this.res))
})

这里的思路是判断当前状态,如果是前三个就切换到后三个

sendLog是一个已经封装好了的函数,通过这个记录用户的动作,方便运营对数据进行分析。
#### 点击奖励二或三跳到下载页面

this.$activity.on(‘click‘, ‘.download‘, function() {
let text = $(this).attr(‘data-text‘)
sendLog({
type: ‘click‘,
params: {
block_name: ‘点击领取聪明豆下载‘,
text: decodeURIComponent(text)
}
})
authenticationHandle(() => {
ajax({
method: ‘POST‘,
query: {
method: ‘beibei.education.download.reward.check‘
}
})
download()
})
})
```
这一部分的逻辑就是点击的时候跳到下载,但是要登录之后才可以下载。
authenticationHandle()是封装好的登录函数,download是封装好的下载函数。

谈一谈this

见我的另一篇文章this的指向和用法

完整代码https://github.com/hyz1997/beibei-edu-activty






































































以上是关于我的第一个上线H5页面的主要内容,如果未能解决你的问题,请参考以下文章

怎么_如何制作h5页面?

Android使用片段在viewpager中的页面滚动上放置动画

重新创建应用时,片段与底部导航视图图标不匹配

托管小屋,爱心满满,我的第一个微搭低代码应用上线啦

webview 嵌入 h5 页面互相通信

APP中的 H5和原生页面如何分辨?