赵小金

嗨~


  • 首页

  • 归档

使用vue指令开发一个实时时间转换指令v-time

发表于 2018-12-24 | 分类于 js , vue

时间对象

先定义一个与时间有关的对象,将与时间有关的函数封装进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
var Time = {
// 获取当前时间戳
getUnix: function () {
var date = new Date()
return date.getTime()
},
// 获取今天0点0分0秒的时间戳
getTodayUnix: function () {
var date = new Date()
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
return date.getTime()
},
// 获取今年1月1日0点0分0秒的时间戳
getYearUnix: function () {
var date = new Date()
date.setMonth(0)
date.setDate(1)
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
date.setMilliseconds(0)
return date.getTime()
},
// 获取标准年月日
getLastDate: function (time) {
var date = new Date(time)
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
return date.getFullYear() + '-' + month + '-' + day
},
// 转换时间
getFormatTime: function (timestamp) {
var now = this.getUnix() // 获取当前时间戳
var today = this.getTodayUnix() // 获取今天0点时间戳
var year = this.getYearUnix() // 获取今年0点时间戳
var timer = (now - timestamp) / 1000 // 转换为秒级
var tip = ''

if (timer <= 0) {
tip = '刚刚'
} else if (Math.floor(timer/60) <= 0) {
tip = '刚刚'
} else if (timer < 3600) {
tip = Math.floor(timer/60) + '分钟前'
} else if (timer >= 3600 && (timestamp - today >= 0)) {
tip = Math.floor(timer/3600) + '小时前'
} else if (timer/86400 <= 31) {
tip = Math.ceil(timer/86400) + '天前'
} else {
tip = this.getLastDate(timestamp)
}
return tip
}
}

自定义指令v-time

1
2
3
4
5
6
7
8
9
10
11
12
Vue.directive('time', {
bind: function (el, binding) {
el.innerHTML = Time.getFormatTime(binding.value)
el.__timeout__ = setInterval(function () {
el.innerHTML = Time.getFormatTime(binding.value)
}, 60000)
},
unbind: function () {
clearInterval(el.__timeout__)
delete el.__timeout__
}
})

定时器el.__timeout__每分钟触发一次,在unbind钩子中清除

html代码

1
2
3
<div id="app">
<div class="time" v-time="1545719797346"></div>
</div>

JS如何实现在IOS中video全屏播放

发表于 2018-12-21 | 分类于 js

现在开发人员不容易呀,产品、运营天天各种需求,哎这个顶导要在页面往上滑的时候缓缓的隐藏,下拉的时候在缓缓的显示~ 哎这个图片要自适应的呀,就是那种不够的话补黑边的呀~ 哎视频的进度条要自定义的呀,原生的那个多丑呀~ 哎。。。

唉,怎么办呢,没有办法呀,使劲磕呗,那今天的话题我们就来说说IOS中video全屏的问题,有需要的朋友可以参考下

video的几个重要的属性

controls: 显示播放控件;controls属性规定浏览器应该为视频提供播放控件,换句话说,只有写了这个属性才会有播放控件,不写的话默认是没有的,所有如果要自定义播放控件就不需要写controls属性
写法:

1
<video controls src='1.mp4'></video>

autoplay:自动播放;指定后,视频会马上自动开始播放,不会停下来等着数据载入结束
写法:

1
<video autoplay src='1.mp4'></video>

playsinline:取消全屏;只需在video上添加该属性,便可使视频播放时局域播放,不脱离文档流,但是这个属性需要APP支持,在APP开发中设置UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES才能生效
写法:

1
<video webkit-playsinline="true" playsinline="playsinline" src='1.mp4'></video>

js自定义video全屏

众所周知,IOS是不支持全屏API的,于是requesrFullScreen事件对于video全屏是不起作用的,但是IOS9+对于video标签有一个很重要的属性,那就是playsinline,这个属性去掉之后视频就可以全屏,但不是直接生效,而是下次播放的时候才可以,于是我们需要先把视频短暂的暂停一下,在播放就可以了,具体实现方法:

1
2
3
4
video.pause()
video.removeAttribute('playsinline')
video.removeAttribute('webkit-playsinline')
video.play()

这个仅对IOS中的全屏有用,如果兼容Android需要使用requestFullScreen方法,具体实现方法:

