JavaScript 学习笔记(二)

函数

闭包

箭头函数 (ES6引入)

返回是对象,注意加()

1
2
var pow = x => x*x;
var createPerson = () => ({ name: "alice"})

箭头函数this的作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'use strict'
var obj = {
name: "alice",
birth: 1990,
getAge: function(){
var b = this.birth;
/*
function fn(){
return new Date().getFullYear() - this.birth; // this undefined
}
*/
var fn = () => new Date().getFullYear() - this.birth; ;
return fn;
}
};
console.info(obj.getAge()());

1
2
3
4
5
6
7
8
9
10
'use strict'
var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = (y) => y - this.birth; // this.birth仍是1990
return fn.call({dfj:123}, year);
}
};
console.info(obj.getAge(2015));// 25

generator yield

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
'use strict'
function* fibonacci(maxCount){
var count = 0,
a = 0,
b = 1,
tmp;
while(count < maxCount){
yield a;
tmp = a + b
a = b;
b = tmp;
count ++;
}
}
var iterator = fibonacci(5);
console.info(iterator);//{[[GeneratorStatus]]: "suspended"}
console.info(iterator.next()); //{value:0,done:false}
console.info(iterator);
console.info(iterator.next());
console.info(iterator);
console.info(iterator.next());
console.info(iterator.next());
console.info(iterator.next());
console.info(iterator.next()); //{value:undefined,done:true}
console.info(iterator); //{[[GeneratorStatus]]: "closed"}//
for(var el of iterator){
console.info(el);
}

标准对象

特别注意null,Array,{}的类型是object

1
2
3
4
5
6
7
8
9
10
'use strict'
console.info("typeof 123 = " + typeof 123); //number
console.info("typeof NaN = " + typeof NaN ); //number
console.info("typeof '123' = " + typeof '123'); //string
console.info("typeof true = " + typeof true); //boolean
console.info("typeof undefined = " + typeof undefined); //undefined
console.info("typeof Math.abs = " + typeof Math.abs); //function
console.info("typeof [] = " + typeof []); //object
console.info("typeof {} = " + typeof {}); //object
console.info("typeof null = " + typeof null); //object

包装对象

number、boolean和string 有包装对象,使用 new 来创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'use strict'
var n = new Number(123); //object
var s = new String("hello"); //object
var b = new Boolean(true);//object
var n1 = Number(n); //number
var s1 = String(s); //string
var b1 = Boolean(b);//boolean
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false

Number()、Boolean和String()被当做普通函数,把任何类型的数据转换为number、boolean和string类型

1
2
3
4
5
6
7
8
9
10
11
var n = Number('123'); // 123,相当于parseInt()或parseFloat()
typeof n; // 'number'
var b = Boolean('true'); // true
typeof b; // 'boolean'
var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串!
var b3 = Boolean(''); // false
var s = String(123.45); // '123.45'
typeof s; // 'string'

调用包装对象方法

1
2
123..toString(); // '123', 注意是两个点!
(123).toString(); // '123'

总结

  • parseInt()parseFloat() 来转换任意类型到 number
  • String() 来转换任意类型到 string ,或者直接调用某个对象的 toString() 方法;
  • 通常不必把任意类型转换为 boolean 再判断,因为可以直接写 if (myVar) {…}
  • typeof 操作符可以判断出 numberbooleanstringfunctionundefined
  • 判断 Array 要使用 Array.isArray(arr)
  • 判断 null 请使用 myVar === null
  • 判断某个全局变量是否存在用 typeof window.myVar === ‘undefined’
  • 函数内部判断某个变量是否存在用 typeof myVar === ‘undefined’

Date 对象

1
2
3
4
5
6
7
8
9
10
11
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形式表示的时间戳

注意:JavaScript的月份范围用整数表示是0~11

1
2
var d = new Date(2015, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)

第二种创建一个指定日期和时间的方法是解析一个符合 ISO 8601 格式的字符串

1
2
3
4
var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875
var d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)

时区

Date对象表示的时间总是按浏览器所在时区显示的,不过我们既可以显示本地时间,也可以显示调整后的UTC时间:

