JavaScript复习笔记
js复习笔记
js复习笔记,内容来源自廖雪峰JavaScript教程,w3school,菜鸟教程
一.快速入门
1.基本语法
1)js是一种直译式脚本语言
2)js结束语句后的;可以省略不写,原因是执行js时浏览器相关引擎会自动加上
3)js的数据类型有Number(js不分整数和浮点数),字符串,布尔值,数组,对象(键值对的一种无序集合)
var person = {name: 'Bob',age: 20,tags: ['js', 'web', 'mobile'],city: 'Beijing',hasCar: true,zipcode: null
};
//获取方式
person.name
4)strict模式——在这个模式下会强制用
var来声明变量,防止变量被自动声明为全局变量
5)js字符串——字符串的相关操作和其他语言差不多。符号``,可以来对字符串进行拼接
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);
#操作字符串相关方法:
- toUpperCase()把一个字符串全部变为大写
- toLowerCase()把一个字符串全部变为小写
- indexOf()会搜索指定字符串出现的位置
- substring()返回指定索引区间的子串
6)js数组——js的Array可以包含任意数据类型,真是强大,arr.length可以获取数组长度,当然js数组不建议直接修改arr的大小,确保索引不会报错。多维数组懂得都懂,利益相关。
- indexOf()来搜索一个指定元素的下标
- slice()来截取arr的部分元素,返回一个新的arr,属于不完全的深拷贝
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
- push()和pop(),跟数据结构的栈差不多,先进后出,push添加数据,pop返回数据
- unshift()在arr的头部添加元素,shift()在arr的第一个元素删掉
- sort()方法对arr排序(快排),Array的sort()方法默认把所有元素先转换为String再排序
- reserve()方法反转数组
- splice()方法可以从指定的索引开始删除若干个元素,然后也可以在该位置添加若干元素,开发时间轴记事本的删除功能就使用了splice()方法,很简便
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
- concat()方法可以实现数组拼接,返回的是一个新的arr
- join()方法是可以用指定的符号对数组进行拼接(若原数组元素不是字符串,则自动转为字符串,老牛逼了)
var arr=['a',1,2,3,4];
arr.join('+');//'a+1+2+3+4'
7)js对象——是一种无序的集合数据类型,它由若干键值对组成。
var xiaoming = {name: '小明',birth: 1990,school: 'No.1 Middle School',height: 1.70,weight: 65,score: null
};
访问属性用 . 来操作,如果属性名包含特殊字符,则需用’'包起来,访问则需要[‘xxx’]这样来访问
对象的添加和删除属性方法:
var xiaoming = {name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined
delete xiaoming['name']; // 删除name属性
xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错
通过in 判断某个对象是否有某一属性
,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的,而判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法
'name' in xiaoming;
xiaoming.hasOwnProperty('name');
8)条件,循环不记
9)Map和Set——js的对象的键必须是字符串,所以需要引入Map
Map:
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
Set:
- 通过add(key)方法可以添加元素到Set中
- 通过delete(key)方法可以删除元素
10)iterable类型(arr,map,set)可以用for … of循环遍历
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Arrayconsole.log(x);
}
for (var x of s) { // 遍历Setconsole.log(x);
}
for (var x of m) { // 遍历Mapconsole.log(x[0] + '=' + x[1]);
}
- 更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数.
var a = ['A', 'B', 'C'];
a.forEach(function (element) {console.log(element);
});
/*
A
B
C
*/
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (element) {console.log(element);
});
/*
x
y
z
*/
二.函数
1)函数定义如下:
function abs(x) {if (x >= 0) {return x;} else {return -x;}
}
其他不记
2)方法——给对象绑定一个函数,则称为这个对象的方法,其中一个大坑就是this指针。这里附上一个this指针的详解——click
- 检查 ’ . ’ 左边是谁调用 这个函数. 例如 xiaoming.age(); age函数里面有this, 然后 '. ’ 旁边是xiaoming , 那么this就是指向xiaoming了.这种叫做 Implicit Binding.
- 如果点旁边没有,那就检查有没有用到 bind, apply, call 这三种, 有的话就是调用此方法的对象. 这种叫做 explicit binding.
- 如果上面两个都没有就检查代码里面有没有用到new 这个keyword, 有的话那就是指向new旁边的函数对象. 这种叫做new binding
- 上面三个都没有, 检查是不是有arrow function, 有arrow function的话就是, 那么指向是arrow function的lexical binding 的对象. 就是她的parent. 这种叫做 lexical binding
- 全部都没有如果不是strict mode那就是window对象了… strict就是 error (undefined).
3)高阶函数——一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数
function add(x,y,f){return f(x)+f(y);
}
var x=add(-5,6,Math.abs);
console.log(x);//11
- map/reduce
- filter
- sort
- Array
4)闭包——以函数作为返回值实现函数外部访问私有变量的,从而延迟函数的使用(函数套函数,外层函数传回里程函数,里程函数运行才能实现函数操作)
闭包功能:
- 延迟函数使用——副作用:外层变量为定值
- 实现类中私有变量的功能
5)箭头函数——箭头函数相当于匿名函数,并且简化了函数定义。
//1
x => x * x
//2
x => {if (x > 0) {return x * x;}else {return - x * x;}
}
箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。
箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj
var obj = {birth: 1990,getAge: function () {var b = this.birth; // 1990var fn = function () {return new Date().getFullYear() - this.birth; // this指向window或undefined};return fn();}
};
var obj = {birth: 1990,getAge: function () {var b = this.birth; // 1990var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象return fn();}
};
obj.getAge(); // 25
- 由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略
var obj = {birth: 1990,getAge: function (year) {var b = this.birth; // 1990var fn = (y) => y - this.birth; // this.birth仍是1990return fn.call({birth:2000}, year);}
};
obj.getAge(2015); // 25
6)generator(生成器)——generator由function* 定义(注意多出的‘*’号),并且,除了return语句,还可以用yield返回多次。
function* foo(x) {yield x + 1;yield x + 2;return x + 3;
}
var a=foo(1);
a.next();//2
a.next();//3
a.next();//4
a.next();//undefined
next()方法会执行generator的代码,然后,每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。如果done为true,则value就是return的返回值。
当执行到done为true时,这个generator对象就已经全部执行完毕,不要再继续调用next()了
三.标准对象
- Date
Date对象用来表示日期和时间
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳
不过上面这个方式获取是从本机操作系统获取的,不一定准确,可以使用下面这种方法
var d = new Date(2015, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)
这里也有个坑,就是js的月份范围是0-11,所以表示9月就要写8月
这里还有另外一种解析iso 8601格式字符串获取时间戳的方法,不过可以通过转化成一个Date
var d1 = Date.parse('2015-06-24T19:49:22.875+08:00');
var d = new Date(d1);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
d.getMonth(); // 5
使用Date.parse()时传入的字符串使用实际月份01-12,转换为Date对象后getMonth()获取的月份值为0-11。
ps:时间戳是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数。假设浏览器所在电脑的时间是准确的,那么世界上无论哪个时区的电脑,它们此刻产生的时间戳数字都是一样的,所以,时间戳可以精确地表示一个时刻,并且与时区无关
- 正则——懂得都懂,语言互通
- json
1>序列化
var xiaoming = {name: '小明',age: 14,gender: true,height: 1.65,grade: null,'middle-school': '\"W3C\" Middle School',skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
var s = JSON.stringify(xiaoming, ['name', 'skills'], ' ');
console.log(s);
//结果
{"name": "小明","skills": ["JavaScript","Java","Python","Lisp"]
}
2>反序列化
用JSON.parse()把json格式的字符串变成一个JavaScript对象
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45
四.面向对象
js的面向对象和其他语言不大一样。JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程
JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已
1.创建对象
2.原型继承
2.class继承
五.浏览器
1.浏览器对象
- window对象不仅仅是全局作用域,还代表浏览器窗口,有innerWidth和innerHeight属性,分别是浏览器窗口内部的宽度和高度,即是网页的净宽高,对应的,还有一个outerWidth和outerHeight属性,可以获取浏览器窗口的整个宽高。
- navigator对象表示浏览器的信息,常用属性有:
- navigator.appName:浏览器名称;
- navigator.appVersion:浏览器版本;
- navigator.language:浏览器设置的语言;
- navigator.platform:操作系统类型;
- navigator.userAgent:浏览器设定的User-Agent字符串
上面这个navigator在博客旁边的ip签名档使用过
- screen对象表示屏幕的信息:
- screen.width:屏幕宽度,以像素为单位;
- screen.height:屏幕高度,以像素为单位;
- screen.colorDepth:返回颜色位数,如8、16、24。
- location对象表示当前页面的url信息
- 获取url的各个值,可以使用protocol方法(http/https),host方法(域名),port端口,pathname方法(路径名),search方法,hash方法
- 要加载一个新的页面——location.assign(),重新加载当前页面——location.reload()
- document对象表示当前页面,html在浏览器是以DOM形式表示为树形结构的,document对象就是整个DOM树的根节点。
- document的title属性是从HTML文档中的xxx读取的,但是可以动态改变
document.title = '努力学习JavaScript!';
此时浏览器窗口标题变成上面这个
- 查找DOM树的某个节点,可以根据ID和Tag Name来查找,getElementById()和getElementsByTagName()可以按ID获得一个DOM节点和按Tag名称获得一组DOM节点
<dl id="drink-menu" style="border:solid 1px #ccc;padding:6px;"><dt>摩卡</dt><dd>热摩卡咖啡</dd><dt>酸奶</dt><dd>北京老酸奶</dd><dt>果汁</dt><dd>鲜榨苹果汁</dd>
</dl>var menu = document.getElementById('drink-menu');
var drinks = document.getElementsByTagName('dd');
var i, s;s = '提供的饮料有:';
for (i=0; i<drinks.length; i++) {s = s + drinks[i].innerHTML + ',';
}
console.log(s);//提供的饮料有:热摩卡咖啡,北京老酸奶,鲜榨苹果汁,
- document对象有一个cookie属性,可以获取当前页面的cookie,使用方法:
Cookie是什么?Cookie是由服务器发送的key-value标示符。因为HTTP协议是无状态的,但是服务器要区分到底是哪个用户发过来的请求,就可以用Cookie来区分。当一个用户成功登录后,服务器发送一个Cookie给浏览器,例如user=ABC123XYZ(加密的字符串)...,此后,浏览器访问该网站时,会在请求头附上这个Cookie,服务器根据Cookie即可区分出用户。Cookie还可以存储网站的一些设置,例如,页面显示的语言等等。document.cookie;
安全机制:服务器在设置Cookie时可以使用httpOnly,设定了httpOnly的Cookie将不能被JavaScript读取
2.操作DOM
我们操作DOM树,不外乎就四种,更新,遍历,添加,删除
- 操作DOM树前先需要拿到相关节点,最常用的方法是document.getElementById()和document.getElementsByTagName(),以及CSS选择器document.getElementsByClassName(),这个学过爬虫就略知一二了,当然,还有一种方法是使用querySelector()和querySelectorAll()
// 通过querySelector获取ID为q1的节点:
var q1 = document.querySelector('#q1');// 通过querySelectorAll获取q1节点内的符合条件的所有节点:
var ps = q1.querySelectorAll('div.highlighted > p');
- 更新DOM,直接修改节点的文本,有两种方法
- 修改innerHTML属性,这个不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改
使用innerHTML需要注意是否有写入HTML,如果是通过网络拿到的字符串,需要对字符编码来避免XSS攻击
2. 是修改innerText或textContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p>
这两个的区别是:innerText不返回隐藏元素的文本,而textContent返回所有文本
- 插入DOM
- 如果DOM节点是空的,可以通过innerHTML直接插入新的节点,但如果不是空的,则不能这样做,因为innerHTML会替换原来的所有节点
- 如果DOM节点不为空,可以使用appendChild(把一个字节点添加到父节点的最后一个节点)
<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p>
</div>
//插入
varjs = document.getElementById('js'),list = document.getElementById('list');
list.appendChild(js);
//结果
<!-- HTML结构 -->
<div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p><p id="js">JavaScript</p>
</div>
因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。
- 动态添加一个新节点
varlist = document.getElementById('list'),haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
//输出
<!-- HTML结构 -->
<div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p><p id="haskell">Haskell</p>
</div>
- 添加新的CSS定义
var d = document.createElement('style');
d.setAttribute('type', 'text/css');
d.innerHTML = 'p { color: red }';
document.getElementsByTagName('head')[0].appendChild(d);
- 将子节点插入到指定位置
使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前
varlist = document.getElementById('list'),ref = document.getElementById('python'),haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.insertBefore(haskell, ref);
//输出
<!-- HTML结构 -->
<div id="list"><p id="java">Java</p><p id="haskell">Haskell</p><p id="python">Python</p><p id="scheme">Scheme</p>
</div>
- 删除DOM
删除一个节点,需要获得它和它的父节点,然后调用父节点的removeChild把该节点删掉
// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true
注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置
遍历一个父节点的所有子节点进行删除操作时,主要children属性是一个只读属性,会随着子节点的变化实时更新
<div id="parent"><p>First</p><p>Second</p>
</div>var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错
这里报错的原因是,你删了第一个节点,节点是数量就发生改变了,所以索引[1]就不存在了
3.操作表单
HTML表单的输入主要有如下几个控件
- 文本框,对应的,用于输入文本
- 口令框,对应的,用于输入口令;
- 单选框,对应的,用于选择一项;
- 复选框,对应的,用于选择多项;
- 下拉框,对应的,用于选择一项;
- 隐藏文本,对应的,用户不可见,但表单提交时会把隐藏文本发送到服务器;
1)获取值
我们可以通过一个节点的引用来调用value来获取输入值
// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用户输入的值'
这里对于单选框和复选框,value属性返回的永远是HTML预设的值,但我们只需知道用户是否勾上了选项,所以要用checked判断
// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false
2)设置值
和获取值类型,直接设置value就行
// <input type="text" id="email">
var input = document.getElementById('email');
input.value = 'test@example.com'; // 文本框的内容已更新
3)HTML控件
常用的控件有date,datetime,datetime-local,color,它们都使用input标签
<input type="date" value="2015-07-01">
//这里是一个日期的选择控件
<input type="color" value="#ff0000">
//这里编译后的是,一个颜色的选择控件
date类型的input的value将保证是一个有效的YYYY-MM-DD格式的日期
4)提交表单
- 方式一,通过元素的submit()方法提交一个表单,例如,响应一个的click事件,在js代码中提交表单
<!-- HTML -->
<form id="test-form"><input type="text" name="test"><button type="button" onclick="doSubmitForm()">Submit</button>
</form><script>
function doSubmitForm() {var form = document.getElementById('test-form');// 可以在此修改form的input...// 提交form:form.submit();
}
</script>
这种方式的缺点是扰乱了浏览器对form的正常提交。浏览器默认点击时提交表单,或者用户在最后一个输入框按回车键
- 方式二,响应本身的onsubmit事件
<!-- HTML -->
<form id="test-form" onsubmit="return checkForm()"><input type="text" name="test"><button type="submit">Submit</button>
</form><script>
function checkForm() {var form = document.getElementById('test-form');// 可以在此修改form的input...// 继续下一步:return true;
}
</script>
如果这里是return false,浏览器不会提交这个表单,这种情况可以来判断用户输入有误,提示用户错误信息终止提交form
在检查和修改时,要充分利用来传递数据,比如我们可以用MD5加密来实现安全传输问题
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()"><input type="text" id="username" name="username"><input type="password" id="password" name="password"><button type="submit">Submit</button>
</form><script>
function checkForm() {var pwd = document.getElementById('password');// 把用户输入的明文变为MD5:pwd.value = toMD5(pwd.value);// 继续下一步:return true;
}
</script>
这个代码看似没啥问题,但是用户输入口令提交后,口令框会变成32个 * ,因为MD5有32个字符,如果不改变用户的输入,可以通过实现
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()"><input type="text" id="username" name="username"><input type="password" id="input-password"><input type="hidden" id="md5-password" name="password"><button type="submit">Submit</button>
</form><script>
function checkForm() {var input_pwd = document.getElementById('input-password');var md5_pwd = document.getElementById('md5-password');// 把用户输入的明文变为MD5:md5_pwd.value = toMD5(input_pwd.value);// 继续下一步:return true;
}
</script>
注意到id为md5-password的标记了name=“password”,而用户输入的id为input-password的没有name属性。没有name属性的的数据不会被提交
4.操作文件
在HTML表单中,可以上传文件的唯一控件就是。
注意:当一个表单包含时,表单的enctype必须指定为multipart/form-data,method必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。
出于安全考虑,浏览器只允许用户点击来选择本地文件,用JavaScript对的value赋值是没有任何效果的。当用户选择了上传某个文件后,JavaScript也无法获得该文件的真实路径
var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\fakepath\test.png'
if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {alert('Can only upload image file.');return false;
}
对文件扩展名进行检查,防止用户上传无效格式文件
- File API
HTML5的File API提供了File和FileReader两个主要对象,可以获得文件信息并读取文件
varfileInput = document.getElementById('test-image-file'),info = document.getElementById('test-file-info'),preview = document.getElementById('test-image-preview');
// 监听change事件:
fileInput.addEventListener('change', function () {// 清除背景图片:preview.style.backgroundImage = '';// 检查文件是否选择:if (!fileInput.value) {info.innerHTML = '没有选择文件';return;}// 获取File引用:var file = fileInput.files[0];// 获取File信息:info.innerHTML = '文件: ' + file.name + '<br>' +'大小: ' + file.size + '<br>' +'修改: ' + file.lastModifiedDate;if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {alert('不是有效的图片文件!');return;}// 读取文件:var reader = new FileReader();reader.onload = function(e) {vardata = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...' preview.style.backgroundImage = 'url(' + data + ')';};// 以DataURL的形式读取文件:reader.readAsDataURL(file);
});
上面的代码演示了如何通过HTML5的File API读取文件内容。以DataURL的形式读取到的文件是一个字符串,类似于data:image/jpeg;base64,/9j/4AAQSk…(base64编码)…,常用于设置图像。如果需要服务器端处理,把字符串base64,后面的字符发送给服务器并用Base64解码就可以得到原始文件的二进制内容。
- 回调
浏览器的js执行引擎在执行js代码时,总是以单线程模式执行,也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行。
在JavaScript中,执行多任务实际上都是异步调用
reader.readAsDataURL(file);
发起一个异步操作来读取文件内容。因为是异步操作,所以我们在JavaScript代码中就不知道什么时候操作结束,因此需要先设置一个回调函数
reader.onload = function(e) {// 当文件读取完成后,自动调用此函数:
};
当文件读取完成后,JavaScript引擎将自动调用我们设置的回调函数。执行回调函数时,文件已经读取完毕,所以我们可以在回调函数内部安全地获得文件内容。
5.AJAX
6.Promise
- Promise().then().then…catch() 多任务串行执行.
情景化记忆:在一个任务链中,比如我要向上级部门一层层的往上提交申请,if(某种条件)承诺帮你resolve解决问题,else承诺reject你的请求. 他给出的resolve问题的办法只是个空头Promise,then到总经理那实现具体承诺,如果总经理还是给一个空头承诺(返回Promise实例),还得then到董事长那里… 任一一步做出的是reject的承诺,还有什么好说的,被拒绝了,后面的就不会再往上走了呀. 准备catch 拒绝通知吧blablabla
- Promise.all([p1,p2,…])
多任务并行执行
都要成功才进入then,返回结果数组.
- Promise.race([p1,p2,…])
多任务赛跑.
then()和catch(),谁先调用算谁的,其它任务中断.
更多内容
7.Canvas
Canvas是HTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表、动画等。
之前没有Canvas前绘图用Flash插件实现,但是现在Flash逐步被淘汰
一个Canvas定义了一个指定尺寸的矩形框,在这个范围内我们可以随意绘制
<canvas id="test-canvas" width="300" height="200"></canvas>
getContext(‘2d’)方法让我们拿到一个CanvasRenderingContext2D对象,所有的绘图操作都需要通过这个对象完成。
var ctx=canvas.getContext('2d');
绘制3D,可以这么获取
var gl = canvas.getContext("webgl");
- 绘制形状
Canvas的坐标以左上角为原点,水平向右为X轴,垂直向下为Y轴,以像素为单位,所以每个点都是非负整数
varcanvas = document.getElementById('test-shape-canvas'),ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小为200x200的矩形,擦除的意思是把该区域变为透明
ctx.fillStyle = '#dddddd'; // 设置颜色
ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小为130x130的矩形涂色
// 利用Path绘制复杂路径:
var path=new Path2D();
path.arc(75, 75, 50, 0, Math.PI*2, true);
path.moveTo(110,75);
path.arc(75, 75, 35, 0, Math.PI, false);
path.moveTo(65, 65);
path.arc(60, 65, 5, 0, Math.PI*2, true);
path.moveTo(95, 65);
path.arc(90, 65, 5, 0, Math.PI*2, true);
ctx.strokeStyle = '#0000ff';
ctx.stroke(path);
- 绘制文本
绘制文本就是在指定的位置输出文本,可以设置文本的字体、样式、阴影等,与CSS完全一致
varcanvas = document.getElementById('test-text-canvas'),ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = '#666666';
ctx.font = '24px Arial';
ctx.fillStyle = '#333333';
ctx.fillText('带阴影的文字', 20, 40);
Canvas功能很强大,还可以实现动画,缩放,滤镜和像素转化等操作
通过创建一个不可见的Canvas来绘图,然后将最终绘制结果复制到页面的可见Canvas中;
尽量使用整数坐标而不是浮点数;
可以创建多个重叠的Canvas绘制不同的层,而不是在一个Canvas中绘制非常复杂的图;
背景图片如果不变可以直接用标签并放到最底层。
JavaScript复习笔记相关推荐
- HTML+CSS+JavaScript复习笔记持更(一)——标签篇
前言 博主现在还是在校生,目前大三,突然想起HTML的很多基础都忘记的差不多了,于是买了几本基础书,创建这篇博文用于记录复习笔记,也希望我自己在整理的时候,能帮助大家加深一些基础知识的印象,本篇博文将 ...
- HTML+CSS+JavaScript复习笔记持更(六)——CSS3常用属性之文本
文本相关 文本相关,包含了文字样式和文本换行等格式 文字 文字是一个网页最基础的部分,文字主要有以下几种属性: 字体 文字大小 文字颜色 水平对齐方式 段首缩进方式 语法格式: <!DOCTYP ...
- JavaScript复习笔记(3)——数据类型(null、undefined、NaN)与深度克隆
JavaScript中的数据类型:Number.Boolean.String.Object.Function 但是此外还有一些容易混淆的类型如null.undefined.NaN.Array的概念 f ...
- JavaScript复习笔记(1)——AJAX
基本过程 Ajax 提供异步通信和同步通信 核心为XMLHTTPRrequest(IE6不支持) 使用过程: 1.创建Ajax调用 2.向服务器发送请求open(参数1,参数2,参数3,[参数4],[ ...
- HTML+CSS+JavaScript复习笔记持更(十)——CSS3常用属性之定位
定位 定位主要是用来设定元素在页面上的位置的,其代码为:position 定位有三种定位方式: static(无特殊定位,按照dom排序) absolute(绝对定位,往前面找最近的,有定位属性的元素 ...
- HTML+CSS+JavaScript复习笔记持更(九)——CSS3常用属性之盒模型
盒模型 盒模型是CSS中最最重要的概念之一了,这个概念比较抽象,它规定了元素框处理元素内容.外边距.内边距.边框的方式. 内.外边距的属性 内边距:padding 外边距:margin 边框:bord ...
- HTML+CSS+JavaScript复习笔记持更(八)——CSS3常用属性之列表
列表属性 之前已经介绍过了列表标签.主要有有序列表和无序列表,为了更好地控制这两种列表,CSS还提供了这两种列表的样式设置. list-style(简写属性,把所有列表的属性设置写到一个声明中) li ...
- HTML+CSS+JavaScript复习笔记持更(七)——CSS3常用属性之背景
背景设置 HTML页面中的背景是通过background设置的. 语法格式: <!DOCTYPE html> <html lang="en"> <he ...
- HTML+CSS+JavaScript复习笔记持更(五)——CSS选择器
CSS选择器 在一个页面中,必不可少的就是css样式,css样式全都写在style标签中,在使用css时,我们可以用的css选择器非常之多,所以css选择器的分类也很多,但是基本上可以统计分为两类:基 ...
最新文章
- 时间字段 oracle 经验 设计,数据库设计与优化
- linux文泉驿字体调用,使用文泉驿点阵字体解决Linux中文化问题
- ASP.NET防止页面刷新的方法
- Linux Guide for Developers --- ubuntu开发者
- seaborn常用图
- Python代码打包成exe文件
- scp命令 – 远程拷贝文件
- teststand调用python模块_TestStand 基本知识[10]--在序列中调用代码模块之--LabVIEW
- android消息提示方法自定义,Android自定义消息提示容器
- 程序员【超实用】面试问题
- 【环境配置】Visual Studio opencv配置
- 左手补贴右手社交 杀入直播红海的拼多多会有机会吗?
- HearthBuddy卡牌无法识别
- php用代码写的三行情书,三行情书经典语录_最美的三行情书(两行泪,一段情)
- 编程题--疯狂序列----京东大数据笔试
- POJ 1565 Skew Binary
- 小圆象PDF:图片转pdf在线转换器有哪些?照片怎么变成PDF文件?
- 生产订单在做MIGO+101收货时,报错订单不存在有效的订单项
- JWT 生成Token、解析Token的简单工具类
- 国内外知名源码商城系统盘点