1
2
<button onclick="fullscreenFn()">全屏</button>
<video width="400" autoplay="" webkit-playsinline="true" playsinline="playsinline" src='1.mp4' id="video"></video>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 浏览器前缀判断
var videoEle = document.getElementById('video')
function browserPrefix (method) {
let browserPrefixreturn
switch (true) {
// W3C
case (!!(videoEle[method])):
browserPrefixreturn = method
break
// FireFox
case (!!(videoEle['moz' + method[0].toUpperCase() + method.slice(1)])):
browserPrefixreturn = 'moz' + method[0].toUpperCase() + method.slice(1)
break
// Chrome等
case (!!(videoEle['webkit' + method[0].toUpperCase() + method.slice(1)])):
browserPrefixreturn = 'webkit' + method[0].toUpperCase() + method.slice(1)
break
// IE11
case (!!(videoEle['ms' + method[0].toUpperCase() + method.slice(1)])):
browserPrefixreturn = 'ms' + method[0].toUpperCase() + method.slice(1)
break
}
return browserPrefixreturn
}
function fullscreenFn(){
video.pause()
video.removeAttribute('playsinline')
video.removeAttribute('webkit-playsinline')
video.play()
video[browserPrefix('requestFullScreen')]()
event.stopImmediatePropagation()
}

神器甘特图

发表于 2018-06-24 | 分类于 工具

什么东西在我们的生活和工作当中可有可无,但是有了它立马会提升一个档次呀~ ———— 那就是甘特图Gantt chart,就是下面这个东西啦啦啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
gantt
dateFormat YYYY-MM-DD
title 上报事件时间线

section load事件
load(加载开始):load_start_timestamp : p1, 2018-01-01, 1d
load(加载结束):load_end_timestamp : p2, after p4, 1d

section show事件
show(页面曝光) : p3, after p1, 1d

section stay事件
stay(duration第一次):1000 : p4, after p3, 1d
stay(duration持续):5000 : p5, after p2, 5d

section model_show事件
model_show(默认曝光) : p6, after p5, 10d
model_show(滚动曝光) : p7, after p6, 10d

section model_click事件
model_click(点击上报) : p8, after p7, 10d

当当当当~
img

学习日记js小锦囊-持续更新

发表于 2018-05-02 | 分类于 js , 学习日记

两中数字格式化的方法

数字格式化一 e.g. 23422039->2342.2W

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 2342.2W
* @param {number} count 需要格式化的数字
*/
function CounFormat (count) {
var countString = count.toString()
var tmp = ''
var result = ''
if (countString.length >= 5) {
tmp = countString.slice(-4, -3) === '0' ? '' : countString.slice(-4, -3)
if (tmp.slice(tmp.length + 1, 1) === 0) {
result = countString.slice(0, -4).concat('w')
} else {
tmp === '' ? result = countString.slice(0, -4).concat('w') : result = countString.slice(0, -4).concat('.' + tmp + 'w')
}
return result
} else {
return count
}
}

数字格式化二 e.g. 23232222->23,232,222

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 千位符数字格式化23,232,222
* @param {number} num 需要格式化的数字
* @param {int} precision 保留小数位
* @param {String} separator 分隔符
*/
function CounFormat2 (num, precision, separator) {
var parts
if (!isNaN(parseFloat(num)) && isFinite(num)) {
num = Number(num)
num = (typeof precision !== 'undefined' ? num.toFixed(precision) : num).toString()
parts = num.split('.')
parts[0] = parts[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + (separator || ','))
return parts.join('.')
}
return NaN
}

时间格式化的方法

