目录
- JavaScript 基础
- 引入 JavaScript 的三种方式
- 前置知识
- JavaScript 基本数据类型
- JavaScript 数据类型的转换
- 字符串操作
- 条件分支 / 循环分支
- 数组
- 对象
- 函数
- var、let 和 const 的区别
- JavaScript 高级
- 关于 window 对象
- 闭包函数
- 定时器
- 获取时间
- eval 函数
- ES6 中的类
- prototype
- call 和 apply
- ES6 中的箭头函数
- 逗号运算符
- 三元运算符
- ES6 中的 promise
- JavaScript 和 HTML 交互
- JavaScript 进阶
- JQuery 和 Ajax
JavaScript 基础
引入 JavaScript 的三种方式
PS:测试时,双击 HTML 文件跳转到浏览器,此时打开控制台即可输入 JS 指令
- 行内引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- 行内引入 -->
<button onclick="alert('行内引入')">Button</button>
</body>
</html>
- 内部引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<script>
// 内部引入
alert("内部引入");
</script>
<body></body>
</html>
- 外部引入
// out.js 文件中的内容
alert("外部引入");
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<!-- 外部引入 -->
<script src="out.js"></script>
<body></body>
</html>
前置知识
// 三种注释方式 1. // 2. /**/
// 规范的写法,每句代码结尾都应该接分号 ;
// 弹出警告窗口(常用于测试)
alert("弹出警告窗口");
// 控制台显示内容(常用于测试)
console.log("控制台显示内容");
// 声明变量,并赋值
var variable = 10;
// 企图同时声明多个变量,但只有最后一个变量能赋值
// variable0 和 variable1 的值都是 undefined
// 只有 variable2 的值是 10
var variable0, variable1, variable2 = 10;
// 企图赋多个值,但只有最后一个值能赋值成功
// variable3 的值是 30
var variable3 = (10, 20, 30);
// 打印变量的值
console.log(variable);
// 打印变量的类型
console.log(typeof variable);
// JavaScript 中的 局部刷新 相当于 异步加载
JavaScript 基本数据类型
共五种基本数据类型:number、string、boolean、object、undefined
/* 数字(number)*/
var num = 10;
console.log(num); // 10
console.log(typeof num); // number
/* 字符串(string)*/
var string = "10";
console.log(string); // 10
console.log(typeof string); // string
// 布尔值(boolean)*/
var boolean = true;
console.log(boolean); // true
console.log(typeof boolean); // boolean
/* 对象(object)*/
var object = {
a: 10,
b: "10",
c: function () {
console.log("10");
},
};
console.log(typeof object); // object
/* 未定义(undefined)*/
var undefined;
console.log(undefined); // undefined
console.log(typeof undefined); // undefined
注意区分另一种变量值:null,它代表空值(不属于基本数据类型)
var white = null;
console.log(white); // null
console.log(typeof white); // object
// 但如果判断 undefined 和 null 是否相等时,它们是相等的
var undefined;
var white = null;
console.log(undefined == white);
补充:逻辑运算符,用于处理变量之间的运算
var a = 0, b = 1, c = "1";
// 与
console.log(a && b); // 0
// 或
console.log(a || b); // 1
// 取反
console.log(!a); // true
// 比较两个变量的值是否一样
console.log(b == c); // true
// 比较两个变量的类型和值,是完全否一样
console.log(b === c); // false
JavaScript 数据类型的转换
// 字符串转数字
var a = "10";
var b = parseInt(a);
// 数字转字符串
var a = 10;
var b = a.toString();
// 十进制数字 转 十六进制字符串
var a = 10;
var b = a.toString(16);
// 十六进制字符串 转 十进制数字
var a = "a";
var b = parseInt(a, 16);
补充:两种数据类型之间使用 +
拼接打印
var a = 10;
var b = "10";
// 数字 + 数字
console.log(a + a); // 20
// 数字 + 字符串
console.log(a + b); // 1010
// 字符串 + 字符串
console.log(b + b); // 1010
/* 下列组合不常见,仅作为记录用 */
// 数字 + 布尔值
console.log(1 + true); // 2
// 数字 + undefined
console.log(1 + undefined); // NaN
// 数字 + null
console.log(1 + null); // 1
// 字符串 + 布尔值
console.log("1" + true); // 1true
// 字符串 + undefined
console.log("1" + undefined); // 1undefined
// 字符串 + null
console.log("1" + null); // 1null
字符串操作
var s = "123_456_789";
// 字符串分割
var new_s = s.split("_");
console.log(new_s); // ['123', '456', '789']
// 字符串切割,按长度切割,但已经被 ES6 淘汰
var new_s = s.substr(1, 5);
console.log(new_s); // 23_45
// 字符串切片,按位切片
var new_s = s.substring(1, 5);
console.log(new_s); // 23_4
// 字符串切片,按位切片,同上
var new_s = s.slice(1, 5);
console.log(new_s); // 23_4
// 获取字符串长度
var len = s.length;
console.log(len); // 11
// 获取字符串索引处的值
var index = s.charAt(2);
console.log(index); // 3
// 获取字符串索引处的 ASCII 码
var ascii = s.charCodeAt(2);
console.log(ascii); // 51
// 将 ASCII 码转换成字符
var ascii = "51";
var char = String.fromCharCode(51);
console.log(char); // 3
// 返回目标字符串,第一次出现的索引位置,若没有则返回 -1
var begin = s.indexOf("_");
console.log(begin); // 3
// 返回目标字符串,最后一次出现的索引位置,若没有则返回 -1
var end = s.lastIndexOf("_");
console.log(end); // 7
// 判断目标字符串,是否出现在原字符串中
var apper = s.includes("123");
console.log(apper); // true
// 将字符串全部转换成大写字母(类似的还有 lower)
var lower = "abcde";
var upper = lower.toUpperCase();
console.log(upper); // ABCDE
// 判断字符串是否以目标字符串开头
var start = s.startsWith("123");
console.log(start); // true
条件分支 / 循环分支
基本和 C / C++ 语言差不多;注意 switch 语句,如果不加 break
,一旦满足 case
条件,则会无视下一条 case
语句的条件,并直接执行其中的代码,此现象被称为穿透
var variable = 10;
// if
if (variable < 15) {
console.log("yes");
} else {
console.log("no");
}
// while
while (variable < 15) {
variable++;
console.log(variable);
}
// do while
do {
variable++;
console.log(variable);
} while (variable < 20);
// for
for (var i = 0; i < 5; i++) {
variable++;
console.log(variable);
}
// 另一种 for
var arr = [1, 2, 3, 4, 5];
for (var i in arr) {
console.log(i + "_" + arr[i]); // i 代表索引,arr[i] 代表索引值
}
// switch(正常写法)
switch (variable) {
case 10:
console.log("10");
break;
case 5:
console.log("5");
break;
case 0:
console.log("0");
break;
default:
console.log(666);
}
// switch(穿透)
switch (variable) {
case 10:
console.log("10");
case 5:
console.log("5");
case 0:
console.log("0");
default:
console.log(666);
}
数组
var arr = [1, 2, 3, 4, 5];
// 获取数组长度
var len = arr.length;
console.log(len); // 5
// 从后面添加数据
arr.push(6);
console.log(arr); // [1, 2, 3, 4, 5, 6]
// 从前面添加数据
arr.unshift(0);
console.log(arr); // [0, 1, 2, 3, 4, 5, 6]
// 从后面删除数据
arr.pop();
console.log(arr); // [0, 1, 2, 3, 4, 5]
// 从前面删除数据
arr.shift();
console.log(arr); // [1, 2, 3, 4, 5]
// 扁平化处理数组
var arr2 = [1, [2, 3], [[4]], 5];
var new_arr2 = arr2.flat();
console.log(new_arr2); // [1, 2, 3, [4], 5]
// 遍历 arr 中的每一项
arr.forEach(function (a, b, c) {
console.log(a + "__" + b + "_" + c); // a 代表索引值,b 代表索引,c 代表数组本身
});
// 拼劲数组
var arr3 = arr.join("_");
console.log(arr3); // 1_2_3_4_5
对象
JavaScript 的对象和 Python 中的字典相差不大,但是 JS 对象的 key
可以不加引号(详情看这篇博客)
var object = {
name: "云缨",
age: 16,
worship: "李娘子",
introduce: function () {
var myname = this.name;
console.log("我是" + myname);
},
phrase: function () {
this.introduce();
console.log("嗨呀!是我吗?");
},
};
// 获取 object 的 name(方法一)
object.name;
// 获取 object 的 name(方法二)
object["name"];
// 获取 object 的 phrase(方法一)
object.phrase();
// 获取 object 的 phrase(方法二)
object["phrase"]();
// 总结: object.xxx === object["xxx"]
// 对象转 JSON
var object_json = JSON.stringify(object);
// JSON 转对象
var object = JSON.parse(object_json);
函数
/* 正常情况 */
// 声明函数
function func(a, b) {
return a + b;
}
// 调用函数
var result = func(1, 2);
/* 骚操作 */
// 声明函数
var func = function (a, b) {
return a + b;
};
// 调用函数
var result = func(1, 2);
/* 特殊函数名 */
function $() {
return true;
}
function _() {
return false;
}
/* 匿名函数数组 */
arr = [
function () {
return 1;
},
function () {
return 2;
},
function () {
return 3;
},
];
// 调用数组
var result = arr[0];
/* 直接声明并调用 */
// 不获取返回值
(function (a, b) {
return a + b;
})(1, 2);
// 获取返回值
var result = (function (a, b) {
return a + b;
})(1, 2);
// 两种自运行函数(简化)
(function(){})();
(function(){}());
/* 企图多个返回值,但只会返回最后一个 */
var result = function () {
return 1, 2, 3;
};
var、let 和 const 的区别
众所周知,var
和 let
的作用都是创建变量,const
的作用是创建常量,因此主要来论述 var
和 let
的区别
/* var 的变量提升 */
// 未声明,先调用,这在其他语言中是显然不行的
// 但 var 可以,且在调用前被赋值为 undefined
// let 就不存在这种方法了
function func() {
console.log(name);
var name = "云缨";
}
/* 同一作用域内,let 不能重复定义同一变量 */
// 在函数中,var 声明了两次 name
// let 是不能同时声明同一变量两次的
function func() {
var name = "云缨";
var name = "云缨";
}
/* var 和 let 混用可能会出错 */
// 像下面这种用法是会报错的
// 除非将上面的 var 改成 let
// 或者将下面的 let 改成 var
var idol = "云缨";
function func() {
console.log(idol);
let idol = "李娘子";
}
/* 总结就是: let 可以替代 var,且建议这么做 */
JavaScript 高级
关于 window 对象
window 对象可以理解成 JavaScript 的全局对象,默认外部声明的变量都会加入 window 中(除了 let
)
/* 加入 window 对象的外部变量 */
a = 6;
console.log(a === window.a); // true
var b = 6;
console.log(b === window.b); // true
function c() {}
console.log(c === window.c); // true
// 除了 let
let d = 6;
console.log(d === window.d); // false
/* 外部变量很容易被修改 */
// 普通函数修改
e = 6;
function change() {
e = 666;
}
change();
console.log(e); // 666
console.log(e === window.e); // true
// 自运行函数修改
f = 6;
(function () {
f = 666;
})();
console.log(f); // 666
console.log(f === window.f); // true
/* windows 对象结合函数的常用写法 */
// 写法 1
(function () {
let output1 = function () {
console.log("写法 1");
};
window.output1 = output1;
})();
output1(); // 写法 1
// 写法 2
(function (w) {
let output2 = function () {
console.log("写法 2");
};
w.output2 = output2;
})(window);
output2(); // 写法 2
// 写法 3
(function (w) {
let tools = {
b64: function () {
console.log("我是计算 B64");
return "B64";
},
md5: function () {
console.log("我是计算 MD5");
return "MD5";
},
};
w.encryption = {
AES: function (msg) {
return tools.b64(), tools.md5(), msg + " encryption over";
},
DES: function () {
console.log("我是 DES");
},
RSA: function () {
console.log("我是 RSA");
},
};
})(window);
msg = encryption.AES("message");
/*
我是计算 B64
我是计算 MD5
*/
console.log(msg); // message encryption over
闭包函数
闭包是封闭环境,内部的变量只能自我调用,外部不可访问,但返回值可以供外部调用
/* 一般闭包函数单独写在 new.js 中 */
// 相比于 windows 对象,闭包函数更倾向于内容的独立性
let encryption = (function () {
// 内部变量,不允许外部访问
let aes_key = "666";
let des_key = "999";
let tools = {
b64: function () {
console.log("计算 B64");
return "B64";
},
md5: function () {
console.log("计算 MD5");
return "MD5";
},
};
// 闭包的返回值,允许外部进行调用
return {
AES: function (data) {
console.log("RSA 加密");
console.log("秘钥: " + this.get_aes_key());
console.log("数据: " + data);
tools.b64();
return "密文:xxxxxx";
},
DES: function (data) {
console.log("AES 加密");
console.log("秘钥: " + this.get_des_key() + key);
console.log("数据: " + data);
tools.b64();
return "密文:xxxxxx";
},
get_aes_key: function () {
return aes_key;
},
get_des_key: function () {
return des_key;
},
};
})();
msg = encryption.AES("加密内容");
console.log(msg);
/*
RSA 加密
秘钥: 666
数据: 加密内容
计算 B64
密文:xxxxxx
*/
定时器
/* 经过 n 秒之后运行目标函数 */
// 5 秒之后运行目标函数
t1 = setTimeout(function () {
console.log("666");
}, 5000);
/* 每隔 n 秒运行一次目标函数 */
// 5 秒运行一次目标函数
t2 = setInterval(function () {
console.log("666");
}, 5000);
// 多个定时器一起运行是协程
// 停止单个定时器
window.clearTimeout(t1);
window.clearInterval(t2);
获取时间
// 获取系统时间
var d = new Date(); // Sun Nov 20 2022 10:45:21 GMT+0800 (中国标准时间)
// 获取具体时间
var d = new Date("2022-11-20 10:45:21"); // Sun Nov 20 2022 10:45:21 GMT+0800 (中国标准时间)
/* 时间格式化 */
var d = new Date("2022-11-20 10:45:21");
// 获取年
year = d.getFullYear(); // 2022
// 获取月
month = d.getMonth() + 1; // 11
// 获取日期
date = d.getDate(); // 20
// 获取小时
hour = d.getHours(); // 10
// 获取分钟
minute = d.getMinutes(); // 45
// 获取秒
seconds = d.getSeconds(); // 21
// 格式化时间
format_date = year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + seconds; // 2022-11-20 10:45:21
/* 时间戳 */
// 从 1970-1-1 00:00:00 到现在一共经过的毫秒数
var d = new Date("2022-11-20 10:45:21");
console.log(d.getTime()); // 1668912321000
eval 函数
// eval 的功能是将字符串当成 js 代码来运行
str = "console.log('666')";
eval(str); // 666
ES6 中的类
在 ES6 之前,只能用 function
函数来实现类,ES6 才真正有 class
这个类
/* ES6 之前的类 */
// 类内变量和方法都必须用 this 表示
function Person1(name, age) {
this.name = name;
this.age = age;
this.play = function (game) {
console.log(this.name + "在玩" + game);
};
}
let p1 = new Person1("筱团", 20);
console.log(p1); // {name: '筱团', age: 20, play: ƒ}
console.log(p1.play("王者荣耀")); // 筱团在玩王者荣耀
/* ES6 的类 */
// 构造器 constructor 用于存储初始值
// 内部方法可以直接用 fuc_name() 创建
class Person2 {
constructor(name, age) {
this.name = name;
this.age = age;
}
play(game) {
console.log(this.name + "在玩" + game);
}
}
let p2 = new Person2("筱团", 20);
console.log(p2); // {name: '筱团', age: 20, play: ƒ}
console.log(p2.play("王者荣耀")); // 筱团在玩王者荣耀
prototype
prototype
是给类增加扩展功能的一种方法,JavaScript 中对象的继承结构为:object
-> prototype
-> 类 -> 对象
/* ES6 之前的类 */
// prototype 甚至可以补充在已声明对象后面
function Person1(name, age) {
this.name = name;
this.age = age;
this.play = function (game) {
console.log(this.name + "在玩" + game);
};
}
let p1 = new Person1("筱团", 20);
console.log(p1); // {name: '筱团', age: 20, play: ƒ}
Person1.prototype.run = function () {
console.log(this.name + "在跑步");
};
console.log(p1.run()); // 筱团在跑步
/* ES6 的类 */
// prototype 甚至可以补充在已声明对象后面
class Person2 {
constructor(name, age) {
this.name = name;
this.age = age;
}
play(game) {
console.log(this.name + "在玩" + game);
}
}
let p2 = new Person2("筱团", 20);
console.log(p2); // {name: '筱团', age: 20, play: ƒ}
Person2.prototype.run = function () {
console.log(this.name + "在跑步");
};
console.log(p2.run()); // 筱团在跑步
call 和 apply
call
和 apply
都属于 prototype
的一个方法,可以用来修改函数中 this
的指向问题
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
play(game) {
console.log(this.name + "在玩" + game);
}
}
function eat(food1, food2) {
console.log(this.name + "在吃" + food1 + "和" + food2);
}
let p = new Person("筱团", 20);
console.log(p); // {name: '筱团', age: 20, play: ƒ}
// 下面的调用都可以看成是
// object.function(parameter1, parameter2, parameter3)
// call 的调用形式是
// function.call(object, parameter1, parameter2, parameter3)
eat.call(p, "火腿", "泡面"); // 因为 p 就相当于对象,形式如下
eat.call({ name: "筱团", age: 20 }, "火腿", "泡面");
// apply 的调用形式是
// function.apply(object, [parameter1, parameter2, parameter3])
eat.apply(p, ["火腿", "泡面"]); // 因为 p 就相当于对象,形式如下
eat.apply({ name: "筱团", age: 20 }, ["火腿", "泡面"]);
// 上面的调用可以看成是 p.eat("火腿","泡面");
// 但不能直接用,因为 Person 类本身不存在 eat 方法
ES6 中的箭头函数
/* 正常函数的写法 */
// 以自运行函数为例
(function (a, b) {
console.log(a + b); // 30
})(10, 20);
/* 箭头函数的写法 */
// 函数格式为 (n) => {}
((a, b) => {
console.log(a + b); // 30
})(10, 20);
// 如果传参只有一个,省略括号也行
(a => {
console.log(a); // 10
})(10);
逗号运算符
// 逗号运算符的意义是,只操作最后一项
result1 = function run1() {
let num = (10, 20, 30); // num = 30
var a;
return (a = 9), a++, (a += num), { hint: "只返回最后一项", a: a };
};
console.log(result1()); // {"hint": "只返回最后一项", "a": 40}
// 因此上面函数也可以改成如下
result2 = function run2() {
let num = 30;
var a = 9;
a++;
a += num;
return { hint: "只返回最后一项", a: a };
};
console.log(result2()); // {"hint": "只返回最后一项", "a": 40}
三元运算符
// Javascript 的三元运算符与 C / C++ 语言无异
console.log(10 < 20 ? 10 : 20); // 10
// 但是当多个三元运算符出现时,要注意从右至左的顺序
a = 1;
b = 2;
c = 3;
result = a < b ? 10 : b < c ? 20 : 30;
// 上面式子可以看作 a < b ? 10 : (b < c ? 20 : 30)
console.log(result); // 10
ES6 中的 promise
更加清晰的解析看:大白话讲解 Promise
promise
能更好的处理多个回调函数,常用的用法有:then
、catch
、all
、race
/* 链式操作 */
function runAsync1() {
var p = new Promise(function (resolve, reject) {
// 做一些异步操作
setTimeout(function () {
console.log("异步任务 1 执行完成");
resolve("数据 1");
}, 1000);
});
return p;
}
function runAsync2() {
var p = new Promise(function (resolve, reject) {
// 做一些异步操作
setTimeout(function () {
console.log("异步任务 2 执行完成");
resolve("数据 2");
}, 2000);
});
return p;
}
function runAsync3() {
var p = new Promise(function (resolve, reject) {
// 做一些异步操作
setTimeout(function () {
console.log("异步任务 3 执行完成");
resolve("数据 3");
}, 3000);
});
return p;
}
// then 传入的函数,其实就是回调函数
// then 传入的函数,可以直接代回对应函数的 resolve 中
// then 中的返回值可以返回下一个 promise 函数,也可以直接返回数据
runAsync1()
.then(function (data) {
console.log(data);
return runAsync2();
})
.then(function (data) {
console.log(data);
return runAsync3();
})
.then(function (data) {
console.log(data);
});
/*
异步任务 1 执行完成
数据 1
异步任务 2 执行完成
数据 2
异步任务 3 执行完成
数据 3
*/
/* reject 和 catch 的用法 */
function getNumber() {
var p = new Promise(function (resolve, reject) {
//做一些异步操作
setTimeout(function () {
var num = Math.ceil(Math.random() * 10); //生成 1 - 10 的随机数
if (num <= 5) {
resolve(num);
} else {
reject("数字太大了");
}
}, 1000);
});
return p;
}
// 如果满足条件则执行 resolve(num),那么 data 就被赋值为 num
// 否则 data 就被赋值 reason
getNumber()
.then(function (data) {
console.log("resolved");
console.log(data);
})
.catch(function (reason) {
console.log("rejected");
console.log(reason);
});
/*
rejected
数字太大了
*/
// 相比于上面那种情况,多了一行错误代码
// 那么 promise 则会报错 somedata is not defined
getNumber()
.then(function (data) {
console.log("resolved");
console.log(data);
console.log(somedata); // 此处的 somedata 未定义
})
.catch(function (reason) {
console.log("rejected");
console.log(reason);
});
/*
rejected
ReferenceError: somedata is not defined
at test.js:98:17
*/
JavaScript 和 HTML 交互
HTML 与 JavaScript 最简单的交互示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<script>
function fn() {
alert("弹出警示");
}
</script>
<body>
<input type="button" value="点击" onclick="fn()" />
</body>
</html>
上例的 onclick
就是事件,HTML 中可以触发的事件很多,常见的如下:
onclick 点击事件
onfocus 获取焦点
onblur 失去焦点
onsubmit 提交表单
onchange 更换选项
onscroll 滚动条滚动
onmouseover 鼠标滑过
onmouseout 鼠标滑出
onmousemove 鼠标滑动
常见的事件绑定的方案有三个(上例算一个),还有两个方案如下:
<script>
// HTML 的资源从上至下加载
// window.onload 相当于页面加载时的声明
window.onload = function () {
let btn = document.querySelector("#btn");
btn.onclick = function () {
alert("弹出警示");
};
};
</script>
<body>
<input type="button" value="点击" id="btn" />
</body>
<script>
window.onload = function () {
let btn = document.querySelector("#btn");
// 最正宗的事件绑定方案
btn.addEventListener("click", function () {
alert("弹出警示");
});
};
</script>
<body>
<input type="button" value="点击" id="btn" />
</body>
上例的 querySelector
是一个获取元素句柄的方法,类似的还有:
document.querySelector(); //根据 css 选择器获取句柄
document.getElementById(); // 根据 id 的值获取句柄
document.getElementsByClassName(); // 根据 class 的值获取句柄
最后演示 HTML 与 JavaScript 实际中的交互示例(用户登入)如下:
<script>
window.onload = function () {
document.getElementById("btn").addEventListener("click", function () {
// 清空框框中的提示信息
document.getElementById("username_info").innerText = "";
document.getElementById("password_info").innerText = "";
let username = document.getElementById("username").value; // 获取用户名
let password = document.getElementById("password").value; // 获取密码
let flag = true;
if (!username) {
document.getElementById("username_info").innerText = "用户名不能为空";
flag = false;
}
if (!password) {
document.getElementById("password_info").innerText = "密码不能为空";
flag = false;
}
if (flag) {
document.getElementById("login_form").submit();
}
});
};
</script>
<body>
<form action="服务器地址" id="login_form">
<label for="username">用户名:</label><input type="text" name="username" id="username"><span id="username_info"></span><br/>
<label for="password">密码:</label><input type="text" name="password" id="password"><span id="password_info"></span><br/>
<input type="button" id="btn" value="点我登录">
</form>
</body>
JavaScript 进阶
同步、异步
emmm
参考
什么是跨域?跨域解决方法
跨域的解决方法有哪些?
https://www.luffycity.com/play/46226
JQuery
jQuery 一共提出过 3 个大版本,分别是 1.x,2.x 和 3.x,目前最新的是 3.x.,但大多数公司用 1.7.2,而我们学习用 1.9.1
下载方式:字节跳动 CDN 的 jquery.min.js
需要记住的 css 选择器
Ajax
Ajax,全称为Asynchronous Javascript And XML,即异步的JavaScript and XML。它不是一门编程语言,而是利用JavaScript在保证页面不被刷新、页面链接不改变的情况下与服务器交换数据并更新部分网页的技术。
jsonp
jsonp,全称 json with padding
服务器本身是不能跨域,但是 html5 可以,因此就可以使用 JavaScript 实现
现在解决跨域问题,常用 cors或者服务器反向代理,而不是jsonp
跨域的概念:
当前页面 URL | 被请求页面 URL | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http / https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test / baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www / blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080 / 7001) |
- axios
- axios 拦截器
ES6
- emmm
BOM & DOM 编程
- emmm