♌

Mr. Leo


  • 首页

  • 分类26

  • 标签142

  • 归档138

  • 关于

  • 搜索

通过Chrome调试运行在IOS-safari上的页面

发表于 2017-02-15 | 分类于 前端 , 调试 | 评论数: 0 | 阅读次数:

本文重点讨论如何在 Windows 系统中通过 chrome 浏览器调试运行在 iPhone Safari 浏览器中的网页。如果你有一台 iMac/MacBook,可忽略该文档。iMac 环境下,直接通过 USB 将 iphone 与 iMac/MacBook 链接,之后在 iMac/MacBook 中打开 Safari 进入调试模式,即可对运行在手机中的页面进行调试。详情见:Using Web Inspector to Debug Mobile Safari 或 Safari Web Inspector Guide

阅读全文 »

继承

发表于 2017-02-14 | 更新于 2017-09-12 | 分类于 前端 , javascript | 评论数: 0 | 阅读次数:
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
//region A
function A(a){
this.a=a
console.log(this.a)
}

A.prototype.AShow=function(){
console.log(this.a+':show')
}
//endregion

//region B
function B(a,b){
A.call(this,a)
this.b='b'
console.log(this.b)
}

// Object.setPrototypeOf( B.prototype, A.prototype )// ES6+,B继承A,修改既存的`B.prototype`

B.prototype=Object.create(A.prototype)// ES5,B继承A,扔掉默认既存的`B.prototype`
Object.defineProperty(B.prototype,'constructor',{// ES5,修复B继承A后丢失的.constructor
enumerable:false,
writable:true,
configurable:true,
value:B// 使‘.constructor’指向‘B’
})

B.prototype.BShow=function(){
console.log(this.b+':show')
}

var b = new B('a','b')
b.AShow()
b.BShow()
//endregion

重要的部分是B.prototype=Object.create(A.prototype)。Object.create(..)凭空 创建 了一个“新”对象,并将这个新对象内部的[[Prototype]]链接到你指定的对象上(在这里是A.prototype)。

换句话说,这一行的意思是:“做一个 新的 链接到 ‘A.prototype’ 的 ‘B.prototype’ 对象”。

“(原型)继承”

类继承

1
2
3
4
5
6
7
8
9
10
11
12
unction SuperClass(){
this.superValue = true;
}
SuperClass.prototype.getSuperValue = function(){return this.superValue;}

function SubClass(){
this.subValue = true;
}
SubClass.prototype = new SuperClass()//继承父类
SubClass.prototype.getSubValue = function(){return this.subValue;}

//console.log(SubClass.prototype instanceof SuperClass)//=>true

构造函数继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function SuperClass(value){
this.superValue = value;
}
SuperClass.prototype.getSuperValue = function(){return this.superValue;}

function SubClass(value){
SuperClass.call(this, value);//继承父类
this.subValue = value;
}
SubClass.prototype.getSubValue = function(){return this.subValue;}

// var instance = new SubClass(10);
// console.log(instance.superValue);//=>10
// console.log(instance.getSubValue());//=>10
// console.log(instance.getSuperValue());//=>'TypeError'

组合继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function SuperClass(value){
this.superValue = value;
}
SuperClass.prototype.getSuperValue = function(){return this.superValue;}

function SubClass(value){
SuperClass.call(this, value);//构造函数继承父类的 superValue
this.subValue = value;
}
SubClass.prototype = new SuperClass();//类继承父类原型 getSuperValue
SubClass.prototype.getSubValue = function(){return this.subValue;}

// var instance = new SubClass(10);
// console.log(instance.superValue);//=>10
// console.log(instance.getSubValue());//=>10
// console.log(instance.getSuperValue());//=>10

原型继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function inheriteObject(o){
//声明过渡函数对象
function F(){}
//过渡函数对象的原型继承父对象
F.prototype = o;
//返回过渡对象的一个实例,这个实例继承了父对象
return new F();
}