时间格式化 e.g. 1245278300->2009-6-18 06:38

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 时间格式化 2018-09-09 12:02:22
* @param {number} timespan 时间戳
*/
function formatMsgTime (timespan) {
timespan = timespan * 1000
var dateTime = new Date(timespan)
var year = dateTime.getFullYear()
var month = dateTime.getMonth() + 1
var day = dateTime.getDate()
var hour = dateTime.getHours() ? (dateTime.getHours() < 10 ? '0' + dateTime.getHours() : dateTime.getHours()) : '00'
var minute = dateTime.getMinutes() ? (dateTime.getMinutes() < 10 ? '0' + dateTime.getMinutes() : dateTime.getMinutes()) : '00'
// var second = dateTime.getSeconds()
var now = new Date()
// typescript转换写法
var nowNew = now.getTime()
// var nowNew = Date.parse(now.toDateString())
var milliseconds = 0
var timeSpanStr
milliseconds = nowNew - timespan
if (milliseconds <= 1000 * 60 * 1) {
timeSpanStr = '刚刚'
} else if (1000 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60) {
timeSpanStr = Math.round((milliseconds / (1000 * 60))) + '分钟前'
} else if (1000 * 60 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24) {
timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60)) + '小时前'
} else if (1000 * 60 * 60 * 24 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24 * 15) {
timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60 * 24)) + '天前'
} else if (milliseconds > 1000 * 60 * 60 * 24 * 15 && year === now.getFullYear()) {
timeSpanStr = month + '-' + day + ' ' + hour + ':' + minute
} else {
timeSpanStr = year + '-' + month + '-' + day + ' ' + hour + ':' + minute
}
return timeSpanStr
}

视频时长格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 视频时长格式化
* @param {number} seconds
*/
function secondsToHour (seconds) {
var h = parseInt(seconds / 3600)
var m = parseInt((seconds % 3600) / 60)
var s = parseInt(seconds % 60)
h = h ? h + ':' : ''
m = m ? (m < 10 ? '0' + m + ':' : m + ':') : '00:'
s = s ? (s < 10 ? '0' + s : s) : '00'
return h + m + s
}

文案截取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 文案截取
* @param {number} num 截取个数
* @param {String} string 拼接字符串
* @param {String} symbol 拼接字符串
* stringLen("asdsfdfsdf", 80, "...")
*/
function stringLen (string, num, symbol) {
var len = 0
for (var i = 0; i < string.length; i++) {
if (len >= num) {
return string.slice(0, i) + symbol
}
if (string.charCodeAt(i) > 127 || string.charCodeAt(i) === 94) {
len++
} else {
len += 1 / 2
}
}
return string
}

对比版本号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 对比版本号,大于:true 小于:false
* @param {String} v1 2.1.1
* @param {String} v2 2.2.2
*/
function versions(v1, v2) {
var arr1 = v1.replace(/[-_]/g, '.').split('.')
var arr2 = v2.replace(/[-_]/g, '.').split('.')
var len = Math.max(arr1.length, arr2.length)
for (var i = 0; i < len; i++) {
arr1[i] = !arr1[i] ? 0 : arr1[i]
arr2[i] = !arr2[i] ? 0 : arr2[i]
if (parseInt(arr1[i]) > parseInt(arr2[i])) {
return true
} else if (parseInt(arr1[i]) < parseInt(arr2[i])) {
return false
}
}
return true
}

倒计时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 倒计时
* @param {number} msd 截止时间
*/
function MillisecondToDate (msd) {
var now = new Date().getTime()
var time = parseFloat(msd - now) / 1000
if (time !== null && time !== '') {
var timeDay = parseInt(time / 86400.0)
var timeH = parseInt(time / 3600.0 - 24 * timeDay)
var timeM = parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)
var timeS = parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) - parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60)
timeDay = timeDay < 10 ? '0' + timeDay : timeDay
timeH = timeH < 10 ? '0' + timeH : timeH
timeM = timeM < 10 ? '0' + timeM : timeM
timeS = timeS < 10 ? '0' + timeS : timeS
}
return {
'day': timeDay.toString(),
'hour': timeH.toString(),
'minute': timeM.toString(),
'second': timeS.toString()
}
}

学习日记css小锦囊-持续更新

发表于 2018-04-01 | 分类于 css , css3 , 学习日记

css3 截取前几行内容并且垂直居中显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}

/* vue打包会丢失box-orient属性,需要特殊处理 */
/*! autoprefixer: off */
-webkit-box-orient: vertical;
/* autoprefixer: on */

input placeholder修改颜色

1
2
3
4
5
6
7
8
9
10
11
12
::-webkit-input-placeholder { /* WebKit browsers */ 
color: #999;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #999;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #999;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #999;
}

手动写三角

1
2
3
4
5
6
7
{
width: 0px;
height: 0;
border: .11rem solid transparent;
border-top: .15rem solid #8D3A3A;
display: block;
}

Node.js小试牛刀

发表于 2018-02-16

学习日记es6-polyfill

发表于 2018-02-16 | 分类于 es6 , 学习日记

浮点数误差