1
2
3
var d = new Date(1435146562875);
d.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间,与本地时间相差8小时

时间戳是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数。

1
2
3
4
5
6
/* 获取时间戳 */
if (Date.now) {
alert(Date.now()); // 老版本IE没有now()方法
} else {
alert(new Date().getTime());
}

正则表达式

1
2
3
4
5
6
7
'use strict'
var re1 = /([0-9]{3})-([0-9]{8})/;
var result = re1.exec("021-12345678");
result; //["021-12345678", "021", "12345678", index: 0, input: "021-12345678"]
var area = result[2];
var number = result[3];
console.info(re1.test("021-12345678"));

贪婪搜索 与 解除

1
2
3
4
5
6
7
'use strict'
var re1 = /(\d+)(\0*)$/;
var result = re1.exec("20300");
result; // ["20300", "20300", "", index: 0, input: "20300"]
re1 = /(\d+?)(0*)$/;//解除贪婪
result = re1.exec("20300");
result; // ["20300", "203", "00", index: 0, input: "20300"]

全局搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'use strict'
var str = 'JavaScript, VBScript, JScript and ECMAScript';
var rel=/[a-zA-Z]+Script/g;
rel.exec(str);
var idx = rel.lastIndex;
console.info(str.substring(0,idx));
console.info(rel.lastIndex);
rel.exec(str);
console.info(str.substring(idx+2,rel.lastIndex));
idx = rel.lastIndex;
console.info(rel.lastIndex);
rel.exec(str);
console.info(str.substring(idx,rel.lastIndex));
console.info(rel.lastIndex);
idx = rel.lastIndex;
rel.exec(str);
console.info(str.substring(idx,rel.lastIndex));
console.info(rel.lastIndex);
idx = rel.lastIndex;

练习email 正则

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
'use strict'
var re = /^\w[a-zA-z0-9_.-]+@[a-zA-z0-9_.-]+\.[a-zA-z]{2,4}$/;
var test = re.test("jake.tia3n@goo-gle.co");
console.info(test);
// 测试:
var
i,
success = true,
should_pass = ['someone@gmail.com', 'bill.gates@microsoft.com', 'tom@voyager.org', 'bob2015@163.com'],
should_fail = ['test#gmail.com', 'bill@microsoft', 'bill%gates@ms.com', '@voyager.org'];
for (i = 0; i < should_pass.length; i++) {
if (!re.test(should_pass[i])) {
alert('测试失败: ' + should_pass[i]);
success = false;
break;
}
}
for (i = 0; i < should_fail.length; i++) {
if (re.test(should_fail[i])) {
alert('测试失败: ' + should_fail[i]);
success = false;
break;
}
}
if (success) {
alert('测试通过!');
}

练习2

1
2
3
4
5
6
7
8
9
10
'use strict'
var re = /<(\w+\s\w+)> ([a-z]+@.*)$/;
var r = re.exec('<Tom Paris> tom@voyager.org');
console.info(r);
if (r === null || r.toString() !== ['<Tom Paris> tom@voyager.org', 'Tom Paris', 'tom@voyager.org'].toString()) {
console.info('测试失败!');
}
else {
console.info('测试成功!');
}

JSON

1
2
3
4
5
6
7
8
9
10
11
12
'use strict'
var student = {
name:"alice",
age:15
};
var strJson = JSON.stringify(student,function(key,value){
return typeof value === 'string' ? value.toUpperCase() : value;
}," ");
student = JSON.parse(strJson,function(key,value){
return key === "name" ? "王" + value : value;
});//转换回对象
console.info(student);

面向对象编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'use strict'
//原型对象
var Student = {
age:15,
run:function(){
return "run:" + this.name ;
}
};
//写法一
var createStudent = function(name){
var ret = Object.create(Student);
ret.name = name;
return ret;
};
var xiaoming = createStudent("小明");
//写法二
var zhangsan = {name:"张三", __proto__:Student};
console.info(xiaoming.run() + " 年龄: " + xiaoming.age + "xiaoming.__proto__ === Student : " + new String( xiaoming.__proto__ === Student )) ;
console.info(zhangsan.run() + " 年龄: " + zhangsan.age + "zhangsan.__proto__ === Student : " + new String( zhangsan.__proto__ === Student )) ;
console.info(xiaoming.__proto__ === zhangsan.__proto__); //true

