TeaCoder

生命不息,代码不止


  • 首页

  • 分类

  • 归档

  • 标签

  • 搜索
close

Javascript开启浏览器全屏模式

发表于 2016-11-04   |   分类于 前端

通常在某些情况下,我们需要让浏览器开启全屏模式,以便获得更好的视觉体验,先看下全屏模式简单的几个API。

浏览器默认绑定

非全屏模式下, document的F11按键绑定开启全屏模式
全屏模式下, document的esc和F11 按键绑定关闭全屏模式

屏幕全屏模式改变事件

当成功进入全屏模式后, document会收到一个fullscreenchange 事件。 当退出全屏状态后, document又会收到fullscreenchange 事件。

1
var screenChange = 'webkitfullscreenchange' || 'mozfullscreenchange' || 'fullscreenchange'

判断当前是否处于全屏状态

非标准(避免使用):

1
var isFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;

标准:
fullscreenElement 属性会告诉你当前全屏显示的 element。 如果该值为非空,则document进入了全屏模式。如果为空则不在全屏模式。

1
var isFullScreen = document.fullscreenElement || document.mozFullScreenElement ||document.webkitFullscreenElement

判断是否可以进入请求全屏状态

1
var isFullScreenAvailable = document.fullScreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled;

开启全屏模式

参数:element为想要全屏展示的元素比如video,如果想要浏览器全屏展示,则传入document.documentElement即可。

1
2
3
4
5
6
7
8
9
10
11
function launchFullScreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}

注意: requestFullscreen是规范的书写模式( s是小写), 但在Gecko内核中仍使用带前缀的大写模式mozRequestFullScreen。

关闭全屏模式

1
2
3
4
5
6
7
8
9
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}

全屏模式只能由手势触发

了解API后,假如我们监听window.onload事件执行launchFullScreen方法,Chrome浏览器会提示“开启全屏模式API只能由用户手势触发”。

1
"Failed to execute 'requestFullScreen' on 'Element': API can only be initiated by a user gesture."

原因是浏览器采用安全的机制, 将这种强制全屏模式意为“恶意行为”, 一切非用户主观意愿带来的变化都是不允许的。

因此如果你的应用有全屏需求,有两种方案。
1.页面初始化给用户一个“F11开启全屏” 的提示, 并且在延迟几秒之后消失。
2.页面设置一个全屏按钮,单击全屏按钮进入全屏模式,并且隐藏按钮(视觉效果最佳)。

对于第二种方案,需要监听键盘事件:

1
2
3
4
5
6
7
8
9
10
document.addEventListener("keydown", function(e) {
var currKey = 0
//在FireFox或Opera中,隐藏的变量e是存在的,那么e||event返回e,如果在IE中,隐藏变量e是不存在,则返回event。
var e = e || event;
//IE中,只有keyCode属性,而FireFox中有which和charCode属性,Opera中有keyCode和which属性
var currKey = e.keyCode || e.which || e.charCode;
if (currKey == 112) {
launchFullScreen(document.documentElement);
}
}, false);

具备了兼容各种浏览器按键模式的监听,但不知道keycode肿么办,112是哪个键?

字母和数字键的键码值(keyCode)

按键 键码 按键 键码 按键 键码 按键 键码
A 65 J 74 S 83 1 49
B 66 K 75 T 84 2 50
C 67 L 76 U 85 3 51
D 68 M 77 V 86 4 52
E 69 N 78 W 87 5 53
F 70 O 79 X 88 6 54
G 71 P 80 Y 89 7 55
H 72 Q 81 Z 90 8 56
I 73 R 82 0 48 9 57

数字键盘上的键的键码值(keyCode)

按键 键码 按键 键码
0 96 8 104
1 97 9 105
2 98 * 106
3 99 + 107
4 100 Enter 108
5 101 - 109
6 102 . 110
7 103 / 111

功能键键码值(keyCode)

按键 键码 按键 键码
F1 112 F7 118
F2 113 F8 119
F3 114 F9 120
F4 115 F10 121
F5 116 F11 122
F6 117 F12 123

控制键键码值(keyCode)

