JavaScript

目录

  • 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 的区别

众所周知,varlet 的作用都是创建变量,const 的作用是创建常量,因此主要来论述 varlet 的区别

/* 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

callapply 都属于 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 能更好的处理多个回调函数,常用的用法有:thencatchallrace

/* 链式操作 */
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
下载方式:字节跳动 CDNjquery.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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容