// var superObject = {
// name: 'books',
// books:['css','javascript']
// }
// var newSubObject = inheriteObject(superObject);
// console.log(newSubObject.name);//=>'books'
// newSubObject.books.push('html');
// console.log(newSubObject.books);//=>['css','javascript','html']

寄生式继承

1
2
3
4
5
6
7
8
9
10
11
var superObject = {
name: 'books',
books:['css','javascript']
}
function creatBook(obj){
var o = inheriteObject(obj);
o.getBooks = function(){
console.log(name)
}
return o;
}

寄生组合式继承

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

/**
* 寄生组合式继承
* @param subClass 子类
* @param superClass 父类
*/
function inheritePrototype(subClass,superClass){
//复制父类的原型
var p = inheriteObject(superClass.prototype);
//修正因为重写父类原型导致子类 constructor 属性被修改
p.constructor = subClass;
//设置子类的原型
subClass.prototype = p;
}

// //定义父类
// function SuperClass(value){
// this.superValue = value;//父类属性
// }
// //定义父类原型方法
// SuperClass.prototype.getSuperValue = function(){
// console.log(this.superValue);
// }
// //定义子类
// function SubClass(value){
// SuperClass.call(this, value);//构造函数继承
// this.subValue = value;//子类属性
// }
// inheritePrototype(SubClass, SuperClass);//寄生式继承父类原型
// //子类增加原型方法
// SubClass.prototype.getSubValue = function(){
// console.log(this.subValue);
// }
// var instance = new SubClass(10);
// console.log(instance.superValue);//=>10
// console.log(instance.subValue);//=>10
// instance.getSuperValue();//=>10
// instance.getSubValue();//=>10

javascript设计模式

发表于 2017-01-23 | 分类于 前端 , javascript | 评论数: 0 | 阅读次数:

本文参考于《javascript模式》,因此会大量内容会和书中相同,手上有这本书的朋友可以直接看书。因为我的记忆习惯是抄书,所以我会先抄写下来再发到博客上。

阅读全文 »

用hexo搭建自己的私人博客

发表于 2017-01-11 | 分类于 建站 | 评论数: 0 | 阅读次数:

这不是一篇 Hexo 教程,仅是本博的搭建记录。

阅读全文 »

图片压缩上传

发表于 2017-01-10 | 分类于 前端 , javascript | 评论数: 0 | 阅读次数:
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

/**
* @Date: 2016/11/17 0017
* @Time: 10:14
* @Author: lxbin
*
* Created with JetBrains WebStorm.
*/

/**
* https://leonshi.com/2015/10/31/html5-canvas-image-compress-crop/
* https://jafeney.com/2016/08/11/20160811-image-upload/
* https://ilovetile.com/3506
*/

/**
* 读取文件
* @param file 文件对象
* @return {Promise}
*/
function readFileAsync(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = e => resolve(readFile.target.result)
reader.onerror = e => reject(new Error('Could not read file'))
reader.readAsDataURL(file)
})
}

/**
* 加载图片
* @param url 图片地址
* @return {Promise}
*/
function loadImageAsync(url) {
return new Promise((resolve, reject) => {
const image = new Image()
image.onload = () => resolve(image)
image.onerror = () => reject(new Error('Could not load image at ' + url))
image.src = url
})
}

/**
* base64的图片dataUri转Blob
* @param dataURI
* @return {*}
*/
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
const byteString = atob(dataURI.split(',')[1]);

// separate out the mime component
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

// write the bytes of the string to an ArrayBuffer
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}

// write the ArrayBuffer to a blob, and you're done
return new Blob([ab], {type: mimeString});

// Old code
// const bb = new BlobBuilder();
// bb.append(ab);
// return bb.getBlob(mimeString);
}