按键 键码 按键 键码 按键 键码 按键 键码
BackSpace 8 Esc 27 Right Arrow 39 -_ 189
Tab 9 Spacebar 32 Dw Arrow 40 .> 190
Clear 12 Page Up 33 Insert 45 /? 191
Enter 13 Page Down 34 Delete 46 `~ 192
Shift 16 End 35 Num Lock 144 [{ 219
Control 17 Home 36 ;: 186 \ 220
Alt 18 Left Arrow 37 =+ 187 ]} 221
Cape Lock 20 Up Arrow 38 ,< 188 ‘“ 222

其他非标准化的方法

非标准化的方法指的是进入草案前浏览器实现的一些方法。有的目前仍保留,有的已废除,避免使用。
window.fullScreen(Firefox)
HTMLMediaElement.webkitDisplayingFullscreen
HTMLMediaElement.webkitEnterFullscreen
HTMLMediaElement.webkitExitFullscreen
HTMLMediaElement.webkitSupportsFullscreen

HTML5(Audio)移动音乐播放器

发表于 2016-10-30   |   分类于 前端

“咳咳咳..在看正文之前,如果客官有兴趣可以轻点播放按钮聆听一下我的第一首吉他原创歌曲”。——作于大三下学期


“怎么感觉整个人都不好了…还有呜呜呜的声音”

“那时正值寒冬,于学校宿舍顶楼录制,周围一片漆黑,忽一阵冷风袭来,但对我而言那是美丽的协奏”

“什么鬼..!”

“好吧…那听听这首吧,也许能帮到客官您,这是我的第二首原创歌曲”。——作于大四上学期


“怎么比第一首调子还哀伤”?Are you kiding me?

“蓝瘦,香菇,在这里。”

好了,客观见笑了,为了真正治愈你,让我们回归正题吧!

这段时间公司一直在做一个PC的教育类单页应用,庞大复杂,涉及非常多H5的知识,音频就是其中的一部分。闲暇时写了一个移动音乐播放器,除了将之作为练手项目,对于音乐的喜爱也是促使自己想写个播放器的原因。

在线地址:请猛击这里
源码:请猛击这里

注意:使用PC浏览最好打开移动设备模式,使用移动设备浏览需要关闭无痕浏览模式(否则无法使用本地存储,一般浏览器都是默认不开启),项目需要在本地服务器或线上服务器运行,以file:///形式的地址打开是无法进行ajax请求的,从而无法看到音乐数据。
UI图

项目实现的功能及所用知识

  • 播放器的基础操作,上一首,下一首(顺序播放、随机播放、单曲循环),播放暂停,滑动时间轴的歌词定位
  • 初始handlebar模板渲染音乐列表数据,下拉滚动加载音乐列表数据。
  • 歌曲列表可添加喜爱音乐,于下次刷新时更新喜爱音乐列表,基于HTML5本地存储。
  • 布局采用rem布局,自适应移动端手机设备。
  • iconfont在线图标应用的使用

项目目录文件结构

  • css:存放样式文件
  • lib: 存放公共脚本库
  • js: 存放项目脚本文件
  • img: 存放图片
  • fonts: 项目字体文件
  • res: 项目音乐资源
  • ui:项目ui文件(psd)

项目js文件结构

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// ============================配置变量================================
var rootPath = window.location.href.replace(/\/\w+\.\w+/, "/");
var Settings = {
playmode: 0, //0列表循环,1随机,2为单曲循环
volume: 0.5, //音量
initNum: 10, //列表初始化歌曲数
reqNum: 10 //后续请求歌曲数
};
// ============================工具函数================================
var Util = (function() {
return {
}
})()
// ============================Dom选择器================================
var Dom = {
}
// ============================全局变量================================
var winH = $(window).height();
var songNum = 0; //当前列表歌曲数目
var lrcHighIndex = 0; // 歌词高亮索引
var lrcMoveIndex = 0; // 歌词移动单位索引
var moveDis = 0; // 单句歌词每次移动距离
var duration = 0; // 当前歌曲的时间
var index = 0; //当前播放歌曲的索引
var songInfo = null; // 当前歌曲信息
var songModelUI = null; // 当前歌曲UI模型
var timeArr = []; //当前歌曲时间数组
var formatTimeArr = []; //当前歌曲时间数组(格式化为秒数)
// ============================入口函数================================
function main() {
initUIFrame();
var initModel = PlayerModel();
var songListUI = ModelUIFrame(Dom.songListContainer);
var lsongListUI = ModelUIFrame(Dom.lSongListContainer);
initModel.getSongList("data/data.json", function(data) {
// 生成所有歌曲列表
songListUI.renderList(data, 0, null, function() {
songListUI.updateList();
});
// 生成喜爱歌曲列表
initModel.getLoveSongArr(function(lSongArr) {
lsongListUI.renderList(data, 1, lSongArr);
});
// 添加动画
Util.addAnimationDelay(Dom.song);
// 保存歌词数据
initModel.saveLyric(data);
});
EventHandler();
}
// ============================初始化UI函数================================
function initUIFrame() {
}
// ============================实现数据交互方法================================
function PlayerModel() {
}
// ============================模型动态UI模块================================
function ModelUIFrame(container) {
}
// ============================事件绑定模块================================
function EventHandler() {
}
// 调用入口函数
main();

功能点详解

Handlebar.js初次渲染及滚动加载

使用前端模板优点是把数据和结构分离出来,代码更清晰。但后来发现handlerbar.js似乎无法在js中示例模板对象,而html中的handlebar在初次进入页面便会被编译了,因此后续添加音乐还是采用传统的拼接字符串的方式,如果你有更优雅的动态加载方式,欢迎讨论交流。

html: handlebars模板包含在script标签之中并且type类型为”text/x-handlebars-template”,在初始化页面的时候根据js获取数据植入后就渲染出相应的html。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script id="sListTpl" type="text/x-handlebars-template">
{{#each this}}
{{#isInitData this @index}}
<li class="song btm-line" data-src={{songSrc}} data-index={{id}}>
<div class="poster">
<img src={{poster.thumbnail}}>
</div>
<div class="songinfo">
<h2 class="lsongname">{{songName}}</h2>
<sub class="lsinger">{{singer}}</sub>
</div>
<div class="loveflag">
<i class="icon icon-love {{#if loveFlag}}active{{/if}}"></i>
</div>
</li>
{{/isInitData}}
{{/each}}
</script>
<!-- END歌曲列表模块 -->

js:

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
function renderAllList(data) {
var preTpl;
var lsongArr = Util.getItem('lsonglist') === null ? [] : JSON.parse(Util.getItem('lsonglist'));
// 生成列表
if (!sListTpl) {
// 后续动态生成歌曲
var tpl = "";
var songIndex = songNum;
$.each(data, function(index, el) {
if (index >= songIndex && index < songIndex + Settings.reqNum) {
tpl += "<li class='song btm-line' data-src='res/music/" + songNum + ".mp3' data-index='" + songNum + "'><div class='poster'><img src='./img/poster/" + songNum + "-thumbnail.jpg'></div><div class='songinfo'><h2 class='lsongname'>" + el.songName + "</h2><sub class='lsinger'>" + el.singer + "</sub></div><div class='loveflag'><i class='icon icon-love '></i></div></li>";
songNum++;
}
});
$(container).append($(tpl));
} else {
// 首次生成歌曲
preTpl = Handlebars.compile(sListTpl);
$(container).html(preTpl(data));
}
// 更新喜爱图标
if (lsongArr.length !== 0) {
$.each(lsongArr, function(index, val) {
Dom.songListContainer.find(".song").eq(val).find(".icon-love").addClass('active');
});
}
}

rem布局自适应方案

大体上指的是html根元素上定义一个字体大小,然后css样式定义时使用rem作为单位,包括margin、paddding、用于绝对定位的单位等等。然后js根据手机设备的屏幕大小,改变根字体的大小,这样整个页面也会跟着相应的缩小或放大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 根据手机屏幕自适应字体大小(rem自适应方案)
function rescale() {
var docEle = document.documentElement;
var width = docEle.clientWidth || window.innerWidth;
if (width > 640 && width !== 768) {
docEle.style.fontSize = "100px";
} else if (width == 320) {
//iphone5
docEle.style.fontSize = "49px";
} else if (width == 375) {
//iphone6
docEle.style.fontSize = "57px";
} else if (width == 412) {
// Nexus 5X
docEle.style.fontSize = "57px";
} else if (width == 768) {
//ipad
docEle.style.fontSize = "88px";
} else {
docEle.style.fontSize = Math.round(width / 640 * 100) + "px";
}
}

更多详解,请看先前一篇文章《移动端自适应布局解决方案——rem》,您可以猛击这里跳转。

关于歌词的同步方案实现

目前音乐播放器的歌词同步显示大概有两种,一种是精确到单个文字,一种是精确到单行歌词。本文实现的是第二种。

整体实现思路

页面初始化时,请求歌曲数据json(本地json文件模拟),其中歌名、歌手、图片等按需渲染到html中,将歌词存储到localStorage中。此时,F12打开chrome调试器,进入Application-LocalStorage可以看到:
歌词本地存储

点击一首歌进入播放页面后,歌词就会从本地存储中读取,此时你会看到生成这样的歌词结构:
歌词结构
每一行歌词都将要将歌词时间绑定在data-point上,监听歌曲播放的timeupdate事件,当歌曲的时间(经过取整处理)与当前data-point值相等时,就为当前歌词高亮(相当于给p添加current类名),并且根据当前高亮歌词的index索引将整个歌词盒子向上移动p标签的高度+margin-top的高度。

lrc歌词的结构

来自网易云音乐的歌词数据:

1
2
3
4
5
[00:14.64]如果不是那镜子\n[00:16.73]不像你不藏秘密\n[00:21.26]我还不肯相信\n[00:23.02]没有你我的笑更美丽\n[00:28.99]那天听你在电话里略带抱歉的关心\n
[00:16.959]摘一颗苹果\n[00:19.800]等你从门前经过\n[00:22.700]送到你的手中帮你解渴\n[00:25.570]像夏天的可乐\n
[00:00.00] 作曲 : 周杰伦\n[00:01.00] 作词 : 周杰伦\n[00:05.620]\n[00:37.980]亲吻你的手\n

可以看到格式 = [时间点] + 要显示的文字 + \n
这里有两个坑需要注意:

  • 有的歌词秒数是精确到小数点后两位,有的是三位。
  • 有的歌词(周杰伦《算什么男人》)格式是 [时间点]+\n

时间歌词创建映射

首先以\n将歌词字符串分割成以[时间点]文字的数组,但由于这样分割之后最后一个元素是空的,所以用tempArr.splice(-1, 1)删除最后一个元素。

接下来循环遍历这个临时数组,由于上面提到的秒数精确度的问题,所以判断一下index为9是否为数字,若为数字则将该位数字删除。(采用字符串截取方式,若你对js字符串方法不熟悉,可以猛击这里)

经过这样的处理之后,临时数组的元素格式不再有区别了,此时再进行字符串截取,将截取到的时间点放入timeArr,将截取的歌词放入lyricArr,并以返回保存着这两个变量的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function createArrMap(lyric) {
var timeArr = [],
lyricArr = [];
var tempArr = lyric.split("\n");
tempArr.splice(-1, 1);
var tempStr = "";
$(tempArr).each(function(index) {
tempStr = this;
if (tempStr.charAt(9).match(/\d/) !== null) {
tempStr = tempStr.substring(0, 9) + tempStr.substring(10);
}
timeArr.push(tempStr.substring(0, 10));
lyricArr.push(tempStr.substring(10));
});
return {
timeArr: timeArr,
lyricArr: lyricArr
};
}

生成歌词

由于上面歌词格式造成时间点对应的歌词为空,此时如果渲染出一个

标签的高度将为0,这会影响歌词向上移动距离的不统一。因此下面作出个判断如果为空,则替换为“————–”。(为空的时候大多数是歌曲中间停顿或过渡的时候)

1
2
3
4
5
6
7
8
9
function renderLyric(songinfo) {
var arrMap = Util.createArrMap(songinfo.lyric);
var tpl = "";
$.each(arrMap.lyricArr, function(index, lyric) {
var lyricContent = lyric === "" ? "--------------" : lyric;
tpl += "<p class='' data-point='" + arrMap.timeArr[index] + "'>" + lyricContent + "</p>";
});
Dom.lrcwrap.html(tpl);
}

歌词同步

歌词同步我写在了syncLyric方法中,监听audio元素的timeupdate事件调用。
这个方法接收两个参数,第一个是当前播放歌曲时间(秒),第二个是转化为秒数的时间点数组。
如果当前时间>=时间点,那么高亮当前歌词(以lrcHighIndex)存储,并且lrcHighIndex自增1。
当歌词高亮索引lrcHighIndex>=1即歌词高亮不为第一句时,计算索引并让歌词盒子向上移动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function syncLyric(curS, formatTimeArr) {
if (Math.floor(curS) >= formatTimeArr[lrcHighIndex]) {
Dom.lrc.eq(lrcHighIndex).addClass('current').siblings().removeClass('current');
if (lrcHighIndex >= 1) {
lrcMoveIndex = lrcHighIndex - 2;
moveDis += Util.getMoveDis(lrcMoveIndex);
Dom.lrcwrap.animate({
"top": "-" + moveDis + "px"
}, 100);
lrcMoveIndex++;
}
lrcHighIndex++;
}
}

2016.10.3长沙之旅

发表于 2016-10-03   |   分类于 旅行

蓝瘦
橘子洲夕阳
极致美颜
万达
湖南大学
湖南电视台

毕业一年,如期而至

发表于 2016-09-08

poster

移动端图片画廊

发表于 2016-09-04   |   分类于 前端

移动端图片画廊,采用css3的flex布局结合object-fit属性,实现类似Google Photo 等高自适应的图片布局效果
demo
你也可以点击在线地址 查看预览:

关于flex-box布局

flex布局简直是移动端的神器,因为移动端不存在兼容性问题,几乎所有手机浏览器都采用相同的标准。

几分钟快速了解flex-box布局

采用flex布局(作用于容器)

块状元素:

1
2
3
.box{
display:flex;
}

行内元素:

1
2
3
.box{
display: inline-flex;
}

容器的属性

寻找好基友:
flex-direction、 flex-wrap、flex-flow
justify-content、align-items、align-content

解释:

  • flex-direction:决定主轴的方向(即项目的排列方向)
  • flex-wrap:默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行
  • strong textflex-flow:flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
  • justify-content:定义了项目在主轴上的对齐方式(flex-start | flex-end | center | space-between | space-around)
  • align-items:定义项目在交叉轴上如何对齐(flex-start | flex-end | center | baseline | stretch)
  • align-content:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。(flex-start | flex-end | center | space-between | space-around | stretch;)

项目的属性

基友:
flex-grow、flex-shrink、flex-basis、flex
order (规整有序)
alignself (特立独行)

解释:
flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
flex:flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。

align-self:属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

关于object-fit属性

适用范围:替换元素

<img>、<input>、<textarea>、<select>、<object>等
浏览器根据其标签的元素与属性来判断显示具体的内容

值:
fill: 默认值。替换内容拉伸填满整个content box, 不保证保持原有的比例。
contain: 保持原有尺寸比例。保证替换内容尺寸一定可以在容器里面放得下。因此,此参数可能会在容器内留下空白。
cover: 保持原有尺寸比例。保证替换内容尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,此参数可能会让替换内容(如图片)部分区域不可见。
none: 保持原有尺寸比例。同时保持替换内容原始尺寸大小。
scale-down: 就好像依次设置了none或contain, 最终呈现的是尺寸比较小的那个。

DEMO解释

html:

1
2
3
4
5
6
7
8
<div class="page">
<div class="m-gallery">
<!-- <div><img class="animated bounceIn" src="img/1.jpg"></div> -->
</div>
<div class="m-viewbox hide">
<img class="bigimg animated bounceIn" src="">
</div>
</div>

css:

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
.m-gallery{
display: flex; //采用flex布局
flex-wrap: wrap; //规定一行放不下flex元素时自动换行
}
.m-gallery div{
height: 100px;
flex-grow:1; //每个flex元素占的宽度相同
margin: 2px;
}
.m-gallery img{
height: 100px;
min-width: 100%;
max-width: 100%;
object-fit: cover; //使图片等比拉伸,可能会被裁减
vertical-align: bottom;
}
@media (max-width: 1000px) and (min-width: 900px) {
.m-gallery::after {
content: '';
flex-grow: 999999999; //当最后一行图片太少的时候,比如只有一张,因为 grow 的关系,它将占满一整行,通过伪元素来占满剩余空间,防止图片拉伸
}
}
@media (max-width: 1100px) and (min-width: 1000px) {
.m-gallery::after {
content: '';
flex-grow: 999999999;
}
}

CSS3变换及CSS3动画

发表于 2016-06-16   |   分类于 前端

CSS3变换动画

指定三维视角

perspective 属性定义 3D 元素距视图的距离,以像素计。
当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。

三维变形

三维变形的变形方式:四种方法
旋转——缩放——平移——扭曲——指定变形基点

旋转

transform:rotate(45deg);
该语句使div元素顺时针旋转45度。

缩放

transform:scale(0.8,1);
使用缩放的方法实现文字或图像的缩放效果,在参数中指定缩放倍率。该语句使用scale方法使该元素在水平方向上缩小了20%,垂直方向上不缩放。

平移

translate(50px,50px);
使用translate方法来将文字或图像在水平方向和垂直方向上分别垂直移动50像素。

扭曲

transform:skew(30deg,0deg);
该实例通过skew方法把元素水平方向上倾斜30度,处置方向保持不变。

指定变形基点

在使用transform方法进行文字或图像的变形时,是以元素的中心点为基准点进行的。使用transform-orign属性,可以改变变形的基准点。
transorm-origin:left bottom;
left和bottom是基准点在元素水平方向和垂直方向上的位置。

形成过渡动画

元素在定义了变化终点状态之后,在元素本身设置transition即可形成过渡动画。

Animation动画

animation属性值:

属性 说明
@keyframes 定义动画名称
animation 所有动画属性的简写属性,除了animation-play-state属性。
animation-name 规定 @keyframes 动画的名称。
animation-duration 规定动画完成一个周期所花费的时间。默认是0s。
animation-timing-function 规定动画的速度曲线。默认是 “ease”。
animation 规定动画何时开始。默认是0s。
animation-iteration-count 规定动画被播放的次数。默认是1。
animation-direction 规定动画是否在下一周期逆向地播放。默认是 “normal” 。逆向alternate
animation-play-state 规定动画是否正在运行或暂停。默认是 “running”,暂停时pause
animation-fill-mode 规定对象动画时间之外的状态。forwards:设置对象状态为动画结束时的状态;backwards:设置对象状态为动画开始时的状态;both:设置对象状态为动画开始或结束的状态

两者区别

1、变换动画不能自行触发,通过hover等动作或结合JS进行触发。anmiation可以自行运行。
2、变换动画可控性较弱,只能指定起始状态和结束状态,而animation可以定义多个关键帧。
3、变换动画在运行结束之后,需要回到初始状态
4、变换动画的作用在于平滑的改变CSS样式
5、animation多两个参数,循环和动画的方式。

HTML5新增input类型

发表于 2016-06-16   |   分类于 前端

HTML5表单新增input类型

在HTML4等早期版本中,input元素已经有了一些type类型,type可取的值有下面这些:
text文本类型:<input type="text"/>
password密码类型:<input type="password"/>
radio 单选类型:<input type="radio"/>选项
checkbox 多选类型:<input type="checkbox"/>选项
file 文件类型:<input type="file"/>
submit 提交按钮:<input type="submit"value="提交"/>
reset重置按钮:<input type="reset"value=重置"/>
button定义按钮:<input type="button"value="按钮1"/>
image 定义图片按钮:<input type="image"src=".."/>
hidden定义隐藏域:<input type="hidden"/>

在HTML5中,input元素新增了一些类型,有email邮件类型、number数字类型、range数字滑动条、url地址类型、date日期类型及search搜索类型。下面我们来逐个介绍一下它们。

email邮件类型

跟文本框类似,但它只接受符合email邮件格式的字符串,当表单提交时会自动检测,若不合法,则会给出提示。
html代码如下:

<input type="email" name="" value="">

number数字类型

跟文本框类似,它只接受数字类型的值,表单提交时会自动检测,若不合法,则会给出提示。
html代码如下:

<input type="number" name="" value="">

range数字滑动条

它展现出来是一个可以拖拉的滑动条,包含一定的数字范围,如:

<input type="range" min="1" max="10">

当拖动滑动块时,它的value值会在1到10之间变化。

url地址类型

跟文本框类似,它只接受网址类型的值,表单提交时会自动检测,若不合法,则会给出提示。
html代码如下:

<input type="url">

date日期类型

当此类表单成为焦点时,会自动弹出日历或者是调节按钮,但其样式会由于浏览器内核的不同而不同,此类型有一系列的只可选:
date:选取日、月、年
month:选取月、年
week:选取周、年
time:选取时间(小时和分钟)
datetime:选取时间、日、月、年,为UTC时间
datetime-local:选取时间、日、月、年,为本地时间
html代码如下:

<input type="date">

其它的只需更改type值就可以了,就不一一列举了。

search搜索类型

跟文本框类似,它可以接受任意的值作为关键字,我们可以通过value获取这些关键字。
html代码如下:

<input type="search">

移动端自适应布局解决方案——rem

发表于 2016-06-16

自适应布局方案有百分比布局、flex布局、弹性flex布局等,但是都有一些缺点。

  • 百分比布局缺点:字体大小需要另外一套自适应方法来调整;当屏幕宽度大于700px后,继续按照百分比元素会偏大,这个时候调整起来会比较麻烦。

  • flex布局、弹性flex布局:在移动端会出现一些支持的兼容问题。

rem

W3C官网描述是“font size of the root element”,即rem是相对于根元素。
我们只需要在HTML根元素确定一个参考值,css中其他使用rem作为单位的值都基于这个值进行计算。

rem实现宽度自适应的原理

通过JS使页面的fontsize会根据屏幕的宽度自动调整。
具体是根据屏幕宽度和所设字体大小的比值是固定的,获取屏幕宽度后,按照固定比例缩小后作为rem的单位长度实现自适应。

另外值得说的是即使采用了rem布局方案,页面上不一定所有的元素都是采用rem作为单位。,比如下面淘宝的案例。底部固定的导航条采用的是高度使用固定的像素值,宽度flex布局的方案。
淘宝案例

1
2
3
4
5
6
7
8
9
10
11
12
13
footer{
height:114px;
/*这三个样式需要补充prefix*/
/*通过一起使用box-align和box-pack属性,对div框的子元素进行居中*/
display:flex;
box-pack: justify;
box-align: center;
justify-content: space-between; //在flex容器内的各项没有占用主轴所有可用的空间时,元素的各项周围留有空白
align-content: center; //在flex容器内的各项没有占用纵轴上所有可用的空间时,元素居中对齐
}

代码详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if(clientWidth>=640){
docEl.style.fontSize = '100px';
}else{
docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

代码解释:
如果页面的宽度超过了640px,那么页面中html的font-size恒为100px,否则,页面中html的font-size的大小为: 100 * (当前页面宽度 / 640)

为什么是640px?

三个概念:屏幕分辨率、设备像素、css像素
屏幕分辨率和设备像素是物理概念,而CSS像素是WEB编程的概念;屏幕分辨率和设备像素的差别在于设备像素显示密度。
当设备屏幕分辨率=100%的时候,浏览器CSS像素尺寸和设备像素相等,而当像素密度(pixel density)为1的时候,屏幕分辨率和设备像素相等。

对于手机屏幕来说,640px的页面宽度是一个安全的最大宽度,保证了移动端页面两边不会留白。注意这里的px是css逻辑像素,与设备的物理像素是有区别的。如iPhone 5使用的是Retina视网膜屏幕,使用2px x 2px的 device pixel 代表 1px x 1px 的 css pixel,所以设备像素数为640 x 1136px,而它的CSS逻辑像素数为320 x 568px。

为什么要设置html的font-size?

rem就是根元素(即:html)的字体大小。html中的所有标签样式凡是涉及到尺寸的(如: height,width,padding,margin,font-size。甚至,left,top等)你都可以放心大胆的用rem作单位。
如果你把html的font-size设为20px,前面说过,rem就是html的字体大小,那么1rem = 20px。

浏览器一般都有最小字体限制,比如谷歌浏览器,最小中文字体就是12px,所以实际上没有办法让1rem=1px

根据上面的js代码,如果页面宽度低于640px,那么页面中html的font-size也会按照(当前页面宽度/640)的比例变化。这样,页面中凡是应用了rem的作尺寸单位的元素都会随着页面变化而等比例缩放了。

怎么计算出不同分辨率下font-size的值?

假设页面设计稿是按照640的标准尺寸设计的,(当然这个尺寸肯定不一定是640,可以是320,或者480,又或是375)来看一组表格。
rem

以640的宽度去切的,怎么计算不同宽度下font-site的值,大家看表格上面的数值变化应该能明白。举个例子:384/640 = 0.6,384是640的0.6倍,所以384页面宽度下的font-size也等于它的0.6倍,这时384的font-size就等于12px。在不同设备的宽度计算方式以此类推。

除了上面通过JS去动态计算根元素的font-size,也可采用媒体查询。一般我们在做web app都会先统计自己网站有哪些主流的屏幕设备,然后去针对那些设备去做media query设置也可以实现适配,例如下面这样(参考):

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
html{
font-size:10px
}
@media screen and (min-width:321px) and (max-width:375px){
html{
font-size:11px
}
}
@media screen and (min-width:376px) and (max-width:414px){
html{
font-size:12px
}
}
@media screen and (min-width:415px) and (max-width:639px){
html{
font-size:15px
}
}
@media screen and (min-width:640px) and (max-width:719px){
html{
font-size:20px
}
}
@media screen and (min-width:720px) and (max-width:749px){
html{
font-size:22.5px
}
}
@media screen and (min-width:750px) and (max-width:799px){
html{
font-size:23.5px
}
}
@media screen and (min-width:800px){
html{
font-size:25px
}
}

使用媒体查询的缺点是不能所有设备全适配,但是用JS是可以实现全适配。具体使用上根据需求来定。

IcoMoon将图标转换成web字体

发表于 2016-06-16   |   分类于 前端

本文总结一款免费开源的Web应用程序IcoMoon制作web图标字体。

使用web字体图标优势

适用性:一个图标字体比一系列的图像(特别是在Retina屏中使用双倍大小的图像)要小。一旦图标字体加载了,你的图标就会马上渲染出来,不需要下载一个图像。

可扩展性:图标字体可以用过font-size属性设置其任何大小。这使您能够随时输出不同大小的图标,然而,使用位图,你必须得为每个不同大小的图像输出一个不同文件。

灵活性:文字效果可以很容易地应用到你的图标上,包括颜色,阴影和翻转等效果。他们还可以在任何背景下显示。

兼容性:网页字体支持所有现代浏览器,包括IE低版本。详细兼容性可以点击这里。

IconMoon优势

提供完整图标解决方案:
600+字符,您可以根据自己需求定制(如就选两个);可以导入其他字体,也进行特别定制(类似fontforge功能);定制字体提供打包导出功能(省去了字体转换),兼容IE6+,现代浏览器以及各类手机设备,且有demo实例,并对字符进行了HTML转化。

IconMoon使用方法

导入或选择图标、对图标进行编辑、生成并输出成zip文件(含字体本身、HTML实例页面和相应的CSS)

导入或选择图标

选择内置图标只需在界面单击相应图标,图标高亮即为选中。
选择
如果你通过AI做好了一个图标想导入,只需点击“Imorticons”按钮,然后选择您想要添加的SVG文件——您也可以一次添加多个文件。这些图标将会出现在“Your Custom Icons”区域中。如果他们是高亮的黄色显示,表示这些图标是你将要创建的图标字体。

对图标进行编辑

编辑
如果你想调整图标的位置、大小或旋转,你可以点击“Edit”按钮。可以使用“Save Copy”按钮来创建图片的变化(例如,一个镜像的衅标)。添加一个有意义的图标标记,因为这将被用来生成类名。

生成并输出成zip文件

点击屏幕底部的“Font”按钮开始生成字体。这样你就可以指定哪个图标映射到哪个字符上,例如,如果你要设置一套六个旋转的球,你可以每 这六个球分别指定字符:q、w、e、r、t和y。你也可以根据你自己的爱好选择一个字体的名字。
输出
单击“Download”下载字体包到你的电脑上。他有一个字文件夹包含了字体本身(woff,eot,ttf格式),以及一个HTML示例页面和相应的CSS。甚至还有一个javascript文件和一个解决方法,如果你需要支持IE或IE7。

如何使用这些图标字体

@font-face引入字体库、调用图标字体

@font-face引入字体库

语法:

1
2
3
4
5
6
@font-face {
font-family: <YourWebFontName>;
src: <source> [<format>][,<source> [<format>]]*;
[font-weight: <weight>];
[font-style: <style>];
}

兼容多种浏览器示例;如果只需兼容现代浏览器,可以按需删除src一些代码。

1
2
3
4
5
6
7
8
9
10
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?1h4iu7'); /* IE9 Compat Modes */
src: url('fonts/icomoon.eot?1h4iu7#iefix') format('embedded-opentype'),/* IE6-IE8 */
url('fonts/icomoon.ttf?1h4iu7') format('truetype'), /* Modern Browsers */
url('fonts/icomoon.woff?1h4iu7') format('woff'), /* Safari, Android, iOS */
url('fonts/icomoon.svg?1h4iu7#icomoon') format('svg'); /* Legacy iOS */
font-weight: normal;
font-style: normal;
}

调用图标字体

通过css属性选择器指定类为”icon-“开头的元素的font-family,并为icon-创建的图标类名定义content。与fontAwesome图标字体使用方法是相同的
css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[class^="icon-"], [class*=" icon-"] {
/* 使用!important 使样式获得最高优先级 */
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* 使字体变得平滑 =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-home:before {
content: "\e900";
}
.icon-office:before {
content: "\e904";
}

然后html中定义类名调用即可:

1
<span class="icon-home"></span>

最简单的方法就是将文件夹中的style.css样式文件粘贴到自己项目中的样式表即可。

JavaScript获取DOM尺寸大小和元素位置

发表于 2016-06-15

JavaScript处理一些DOM元素的动态效果经常需要一些元素的尺寸大小和位置。body节点主要用于获取页面宽高和滚动条的滚动距离,以下出现body节点可以替换为其他DOM元素表示在该元素下获取或设置这些属性。作为HTML元素,都具有下列属性:
大小、位置属性
这些属性的笼统特征:
client:元素内容+内边距 大小,不包括边框、外边距、滚动条部分
offset:元素内容+内边距+边框 不包括外边距和滚动条部分
scroll:与元素的滚动相关

尺寸大小

一张网页的全部面积,就是它的大小。通常情况下,网页的大小由内容和CSS样式表决定。
视口是指在浏览器窗口中看到的那部分网页面积。

获取网页的大小(都不包括外边距、滚动条)

宽(值随窗口大小发生改变): document.body.clientWidth(不包括border,只包括内容+padding)
或者 document.body.offsetWidth(包括border)
或者 document.body.scrollWidth
高(值固定): document.body.clientHeigth(不包括border,只包括内容+padding)
或者 document.body.offsetHeight(包括border)
或者 document.body.scrollHeight
说明:通常使用document.body.scrollWidth和document.body.scrollHeight

获取屏幕相关属性

使用window.screen对象的属性。这些属性有个特点,不会随着窗口的伸缩而改变数值
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth=屏幕分辨率的宽

获取视口大小

在声明了DOCTYPE的浏览器中:
document.documentElement.clientWidth
document.documentElement.clientHeight
说明:IE,FF,Safari皆支持该方法,opera虽支持该属性,但是返回的是页面尺寸
除了IE7及以下版本的所有浏览器都将此信息保存在window对象中
window.innerWidth
window.innerHeight
说明:包含滚动条
IE7及以下版本方获取视口方法
document.body.offsetWidth
document.body.offsetHeight

元素位置

绝对位置

绝对位置:网页元素的绝对位置,指该元素的左上角相对于整张网页左上角的坐标。这个绝对位置要通过计算才能得到。
获取绝对高度: DOMElement.offsetTop
获取绝对宽度:DOMElement.offsetLeft

相对位置

相对位置:网页元素的相对位置,指该元素左上角相对于浏览器窗口左上角的坐标。

由此有:元素绝对位置坐标=元素相对位置坐标+滚动条滚动的距离
要知道元素的相对位置就要知道滚动条滚动的距离,那么滚动条的滚动距离怎么获取呢?

获取滚动条的滚动距离

竖:document.body.scrollTop 或window.scrollY
横:document.body.scrollLeft 或window.scrollX

窗口相对于屏幕的位置

窗口相对于屏幕的X坐标:window.screenLeft(通常为0)
窗口相对于屏幕的Y坐标:window.screenTop

jQuery如何获取

使用原生的js方法获取DOM尺寸大小和元素位置仍然不太方便,比如兼容性,jQuery封装的函数就很好的解决了这个问题。

时下页面大小

当窗口大小改变,宽度值改变,高度值固定

1
2
$(document).width() //浏览器时下窗口文档的宽度
$(document).height() //浏览器时下窗口文档的高度

时下元素大小

当窗口大小改变,宽度值改变,高度值固定
以下以body节点为例,可替换成DOM元素调用方法

1
2
3
4
$(document.body).width()      //浏览器时下窗口文档body的宽度
$(document.body).height()      //浏览器时下窗口文档body的高度
$(document.body).outerWidth(true)  //浏览器时下窗口文档body的总宽度(包括padding、border)
$(document.body).outerHeight(true) //浏览器时下窗口文档body的总高度(包括padding、border)

时下可视区大小

当窗口大小改变,宽度、高度皆改变

1
2
$(window).height()  //浏览器时下窗口可视区域高度
$(window).width()   //浏览器时下窗口可视区域宽度

1234
TeaCoder

TeaCoder

写精致代码,过简单生活

36 日志
6 分类
35 标签
RSS
掘金 GitHub 知乎
© 2015 - 2021 TeaCoder