记最新几个新的小知识点

记录下最近零零散散学的几个知识点。


图片显示方式

有的时候看到网络上有些图示由模糊变清晰,有些是一直清晰,但是会逐行显示(慢慢的展示全), 是什么因素导致了他们的显示方式?

实际是图片在压缩的时候算法决定了它的显示方式。比如:
小波算法:先模糊然后清晰
离散余弦变换:清晰,逐行显示

前端可以准备多种样子或者分辨率的图片,当网络好或者网络不好,再或者不同的屏幕分辨率的图片。现在出来了一种新的方式:

HTML <picture>元素是一个容器,用来为其内部特定的 <img>元素提供多样的 <source> 元素。浏览器会根据当前页面(即图片所在的盒子的容器)的布局以及当前浏览的设备(比如普通的屏幕和高清屏幕)去从中选择最合适的资源。

1
2
3
4
5
<picture>
<source srcset="smaller.png" media="(max-width:700px)"></source>
<source srcset="bigger.png" media="(max-width:1000px)"></source>
<img srcset="default.png" alt="美女">
</picture>

当然并不是每个浏览器都支持,在实验中。


图片分类

  1. jpg,jpeg,以24位颜色存储单个位图,可压缩
  2. png,可做透明图片,体积较大,需要清晰的显示颜色丰富的图片时用
  3. gif,全透/全不透,不支持半透明
  4. svg,矢量图,地图中用的多,体积小

注意有的时候只把 尾缀比如.jpg更改为.png 不行,因为只是名称改了,实际上它本质没有更改。需要用工具转换。


播放器形式

【video播放器】
优点:不需要下载额外资源(如:flash播放器需要下载.swf辅助插件),控制简单有较为完整的api。
缺点:每个浏览器的外观都不一样,如果要统一需要自己写ui实现。

【flash播放器】
flash 播放器,兼容性比较好,只需要下载 flash player 即可使用。
缺点是必须要下载额外的 swf 才可以。

视频的外部资源可使用 link 加载样式,这样可以被提前加载。让视频先运行。这是个小 hack。


缓存

页面刷新的时候 sessionStorage (标准浏览器) 是仍然存在的,只有关闭的时候才不存在。同一个浏览器,不同的标签,也是不共享的。

userData 是 IE 的先驱者。

cookie 所有浏览器基本都支持,大小限制不同浏览器也不同,会把数据带给服务器。

openDataBase 是类似于本地数据库这种形式。可以做的东西更多。

localStorage 的缺点是 IE9, IE10 不支持, 注意下 safari 读不到 chrome 的 localStorage。

localStorage 不能跨域,所以存储的时候是在 localStorage 下,按照域名存放的。


造成页面卡死的原因

如果页面突然一直 loading 或者 卡死,可能有以下一些原因。

  1. 死循环 (while 1 了 ?)
  2. 大文件占用资源 loading
  3. 频繁的读写本地资源

页面的重绘和回流

回流一定触发重绘,但是重绘不一定触发回流。
DOM元素的添加、修改(内容)、删除(Reflow+Repaint)
仅修改DOM元素的字体颜色(只有Repaint、因为不需要调整布局)

如何判断是否重绘了呢?

1
chrome 开发者工具 =>  settings ,more tools, rendering, Paint flashing即可, 看到绿色的部分即为发生了重绘的部分

触发重绘可能有的情况:
1、改变字体
2、增加或移除样式表
3、内容变化,如用户在input框输入文字
4、激活css伪类,如:hover
5、脚本操作DOM
6、计算可见的宽高属性
7、设置style属性的值


git 常用命令总结

我总结了已经好多次了,有些命令一段时间不用又会忘记。好记性不如烂笔头。

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
git log --pretty=oneline
git log --graph

git reset --hard HEAD^
git reset --hard 版本(可省略写)

// add 后放弃
git checkout -- file

// add -> commit 后放弃
git reset HEAD file
git checkout --file

git remote add origin git@server-name:path/repo-name.git
git push -u origin master

git checkout -b dev
等同于
git branch dev
git checkout dev

git branch -d/-D dev

git stash apply 恢复
git stash drop 恢复后删除 stash
git stash pop = git stash apply + git stash drop

git stash list

git branch --set-upstream dev origin/dev

git tag name 打标签
git tag 显示所有 tag
git tag -d v0.1 删除某个tag
git push origin v1.0 推送某个标签
git push origin --tags 一次推送所有 tag

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

rebase merge 的使用法则。

In general the way to get the best of both worlds is to rebase local changes you’ve made but haven’t shared yet before you push them in order to clean up your story, but never rebase anything you’ve pushed somewhere


学习一段代码

这是最近在慕课上看到的一段代码,没事没事看看别人的代码还是有点收获的,比较下自己觉得好的和自己觉得别人可能有所需要改进的。下面这些代码是一位老师写的,大概就是根据版本号来判断资源是不是需要缓存,如果版本号更新了,就去重新拉取资源,并且更新本地缓存。如果版本号没有更新,就直接用本地的缓存。

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
window.Xhrfactory = function() {
this.init.apply(this, arguments);
};

window.Xhrfactory.prototype = {
init: function() {
this.xhr = this.create();
},
create: function() {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXobject) {
xhr = new ActiveXobject('Msml2.Xmlhttp');
} else {
xhr = new ActiveXobject('Microsoft.Xmlhttp');
}
return xhr;
},
readystate: function(callback) {
this.xhr.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
callback(this.responseText);
console.log(this);
}
}
},
para: function(data) {
var datastr = '';
if (data && Object.prototype.toString.call(data) === "[object object]") {
for (var i in data) {
for (var i = 0; i < lenght; i++) {
datastr += i + '='
data[i] + '&';
}
}
}
},

