Repository: MengZhaoFly/wechatApp-netease_cloudmusic
Branch: master
Commit: 881767e92f5a
Files: 35
Total size: 77.3 KB
Directory structure:
gitextract_ejhowmuo/
├── README.md
├── app.js
├── app.json
├── app.wxss
├── common.js
├── pages/
│ ├── account/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ ├── logs.js
│ │ ├── logs.json
│ │ ├── logs.wxml
│ │ └── logs.wxss
│ ├── find/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── logs/
│ │ ├── logs.js
│ │ ├── logs.json
│ │ ├── logs.wxml
│ │ └── logs.wxss
│ ├── my/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── now/
│ ├── index.js
│ ├── index.json
│ ├── index.wxml
│ └── index.wxss
├── style/
│ └── weui.wxss
└── utils/
└── util.js
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================


## 初窥

todo:
- [ ] 添加音乐到收藏(最近)列表
- [ ] 歌词滚动
## 从一个hello world开始
微信开发者工具生成 目录如下:
```
.
|-- app.js
|-- app.json
|-- app.wxss
|-- pages
| |-- index # 主页
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| `-- log # 日志页面
| | |-- log.js
| | |-- log.json
| | |-- log.wxml
| | `-- log.wxss
`-- utils # 工具
`-- util.js
```
大体为:
每一个page即是一个页面文件 ,每个页面有一个js/wxml/wxss/json文件 规定:**描述页面的这四个文件必须具有相同的路径与文件名。**
全局下同路,为公共的逻辑,样式,配置
与html不同:用`view text navigator` 代替 `div span a`
## 开发者文档走马观花
**app.json:** 注册pages window tabBar networkTimeout
[组件说明](https://mp.weixin.qq.com/debug/wxadoc/dev/component/)
***.js:** 作为逻辑层 与wxml交互 有着丰富的
网络,
媒体,
文件,
数据缓存,
位置,
设备,
界面...的api
[官方文档](https://mp.weixin.qq.com/debug/wxadoc/dev/api/)
***.wxml:** 数据驱动的视图层 + 微信提供了大量的组件 表单 导航 媒体 ...
## 官方组件不够,weui来凑
weui为小程序提供了 weui.wxcss 但大多是造官方组件的轮子
这里精选,也算是补充两个常用组件
**对于小程序没有DOM操作 不熟悉mvvm思想的同学 是个很好的入门**
1. navbar

```html
{{item}}
选项一的内容
选项二的内容
选项三的内容
```
block渲染data里面的四个tabs,slider为激活tab选项时候的表现,panel为内容面板
```js
//js
var sliderWidth = 96; // 需要设置slider的宽度,用于计算中间位置
Page({
data: {
tabs: ["选项一", "选项二", "选项三"],
activeIndex: 1,
sliderOffset: 0,
sliderLeft: 0
},
onLoad: function () {
var that = this;
wx.getSystemInfo({
success: function(res) {
that.setData({
sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2,
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
},
tabClick: function (e) {
this.setData({
sliderOffset: e.currentTarget.offsetLeft,
activeIndex: e.currentTarget.id
});
}
});
```
了解mvvm思想的同学不难看出 通过tabs数组渲染出来选项后每次点击获取id 然后通过设置hidden显示或隐藏
2. searchbar

```html
取消
实时搜索文本
```
一个input输入框+一个搜索label+一个清楚内容的icon + 取消按钮
```js
Page({
data: {
inputShowed: false,
inputVal: ""
},
showInput: function () {
this.setData({
inputShowed: true
});
},
hideInput: function () {
this.setData({
inputVal: "",
inputShowed: false
});
},
clearInput: function () {
this.setData({
inputVal: ""
});
},
inputTyping: function (e) {
this.setData({
inputVal: e.detail.value
});
}
});
```
input上面有一层label 通过Page里面状态的改变而操作其wxml状态的改变
不难体会到:**小程序和Vue**的思想还是挺接近的
## 站在巨人的肩膀上为大佬们提供云音乐api
---获取云音乐api
>[巨人的源github项目](https://github.com/Binaryify/NeteaseCloudMusicApi)
在此我将他部署到leancloud上
即可在线访问,免去烦人的本地localhost启动,在线url
http://neteasemusic.leanapp.cn
调用例子:
http://neteasemusic.leanapp.cn/search?keywords=海阔天空
http://neteasemusic.leanapp.cn/lyric?id=347230

具体参考api
>[详细文档](https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi)
## 一切具备 只欠东风
生成目录
```
.
|-- app.js
|-- app.json
|-- app.wxss
|-- common.js #公用js
|-- images #存放项目图片
|-- style
| |-- weui.wxss # 引入weui样式 万一你自己不想写css样式呢
|-- pages
| |-- find # 发现音乐
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| |--my # 我的音乐
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| |--now # 正在播放
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| |--account # 账号
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| |-- index # 主页
| | |-- index.js
| | |-- index.json
| | |-- index.wxml
| | `-- index.wxss
| `-- log # 日志页面
`-- utils # 工具
`-- util.js
```
请先在在app.json中注册页面,设置navigation,配置tabbar
```js
{
"pages":[
"pages/find/index",
"pages/my/index",
"pages/now/index",
"pages/account/index",
"pages/index/index"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#D43C33",
"navigationBarTitleText": "网易云音乐",
"navigationBarTextStyle":"white",
"backgroundColor": "#FBFCFD"
},
"tabBar": {
"backgroundColor":"#2A2C2E",
"color": "#a7a7a7",
"selectedColor": "#ffffff",
"list": [{
"iconPath":"./images/find.png",
"selectedIconPath":"./images/find1.png",
"pagePath":"pages/find/index",
"text": "发现音乐"
}, {
"iconPath":"./images/my.png",
"selectedIconPath":"./images/my1.png",
"pagePath": "pages/my/index",
"text": "我的音乐"
}, {
"iconPath":"./images/now.png",
"selectedIconPath":"./images/now1.png",
"pagePath": "pages/now/index",
"text": "正在播放"
}, {
"iconPath":"./images/account.png",
"selectedIconPath":"./images/account1.png",
"pagePath": "pages/account/index",
"text": "账号"
}]
}
}
```
- 发现音乐

布局分为搜索框,navbar,swiper滑动,三列,以及两行三列构成
tips:小程序中`flex`布局基本无兼容性问题 ,可大胆使用
前三个可用上文提到的组件和小程序swiper组件快速完成,
对于搜索功能
我们在搜索input上绑定一个`inputTyping`事件,这样每次键入完毕都可以得到结果,然后我们直接请求api
```js
//index.js
//获取应用实例
// 个人网易云音乐 ID 66919655
var app = getApp()
Page({
data: {
searchReault: []
},
//绑定事件
inputTyping: function (e) {
let that = this
console.log(e.detail)
this.setData({
inputVal: e.detail.value
});
wx.request({
url: 'http://neteasemusic.leanapp.cn/search',
data: {
keywords: e.detail.value
},
method: 'GET',
success: function (res) {
let temp = []
if(!res.data.result.songs){
return ;
}
//遍历数据
res.data.result.songs.forEach((song, index) => {
temp.push({
id: song.id,
name: song.name,
mp3Url: song.mp3Url,
picUrl: song.album.picUrl,
singer: song.artists[0].name
})
//设置数据
that.setData({
searchReault: temp
})
})
// 存入搜索的结果进缓存
wx.setStorage({
key:"searchReault",
data:temp
})
}
})
}
});
```
data里面的searchReault数组存入搜索结果,发起一个wx.request,用GET方式传入参数,组织好json后设置data,然后将搜索结果存入本地缓存
**wxml渲染searchReault:**

并且自定义data属性,navigator的打开方式为tab切换`open-type="switchTab"` ,绑定一个tonow事件bindtap="tonow"
```html
{{item.name}}
{{item.singer}}
```
在tonow事件中,获取当前的歌曲
```
tonow: function (event) {
let songData = {
id: event.currentTarget.dataset.id,
name: event.currentTarget.dataset.name,
mp3Url: event.currentTarget.dataset.songurl,
picUrl: event.currentTarget.dataset.picurl,
singer: event.currentTarget.dataset.singer
}
// 将当前点击的歌曲保存在缓存中
wx.setStorageSync('clickdata', songData)
wx.switchTab({
url: '../now/index'
})
}
```
- 正在播放

**布局:**歌曲封面,滑动条上下为操作按钮,
封面在采用圆角,rotate,transition既可以
**滑动快进:**在滑动条上绑定事件 slider3change
```js
//滑动 歌曲快进
function sliderToseek(e, cb) {
wx.getBackgroundAudioPlayerState({
success: function (res) {
var dataUrl = res.dataUrl
var duration = res.duration
let val = e.detail.value
let cal = val * duration / 100
cb && cb(dataUrl, cal);
}
})
}
//分隔 在page中调用
slider3change: function (e) {
sliderToseek(e, function (dataUrl, cal) {
wx.playBackgroundAudio({
dataUrl: dataUrl
})
wx.seekBackgroundAudio({
position: cal
})
})
},
```
一个自定义的sliderToseek函数:
参数e 可以获取滑动的值,获取正在播放的音乐信息成功后执行`回调函数1->播放 回调函数2->跳到指定位置`;
**拆分歌词:**
在api中得到的歌词:"[00:00.00] 作曲 : 黄家驹 [00:01.00] 作词 : 黄家驹 [00:18.580]今天我 寒夜里看雪飘过 [00:25.050]怀着冷却了的心窝漂远方 [00:30.990]风雨里追赶 "
在page外定义函数:
以`]`划分数组 第二部分就是歌词内容:`item.split(']')[1]` 第一部分即为对应的时间:`item.split(']')[0]`
```js
// 获取歌词
function getlyric(id,cb) {
console.log('id:',id)
let url = `http://neteasemusic.leanapp.cn/lyric`
wx.request({
url: url,
data: {
id: id
},
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header
success: function (res) {
// success
if (!res.data.lrc.lyric) return false;
let lyric = res.data.lrc.lyric
let timearr = lyric.split('[')
let obj = {}
let lyricArr=[]
// seek 为键 歌词为value
timearr.forEach((item) => {
let key = parseInt(item.split(']')[0].split(':')[0]) * 60 + parseInt(item.split(']')[0].split(':')[1])
let val = item.split(']')[1]
obj[key] = val
})
for(let key in obj){
// obj[key] = obj[key].split('\n')[0]
lyricArr.push(obj[key])
}
cb&&cb(obj,lyricArr)
},
fail: function (res) {
// fail
},
complete: function (res) {
// complete
}
})
}
```
在page中调用:传入歌曲ID(上文我们已经存入缓存,在缓存中取出即可),和将其设置在data的回调
```js
getlyric(id,function(data, lyricArr){
that.setData({
lyricobj:data,
lyricArr:lyricArr
})
})
```
wxml进行渲染:
```html
{{item}}
```
**添加歌曲:**

我的可以在本地缓存中添加两个key入对应的信息
like:我的喜欢
recent:最近
选择事件
```js
radioChange: function(e) {
console.log('radio发生change事件,携带value值为:', e.detail.value)
this.setData({
percent:'100%'
})
},
//radio发生change事件,携带value值为: like
//radio发生change事件,携带value值为: recent
```
点击添加按钮,向上呼出选项,将当前播放的歌曲设置到对应的数组即可
**进行当前歌曲的播放:**
页面onshow的时候,获取本地缓存的信息,在success的回调中,设置到data,以供页面解析,而后在获取歌词的函数中也进行一次回调,设置歌词,
播放本地音乐,播放成功之后,在success的回调中,获取正在播放的音乐信息,包括该歌曲的总时长,再进行设置。
```
onShow: function () {
var that = this;
console.log('正在播放 is on show')
// 获取缓存
wx.getStorage({
key: 'clickdata',
success: function (res) {
var value = res.data
var id = value.id
if (value) {
// 设置到data
that.setData({
id:id,
name: value.name,
src: value.mp3Url,
poster: value.picUrl,
author: value.singer
})
getlyric(id,function(data, lyricArr){
that.setData({
lyricobj:data,
lyricArr:lyricArr
})
})
}
let url = that.data.src || value.mp3Url;
// 播放
wx.playBackgroundAudio({
dataUrl: value.mp3Url,
title: value.name,
coverImgUrl: value.picUrl,
success: function () {
wx.hideLoading()
console.log('url',url)
setTimeout(function(){
wx.getBackgroundAudioPlayerState({
success: function (res) {
var tempduration = res.duration
console.log('get bg success', tempduration, res)
// 设置时长
that.setData({
sumduration: tempduration
})
},
complete: function (res) {
console.log(' get bg complete:', res)
}
})
},1000)
},
complete:function(){
// 获取正在播放的信息
console.log('play',url)
}
})
}
})
},
```
这样我们不知不觉进入多个回调嵌套的问题
## 代码优化,使用Promise,较为优雅地解决回调
**小程序暂时不支持async await**
在 common.js 中为小程序提供的api上裹上一层Promise,并且通过`module.exports = operation`暴露出去
```js
const operation = {
getMusicData: function () {
return new Promise((resolve, reject) => {
wx.getBackgroundAudioPlayerState({
success: function (res) {
resolve(res);
},
fail: function (err) {
reject(err);
}
})
})
},
// 播放音乐 参数:url title 图片url
playMusic: function (url, title, pic) {
return new Promise((resolve, reject) => {
wx.playBackgroundAudio({
dataUrl: url,
title: title,
coverImgUrl: pic,
success: function () {
resolve(true)
},
fail: function () {
reject(new Error('播放错误'));
}
})
})
},
asyncGetStorage: function (key) {
return new Promise((resolve, reject) => {
wx.getStorage({
key: key,
success: function (res) {
resolve(res.data)
},
fail: function (err) {
reject(err)
}
})
})
},
getlyric: function (id) {
return new Promise((resolve, reject) => {
console.log('id:', id)
let url = `http://neteasemusic.leanapp.cn/lyric`
wx.request({
url: url,
data: {
id: id
},
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header
success: function (res) {
// success
if (!res.data.lrc.lyric) return false;
let lyric = res.data.lrc.lyric
let timearr = lyric.split('[')
let obj = {}
let lyricArr = []
// seek 为键 歌词为value
timearr.forEach((item) => {
let key = parseInt(item.split(']')[0].split(':')[0]) * 60 + parseInt(item.split(']')[0].split(':')[1])
let val = item.split(']')[1]
obj[key] = val
})
for (let key in obj) {
// obj[key] = obj[key].split('\n')[0]
lyricArr.push(obj[key])
}
// cb && cb(obj, lyricArr)
resolve(lyricArr)
},
fail: function (err) {
reject(err)
},
complete: function (res) {
// complete
}
})
})
}
}
module.exports = operation
```
重写一下**当前歌曲播放事件**
```js
onShow: function () {
let that = this;
Common.asyncGetStorage('clickdata')//本地缓存
.then(data => {
// console.log(data)
if (!data) return;
that.setData({
id: data.id,
name: data.name,
src: data.mp3Url,
poster: data.picUrl,
author: data.singer
})
return Common.playMusic(data.mp3Url, data.name, data.picUrl);
})
.then(status => {
if(!status) return;
wx.hideLoading();
console.log('id,',that.data.id)
return Common.getlyric(that.data.id)
})
.then((lyricArr) => {
console.log('lyricArr',lyricArr)
that.setData({
lyricArr: lyricArr
})
return Common.getMusicData()
})
.then(data => {
let tempduration = data.duration
console.log('get bg success', tempduration, data)
// 设置时长
that.setData({
sumduration: tempduration
})
})
},
```
这样即可缩减部分代码.
***
## 有帮助可以Star
18届小前端求职中`['html/html5', 'css/css3', 'js/es5/es6', 'node']`
1424254461@qq.com
================================================
FILE: app.js
================================================
//app.js
App({
onLaunch: function () {
//调用API从本地缓存中获取数据
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
wx.showLoading({
title: '加载中',
mask: true
})
},
getUserInfo:function(cb){
var that = this
if(this.globalData.userInfo){
typeof cb == "function" && cb(this.globalData.userInfo)
}else{
//调用登录接口
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
that.globalData.userInfo = res.userInfo
typeof cb == "function" && cb(that.globalData.userInfo)
}
})
}
})
}
},
globalData:{
userInfo:null
}
})
================================================
FILE: app.json
================================================
{
"pages":[
"pages/find/index",
"pages/my/index",
"pages/now/index",
"pages/account/index",
"pages/index/index"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#D43C33",
"navigationBarTitleText": "网易云音乐",
"navigationBarTextStyle":"white",
"backgroundColor": "#FBFCFD"
},
"tabBar": {
"backgroundColor":"#2A2C2E",
"color": "#a7a7a7",
"selectedColor": "#ffffff",
"list": [{
"iconPath":"./images/find.png",
"selectedIconPath":"./images/find1.png",
"pagePath":"pages/find/index",
"text": "发现音乐"
}, {
"iconPath":"./images/my.png",
"selectedIconPath":"./images/my1.png",
"pagePath": "pages/my/index",
"text": "我的音乐"
}, {
"iconPath":"./images/now.png",
"selectedIconPath":"./images/now1.png",
"pagePath": "pages/now/index",
"text": "正在播放"
}, {
"iconPath":"./images/account.png",
"selectedIconPath":"./images/account1.png",
"pagePath": "pages/account/index",
"text": "账号"
}]
}
}
================================================
FILE: app.wxss
================================================
/**app.wxss**/
@import 'style/weui.wxss';
.container {
height: 100%;
width: 100%;
box-sizing: border-box;
font-size: 16px;
font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
}
.searchbar-result{
position: fixed;
left: 0;
top: 26px;
width: 100%;
}
.weui-navbar__item.weui-bar__item_on {
color:#D43C33;
}
.weui-navbar__slider {
background-color:#D43C33;
}
swiper image{
width: 100%;
}
.three-circle .weui-grids navigator{
background-color: #fff;
border-right:none;
}
.weui-grid__label {
font-size:12px;
}
.weui-grid__icon {
width:40px;
height:40px;
margin:0 auto;
}
.header{
position: relative;
background-color: #fff;
}
.header text{
font-size:20px;
font-weight:400;
padding: 20px 0;
}
.header text:first-child{
padding-left: 15px;
}
.header text:first-child::before{
content: '';
display: inline-block;
width: 2px;
height: 20px;
vertical-align: middle;
background-color: #D43C33;
position: absolute;
left: 0;
top: 6px;
}
.header text:last-child{
padding-left: 10px;
}
.lists-content{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.lists-content navigator{
width: calc((100% - 8px) / 3);
margin-top: 12px;
}
.lists-content .image{
width: 100%;
height: 130px;
margin: 0 auto;
}
.image{
background-size: cover;
}
.lists-content navigator view:last-child{
font-size: 14px;
width: 100%;
height: 44px;
margin-top: 5px;
display:block;white-space: normal; overflow: hidden; text-overflow:ellipsis;
}
.weui-cells::after {
border-bottom:none;
}
.weui-cell::before {
left:60px;
}
.weui-cell__bd{
padding-left: 15px;
}
.listen-content .weui-cell::before {
left:80px;
}
.searchbar-result .weui-cell::before {
left: 0;
}
.searchbar-result .weui-cells{
overflow-y: scroll;
}
.weui-search-bar__cancel-btn{
color: #D43C33;
}
================================================
FILE: common.js
================================================
const operation = {
getMusicData: function () {
return new Promise((resolve, reject) => {
wx.getBackgroundAudioPlayerState({
success: function (res) {
resolve(res);
},
fail: function (err) {
reject(err);
}
})
})
},
// 播放音乐 参数:url title 图片url
playMusic: function (url, title, pic) {
return new Promise((resolve, reject) => {
wx.playBackgroundAudio({
dataUrl: url,
title: title,
coverImgUrl: pic,
success: function () {
resolve(true)
},
fail: function () {
reject(new Error('播放错误'));
}
})
})
},
asyncGetStorage: function (key) {
return new Promise((resolve, reject) => {
wx.getStorage({
key: key,
success: function (res) {
resolve(res.data)
},
fail: function (err) {
reject(err)
}
})
})
},
getlyric: function (id) {
return new Promise((resolve, reject) => {
console.log('id:', id)
let url = `http://neteasemusic.leanapp.cn/lyric`
wx.request({
url: url,
data: {
id: id
},
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header
success: function (res) {
// success
if (!res.data.lrc.lyric) return false;
let lyric = res.data.lrc.lyric
let timearr = lyric.split('[')
let obj = {}
let lyricArr = []
// seek 为键 歌词为value
timearr.forEach((item) => {
let key = parseInt(item.split(']')[0].split(':')[0]) * 60 + parseInt(item.split(']')[0].split(':')[1])
let val = item.split(']')[1]
obj[key] = val
})
for (let key in obj) {
// obj[key] = obj[key].split('\n')[0]
lyricArr.push(obj[key])
}
// cb && cb(obj, lyricArr)
resolve(lyricArr)
},
fail: function (err) {
reject(err)
},
complete: function (res) {
// complete
}
})
})
}
}
module.exports = operation
================================================
FILE: pages/account/index.js
================================================
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {}
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
console.log('onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function(userInfo){
//更新数据
that.setData({
userInfo:userInfo
})
}),
wx.setNavigationBarTitle({
title: '个人中心'
})
}
})
================================================
FILE: pages/account/index.json
================================================
{}
================================================
FILE: pages/account/index.wxml
================================================
{{userInfo.nickName}}
================================================
FILE: pages/account/index.wxss
================================================
/**index.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
.flex-item{
width: 100rpx;
height: 100rpx;
background-color: red;
}
================================================
FILE: pages/account/logs.js
================================================
// pages/account/logs.js
Page({
data:{},
onLoad:function(options){
// 页面初始化 options为页面跳转所带来的参数
},
onReady:function(){
// 页面渲染完成
},
onShow:function(){
// 页面显示
},
onHide:function(){
// 页面隐藏
},
onUnload:function(){
// 页面关闭
}
})
================================================
FILE: pages/account/logs.json
================================================
{}
================================================
FILE: pages/account/logs.wxml
================================================
pages/account/logs.wxml
================================================
FILE: pages/account/logs.wxss
================================================
/* pages/account/logs.wxss */
================================================
FILE: pages/find/index.js
================================================
//index.js
//获取应用实例
// 个人网易云音乐 ID 66919655
var app = getApp()
Page({
data: {
inputShowed: false,
inputVal: "",
tabs: ["个性推荐", "歌单", "主播电台", "排行榜"],
activeIndex: 0,
sliderOffset: 0,
sliderLeft: 0,
imgUrls: [
'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
],
indicatorDots: true,
autoplay: true,
interval: 2000,
duration: 1000,
circular: true,
// 歌曲搜索的结果
searchReault: []
},
showInput: function () {
this.setData({
inputShowed: true
});
},
hideInput: function () {
this.setData({
inputVal: "",
inputShowed: false
});
},
clearInput: function () {
this.setData({
inputVal: ""
});
},
inputTyping: function (e) {
let that = this
console.log(e.detail)
this.setData({
inputVal: e.detail.value
});
// let url = `http://localhost:3000/search?keywords=${e.detail.value}`
wx.request({
url: 'http://neteasemusic.leanapp.cn/search',
data: {
keywords: e.detail.value
},
method: 'GET',
success: function (res) {
let temp = []
if(!res.data.result.songs){
return ;
}
res.data.result.songs.forEach((song, index) => {
temp.push({
id: song.id,
name: song.name,
mp3Url: song.mp3Url,
picUrl: song.album.picUrl,
singer: song.artists[0].name
})
that.setData({
searchReault: temp
})
})
// 存入搜索的结果进缓存
wx.setStorage({
key:"searchReault",
data:temp
})
},
fail: function (res) {
// fail
},
complete: function (res) {
// complete
}
})
},
onShow: function(){
wx.hideLoading()
},
onLoad: function () {
var that = this;
wx.getSystemInfo({
success: function (res) {
that.setData({
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
},
tabClick: function (e) {
this.setData({
sliderOffset: e.currentTarget.offsetLeft,
activeIndex: e.currentTarget.id
});
},
tonow: function (event) {
let songData = {
id: event.currentTarget.dataset.id,
name: event.currentTarget.dataset.name,
mp3Url: event.currentTarget.dataset.songurl,
picUrl: event.currentTarget.dataset.picurl,
singer: event.currentTarget.dataset.singer
}
// 将当前点击的歌曲保存在缓存中
wx.setStorageSync('clickdata', songData)
wx.switchTab({
url: '../now/index'
})
}
});
================================================
FILE: pages/find/index.json
================================================
{}
================================================
FILE: pages/find/index.wxml
================================================
取消
{{item.name}}
{{item.singer}}
{{item}}
私人FM
每日歌曲推荐
云音乐热歌榜
考验听力的时候|一首歌证明你是hlhkllhlk
华语白首| 回忆伤人无声,唱不尽
钢琴的轻吟
入耳便爱上的英文歌曲
一名90后看过的香港电影
老歌曲终究经得起时间推敲
选项二的内容
选项三的内容
排行榜
================================================
FILE: pages/find/index.wxss
================================================
/**index.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
.song-name{
color: #507daf;
font-size: 18px;
}
.song-singer{
color: #888888;
font-size: 12px;
}
================================================
FILE: pages/index/index.js
================================================
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {}
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
console.log('onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function(userInfo){
//更新数据
that.setData({
userInfo:userInfo
})
})
wx.playBackgroundAudio({
dataUrl: 'http://m2.music.126.net/Yev_vdcos-1_SX2qC9WUfw==/7856010580878729.mp3'
})
}
})
================================================
FILE: pages/index/index.json
================================================
{}
================================================
FILE: pages/index/index.wxml
================================================
================================================
FILE: pages/index/index.wxss
================================================
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
/**index.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
.flex-item{
width: 100rpx;
height: 100rpx;
background-color: red;
}
================================================
FILE: pages/logs/logs.js
================================================
//logs.js
var util = require('../../utils/util.js')
Page({
data: {
logs: []
},
onLoad: function () {
this.setData({
logs: (wx.getStorageSync('logs') || []).map(function (log) {
return util.formatTime(new Date(log))
})
})
}
})
================================================
FILE: pages/logs/logs.json
================================================
{
"navigationBarTitleText": "查看启动日志"
}
================================================
FILE: pages/logs/logs.wxml
================================================
{{index + 1}}. {{log}}
================================================
FILE: pages/logs/logs.wxss
================================================
.log-list {
display: flex;
flex-direction: column;
padding: 40rpx;
}
.log-item {
margin: 10rpx;
}
================================================
FILE: pages/my/index.js
================================================
//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {}
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},
redirect:function(){
console.log('点击');
wx.navigateTo({
url: '../index/index',
success: function(res){
console.log(res)
},
fail: function(res) {
// fail
console.log(res)
},
complete: function(res) {
// complete
console.log(res)
}
})
},
onLoad: function () {
console.log('onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function(userInfo){
//更新数据
that.setData({
userInfo:userInfo
})
}),
wx.setNavigationBarTitle({
title: '我的音乐'
})
}
})
================================================
FILE: pages/my/index.json
================================================
{
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#D43C33",
"navigationBarTitleText": "我的音乐",
"navigationBarTextStyle":"white",
"backgroundColor": "#FBFCFD"
}
}
================================================
FILE: pages/my/index.wxml
================================================
本地播放
0
最近播放
100
我的电台
0
我的收藏
1
本地播放
41首
最近
13首
================================================
FILE: pages/my/index.wxss
================================================
/**index.wxss**/
.header{
color: #888;
}
.listen-content .item{
display: flex;
padding: 10px;
align-items: center;
}
.bg-img{
width: 30px;
height:30px;
background-size: cover;
background-repeat: no-repeat;
}
.count{
color: #888888;
}
.listen-content .bg-img{
width: 50px;
height: 50px;
}
.header{
padding-left: 15px;
background-color: #eeeff0;
}
.listen-content .weui-cell:first-child{
}
.weui-cells::before {
border-top:none;
}
================================================
FILE: pages/now/index.js
================================================
//index.js
//获取应用实例
var Common = require('../../common')
var app = getApp()
Page({
data: {
id: 436514312,
name: "成都",
src: "http://m2.music.126.net/7o5D4dA6271VktgawcbZFA==/18665309393829604.mp3",
poster: "http://p1.music.126.net/34YW1QtKxJ_3YnX9ZzKhzw==/2946691234868155.jpg",
author: "赵雷",
isplaying: true,
islyric: false,
sumduration: 0,
lyricobj:{},
lyricArr:[],
isadd:false,
items: [
{name: 'recent', value: '最近'},
{name: 'like', value: '我的收藏'}
],
percent:'100%'
},
addsong:function(){
this.setData({
percent:'0'
})
},
radioChange: function(e) {
console.log('radio发生change事件,携带value值为:', e.detail.value)
this.setData({
percent:'100%'
})
},
//事件处理函数
bindViewTap: function () {
wx.navigateTo({
url: '../logs/logs'
})
},
showCircle:function(){
this.setData({
islyric: true,
percent:'100%'
})
},
showlyric:function(){
this.setData({
islyric: false,
percent:'100%'
})
},
onLoad: function () {
wx.showLoading({
title: '加载中',
mask: true
})
console.log('正在播放 onLoad')
var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function (userInfo) {
//更新数据
that.setData({
userInfo: userInfo
})
}),
wx.setNavigationBarTitle({
title: '正在播放'
})
},
onShow: function () {
let that = this;
Common.asyncGetStorage('clickdata')//本地缓存
.then(data => {
// console.log(data)
if (!data) return;
that.setData({
id: data.id,
name: data.name,
src: data.mp3Url,
poster: data.picUrl,
author: data.singer
})
return Common.playMusic(data.mp3Url, data.name, data.picUrl);
})
.then(status => {
if(!status) return;
wx.hideLoading();
console.log('id,',that.data.id)
return Common.getlyric(that.data.id)
})
.then((lyricArr) => {
console.log('lyricArr',lyricArr)
that.setData({
lyricArr: lyricArr
})
return Common.getMusicData()
})
.then(data => {
let tempduration = data.duration
console.log('get bg success', tempduration, data)
// 设置时长
that.setData({
sumduration: tempduration
})
})
},
audioPlay: function () {
//背景音乐信息
wx.getBackgroundAudioPlayerState({
success: function (res) {
var status = res.status
var dataUrl = res.dataUrl
var currentPosition = res.currentPosition
var duration = res.duration
var downloadPercent = res.downloadPercent
wx.playBackgroundAudio({
dataUrl: dataUrl
})
wx.seekBackgroundAudio({
position: currentPosition
})
}
})
this.setData({
isplaying: true
})
},
audioPause: function () {
wx.pauseBackgroundAudio()
this.setData({
isplaying: false
})
},
audio14: function () {
},
audioStart: function () {
},
slider3change: function (e) {
sliderToseek(e, function (dataUrl, cal) {
wx.playBackgroundAudio({
dataUrl: dataUrl
})
wx.seekBackgroundAudio({
position: cal
})
})
},
prev:function(){
prevSong(this)
}
})
// 上一曲
function prevSong(that){
let id = that.data.id
console.log('id',id)
wx.getStorage({
key: 'searchReault',
success: function(res) {
console.log(res.data)
let currentSongIndex = res.data.findIndex((item)=>{
return item.id == id;
})
console.log(currentSongIndex)
currentSongIndex -- ;
console.log(res.data[currentSongIndex])
wx.playBackgroundAudio({
dataUrl: res.data[currentSongIndex].mp3Url
})
wx.switchTab({
url: '../now/index'
})
}
})
}
//滑动 歌曲快进
function sliderToseek(e, cb) {
wx.getBackgroundAudioPlayerState({
success: function (res) {
var dataUrl = res.dataUrl
var duration = res.duration
let val = e.detail.value
let cal = val * duration / 100
cb && cb(dataUrl, cal);
}
})
}
// 获取歌词
function getlyric(id,cb) {
console.log('id:',id)
let url = `http://neteasemusic.leanapp.cn/lyric`
wx.request({
url: url,
data: {
id: id
},
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header
success: function (res) {
// success
if (!res.data.lrc.lyric) return false;
let lyric = res.data.lrc.lyric
let timearr = lyric.split('[')
let obj = {}
let lyricArr=[]
// seek 为键 歌词为value
timearr.forEach((item) => {
let key = parseInt(item.split(']')[0].split(':')[0]) * 60 + parseInt(item.split(']')[0].split(':')[1])
let val = item.split(']')[1]
obj[key] = val
})
for(let key in obj){
// obj[key] = obj[key].split('\n')[0]
lyricArr.push(obj[key])
}
cb&&cb(obj,lyricArr)
},
fail: function (res) {
// fail
},
complete: function (res) {
// complete
}
})
}
// ----------------------------------------------------
================================================
FILE: pages/now/index.json
================================================
{
}
================================================
FILE: pages/now/index.wxml
================================================
{{item}}
================================================
FILE: pages/now/index.wxss
================================================
/**index.wxss**/
page{
width: 100%;
height: 100%;
}
.container {
position: relative;
overflow: hidden;
}
.container-content{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
.cicle-infor{
width: 230px;
height: 230px;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
border-radius: 50%;
animation: rotate 10s linear infinite forwards;
margin: 0 auto;
}
@keyframes rotate{
0%{
transform: rotate(0deg)
}100%{
transform: rotate(360deg)
}
}
.fengmian{
flex: 1;
display: flex;
align-items: center;
}
.other-content{
height: 170px;
}
.container{
text-align: center;
}
.icon-choose{
}
.icon-choose, .operations{
display: flex;
justify-content: center;
align-items: center;
}
.icon{
width: 30px;
height: 30px;
background-size: cover;
margin: 10px;
}
.like{
background-image:url(http://op4j4esv2.bkt.clouddn.com/like.png) ;
}
.download{
background-image:url(http://op4j4esv2.bkt.clouddn.com/download.png) ;
}
.add{
background-image:url(http://op4j4esv2.bkt.clouddn.com/add.png) ;
}
.btn{
width: 40px;
height: 40px;
background-size: cover;
margin: 10px;
}
.prev{
background-image:url(http://op4j4esv2.bkt.clouddn.com/pre.png) ;
}
.play, .pause{
background-image:url(http://op4j4esv2.bkt.clouddn.com/play.png) ;
width: 50px;
height: 50px;
}
.pause{
background-image:url(http://op4j4esv2.bkt.clouddn.com/pause.png) ;
}
.next{
background-image:url(http://op4j4esv2.bkt.clouddn.com/next.png) ;
}
.active{
color: #fff;
}
.lists{
position: absolute;
bottom: 0;
opacity: .8;
/*transform: translateY(170px);*/
z-index: 3;
background: linear-gradient(to top, transparent 0%, #D43C33 100%);
width: 100%;
transition: all .5s;
}
.lists radio-group{
display: flex;
flex-direction: column;
align-items: flex-start;
height: 170px;
overflow-y: scroll;
}
.lists radio-group label{
padding: 5px 0 5px 20px;
}
================================================
FILE: style/weui.wxss
================================================
page {
line-height: 1.6;
font-family: -apple-system-font, "Helvetica Neue", sans-serif;
}
icon {
vertical-align: middle;
}
.weui-cells {
position: relative;
margin-top: 1.17647059em;
background-color: #FFFFFF;
line-height: 1.41176471;
font-size: 17px;
}
.weui-cells:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #D9D9D9;
color: #D9D9D9;
}
.weui-cells:after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1rpx solid #D9D9D9;
color: #D9D9D9;
}
.weui-cells__title {
margin-top: .77em;
margin-bottom: .3em;
padding-left: 15px;
padding-right: 15px;
color: #999999;
font-size: 14px;
}
.weui-cells_after-title {
margin-top: 0;
}
.weui-cells__tips {
margin-top: .3em;
color: #999999;
padding-left: 15px;
padding-right: 15px;
font-size: 14px;
}
.weui-cell {
padding: 10px 15px;
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-cell:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #D9D9D9;
color: #D9D9D9;
left: 15px;
}
.weui-cell:first-child:before {
display: none;
}
.weui-cell_active {
background-color: #ECECEC;
}
.weui-cell_primary {
-webkit-box-align: start;
-webkit-align-items: flex-start;
align-items: flex-start;
}
.weui-cell__bd {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-cell__ft {
text-align: right;
color: #999999;
}
.weui-cell_access {
color: inherit;
}
.weui-cell__ft_in-access {
padding-right: 13px;
position: relative;
}
.weui-cell__ft_in-access:after {
content: " ";
display: inline-block;
height: 6px;
width: 6px;
border-width: 2px 2px 0 0;
border-color: #C8C8CD;
border-style: solid;
-webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
position: relative;
top: -2px;
position: absolute;
top: 50%;
margin-top: -4px;
right: 2px;
}
.weui-cell_link {
color: #586C94;
font-size: 14px;
}
.weui-cell_link:active {
background-color: #ECECEC;
}
.weui-cell_link:first-child:before {
display: block;
}
.weui-icon-radio {
margin-left: 3.2px;
margin-right: 3.2px;
}
.weui-icon-checkbox_circle,
.weui-icon-checkbox_success {
margin-left: 4.6px;
margin-right: 4.6px;
}
.weui-check__label:active {
background-color: #ECECEC;
}
.weui-check {
position: absolute;
left: -9999px;
}
.weui-check__hd_in-checkbox {
padding-right: 0.35em;
}
.weui-cell__ft_in-radio {
padding-left: 0.35em;
}
.weui-cell_input {
padding-top: 0;
padding-bottom: 0;
}
.weui-label {
width: 105px;
word-wrap: break-word;
word-break: break-all;
}
.weui-input {
height: 2.58823529em;
min-height: 2.58823529em;
line-height: 2.58823529em;
}
.weui-toptips {
position: fixed;
-webkit-transform: translateZ(0);
transform: translateZ(0);
top: 0;
left: 0;
right: 0;
padding: 5px;
font-size: 14px;
text-align: center;
color: #FFFFFF;
z-index: 5000;
word-wrap: break-word;
word-break: break-all;
}
.weui-toptips_warn {
background-color: #E64340;
}
.weui-textarea {
display: block;
width: 100%;
}
.weui-textarea-counter {
color: #B2B2B2;
text-align: right;
}
.weui-textarea-counter_warn {
color: #E64340;
}
.weui-cell_warn {
color: #E64340;
}
.weui-form-preview {
position: relative;
background-color: #FFFFFF;
}
.weui-form-preview:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #D9D9D9;
color: #D9D9D9;
}
.weui-form-preview:after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1rpx solid #D9D9D9;
color: #D9D9D9;
}
.weui-form-preview__value {
font-size: 14px;
}
.weui-form-preview__value_in-hd {
font-size: 26px;
}
.weui-form-preview__hd {
position: relative;
padding: 10px 15px;
text-align: right;
line-height: 2.5em;
}
.weui-form-preview__hd:after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1rpx solid #D9D9D9;
color: #D9D9D9;
left: 15px;
}
.weui-form-preview__bd {
padding: 10px 15px;
font-size: .9em;
text-align: right;
color: #999999;
line-height: 2;
}
.weui-form-preview__ft {
position: relative;
line-height: 50px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.weui-form-preview__ft:after {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #D5D5D6;
color: #D5D5D6;
}
.weui-form-preview__item {
overflow: hidden;
}
.weui-form-preview__label {
float: left;
margin-right: 1em;
min-width: 4em;
color: #999999;
text-align: justify;
text-align-last: justify;
}
.weui-form-preview__value {
display: block;
overflow: hidden;
word-break: normal;
word-wrap: break-word;
}
.weui-form-preview__btn {
position: relative;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
color: #3CC51F;
text-align: center;
}
.weui-form-preview__btn:after {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 1px;
bottom: 0;
border-left: 1rpx solid #D5D5D6;
color: #D5D5D6;
}
.weui-form-preview__btn:first-child:after {
display: none;
}
.weui-form-preview__btn_active {
background-color: #EEEEEE;
}
.weui-form-preview__btn_default {
color: #999999;
}
.weui-form-preview__btn_primary {
color: #0BB20C;
}
.weui-cell_select {
padding: 0;
}
.weui-select {
position: relative;
padding-left: 15px;
padding-right: 30px;
height: 2.58823529em;
min-height: 2.58823529em;
line-height: 2.58823529em;
border-right: 1rpx solid #D9D9D9;
}
.weui-select:before {
content: " ";
display: inline-block;
height: 6px;
width: 6px;
border-width: 2px 2px 0 0;
border-color: #C8C8CD;
border-style: solid;
-webkit-transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
position: relative;
top: -2px;
position: absolute;
top: 50%;
right: 15px;
margin-top: -4px;
}
.weui-select_in-select-after {
padding-left: 0;
}
.weui-cell__hd_in-select-after,
.weui-cell__bd_in-select-before {
padding-left: 15px;
}
.weui-cell_vcode {
padding-right: 0;
}
.weui-vcode-img {
margin-left: 5px;
height: 2.58823529em;
vertical-align: middle;
}
.weui-vcode-btn {
display: inline-block;
height: 2.58823529em;
margin-left: 5px;
padding: 0 0.6em 0 0.7em;
border-left: 1px solid #E5E5E5;
line-height: 2.58823529em;
vertical-align: middle;
font-size: 17px;
color: #3CC51F;
white-space: nowrap;
}
.weui-vcode-btn:active {
color: #52a341;
}
.weui-cell_switch {
padding-top: 6px;
padding-bottom: 6px;
}
.weui-uploader__hd {
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding-bottom: 10px;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-uploader__title {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-uploader__info {
color: #B2B2B2;
}
.weui-uploader__bd {
margin-bottom: -4px;
margin-right: -9px;
overflow: hidden;
}
.weui-uploader__file {
float: left;
margin-right: 9px;
margin-bottom: 9px;
}
.weui-uploader__img {
display: block;
width: 79px;
height: 79px;
}
.weui-uploader__file_status {
position: relative;
}
.weui-uploader__file_status:before {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.weui-uploader__file-content {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
color: #FFFFFF;
}
.weui-uploader__input-box {
float: left;
position: relative;
margin-right: 9px;
margin-bottom: 9px;
width: 77px;
height: 77px;
border: 1px solid #D9D9D9;
}
.weui-uploader__input-box:before,
.weui-uploader__input-box:after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #D9D9D9;
}
.weui-uploader__input-box:before {
width: 2px;
height: 39.5px;
}
.weui-uploader__input-box:after {
width: 39.5px;
height: 2px;
}
.weui-uploader__input-box:active {
border-color: #999999;
}
.weui-uploader__input-box:active:before,
.weui-uploader__input-box:active:after {
background-color: #999999;
}
.weui-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.weui-article {
padding: 20px 15px;
font-size: 15px;
}
.weui-article__section {
margin-bottom: 1.5em;
}
.weui-article__h1 {
font-size: 18px;
font-weight: 400;
margin-bottom: .9em;
}
.weui-article__h2 {
font-size: 16px;
font-weight: 400;
margin-bottom: .34em;
}
.weui-article__h3 {
font-weight: 400;
font-size: 15px;
margin-bottom: .34em;
}
.weui-article__p {
margin: 0 0 .8em;
}
.weui-msg {
padding-top: 36px;
text-align: center;
}
.weui-msg__link {
display: inline;
color: #586C94;
}
.weui-msg__icon-area {
margin-bottom: 30px;
}
.weui-msg__text-area {
margin-bottom: 25px;
padding: 0 20px;
}
.weui-msg__title {
margin-bottom: 5px;
font-weight: 400;
font-size: 20px;
}
.weui-msg__desc {
font-size: 14px;
color: #999999;
}
.weui-msg__opr-area {
margin-bottom: 25px;
}
.weui-msg__extra-area {
margin-bottom: 15px;
font-size: 14px;
color: #999999;
}
@media screen and (min-height: 438px) {
.weui-msg__extra-area {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
text-align: center;
}
}
.weui-flex {
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.weui-flex__item {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-btn {
margin-top: 15px;
}
.weui-btn:first-child {
margin-top: 0;
}
.weui-btn-area {
margin: 1.17647059em 15px 0.3em;
}
.weui-agree {
display: block;
padding: .5em 15px;
font-size: 13px;
}
.weui-agree__text {
color: #999999;
}
.weui-agree__link {
display: inline;
color: #586C94;
}
.weui-agree__checkbox {
position: absolute;
left: -9999px;
}
.weui-agree__checkbox-icon {
position: relative;
top: 2px;
display: inline-block;
border: 1px solid #D1D1D1;
background-color: #FFFFFF;
border-radius: 3px;
width: 11px;
height: 11px;
}
.weui-agree__checkbox-icon-check {
position: absolute;
top: 1px;
left: 1px;
}
.weui-footer {
color: #999999;
font-size: 14px;
text-align: center;
}
.weui-footer_fixed-bottom {
position: fixed;
bottom: .52em;
left: 0;
right: 0;
}
.weui-footer__links {
font-size: 0;
}
.weui-footer__link {
display: inline-block;
vertical-align: top;
margin: 0 .62em;
position: relative;
font-size: 14px;
color: #586C94;
}
.weui-footer__link:before {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 1px;
bottom: 0;
border-left: 1rpx solid #C7C7C7;
color: #C7C7C7;
left: -0.65em;
top: .36em;
bottom: .36em;
}
.weui-footer__link:first-child:before {
display: none;
}
.weui-footer__text {
padding: 0 .34em;
font-size: 12px;
}
.weui-grids {
border-top: 1rpx solid #D9D9D9;
border-left: 1rpx solid #D9D9D9;
overflow: hidden;
}
.weui-grid {
position: relative;
float: left;
padding: 20px 10px;
width: 33.33333333%;
box-sizing: border-box;
border-right: 1rpx solid #D9D9D9;
border-bottom: 1rpx solid #D9D9D9;
}
.weui-grid_active {
background-color: #ECECEC;
}
.weui-grid__icon {
display: block;
width: 28px;
height: 28px;
margin: 0 auto;
}
.weui-grid__label {
margin-top: 5px;
display: block;
text-align: center;
color: #000000;
font-size: 14px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.weui-loading {
margin: 0 5px;
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
-webkit-animation: weuiLoading 1s steps(12, end) infinite;
animation: weuiLoading 1s steps(12, end) infinite;
background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;
background-size: 100%;
}
.weui-loading.weui-loading_transparent {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 100 100'%3E%3Cpath fill='none' d='M0 0h100v100H0z'/%3E%3Crect xmlns='http://www.w3.org/2000/svg' width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.56)' rx='5' ry='5' transform='translate(0 -30)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.5)' rx='5' ry='5' transform='rotate(30 105.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.43)' rx='5' ry='5' transform='rotate(60 75.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.38)' rx='5' ry='5' transform='rotate(90 65 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.32)' rx='5' ry='5' transform='rotate(120 58.66 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.28)' rx='5' ry='5' transform='rotate(150 54.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.25)' rx='5' ry='5' transform='rotate(180 50 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.2)' rx='5' ry='5' transform='rotate(-150 45.98 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.17)' rx='5' ry='5' transform='rotate(-120 41.34 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.14)' rx='5' ry='5' transform='rotate(-90 35 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.1)' rx='5' ry='5' transform='rotate(-60 24.02 65)'/%3E%3Crect width='7' height='20' x='46.5' y='40' fill='rgba(255,255,255,.03)' rx='5' ry='5' transform='rotate(-30 -5.98 65)'/%3E%3C/svg%3E");
}
@-webkit-keyframes weuiLoading {
0% {
-webkit-transform: rotate3d(0, 0, 1, 0deg);
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
-webkit-transform: rotate3d(0, 0, 1, 360deg);
transform: rotate3d(0, 0, 1, 360deg);
}
}
@keyframes weuiLoading {
0% {
-webkit-transform: rotate3d(0, 0, 1, 0deg);
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
-webkit-transform: rotate3d(0, 0, 1, 360deg);
transform: rotate3d(0, 0, 1, 360deg);
}
}
.weui-badge {
display: inline-block;
padding: .15em .4em;
min-width: 8px;
border-radius: 18px;
background-color: #E64340;
color: #FFFFFF;
line-height: 1.2;
text-align: center;
font-size: 12px;
vertical-align: middle;
}
.weui-badge_dot {
padding: .4em;
min-width: 0;
}
.weui-loadmore {
width: 65%;
margin: 1.5em auto;
line-height: 1.6em;
font-size: 14px;
text-align: center;
}
.weui-loadmore__tips {
display: inline-block;
vertical-align: middle;
}
.weui-loadmore_line {
border-top: 1px solid #E5E5E5;
margin-top: 2.4em;
}
.weui-loadmore__tips_in-line {
position: relative;
top: -0.9em;
padding: 0 .55em;
background-color: #FFFFFF;
color: #999999;
}
.weui-loadmore__tips_in-dot {
position: relative;
padding: 0 .16em;
width: 4px;
height: 1.6em;
}
.weui-loadmore__tips_in-dot:before {
content: " ";
position: absolute;
top: 50%;
left: 50%;
margin-top: -1px;
margin-left: -2px;
width: 4px;
height: 4px;
border-radius: 50%;
background-color: #E5E5E5;
}
.weui-panel {
background-color: #FFFFFF;
margin-top: 10px;
position: relative;
overflow: hidden;
}
.weui-panel:first-child {
margin-top: 0;
}
.weui-panel:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #E5E5E5;
color: #E5E5E5;
}
.weui-panel:after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1rpx solid #E5E5E5;
color: #E5E5E5;
}
.weui-panel__hd {
padding: 14px 15px 10px;
color: #999999;
font-size: 13px;
position: relative;
}
.weui-panel__hd:after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1rpx solid #E5E5E5;
color: #E5E5E5;
left: 15px;
}
.weui-media-box {
padding: 15px;
position: relative;
}
.weui-media-box:before {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1rpx solid #E5E5E5;
color: #E5E5E5;
left: 15px;
}
.weui-media-box:first-child:before {
display: none;
}
.weui-media-box__title {
font-weight: 400;
font-size: 17px;
width: auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
word-wrap: break-word;
word-break: break-all;
}
.weui-media-box__desc {
color: #999999;
font-size: 13px;
line-height: 1.2;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.weui-media-box__info {
margin-top: 15px;
padding-bottom: 5px;
font-size: 13px;
color: #CECECE;
line-height: 1em;
list-style: none;
overflow: hidden;
}
.weui-media-box__info__meta {
float: left;
padding-right: 1em;
}
.weui-media-box__info__meta_extra {
padding-left: 1em;
border-left: 1px solid #CECECE;
}
.weui-media-box__title_in-text {
margin-bottom: 8px;
}
.weui-media-box_appmsg {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-media-box__thumb {
width: 100%;
height: 100%;
vertical-align: top;
}
.weui-media-box__hd_in-appmsg {
margin-right: .8em;
width: 60px;
height: 60px;
line-height: 60px;
text-align: center;
}
.weui-media-box__bd_in-appmsg {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
min-width: 0;
}
.weui-media-box_small-appmsg {
padding: 0;
}
.weui-cells_in-small-appmsg {
margin-top: 0;
}
.weui-cells_in-small-appmsg:before {
display: none;
}
.weui-progress {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-progress__bar {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-progress__opr {
margin-left: 15px;
font-size: 0;
}
.weui-navbar {
display: -webkit-box;
display: -webkit-flex;
display: flex;
position: absolute;
z-index: 500;
top: 0;
width: 100%;
border-bottom: 1rpx solid #CCCCCC;
}
.weui-navbar__item {
position: relative;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
padding: 13px 0;
text-align: center;
font-size: 0;
}
.weui-navbar__item.weui-bar__item_on {
color: #1AAD19;
}
.weui-navbar__slider {
position: absolute;
content: " ";
left: 0;
bottom: 0;
width: 6em;
height: 3px;
background-color: #1AAD19;
-webkit-transition: -webkit-transform .3s;
transition: -webkit-transform .3s;
transition: transform .3s;
transition: transform .3s, -webkit-transform .3s;
}
.weui-navbar__title {
display: inline-block;
font-size: 15px;
max-width: 8em;
width: auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
}
.weui-tab {
position: relative;
height: 100%;
}
.weui-tab__panel {
box-sizing: border-box;
height: 100%;
padding-top: 50px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.weui-search-bar {
position: relative;
padding: 8px 10px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
box-sizing: border-box;
background-color: #EFEFF4;
border-top: 1rpx solid #D7D6DC;
border-bottom: 1rpx solid #D7D6DC;
}
.weui-icon-search {
margin-right: 8px;
font-size: inherit;
}
.weui-icon-search_in-box {
position: absolute;
left: 10px;
top: 7px;
}
.weui-search-bar__text {
display: inline-block;
font-size: 14px;
vertical-align: middle;
}
.weui-search-bar__form {
position: relative;
-webkit-box-flex: 1;
-webkit-flex: auto;
flex: auto;
border-radius: 5px;
background: #FFFFFF;
border: 1rpx solid #E6E6EA;
}
.weui-search-bar__box {
position: relative;
padding-left: 30px;
padding-right: 30px;
width: 100%;
box-sizing: border-box;
z-index: 1;
}
.weui-search-bar__input {
height: 28px;
line-height: 28px;
font-size: 14px;
}
.weui-icon-clear {
position: absolute;
top: 0;
right: 0;
padding: 7px 8px;
font-size: 0;
}
.weui-search-bar__label {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
border-radius: 3px;
text-align: center;
color: #9B9B9B;
background: #FFFFFF;
line-height: 28px;
}
.weui-search-bar__cancel-btn {
margin-left: 10px;
line-height: 28px;
color: #09BB07;
white-space: nowrap;
}
================================================
FILE: utils/util.js
================================================
function formatTime(date) {
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
module.exports = {
formatTime: formatTime
}