原型链

graph LR XM(xiaoming)-->C(constructor) ZS(zhangsan)-->C C-->S(Student.prototype) S-->C C-->OBJ(某个对象) OP(Object.prototype)-->OBJ OBJ-->N(null)

一个常用编程模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'use strict'
//一个常用的编程模式
function Student(props) {
this.name= props.name || "anonym";
this.grade= props.grade || 1;
}
Student.prototype.hello = function(){
return "hello, " + this.name + "!";
}
var createStudent = function(props){
return new Student(props||{});
};
//测试
var xiaoming = createStudent({name:"小明"});
var xiaohong = createStudent({name:"小红"});
if(xiaoming.hello() === "hello, 小明!"){
console.info("测试通过");
}else{
console.info(xiaoming.hello());
}

inherit 继承

  • 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
  • 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
  • 继续在新的构造函数的原型上定义新方法。
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
'use strict'
//原型实现继承
function Student(props){
this.name = props.name || "anonyms";
}
Student.prototype.hello = function(){
return "hello, " + this.name;
};
function PrimeryStudent(props){
Student.call(this,props);
this.grade = props.grade || 1;
}
function inherit(child,parent){
function F(){};
F.prototype = parent.prototype;
child.prototype = new F();
child.prototype.constructor = child;
}
inherit(PrimeryStudent,Student);
PrimeryStudent.prototype.getGrade = function(){
return this.grade;
}
var xiaoming = new PrimeryStudent({
name:"小明",
grade:3
});
console.info(`xiaoming grade:${xiaoming.getGrade()} ,name:${xiaoming.name} `);

class 继承 (ES6 引入)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'use strict'
class Student{
constructor(name){
this.name = name;
}
}
class PrimeryStudent extends Student{
constructor(name,grade){
super(name);
this.grade = grade;
}
getGrade(){
return this.grade;
}
}
var xiaoming = new PrimeryStudent("小明",5);
var xiaohong = new PrimeryStudent("小红",6);

浏览器

  • IE 6~11:国内用得最多的IE浏览器,历来对W3C标准支持差。从IE10开始支持ES6标准;
  • Chrome:Google出品的基于Webkit内核浏览器,内置了非常强悍的JavaScript引擎——V8。由于Chrome一经安装就时刻保持自升级,所以不用管它的版本,最新版早就支持ES6了;
  • Safari:Apple的Mac系统自带的基于Webkit内核的浏览器,从OS X 10.7 Lion自带的6.1版本开始支持ES6,目前最新的OS X 10.11 El Capitan自带的Safari版本是9.x,早已支持ES6;
  • Firefox:Mozilla自己研制的Gecko内核和JavaScript引擎OdinMonkey。早期的Firefox按版本发布,后来终于聪明地学习Chrome的做法进行自升级,时刻保持最新;

不同的浏览器对JavaScript支持的差异主要是,有些API的接口不一样,比如AJAX,File接口。对于ES6标准,不同的浏览器对各个特性支持也不一样。
在编写JavaScript的时候,就要充分考虑到浏览器的差异,尽量让同一份JavaScript代码能运行在不同的浏览器中。

排序列表内容

1
2
3
4
5
6
7
8
<!-- HTML结构 -->
<ol id="test-list">
<li class="lang">Scheme</li>
<li class="lang">JavaScript</li>
<li class="lang">Python</li>
<li class="lang">Ruby</li>
<li class="lang">Haskell</li>
</ol>
1
2
3
4
5
6
7
8
9
10
11
12
13
'use strict'
var listEl = document.getElementById("test-list");
var els = document.getElementsByClassName("lang");
var arr = [];
for(let i=0;i<listEl.children.length;i++){
//console.info();
arr.push(listEl.children[i].innerHTML);
}
arr.sort();
for(let i=0;i<listEl.children.length;i++){
listEl.children[i].innerHTML = arr[i];
}
console.info(arr);