/**
* 图片转Blob
* @param image 图片对象
* @param quality 图片质量(0到1之间)
* @param scale 缩放比例(0到1之间)
* @return {Promise}
*/
function imageToBlob(image, quality, scale) {
return new Promise((resolve, reject) => {
try {
let canvas = document.createElement('canvas')
canvas.width = image.naturalWidth * scale
canvas.height = image.naturalHeight * scale
while (canvas.width >= 3264 || canvas.height >= 2448) {//超过这个值base64无法生成,在IOS上
canvas.width = canvas.naturalWidth * scale
canvas.height = canvas.naturalHeight * scale
}

let ctx = canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height)

//方式一:低版本兼容性差些
//canvas.toBlob(function (blob) {
// console.group('[Leo]file compress to blob')
// console.log('文件类型 => ' + image.type)
// console.log('文件大小 => ' + (image.size / 1024 / 1024).toFixed(2) + 'M')
// console.log('blob质量 => ' + quality)
// console.log('blob大小 => ' + (blob.size / 1024 / 1024).toFixed(2) + 'M')
// console.groupEnd()
// resolve(blob)
//}, 'image/jpeg', quality)

//方式二:
const base64 = canvas.toDataURL('image/jpeg', quality);
const blob = dataURItoBlob(base64);
blob.name = blob.filename = image.name
console.group('[Leo]image compress to blob')
console.log('文件类型 => ' + image.type)
console.log('文件大小 => ' + (image.size / 1024 / 1024).toFixed(2) + 'M')
console.log('blob质量 => ' + quality)
console.log('blob大小 => ' + (blob.size / 1024 / 1024).toFixed(2) + 'M')
console.groupEnd()
resolve(blob);
} catch (e) {
reject(new Error("Image could not convert to blob :" + e))
}
})
}

/**
* Ajax上传
* @param uri 上传的Action地址
* @param file 文件对象
* @return {Promise}
*/
function uploadFile(uri, file) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
if (xhr.upload) {
xhr.upload.addEventListener("progress", (e) => {// 处理上传进度
if (e.lengthComputable) {
let percent = (e.loaded / e.total * 100).toFixed(2) + '%'
console.log("上传中(" + percent + ")");
//TODO:反馈到DOM里显示
} else {
console.log('unable to compute');
}
}, false)
}
xhr.onreadystatechange = (e) => {// 文件上传成功或是失败
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText)// 上传成功
} else {
reject(xhr.responseText)// 上传出错处理
}
}
}
xhr.open("POST", uri, true)// 开始上传
let form = new FormData()
form.append("filedata", file, file.name)
xhr.send(form)
})
}

/**
* 上传文件
* @param file 文件对象
* @param quality 图片质量(0到1之间)
* @param scale 缩放比例(0到1之间)
*/
export default async function fileUpload(file, quality, scale) {
try {
let fileUrl = await readFileAsync(file)
let image = await loadImageAsync(fileUrl)
image.name = file.name
let blob = await imageToBlob(image, quality, scale)
let upload = await uploadFile(blob)
return upload
} catch (e) {
console.log('file upload failed')
}
}

参考:
https://leonshi.com/2015/10/31/html5-canvas-image-compress-crop/
https://jafeney.com/2016/08/11/20160811-image-upload/
https://ilovetile.com/3506

vue学习

发表于 2017-01-08 | 分类于 前端 , vue | 评论数: 0 | 阅读次数:

我的 Demo

  • Vue-IM
  • vue2.0 demo
  • Vue-视频
阅读全文 »

vue错误搜集

发表于 2017-01-08 | 分类于 前端 , vue | 评论数: 0 | 阅读次数:

#把业务逻辑拆分到独立的 JS 文件中时,import 语句会出现错误
需要在.babelrc 文件中增加如下配置:”passPerPreset”: true。

1
2
3
4
5
6
{
"passPerPreset": true,
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"],
"comments": false
}
阅读全文 »

到底用prop还是事件

发表于 2017-01-08 | 更新于 2021-05-12 | 分类于 前端 , vue | 评论数: 0 | 阅读次数:

组件之间数据交互,主要有prop和事件两种。

阅读全文 »
1…101112…18
Leo

Leo

😆
138 日志
26 分类
142 标签
RSS
QQ 微博 E-Mail GitHub 我的主页
Creative Commons
友情链接
  • ZM
  • july
0%
© 2016 – 2021 Leo
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Gemini v7.0.1
|