get: function(url, data, callback) {

this.readystate(callback);
var newurl = url;
var datastr = this.para(data);
newurl = url + '?' + datastr;
this.xhr.open('get', newurl, true);
this.xhr.send(null);

}
};

// 后台程序的模板变量
var localStorageSign = 'on';
// 版本控制
var resourceVersion = '12312443243202';

// 本地的Sdk主方法
window.mLocalSdk = {

resourceJavascriptList: [{
id: '1232131241',
url: '/dest/js/lib/core.js',
type: 'javascript'
}, {
id: '1232131242',
url: '/dest/js/lib/log.js',
type: 'javascript'
}, {
id: '1232131243',
url: '/dest/js/lib/report.js',
type: 'javascript'
}],

needUpdate: (function() {
return localStorage.getItem('resourceVersion') === resourceVersion;
})(),


isIE: (function() {
var v = 3;
var div = document.createElement('div');
var all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!-- [if gt IE' + (++v) + ']><i></i><![endif] -->', !all[0])
{
if(v > 11){return false}
}
return v > 3 ? v : false;
})(),


checkHedge: function() {
var localStorageLength = localStorage.length;
var localStorageSize = 0;
for (var i = 0; i < localStorageLength; i++) {
var key = localStorage.key(i);
localStorageSize += localStorage.getItem(key).length;
}
return localStorageSize;
},
saveSdk: function() {
try {
localStorage.setItem('resourceVersion', resourceVersion);
} catch (oException) {
if (oException.name == 'QuotaExceededError') {
localStorage.clear();
localStorage.setItem('resourceVersion', resourceVersion);
}
alert('QuotaExceededError');
}

for (var i = 0; i < this.resourceJavascriptList.length; i++) {
_self = this;
(function(i){
var scriptId = _self.resourceJavascriptList[i]['id'];
var xhr = new Xhrfactory();
xhr.get(_self.resourceJavascriptList[i]['url'], null, function(data) {
try {
localStorage.setItem(scriptId, data);
} catch (oException) {
console.log('oException',oException);
if (oException.name == 'QuotaExceededError') {
localStorage.clear();
localStorage.setItem(scriptId, data);
}
}
});
})(i);
// XXX addhtml 加载到页面
}
},

startup: function() {
// 满足一下条件
var _self = this;
if (localStorageSign === 'on' && !this.isIE && window.localStorage) {

if (this.needUpdate === true) {
//不需要更新
return (function() {

for (var i = 0; i < _self.resourceJavascriptList.length; i++) {
// 获取本地缓存列表 输入到html上
var scriptId = _self.resourceJavascriptList[i]['id'];
// 把我们的列表中的js文件 渲染到页面

// 去读取本地文件
window.mDomUtils.addJavascriptByInline(scriptId);
}
})();

} else {
// 保存我们请求到的js文件
return (function() {
_self.saveSdk();
for (var i = 0; i < _self.resourceJavascriptList.length; i++) {
// 获取本地缓存列表 输入到html上
var scriptId = _self.resourceJavascriptList[i]['id'];
// 把我们的 列表中的js文件 渲染到页面

// 去读取本地文件
window.mDomUtils.addJavascriptByInline(scriptId);
}
})();


//***
// 把从网络获取到的javascript 输入到html上;
// save localstroage
}
} else {

return function() {
alert(2);
for (var i = 0; i < resourceJavascriptList.length; i++) {
// 获取本地缓存列表 输入到html上
var scriptId = resourceJavascriptList[i]['scriptId'];
// 把我们的列表中的js文件 渲染到页面

// 读取网络上得到的资源
window.mDomUtils.addJavascriptByLink(scriptId, resourceJavascriptList[i]['url']);
}
}
//***
// 把从网络获取到的javascript 输入到html上;
// 原始方法加载javascriopt
}

}
// 写入本地localstorage


};

window.mDomUtils = {
// 内联方式添加javascript
addJavascriptByInline: function(scriptId) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.id = scriptId;
var heads = document.getElementsByTagName('head');
if (heads.lenght) {
heads[0].appendChild(script);
} else {
document.documentElement.appendChild(script);
}
script.innerHTML = localStorage.getItem(scriptId);
},


// 外链方式添加javascript
addJavascriptByLink: function(scriptId, url) {
var script = document.createElemet('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
script.id = scriptId;
var heads = document.getElementsByTagName('head');
if (heads.length) {
heads[0].appendChild(script);
} else {
document.documentElement.appendChild(script);
}
},


// 外链方式添加css

addCssByLink: function(url) {
var doc = document;
var link = doc.createElemet('link');
link.setAttribute('type', 'text/css');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', url);
var heads = doc.getElementsByTagName('head');
if (heads.length) {
heads[0].appendChild(link);
} else {
doc.documentElement.appendChild(link);
}
},

// 外链方式添加css

addCssByLink: function(cssString) {
var doc = document;
var link = doc.createElemet('link');
link.setAttribute('type', 'text/css');
link.setAttribute('rel', 'stylesheet');

if (link.stylesheet) {
// IE支持
link.stylesheet.cssText = cssString;
} else {
// w3c
var cssText = doc.createTextNode(cssString);
link.appendChild(cssText);
}

var heads = doc.getElementsByTagName('head');
if (heads.length) {
heads[0].appendChild(link);
} else {
doc.documentElement.appendChild(link);
}
}
};

觉得比较好的,一个是它判断 IE 的方法,利用了只有 IE 可以识别的特性。另外一个是它判断 localStorage 缓存的大小。

还有一个是它利用了自执行函数来去做其实只用去初始化一次的工作。比如判断本地的缓存是否是需要跟新(根据版本号),而不是做成一个函数每次去执行一次。

不好的就是,可能是因为现场写代码,随机想的,所以有些地方可以封装,都没有封装好。