表单操作练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<form id="test-register" action="#" onsubmit="return checkRegisterForm()">
<p id="test-error" style="color:red"></p>
<p>
用户名: <input type="text" id="username" name="username" value="a12345" >
</p>
<p>
口令: <input type="password" id="password" name="password" value="111111">
</p>
<p>
重复口令: <input type="password" id="password-2" value="111111">
</p>
<p>
<button type="submit">提交</button> <button type="reset">重置</button>
</p>
</form>

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
'use strict'
function checkRegisterForm(){
var elUserName = document.querySelector("#username");
var elPassword = document.querySelector("#password");
var elPassword2 = document.querySelector("#password-2");
var userNameRegExp = /^\w{3,10}$/;
var pwdRegExp = /^.{6,20}$/;
var ret = userNameRegExp.test(elUserName.value) && pwdRegExp.test(elPassword.value) && elPassword.value === elPassword2.value;
//console.info(ret);
//console.info(userNameRegExp.test("_d12345678900987654321"));
return ret;
}
// 测试:
(function () {
window.testFormHandler = checkRegisterForm;
var form = document.getElementById('test-register');
if (form.dispatchEvent) {
var event = new Event('submit', {
bubbles: true,
cancelable: true
});
form.dispatchEvent(event);
} else {
form.fireEvent('onsubmit');
}
})();

Promise

理解后写的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'use strict'
new Promise(function(resolve,reject){
var timeout = Math.random() * 2;
setTimeout(function() {
if(timeout<1){
resolve(`resolve : ${timeout}`);
}else{
reject(`reject : ${timeout}`);
}
}, timeout*1000);
}).then(function(r){
console.info(r); // resolve : 0.3232423432
}).catch(function(reason){
console.info(reason); //reject : 1.235433255
});

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
'use strict'
var logging = document.getElementById("test-promise-log");
//清除log
while(logging.children.length > 1){
logging.removeChild(logging.children.length-1);
}
function log(s){
var p = document.createElement("p");
p.innerHTML = s;
logging.appendChild(p);
}
new Promise(function(resolve,reject){
log("start new Promise...");
var timeout = Math.random() * 2;
log(`timeout = ${timeout}`);
log(`set timeout to : ${timeout} seconds.`);
setTimeout(function(){
if(timeout < 1){
log("call resolve()...");
resolve("200 OK")
}else{
log("call reject...");
reject(`timeout in ${timeout} seconds`);
}
},timeout * 1000);
}).then(function(r){
log("Done: " + r )
}).catch(function(reason){
log('Failed: ' + reason);
});

串行执行异步任务

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
'use strict'
function add(input){
return new Promise(function(resolve,reject){
setTimeout(resolve, 2000, input + input);
});
}
function mutiply(input){
return new Promise(function(resolve,reject){
setTimeout(resolve, 2000, input * input);
});
}
new Promise(function(resolve,reject){
resolve(3);
}).then(add).then(mutiply)
.then(function(r){
console.info(r);
});
var i=0;
/*
使用setTimeout实现 setInteval 功能
*/
function selfCall(){
if(i>=6) return;
i++;
console.info(new Date() + " i = " + i);
setTimeout(run,1000);
}
var si = setInterval(function(){
i++;
if (i>=6) {
console.info("clearInterval");
clearInterval(si);
}
console.info(new Date() + " -- " + i );
},1000);