对于javascript的数字来说,“机器精度”的值通常为2^-52
ES6开始,该值定义在Number.EPSILON中,我们可以拿来直接用,也可以为ES6之前的版本写polyfill

1
2
3
if(  !Number.EPSILON  ){
Number.EPSILON = Math.pow(2,-52);
}

可以用Number.EPSILON来比较两个数字是否相等(在制定误差范围内)

1
2
3
function numbersCloseEnoughToEqual(  n1,  n2 ){
return Math.abs( n1 - n2 ) < Number.EPSILON ;
}

扒一扒deepLink:应用深度链接

发表于 2017-02-27 | 分类于 js , ios

总想着要做一个自己的博客,可是总是又因为各种各样的事情一直没有做,工作中的记录都在有道云笔记中,因为我觉得有道云笔记真的是个神器,但是作为博客来说是有点不太上台面,终于下定决心要在这过年的假期完成这件事,因为我发现我最近真的越来越忙了,再不做真的没有时间了呀~

什么是deepLink

scheme(原始唤起码)+Universal Links(通用链接)+下载后通过设备指纹识别唤起客户端指定页

deepLink起源

起源就是领导说要做一套可以无缝唤起客户端的系统,如果完不成就要用第三方的系统,但是我们已经完成了scheme(原始唤起码)+Universal Links(通用链接),只剩下载后通过设备指纹识别唤起客户端指定页,我们能妥协吗,当然不行!


实现方式

ios9-,H5与客户端通信方式为scheme
  • 协议形式为miaopai:// ,这样的唤起码浏览器不会识别,只有客户端可以识别,浏览器不会报错
  • 所以为了达到唤起不成功可以下载的功能,页面做了在唤起码执行完成2s后定时执行下载或者一些别的操作(跳转到指定H5……)
    ios9+,H5与客户端通信方式为scheme或者通用链接
1
2
什么是通用链接(Universal Links)?
Apple 为了大力推动 APP 开发者在深层链接上有更好的体验。 推出通用链接:一种能够方便的通过传统 HTTP 链接来启动 APP, 使用相同的网址打开网站和APP。
  • 协议形式为https://app.yixia.com,这样的唤起码浏览器和APP都会识别,跳转方式为:

    • 已安装客户端会直接识别唤起码
    • 未安装客户端会跳转至通用链接指定页(中转页)
  • 客户端与Safari之间的通信方式
    • 客户端点击右上角yixia.com在Safari中打开
    • Safari下拉页面在客户端中打开
    • 手机会默认记住这种选择作为偏好操作

下载后通过设备指纹识别唤起客户端指定页

IOS Android下载后唤起指定页

没安装的情况下,点击任意唤起链接,即种植当前链接到服务端,8分钟内下载完成并唤起之后即可自动跳转到已种植的站内页面(仅限于下载后第一次启动)


IOS Android下载后唤起指定页用到的参数和流程

  • h5页下载之前将以下参数种植到接口中(类似于一个.json文件),IOS如下
1
2
3
4
5
6
7
8
9
10
11
12

{
"width" : 手机屏幕宽度 [ 320 || 375 || 414 ],
"height" : 手机屏幕高度 [ 568 || 667 || 736 ],
"os" : 手机系统 [ iphone os 9_1 ], //统一小写
"time" : 当前时间戳,
"ip":111.202.106.229,
"code" : h5页面传给客户端的参数(唤起码)
}
/** h5页面的os来自当前浏览器的navigator.userAgent值,
"Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"
*/
  • Android统一在下载之前种植
1
2
3
4
5
6
7
8
9
10
11
12
13
android:
{
"width": 1,
"height": 1,
"os": 安卓的设备号 [ m1-note ],//统一小写,空格变-
"time" : 当前时间戳,
"ip":111.202.106.229,
"code": h5页面传给客户端的参数(唤起码)
}
/** h5页面的os来自当前浏览器的navigator.userAgent值,
"Mozilla/5.0 (Linux; Android 5.1; MZ-m1 note Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.94 Mobile Safari/537.36"
三星和魅族手机去前缀,统一小写,空格变-:
MZ-m1 note => m1-note
  • 种植成功之后,首次唤起客户端发送相同参数到服务端进行比对,如完全一致则发送code至客户端进行跳转操作(测试包新唤起会进行如上操作)
123

赵小金

赵小金的博客

28 日志
14 分类
9 标签
© 2022 赵小金
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4