Promise 结合 AJAX

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
'use strict'
var request ;
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
}else{
request = new ActiveXObjcet("Microsoft.XMLHttp");
}
request.onreadyStateChange = function(){
if(request.readyState == 4){
if(request.status == 200){
console.info(responseText);
}else{
console.info(request.status);
}
}else{
//http 请求还在继续
}
};
request.open("Get" , "/categories");
request.send();
//使用Promise写法
function ajax(method,url,data){
var p1 = new Promise(function(resolve,reject){
request.onreadyStateChange = function(){
if(request.readyState == 4){
if(request.status == 200){
resolve(request.responseText);
}else{
reject(request.status);
}
}
}
request.open(method,url);
request.send(data);
});
return p1;
}
var p = ajax("GET","/api/categories");
p1.then(function(r){
console.info(r);
}).catch(function(reason){
console.info(reason);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*<canvas width =300px height=300px > </canvas>*/
(function() {
"use strict"
var el_cav = document.getElementById("cav");
if(el_cav.getContext ){
var ctx = el_cav.getContext("2d");
ctx.strokeStyle = "#ff0000";
var path = new Path2D();
path.arc(150,150,100,0,Math.PI*2,true);
path.moveTo(220,150)
path.arc(150,150,70,0,Math.PI,false);
path.moveTo(110,100);
path.arc(100,100,10,0,Math.PI*2,false);
path.moveTo(210,100);
path.arc(200,100,10,0,Math.PI*2,false);
ctx.stroke(path);
}else{
alert("您的浏览器不支持canvas!");
}
})();

笑脸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(function() {
"use strict"
var el_cav = document.getElementById("cav");
if(el_cav.getContext ){
var ctx = el_cav.getContext("2d");
ctx.strokeStyle = "#ff0000";
var path = new Path2D();
path.arc(150,150,100,0,Math.PI*2,true);
path.moveTo(220,150)
path.arc(150,150,70,0,Math.PI,false);
path.moveTo(110,100);
path.arc(100,100,10,0,Math.PI*2,false);
path.moveTo(210,100);
path.arc(200,100,10,0,Math.PI*2,false);
ctx.stroke(path);
}else{
alert("您的浏览器不支持canvas!");
}
})();

从sina获取股票数据,显示k线图

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
var el_cav = null;
(function() {
"use strict"
el_cav = document.createElement("canvas");
el_cav.setAttribute("width",window.innerWidth-50);
el_cav.setAttribute("height",window.innerHeight-50);
document.getElementsByTagName("body")[0].appendChild(el_cav);
var ctx = null;
if(el_cav.getContext ){
ctx = el_cav.getContext("2d");
}else{
alert("您的浏览器不支持canvas!");
}
var el = document.createElement("script");
el.setAttribute("src","http://img1.money.126.net/data/hs/kline/day/history/2017/0000001.json?callback=drawCandles&t=568859042");
el.setAttribute("type","text/javascript");
document.getElementsByTagName("head")[0].appendChild(el);
})();
function drawCandles(prop){
console.debug(prop);
var candles_count = prop.data.length;
var candles = [];
for(d of prop.data){
if(candles.length< candles_count){
candles.push(d);
}else{
break;
}
}
console.info(candles);
var h_price = [], l_price = [];
candles.forEach(function(el,idx,arr){
h_price.push(el[3]);
l_price.push(el[4]);
});
var price_max = Math.max.apply(null,h_price);
var price_min = Math.min.apply(null,l_price);
var ctx = el_cav.getContext("2d");
var pxs_per_price = el_cav.height / (price_max - price_min);
var candles_placehold_width = el_cav.width / candles_count;
console.info(`price_max = ${price_max} price_min = ${price_min}`);
ctx.strokeStyle = "#ff0000";
ctx.lineWidth = 0.5;
ctx.moveTo(1,0);
ctx.lineTo(1,el_cav.height);
ctx.moveTo(0,el_cav.height-1);
ctx.lineTo(el_cav.width,el_cav.height-1);
ctx.stroke();
ctx.fillStyle = "red";
ctx.fillText(price_min + (price_max - price_min) / 4 * 3 ,el_cav.width-60, el_cav.height/4 - 5);
ctx.fillText(price_min + (price_max - price_min) / 4 * 2 ,el_cav.width-60, el_cav.height/4*2 - 5);
ctx.fillText(price_min + (price_max - price_min) / 4 * 1 ,el_cav.width-60, el_cav.height/4*3 - 5);
ctx.fillText(price_min + (price_max - price_min) / 4 * 0 ,el_cav.width-60, el_cav.height/4*4 - 5);
ctx.moveTo(0,el_cav.height/4);
ctx.lineTo(el_cav.width,el_cav.height/4);
ctx.moveTo(0,el_cav.height/4*2);
ctx.lineTo(el_cav.width,el_cav.height/4*2);
ctx.moveTo(0,el_cav.height/4*3);
ctx.lineTo(el_cav.width,el_cav.height/4*3);
ctx.stroke();
ctx.lineWidth =1;
candles.forEach(function(el,idx,arr){
var x = getX(idx,candles_placehold_width);
var y = el[1]>=el[2] ? el[1] : el[2];
if(el[1]>=el[2]){
ctx.strokeStyle = "#00ff00";
}else{
ctx.strokeStyle = "#ff0000";
}
ctx.beginPath();
y = getY(y,pxs_per_price,price_min,el_cav);
var w = candles_placehold_width/2
var h = Math.abs((el[1]-el[2]))*pxs_per_price;
ctx.moveTo(x + candles_placehold_width/4 , y);
ctx.lineTo(x + candles_placehold_width/4 , getY(el[3],pxs_per_price,price_min,el_cav) );
ctx.moveTo(x + candles_placehold_width/4 , getY(el[1]>el[2] ? el[2] : el[1],pxs_per_price,price_min,el_cav));
ctx.lineTo(x + candles_placehold_width/4 , getY(el[4],pxs_per_price,price_min,el_cav));
ctx.strokeRect(x,y,w,h);
ctx.stroke();
});
function getX(i,width){
return ( i+0.5 ) * width - width / 4 ;
}
function getY(price,pxs_per_price,price_min,el_cav){
var y = 0 ;
y = el_cav.height - (price - price_min) * pxs_per_price;
return y;
}
}
/*
drawCandles({data:[
["20170101",3008.10,3100.52,3103.88,3001.28,53135239100,3.58],
["20170102",3005.10,3097.52,3100.88,2998.28,53135239100,3.58],
["20170103",3011.10,3103.52,3106.88,3004.28,53135239100,3.58]
]});
*/

JQuery

如果$这个变量不幸地被占用了,而且还不能改,那我们就只能让jQuery把$变量交出来,然后就只能使用jQuery这个变量:

1
2
3
4
$; // jQuery(selector, context)
jQuery.noConflict();
$; // undefined
jQuery; // jQuery(selector, context)

1
2
3
4
5
6
7
<div id="test-div">
<ul>
<li class='dy'><span id='swift'>Swift</span></li>
<li><span>JavaScript</span></li>
<li class='dy'><span>Python</span></li>
</ul>
</div>

filter() 用法

1
2
3
4
5
6
7
8
9
10
11
12
'use strict'
var langs = $("ul li");
var boo = langs.filter(function(){
var ret = 1;
if($(this).text() === "Python"){
ret = 0; //返回0结果种将剔除此项
}
return ret;
});
boo.css({"background-color":"yellow"}); //受影响 swift,javascript
//langs.filter(".dy"); // 返回 swift,python
console.info(boo);

JQuery 对象的 map 的用法

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
/*
<!-- HTML结构 -->
<form id="test-form" action="#0" onsubmit="return false;">
<p><label>Name: <input name="name"></label></p>
<p><label>Email: <input name="email"></label></p>
<p><label>Password: <input name="password" type="password"></label></p>
<p>Gender: <label><input name="gender" type="radio" value="m"> Male</label>
<label><input name="gender" type="radio" value="f"> Female</label></p>
<p><label>City: <select name="city">
<option value="BJ" selected>Beijing</option>
<option value="SH">Shanghai</option>
<option value="CD">Chengdu</option>
<option value="XM">Xiamen</option>
</select></label></p>
<p><button type="submit" onclick="getJson()">Submit</button></p>
</form>
*/
'use strict'
function getJson(){
var inputs = $("#test-form :input");
var rmap = [];
inputs.map(function(idx,html){
if(html.type === "radio"){
rmap[html.name] = $("input[name=gender]:checked").val();
}else{
rmap[html.name] = html.value;
}
});
inputs.css("background-color","yellow");
console.info(rmap);
}

使用jquery 排序一个ul列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'use strict'
var lis = $("#test-div li");
var liArr = lis.map(function(idx,html){
return html;
}).get();
liArr.sort(function(x,y){
if($(x).text()>$(y).text()){
return 1;
}else{
return -1;
}
});
$("#test-div ul").append(liArr);
console.info(liArr);

事件

鼠标事件

  • click: 鼠标单击时触发;
  • dblclick:鼠标双击时触发;
  • mouseenter:鼠标进入时触发;
  • mouseleave:鼠标移出时触发;
  • mousemove:鼠标在DOM内部移动时触发;
  • hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。

键盘事件

键盘事件仅作用在当前焦点的DOM上,通常是<input>和<textarea>。

  • keydown:键盘按下时触发;
  • keyup:键盘松开时触发;
  • keypress:按一次键后触发。

其他事件

  • focus:当DOM获得焦点时触发;
  • blur:当DOM失去焦点时触发;
  • change:当<input>、<select>或<textarea>的内容改变时触发;
  • submit:当<form>提交时触发;
  • ready:当页面被载入并且DOM树完成初始化后触发。

事件的绑定和取消

1
2
3
4
5
6
7
8
9
10
11
12
13
'use strict'
$(function(){
function b1(){
console.info("b1");
}
function b2(){
console.info("b2");
}
var btn = $("#btn");
btn.on("click",b1);
btn.on("click",b2);
btn.off("click",b2);
});

综合作业 checkbox 全选 反选 状态控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<form id="test-form" action="test">
<legend>请选择想要学习的编程语言:</legend>
<fieldset>
<p>
<label class="selectAll">
<input type="checkbox">
<span class="selectAll">全&nbsp;&nbsp;选</span>
<span class="deselectAll">全不选</span>
</label>
<a href="#0" class="invertSelect">反选</a>
</p>
<p><label><input type="checkbox" name="lang" value="javascript"> JavaScript</label></p>
<p><label><input type="checkbox" name="lang" value="python"> Python</label></p>
<p><label><input type="checkbox" name="lang" value="ruby"> Ruby</label></p>
<p><label><input type="checkbox" name="lang" value="haskell"> Haskell</label></p>
<p><label><input type="checkbox" name="lang" value="scheme"> Scheme</label></p>
<p><button type="submit">Submit</button></p>
</fieldset>
</form>

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
'use strict'
$(function(){
var el_ckb_all_flag = $("label.selectAll input[type=checkbox]");
var langs = $("#test-form input[name=lang]");
langs.change(function(e){
if(!this.checked){
$(this).prop("checked",false);
}else{
$(this).prop("checked",true)
}
updateCkbAll();
});
$(".invertSelect").click(function(){
langs.each(function(idx,el){
var el = $(el);
el.prop("checked" , !el.prop("checked") );
});
updateCkbAll();
});
function updateCkbAll(){
var allSelected = true;
for(let i=0;i<langs.length;i++){
var el = langs.get(i);
if(!$(el).prop("checked")){
allSelected = false;
break;
}
}
if(allSelected ){
el_ckb_all_flag.prop("checked",true);
$("span.selectAll").hide();
$("span.deselectAll").show();
}else{
el_ckb_all_flag.prop("checked",false);
$(".selectAll").show();
$(".deselectAll").hide();
}
}
function selectAllLang(){
el_ckb_all_flag.prop("checked","checked");
langs.each(function(idx,el){
$(el).prop("checked",true);
});
}
function deselectAll(){
el_ckb_all_flag.prop("checked",false);
langs.each(function(idx,el){
$(el).prop("checked",false);
});
}
el_ckb_all_flag.change(function(){
if(el_ckb_all_flag.prop("checked")){
//console.info("all");
selectAllLang();
}else{
deselectAll();
}
updateCkbAll();
});
$("#btn-test").click(function(){
updateCkbAll();
});
updateCkbAll();
});

async 和 await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
'use strict'
const fs = require("fs");
var readFile = function (fileName){
return new Promise(function (resolve, reject){
fs.readFile(fileName, function(error, data){
if (error) reject(error);
resolve(data);
});
});
};
var asyncReadFile = async function (){
var f1 = await readFile('a.txt');
var f2 = await readFile('app.js');
console.log("f1: " + f1.toString().substr(0,10));
console.log("f2:" + f2.toString().substr(0,10));
};
asyncReadFile();
console.log("代码已经结束");