JavaScript

JavaScript

重点集结

了解】了解什么是JavaScript

了解】为什么要学JavaScript

【掌握】掌握JavaScript的组成

【掌握】掌握在HTML中使用JavaScript

【掌握】掌握ECMAScript语法结构

【掌握】掌握ECMAScript常见内置对象

【了解】什么是浏览器对象模型

【了解】什么是文档对象模型

【掌握】掌握常用window对象函数

【了解】基本浏览器对象

【掌握】掌握文档对象模型结构以及相关操作

【掌握】掌握正则表达式实现表单验证

【掌握】掌握Promise的使用

一、初识JavaScript

官网: https://www.w3.org/standards/webdesign/script

说明:

JavaScript语法规范是ECMAScript,ECMAScript由ECMA国际(前身European Computer Manufacturers Association 欧洲计算机制造商协会)设计,但是其中的浏览器API由W3C进行维护。

ECMA标准列表: https://www.ecma-international.org/publications/standards/Stnindex.htm

ECMAScript标准: https://www.ecma-international.org/publications/standards/Ecma-262.htm

ECMAScript标准内容: https://www.ecma-international.org/ecma-262/11.0/index.html

JavaScript推荐教程:
英文: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps

中文: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference

W3School JavaScript资料 : https://www.w3school.com.cn/js/index.asp

菜鸟教程 JS资料:https://www.runoob.com/js/js-tutorial.html

ES6参考书:https://es6.ruanyifeng.com/

1.1 什么是JavaScript

JavaScript和Java没有任何关系。

JavaScript(缩写:JS)是一门完备的动态编程语言。当应用于 HTML 文档时,可为网站提供动态交互特性。

JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。

JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。

特点:

是一种轻量级解释性语言,边解释便执行(对比:Java语言执行→编写Java代码,编译成class字节码,通过虚拟机加载运行)

是一种弱类型语言:声明变量不能使用具体的数据类型,变量的数据类型由值决定。(Java声明变量必须有具体的数据类型)

通常用来HTML网页中,用来处理与用户的交互。

脚本语言:

在运行之前不需要预处理的程序语言。通常由语言的解析引擎来解释执行。

说明:

JavaScript很多场景下简称为js

1.2 为什么要学习JavaScript

  • 用于表单验证
    • 用于检验数据的合法性,避免错误数据的产生
    • 用于减轻服务器的压力
  • 用于页面的交互特效
    • 常见的页面动画效果
    • 软件业务要求的处理
  • jQuery、Vue.js、React.js、微信小程序等等的学习基础
  • 因为其是脚本语言,所以它还可以用于游戏的编写

二、JavaScript的组成

  • ECMAScript:语法规范标准,现在常用的语法规范标准是ES6版本。
    • 变量
    • 数据类型
    • 运算符
    • 程序逻辑:顺序结构,分支结构(条件结构),循环结构
    • 数组、函数
    • 对象
    • 关键字,保留字
  • BOM对象:(Brower Object Model)浏览器对象模型,提供了与浏览器交互通信。(面试常问)
  • DOM对象:(Document Object Model)文档对象模型,用来访问和操作HTML文档。(面试常问)

三、ECMAScript的语法

3.1 使用JavaScript的方式

在HTML中使用JS脚本的三种方式

3.1.1 嵌入式:

内部JavaScript(Internal JavaScript):通过在页面中使用

<script type="text/javascript">
    // 书写JS代码(在控制台显示内容)
    console.log('Hello World!!!')
    // 书写JS代码(在页面显示内容)
    document.write('Hello World!!!');
</script>
3.1.2 外部文件引入(External JavaScript):

通过页面中使用

<!-- 引入外部自定义js文件 -->
<script type="text/javascript" src="./js/index.js"></script>
3.1.3 事件定义方式(Inline JavaScript handlers):

通过在页面标签中添加事件属性,书写JS脚本(不推荐)

<button onclick="console.log('你点了我')">点我</button>

3.2 变量(熟记)

​ 官方地址:https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps/Variables

  • 变量的命名规则
    • 首字符:只能使用 字母、下划线(_)、美元符号($)
    • 其余部分:只能使用 字母、下划线(_)、美元符号($)和数字
    • 不能使用关键字和保留字(ES6关键字和保留字:http://wiki.xuetang9.com/?p=7476)
  • 变量的命名规范
    • 使用驼峰命名:第一个单词的首字母小写,其余单词的首字母大写
    • 不建议使用单个字母作为变量名,取名要语义化。见名知意
  • 变量的使用步骤
    • 声明变量
    • 变量赋值
    • 使用变量
3.2.1 var声明变量

JavaScript是一种弱类型语言,没有明确的数据类型

在声明变量时,不需要指定变量类型,变量的类型由赋给变量的值决定

我们每一行代码结尾都是使用了;号表示一行代码的结束,在非严格要求下是可以不写;号的,推荐加上

//先声明后赋值
var number;
number = 20;
//声明并赋值
var name = "Jack";
var weight = 120,height = 175;
//不声明直接赋值(不允许使用)
count = 1000;
// 在ES5中没有赋值的变量默认值为 undefined
var age;
console.log(age);

// ES5变量提升(不允许使用)
console.log(sex);
var sex = 12;
3.2.2 let声明变量

ES6.0 新增了let命令,用来声明变量,它的用法类似于var,let与var的作用域不同且不会变量提升

//ES6作用域不同
{
   var num1 = 1;
   let num2 = 2;
}
console.log(num1);//输出1
console.log(num2);//异常

//ES6没有变量提升
console.log(sex);
let sex = 12;

3.3 常量(熟记)

使用const关键字定义常量。常量不能再次赋值。通常常量名使用全大写,多个单词使用下划线连接。

// 定义常量
const DAYS = 7;
const ADD_USER_INFO;
// 常量不能再次赋值
DAYS ++; //Uncaught TypeError: Assignment to constant variable.
// 常量在定义时必须赋值
const FOO;	//SyntaxError: Missing initializer in const declaration

3.4 数据类型(熟记)

尽管在声明变量时不需要声明变量的数据类型,这并不代表JavaScript中没有数据类型,它由赋给变量的值决定。在JavaScript中,提供了常用的基本数据类型

3.4.1 5种简单数据类型
类型说明
number数值,包括整数浮点数
string字符串,使用单引号或者双引号包裹
booleanboolean类型,0为false,非零为true
null空,表示没有任何值的指向。认为null是一种特殊的object
undefined未赋值,表示未赋值的变量
3.4.2 复杂的数据类型
类型说明
Object对象
Function函数
Array数组,存储多个值(特殊的对象)

判断数据类型:使用 typeof 获取类型

示例:

console.log(1,typeof 1); // number
console.log('123',typeof '123'); // string
console.log(true,typeof true); // boolean
console.log(null,typeof null); // object
console.log(undefined,typeof age);// age未定义,或者没有初始化 ,undefined
console.log({},typeof {}); // object
console.log(function(){},typeof function(){}); // function
console.log([],typeof []); // object 

3.4 运算符(熟记)

3.4.1算数运算符

+、-、 *、 /、 %、**、++、--

说明

两个数字不能计算时:结果为 NAN。

除0的时候:结果Infinity。表示无限大

在JavaScript中**表示指数运算

console.log('加法运算:%d',1 + 2); 
console.log('减法运算:%d',20 - 58); 
console.log('乘法运算:%d',5 * 6); 
console.log('除法运算:%f',60 / 7); 
console.log('取模运算:%d',3000 % 67);
let num1 = 100,num2 = 80;
console.log('数字++:%d',num1++);
console.log('数字++之后:%d',num1); 
console.log('++数字:%d',++num2);
let num3 = 50,num4 = 30;
console.log('数字--:%d',num3--); 
console.log('数字--之后:%d',num3); 
console.log('--数字:%d',--num4);
3.4.2 关系运算符(比较运算符)

>、< 、>= 、<=、==、!=、===、!==

说明

=、! 表示恒等或恒不等,比较过程中会比较数据的类型

3.4.3 逻辑运算符

! 、&&、||

  • 逻辑或:通常用于赋默认值。
3.4.4 赋值运算符:

= 、+= 、-=、*= 、/= 、%= 、**=

3.5 程序逻辑(熟记)

3.5.1 顺序

一般情况下都是同步逻辑,即从上至下依次执行代码。后续我们会接触到异步逻辑,其逻辑会延迟等待服务器响应后才会继续执行。

3.5.2 分支
  1. if-[else if]-else

说明:

  1. 基础的条件结构
  2. ES中依旧支持三元运算符
  3. 配合逻辑运算符使用:
    • &&:多个条件同时为true,则返回true,任意一个条件为false,则返回false
    • ||:任一一个条件为true,则返回true,否则,返回false
    • !:非运算符,表示取反条件,若原条件为true,则返回false,反之返回true

示例:

四川话中形容男的胖叫闷得儿,女的胖叫丰满,男的瘦叫干心儿,女的瘦叫苗条

国际标准体重的计算zd方法是男性标准体重=(身高cm-80)×70﹪,女性标准体重=(身高cm-70)×60﹪。标准体重正负10﹪为正常体重,标准体重正负10﹪~ 20﹪为体重过重或过轻,标准体重正负20﹪以上为肥胖或体重不足

prompt()方法,其作用是弹出一个输入提示框,用于接收用户输入的内容

let sex = prompt('请输入您的性别(男/女)');
if(sex === '男'){
    let height = prompt('先生,请输入您的身高(cm)');
    let weight = prompt('先生,请输入您的体重(kg)');
    let standard = (height - 80) * 0.7;     //计算男士的标准体重
    if(weight > standard * 1.2) {
        alert('闷得儿- 。-!');
    }else if(weight < standard * 0.8) {
        alert('干心儿- 。-!');
    }else {
        alert('标准身材!!');
    }
}else if(sex === '女') {
    let height = prompt('女士,请输入您的身高(cm)');
    let weight = prompt('女士,请输入您的体重(kg)');
    let standard = (height - 70) * 0.6;     //计算女士的标准体重
    if(weight > standard * 1.2) {
        alert('丰满!!');
    }else if(weight < standard * 0.8) {
        alert('苗条!!');
    }else {
        alert('标准身材!!');
    }
}else {
    alert('输入的不是性别,自动结束');
}
  1. switch-case

语法:

switch(表达式或变量) {
     case a:
        代码块
        break;
     case b:
        代码块
        break;
     default:
        默认代码块
} 

说明:

横值判断的条件结构

如果一个case末尾没有写break,那么在当前case的逻辑执行完毕后,会继续执行紧靠的下一个case中的逻辑

示例:

let constellation = prompt('请输入您的星座');
switch (constellation) {
    case '白羊座':
        alert('白羊座是十二宫第一个星座,白羊们乐观开朗,活泼可爱,性格上也大大咧咧,给人一中看上去就非常愉悦的感觉,这是上天赋予他们的天赋,总是那么的热情、阳光、率真。白羊对朋友也非常的仗义,爱恨分明,慷慨大方,虽然有些时候会有一点脾气,但是谁还没有二两脾气呢?和白羊座交朋友,他们会给你带来无限的欢声笑语,让你永远在祥和的气氛中生活。');
        break;
    case '金牛座':
        alert('踏实、稳健的金牛座是一个保守的星座,他们喜欢安定的生活,性格上属于慢热型,无论是工作、生活,他们都需要一段时间的适应。财富是金牛座与生俱来的特质,他们在投资方面有着独到的眼光,金牛座对恋人的格言是:我负责挣钱养家,你只需负责貌美如花。而且金牛座对美食也有着很高的鉴赏水平,喜欢宁静的环境,喜欢一切美好的事物。');
        break;
    case '双子座':
        alert('双子座不会拒绝任何新鲜的事物,好奇的双子座有着极高的情商,和双子座聊天永远不会让你感觉寂寞,聪明的小脑袋里装满都是新鲜和古灵精怪的东西,这也让双子座有着更多的朋友。双子座如果想带你去一个地方玩的话,他会把这个地方说成人间仙境一般,甚至都不落下一个细节。双子总是给人一种花心的感觉,实际上双子只是喜欢新鲜事物,而且一直追求着。');
        break;
    default:
        alert('其他星座');
}
3.5.3 循环
  1. while

只要条件为 true,循环结构中的代码块能够一直重复执行

语法:

while (条件) {
    要执行的代码块
}
  1. do-while

是 while 循环的变体。在检查条件是否为真之前,这种循环会执行一次代码块,然后只要条件为真就会重复循环

语法:

do {
    要执行的代码块
} while (条件);
  1. for

假如您需要运行代码多次,且每次使用不同的值,那么循环for相当方便使用

语法:

for (语句 1; 语句 2; 语句 3) {
     要执行的代码块
}

示例

斐波那契数列:由意大利数学家列昂纳多·斐波那契发明,这个数列从第三项开始,每一项都等于前两项之和,如:1、1、2、3、5、8……
现在我们用for循环来输出前50位斐波那契数列的值

let str = "";
let one = 1,two = 1;    //记录前两个数
let num = 50;           //要输出的总数
for(let i = 1;i <= num; i++) {
    if(i >= 3) {
        let end = one + two;    //先计算当前数的值
        one = two;              //将第二个数的值赋值给第一个数
        two = end;              //将新的值赋值给第二个数
        if(i === 50) {
            str += end;
        }else {
            str += end + '、';
        }
    }else {
        str += 1 + '、';
    }
}
console.log(str);
  1. 结束循环的方式

break:终止整个循环,让逻辑往后继续

continue:跳过本次循环,继续后续的循环

return:它只能放在函数中,其作用是跳出整个函数逻辑,相当于循环也结束了

3.6 函数编程

3.6.1 概念(熟记)

函数 允许你在定义的区块内存储一段代码用来执行一个单独的任务,然后调用该段代码时,你需要使用一个简短的命令,而不用重复编写多次该段代码。

函数与方法

方法是在对象内定义的函数 , 参考链接 https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Building_blocks/Functions

3.6.2 函数语法(熟记)
function 函数名(参数1,参数2...) {
 	// 代码
    [return [返回值];]
}

说明

  1. 普通函数名规则与规范遵守变量命名规则规范,作为构造函数时使用帕斯卡命名规范(后续讲解)
  2. 因为JavaScript本身是弱类型,所以它的参数也没有类型检查和类型限定。函数中的参数是可选的,根据函数是否需要带参,可分为不带参的无参函数和有参函数
  3. 参数列表的多个参数使用逗号隔开,例如(name,age),且参数名不能相同
  4. return语句用来规定函数的返回值,当然函数不一定需要返回值

匿名函数:

使用function定义,function关键字后没有名称时,称为匿名函数

let 函数名 = function(参数1,参数2...){
    ...
}
3.6.3 调用语法(熟记)

要执行一个函数,必须先调用这个函数,当调用函数时,必须指定函数名以及后面的参数(如果是有参函数)

函数名(实参列表);
3.6.4 自执行函数(了解)

直接执行匿名函数,无需通过额外的方式调用

//1 可以使用开头
!function(形参列表){
   //alert(形参列表);
}(实参列表);
//2 使用()将函数及函数后的括号包裹
(function(){}());
//3 使用()值包裹函数值(无法表明函数与之后的()的整体性,不推荐使用)
(function(){})();
3.6.5 参数的默认值(熟记)
function log(x, y = 'World') {
   console.log(x, y);
}
3.6.6 扩展参数rest(了解)

用于获取函数的多余参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中

rest 参数之后不能再有其他参数(即只能是最后一个参数)

function push(...items) {
   console.log(items);
}
push(1, 2, 3);
3.6.7 解构(了解)

ES6可以从数组中提取值,按照对应位置,对变量赋值

let [a, b, c] = [1, 2, 3];
console.log(a); 

let [ , , z] = ["a", "b", "c"];
console.log(z); 

let [head, ...tail] = [1, 2, 3, 4];
console.log(head);
console.log(tail);

let [foo = true] = []; 
3.6.8 闭包(了解)

词法作用域:词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。嵌套函数可访问声明于它们外部作用域的变量

function init() {
    let name = "老九学堂";         // name 是一个被 init 创建的局部变量
    function displayName() {     // displayName() 是内部函数,一个闭包
        alert(name);             // 使用了父函数中声明的变量
    }
    displayName();
}

基础用法

function welcomeFunc() {
    let text = "老九学堂欢迎大家";
    return function () {
        alert(text);
    }
}
let myFunc = welcomeFunc();
myFunc();

进阶用法:

function addFunc(x) {
    return function(y) {
        return x + y;
    };
}

let add5 = addFunc(5);
let add10 = addFunc(10);
console.log(add5(2));        // 7
console.log(add10(2));      // 12

3.7 箭头函数定义(熟记)

箭头函数语法比函数表达式更简洁,但是它没有自己的this

基本语法:

3.7.1 多个参数时
//普通函数
function f(参数1, 参数2,..., 参数N){
	//内部逻辑 
}

//箭头函数
(参数1, 参数2, ..., 参数N) => { 
	//内部逻辑 
}
3.7.2 单个参数时
//普通函数
function f(参数1) {
	//内部逻辑 
}

//箭头函数
参数1 => { 
	//内部逻辑 
}
3.7.3 无参数时
//普通函数
function f() {
	//内部逻辑 
}

//箭头函数
() => { 
	//内部逻辑 
}
3.7.4 返回一个单行表达式
//普通函数
function f() {
	return 表达式;
}

//箭头函数
() => 表达式;
3.7.5 返回对象
//普通函数
function f(参数1, 参数2,..., 参数N) {
	return {
        属性名:,
        ...
    }
}

//箭头函数
(参数1, 参数2,..., 参数N) => ({
    属性名:,
    ...
});

3.8 对象

3.8.1 自定义对象(熟记)
  1. 自定义对象方式:
let 对象名 = {
    属性名:,
    ...
}

属性的值可以是任何数据类型,包括其它对象、函数

  1. 为对象赋值或者添加新的属性并赋值
对象名.属性名 =;
对象名.新属性名 =; // 新属性名在对象的大括号中没有定义
对象名[属性名字符串] =;	//该方式常用于动态设置属性,因为[]中可以是变量
  1. 对象取值
let 变量名 = 对象名.属性名;
let 变量名 = 对象名[属性名字符串];
  1. in运算符:查看对象的某个属性是否存在
let 变量名 =  "属性名" in 对象名;
  1. delete操作符:删除对象的某个属性
delete 对象名.属性名;
3.8.2 遍历对象方式
  1. for-in:遍历对象属性

迭代获取对象属性名称

// 创建对象
let section = {
	id:375,
	name:'官方公告区',
	iconPath:'../imgs/notic.png',
	description:'官方发布公告的内容'
};
// 迭代对象
for(let propertyName in section){
    console.log(propertyName+":"+section[propertyName]);
}
  1. for-of:遍历对象数组

遍历对象数组中的每个对象(类似于java中的foreach结构)

for(let sectionName of sections){
    console.log(sectionName);
}
3.8.3 this关键字

在function定义的函数中,this关键字指代函数的调用对象

var name = 'window';
function show(){
    console.log(this);
    console.log(this.name);	
}
show();      //一次调用
function show2(){
    show();  //二次调用
}
show2();

//对象隐式绑定
var obj = {
      name: 'obj',
      show: show    //对show方法进行引用
}
obj.show();

//显示绑定
show.apply(obj);
show.call(obj);
show.bind(obj)();

箭头函数的this是函数被创建时绑定的,它指向当前词法作用域中的this

  • 自身没有this
  • 不会因被怎么样的方式调用改变绑定
var str = 'window';
const obj = {
      str:'obj',
      nativeFn: function(){
            console.log(this.str, '当前词法作用域中的this');
            return function(){
                  console.log('原生函数',this.str);
            }
      },
      arrowFn: function(){
            console.log(this.str, '当前词法作用域中的this');
            return ()=>{
                  console.log('箭头函数',this.str);
            }
      }
};
const obj2 = { str: 'obj2'};

var nativeFn = obj.nativeFn();
var arrowFn = obj.arrowFn();
console.log('函数调用一 **********');
nativeFn();
arrowFn();

console.log('函数调用二 **********');
nativeFn.call(obj2);
arrowFn.call(obj2);

console.log('函数调用三 **********');
setTimeout(function(){
      nativeFn();
      arrowFn();
},50);

3.9 内置对象(熟记)

3.9.1 String
  1. 构造函数
构造函数说明
String()无参构造创建字符串对象
String(字符串)通过带参构造创建字符串对象

ES中主要使用单引号或者双引号创建字符串对象,注意使用引号创建的字符串属于’string’类型,但是使用new String()创建的对象属于’object’类型

  1. 属性与方法

几乎java字符串有的方法在ES的内置对象String中都有

类别名称说明
属性length获取字符串长度
方法charAt(索引)获取指定索引字符
方法indexOf(查找字符串)获取指定值在字符串中首次发现所在索引,未找到返回-1
方法split(字符)按照指定的字符进行分割形成字符串数组
方法slice(起点,终点)获取指定索引的字符串,不包含终点(终点索引不能比起点小)
方法substr(起点,长度)获取指定索引,指定个数字符组成的字符串
方法substring(起点,终点)获取两个指定索引之间的字符串(终点索引可以比起点小)
方法toLowerCase()/toUperCase()将字符串转换为小写/大写
方法replace(目标字符串,新字符串)将字符串中指定内容替换为新字符串内容(支持正则表达式)
let message = "JavaScript 的标准是 ECMAScript 。截至 2012 年,所有的现代浏览器都完整的支持  ECMAScript 5.1,旧版本的浏览器至少支持 ECMAScript 3 标准。2015年6月17日,ECMA国际组织发布了 ECMAScript 的第六版,该版本正式名称为 ECMAScript 2015,但通常被称为 ECMAScript 6 或者 ES6。自此,ECMAScript 每年发布一次新标准。";

//获取字符串长度
console.log(message.length);
//获取指定索引字符
console.log(message.charAt(5));
//获取首个指定字符串所在的索引位置
console.log(message.indexOf('ECMAScript'));
//拆分
console.log(message.split('。'));
//获取指定索引的字符串,不包含终点(终点索引不能比起点小)
console.log(message.slice(3,5));
//获取指定索引,指定个数字符组成的字符串
console.log(message.substr(3,5));
//获取两个指定索引之间的字符串(终点索引可以比起点小)
console.log(message.substring(3,0));
//将字符串转换为小写
console.log(message.toLocaleLowerCase());
//将字符串转换为大写
console.log(message.toLocaleUpperCase());
//普通文本替换
console.log(message.replace('微博','***'));
//正则表达式替换
console.log(message.replace(/微博/g,'***'));
  1. 模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量(需要将变量名写在${}之中)

它是增强版的字符串,因此它同样可以使用上面的属性和方法

let name = '使命召唤手游';    //游戏名称
let company = '腾讯';     //厂商
let description = '周杰伦助阵代言,TGA最佳移动游戏,《使命召唤手游》终于在战士们的期待声中于2020年12月25日强势登场。作为使命召唤系列在移动端的延续,我们在努力还原经典玩法地图角色的同时,还结合手机端的操作特点进行了适配优化。同时,我们也针对大家反馈的匹配机制、枪械平衡、配音特效等问题进行了调整,希望给战士们带来最优质的游戏体验。';

//字符串拼接方式,繁杂且容易出错
document.write(
    '<h4>游戏名称:' + name + '</h4>' +
    '<h6>厂商:' + company + '</h6>' +
    '<p>' + description + '</p>'
);

//模板字符串方式,简单,不易出错
document.write(`
    <h4>游戏名称:${name}</h4>
    <h6>厂商:${company}</h6>
    <p>${description}</p>
`)
3.9.2 Array
  1. 构造函数
构造函数说明
Array()创建空数组
Array(长度)创建指定空间数组
Array(元素列表)根据传入的元素个数创建数组

说明:

在ES中使用主要中括号方式创建数组

  1. 属性与方法
类别名称说明
属性length设置或返回数组中元素的数目
方法数组[索引]访问数组指定索引元素
方法join(分割符)把数组所有元素放入一个字符串,
通过一个分割符进行分割(不适用于对象数组)
方法push(元素)向数组末尾添加一个或多个元素,并返回新的数组长度
方法pop()移除并返回数组最后一个元素
方法splice(索引,删除个数,添加元素列表)从数组中的指定索引位置,添加或删除指定数量的元素
方法indexOf(元素)获取对应元素的索引位置(不适用于对象数组)
方法concat(待拼接数组列表)把几个数组合并成一个数组并返回
方法forEach(callback(value[,index]))数组每个元素都执行一次回调函数
value为值(必须有)、index为索引(可以有)
方法filter(callback(value[,index]))检测数组元素,并返回符合条件所有元素的数组
value为值(必须有)、index为索引(可以有)
方法map(callback(value[,index]))创建一个新数组,其结果是该数组中的每个元素都
调用一个提供的函数后返回的结果
value为值(必须有)、index为索引(可以有)
//基本数据类型数组
let array1 = [1,2,3,4,5,6];
//对象数组
let array2 = [
    {
        name: '张三',
        age: 12,
        score: 89
    },
    {
        name: '李四',
        age: 14,
        score: 78
    },
    {
        name: '王五',
        age: 13,
        score: 93
    }
];

//获取数组长度
console.log(`数组1的长度为:${array1.length}`);

//获取指定索引元素
console.log(`数组2索引1的数据为:`,array2[1]);

//分割
console.log(`数组1使用短横线分割后:${array1.join('-')}`);

//向数组末尾添加一个或多个元素,并返回新的数组长度
console.log(`数组1添加一个100:${array1.push(100)}`);
array2.push({
    name: '赵六',
    age: 13,
    score: 100
})
console.log(`数组2添加一个对象:`,array2);

//移除最后一个元素
console.log(`移除前:`,array1);
array1.pop();
console.log(`移除后:`,array1);
3.9.3 JSON

JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null

JSON的 属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号

  1. JSON对象基本结构示例
let responseData = {
    "data": {
        "list": [
            {
                "name": '张三',
                "age": 12,
                "score": 89
            },
            {
                "name": '李四',
                "age": 14,
                "score": 78
            },
            {
                "name": '王五',
                "age": 13,
                "score": 93
            }
        ],
        "totalNumber": 48
    },
    "message": '获取学生列表数据成功',
    "code": 200
}
  1. 方法列表
类别名称说明
方法parse解析JSON字符串并返回对应的值
方法stringify返回与指定值对应的JSON字符串

在vue中,我们经常使用JSON.parse(JSON.stringify(数据))的方式,对数据进行深度拷贝

3.9.4 Date
  1. 构造函数
构造函数说明
new Date()当前时间日期对象
new Date(毫秒数)指定毫秒数日期对象,1970-01-01 00:00:00开始
new Date(dateString)指定格式字符串日期,MM DD,YYYY hh:mm:ss
new Date(年,月,日,小时,分,秒,毫秒)创建指定数值的日期对象
  1. 成员方法
名称
getFullYear()从 Date 对象以四位数字返回年份
getMonth()从 Date 对象返回月份 (0 ~ 11)
getDate()从 Date 对象返回一个月中的某一天 (1 ~ 31)
getDay ()从 Date 对象返回一周中的某一天 (0 ~ 6),0为星期天
getHours ()返回 Date 对象的小时 (0 ~ 23),24时自动变为0
getMinutes()返回 Date 对象的分钟 (0 ~ 59)
getSeconds()返回 Date 对象的秒数 (0 ~ 59)
getMilliseconds()返回 Date 对象的毫秒(0 ~ 999)
getTime()返回 1970 年 1 月 1 日至今的毫秒数。
//获取当前的日期对象
let dateData = new Date();

//获取当前的年份
let year = dateData.getFullYear();
console.log(`今年是:${year}年`);
//获取当前的月份(0~11)
let month = dateData.getMonth() + 1;
console.log(`本月是:${month}月`);
//获取当天的日期
let date = dateData.getDate();
console.log(`今天是:${date}日`);
//获取当天的星期数
let day = dateData.getDay();
console.log(`今天的星期数是:${day}`);
//获取当前的小时数(0~23),24时自动变为0
let hour = dateData.getHours();
console.log(`当前是:${hour}点`);
//获取当前的分钟数(0~59)
let minute = dateData.getMinutes();
console.log(`当前是:${minute}分`);
//获取当前的秒数(0~59)
let second = dateData.getSeconds();
console.log(`当前是:${second}秒`);
//获取当前的豪秒数(0~59)
let millisecond = dateData.getMilliseconds();
console.log(`当前是:${millisecond}豪秒`);
//获取 1970 年 1 月 1 日至今的毫秒数
let time = dateData.getTime();
console.log(`1970 年 1 月 1 日至今的毫秒数是:${time}豪秒`);

//获取本月有多少天
let mineDate = new Date(year,month,0);
console.log(`${year}${month}月一共有:${mineDate.getDate()}天`)
3.9.5 Math
  1. 属性和方法
类别方法描述
属性E返回算术常量 e,即自然对数的底数(约等于2.718)
属性PI返回圆周率(约等于3.14159)
方法abs(x)返回 x 的绝对值
方法ceil(x)对 x 进行上舍入
方法floor(x)对 x 进行下舍入
方法max(x,y,z,…,n)返回最高值
方法min(x,y,z,…,n)返回最低值
方法pow(x,y)返回 x 的 y 次幂
方法random()返回 0 ~ 1 之间的随机数(不包括1)
方法round(x)把 x 四舍五入为最接近的整数
方法sqrt(x)返回 x 的平方根
//算术常量e的值
console.log(Math.E);
//圆周率
console.log(Math.PI);
//绝对值
console.log(Math.abs(-183));
//获取最大值
let number = [2,56,23,567,13,54];
console.log(Math.max(...number));

/**
 * 获取指定范围的随机一个整数值
 * @param minNum 最小值
 * @param maxNum 最大值
 * @returns number 整数
 */
function getRandomNum(minNum, maxNum) {
    //假设我们希望获取一个10~100的随机整数
    //1. Math.random() 获取一个0~1的随机小数(不包括1) 也就是[0,1)
    //2. maxNum - minNum 计算出两个数的差值 也就是100-10=90
    //3. Math.random() * (maxNum - minNum) 的值就变成了[0,90)
    //4. Math.random() * (maxNum - minNum) + minNum 的值就变成了[10,100)
    //5. Math.floor(Math.random() * (maxNum - minNum) + minNum) 的值就变成了[10,99],可以发现这里100没有包含进来,因此在maxNum - minNum需要+1
    return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum);
}

8. 浏览器中的JS代码调试

  1. 设置断点
  2. 刷新页面运行程序
  3. 通过单行或者进入的方式查看程序执行过程以及,执行过程中的数据

8.1 设置断点

  1. 通过F12键 ,进入浏览器调试模式
  2. 找到浏览开发者窗体Source选项
  3. 在page界面中找到需要调试的代码
  4. 在代码的指定行设置断点

8.2 开始调试

  1. 在开发者窗体按Ctrl+R
  2. 在页面展示窗体按F5或者Shift + F5, Shift + F5会帮助我们清空本地缓存从服务器重新获取数据

4. 客户端 Web API

全称Client side Web API

w3c官方介绍页:https://www.w3.org/standards/webdesign/script

mozilla Web 介绍首页:https://developer.mozilla.org/zh-CN/docs/learn

mozilla WebAPI参考页:https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Client-side_web_APIs

JavaScript组成部分回顾

  1. ECMAScript, 语法结构组成
  2. BOM (Browser Object Model) , 浏览器对象模型
  3. DOM (Document Object Model) , 文档对象模型

4.1 什么是浏览器对象模型

Internet Explore 3 和 Netspace Navigator3 有一个共同的特色,那就是支持可以访问和操作浏览器窗口的浏览器对象模型(BOM)。开发人员使用BOM可以控制浏览器显示的页面以外的部分。而BOM真正与众不同的地方,还是他作为JavaScript实现的一部分却没有相关的标准。这个问题在HTML5中得到了解决,HTML5致力于把很多BOM功能写入正式规范。

本质上讲,BOM只处理浏览器窗口和框架;但大家习惯上也把所有针对浏览器的JavaScript扩展算作BOM的一部分。算入扩展的内容.

  • 弹出新浏览器窗口的功能
  • 移动、缩放和关闭浏览器的功能
  • 提供浏览器详细的navigator对象
  • 提供浏览器所加载页面的详细信息的location对象
  • 提供用户显示器分辨率详细信息的screen对象
  • 对cookies的支持
  • 像XMLHttpRequest和ActiveObject这样的自定义对象。

上述内容来源于:《Professional JavaScript for Web Developers》 4th Edition , [JavaScript 高级程序设计] 第10~11页。

4.2 什么是文档对象模型

参考链接: https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents

在浏览器标签中当前载入的文档用文档对象模型来表示。这是一个由浏览器生成的“树结构”,使编程语言可以很容易的访问HTML结构 — 例如浏览器自己在呈现页面时,使用它将样式和其他信息应用于正确的元素,而页面呈现完成以后,开发人员可以用JavaScript操作DOM

HTML文档中每个元素或子元素都是一个节点:

  • 整个文档是一个文档节点
  • 每个HTML元素是一个元素节点
  • 包含在HTML元素中的文本是文本节点
  • 每个HTML属性是一个属性节点
  • 注释属于注释节点
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>DOM节点的示例</title>
</head>
<body>
<img src="./img/xuetang9.jpg" alt="老九学堂" id="ljxt" />
<h1>老九学堂校友会</h1>
<p>DOM应用</p>
</body>
</html>

5. 浏览器对象模型

5.1 常见BOM

  1. window : 表示浏览器窗口对象,提供了一系列的函数、属性、可绑定事件。https://developer.mozilla.org/zh-CN/docs/Web/API/Window
  2. location: 表示其链接到的对象的位置(URL)。所做的修改反映在与之相关的对象上。window与document对象都将location对象作为属性。https://developer.mozilla.org/zh-CN/docs/Web/API/Location
  3. history:是一个只读属性,用来获取History 对象的引用,History 对象提供了操作浏览器会话历史(浏览器地址栏中访问的页面,以及当前页面中通过框架加载的页面)的接口。https://developer.mozilla.org/zh-CN/docs/Web/API/History

5.2 window 对象

5.2.1 常用函数

**参考地址:**https://developer.mozilla.org/zh-CN/docs/Web/API/Window

说明:

js内置函数在属于ECMAScript语言与WebAPI无关,不过对于浏览器而言函数直接绑定在window对象上。内置函数地址: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects

函数说明
alert(消息)弹出消息警告窗,包含一个“确认”按钮,传入的任何消息都会转化为文本
confirm(消息)弹出消息确认窗,包含“确定”、“取消"两个按钮,选择确定返回true,否则返回false
prompt(消息,默认值)弹出输入消息窗,当用户确认时返回用户输入内容,否则返回null
parseInt(字符串,进制)js内置函数,将输入字符串转化为整数,进制表示字符串表示字符串的进制单位,默认为10进制
parseFloat(字符串)js内置函数,将输入数据转化为浮点数
isNaN(内容)js内置函数,判断传入内容是否不是一个数字
open(地址,窗口名称,窗口特征)打开一个新的窗口,窗口特征包括 大小,位置,滚动条等
addEventListener(事件名,事件函数)给窗体添加一个指定的事件
removeEventListener(事件名)移除添到窗体的一个指定的事件
setTimeout(函数,延时,参数)在指定延时毫秒单位之后,执行传入函数。函数参数在第三个从参数传递,返回值为定时器编号,可以根据该编号取消执行定时器函数
clearTimeout(编号)取消执行定时器函数,参数为setTimeout()函数返回的编号
setInterval(函数,延时,参数)根据给定的时间周期执行传入的函数,第三个参数为函数执行需要的参数,返回值为定时器编号,可以根据该编号取消执行该函数
clearInterval(编号)取消执行setInterval()启动的定时器,参数会setInterval函数的返回值
getComputedStyle(element)用于计算指定元素的样式信息,只读
5.2.2 常用事件属性

说明:

  1. 事件属性赋值通常直接赋值一个事件回调函数,即事件发生时需要执行的操作
  2. 对于事件而言,参数为事件在执行时,事件执行对象传递给事件指定函数的参数列表,即可以**在方法中接收到的数据**
  3. 未列出事件查看:https://developer.mozilla.org/zh-CN/docs/Web/API/Window
属性名说明
onload在文档装载完成后会触发 load 事件。此时,在文档中的所有对象都在DOM中,所有图片,脚本,链接以及子框都完成了装载
onclose关闭窗体时触发的事件
onresize窗体尺寸发生变化时触发的事件
onscroll窗体页面内容滚动时触发的事件
onkeydown全局监听键盘按下的事件
onkeyup全局监听键盘松开的事件
onkeypress全局监听键盘按下并产生字符时的事件(ctrl、shift之类的键不会触发)
5.2.3 示例
window.onload = function () {
    //将字符转为数字
    let money = "1838";
    console.log(typeof parseInt(money));
    //判断内容是否为数字
    console.log(isNaN("¥1835.00"));

    //添加一个键盘按下事件
    window.addEventListener('keydown',function (e) {
        console.log(e);
    });

    //监听页面滚动事件
    window.onscroll = function (e) {
        console.log(e);
    }
}

5.3 location 对象

5.3.1 常用属性与函数

**参考地址:**https://developer.mozilla.org/zh-CN/docs/Web/API/Location

类别名称说明
属性href表示url的字符串,可以修改用于加载新的页面
属性protocol当前页面的协议
属性host当前页面的域名,域名、端口号
属性hostname当前页面域名,无端口号
属性port当前页面端口号
方法reload()刷新当前页面
方法replace(页面地址)加载一个指定地址的页面
5.3.2 示例
window.onload = function () {
    console.log(`当前页面的连接为:${location.href}`);
    console.log(`当前页面所使用的协议为:${location.protocol}`);
    //按下回车键,页面跳转至百度
    window.addEventListener('keydown',e => {
        if(e.key === 'Enter') {
            //location.href = "http://www.baidu.com";
            location.replace("http://www.baidu.com");
        }
    });
}

5.4 history 对象(了解)

5.4.1 常用属性与函数

**参考地址:**https://developer.mozilla.org/zh-CN/docs/Web/API/History

类别名称说明
属性length当前历史记录中页面的个数,包括当前页面
方法back()回退一个页面,当没有页面的时候不报错
方法forward()前进一个页面,当没有页面的时候不报错
方法go(前进或后退的数值)根据数值前进或者后退,正数前进、负数后退、0刷新
5.4.2 示例

起始页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>history对象起始页面</title>
</head>
<body>
<h2>起始页面</h2>
<a href="./2.4-history-html2.html">前往目标页面</a>
<script type="text/javascript">
    window.addEventListener('keydown',e => {
        //前往下一个
        if(e.key === 'Enter') {
            history.forward();
        }
    });
</script>
</body>
</html>

目标页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>history对象目标页面</title>
</head>
<body>
<h2>目标页面</h2>
<script type="text/javascript">
    window.addEventListener('keydown',e => {
        //返回上一个页面
        if(e.key === 'Enter') {
            history.back();
        }
    });
</script>
</body>
</html>

6. 文档对象模型

6.1 常见DOM

**参考网址:**https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model

  1. Document(文档对象), 表示加载到浏览器的页面文件。提供一系列对页面中标签、标签属性、文本、注释等操作的对象与方法。将页面标签、标签属性、文本、注释放在一颗树结构中进行操作
  2. Node、NodeList、ChildNode、ParentNode(节点对象),页面解析成的树中的所有成员都可以用节点来表示
  3. Element、HTMLElement(元素对象),表示HTML页面上的标签
  4. Attr(属性对象),表示添加在标签上的属性
  5. Text(文本对象), 表示HTML页面上的文本
  6. Comment(注释对象),表示HTML页面上的注释
  7. Event(事件对象),表示为标签、窗体等添加的事件。

6.2 document对象(重要)

6.2.1 常见属性与方法

参考地址: https://developer.mozilla.org/zh-CN/docs/Web/API/Document

类别名称说明
属性body获得页面的body标签对象
属性forms获得页面的表单列表
属性cookie用分号分隔的 cookie 列表,或设置 cookie。HTML5新加
属性referrer获取页面的来源url
属性title获取页面标题字符串
属性defaultView获取界面绑定的window对象
方法getElementById(名称)根据id名称查找一个元素
方法getElementsByClassName(名称)根据样式名称查找元素
方法getElementsByName(名称)根据名称属性名查找元素
方法getElementsByTagName(名称)根据标签名查找元素
方法querySelector(CSS选择器)根据选择器字符串查找单个元素,存在多个取第一个
方法querySelectorAll(CSS选择器)根据选择器字符串查找元素
方法createElement(元素名)根据元素名在内存中创建元素对象
方法write(文本)输出文本到页面上,可以输出标签文本会被解析
方法writeln(文本)输出文本到页面上,可以输出标签文本会被解析,产生换行符

document.write() 系列方法会覆盖原有的代码内容,因此建议少用或者不用

6.2.2 示例
window.onload = function () {
    document.cookie = "name=张三";
    document.cookie = "age=18";
    console.log(document.cookie);
    
    console.log(document.querySelector("p"));
    console.log(document.querySelectorAll("p"));
    console.log(document.createElement("a"));
}

6.3 Node节点对象

说明:

对于Node而言,最重要的是nodeType。主要根据nodeType判断当前是什么节点,用的比较少。

参考链接:https://developer.mozilla.org/zh-CN/docs/Web/API/Node

6.3.1 常见属性
属性说明
nodeType节点类型
nodeName节点名称
nodeValue节点值
childNodes所有的子节点对象数组
parentNode父节点
parentElement父元素节点
firstChild第一个子节点
lastChild最后一个子节点
nextSibling下一个兄弟节点
previousSibling前一个兄弟节点
innerHTML输出或设置HTML代码文本
outerHTML将节点以字符串形式输出
innerText输出或设置源码文本
6.3.2 nodeType对应表
中文名节点类型名Value
元素节点ELEMENT_NODE1
属性节点ATTRIBUTE_NODE2
文本节点TEXT_NODE3
CDATA节点CDATA_SECTION_NODE4
实体引用节点ENTITY_REFERENCE_NODE5
实体节点ENTITY_NODE6
处理指令节点PROCESSING_INSTRUCTION_NODE7
注释节点COMMENT_NODE8
文档节点DOCUMENT_NODE9
文档类型节点DOCUMENT_TYPE_NODE10
文档判断节点DOCUMENT_FRAGMENT_NODE11
符号节点NOTATION_NODE12
6.3.3 示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>演示Node节点对象</title>
</head>
<body>
<div class="container">
    <h2>内容标题</h2>
</div>
<script type="text/javascript">
    window.onload = function () {
        let container = document.querySelector(".container");
        console.log(container.nodeType);    //节点类型
        console.log(container.nodeName);    //节点名称
        console.log(container.nodeValue);   //节点值
        console.log(container.childNodes);  //所有子节点
        console.log(container.innerHTML);
        console.log(container.outerHTML);
    }
</script>
</body>
</html>

6.4 Element节点对象(重要)

**Element节点对象参考链接:**https://developer.mozilla.org/zh-CN/docs/Web/API/Element

6.4.1 常见属性
名称说明
attributes所有属性列表
children子元素列表
style行内样式属性对象
className内部或者外部样式名称
classList样式列表:
add(class1[,class2,…])给元素添加一个或多个类样式名,如果指定的类样式名已存在,则不会添加
remove(class1[,class2,…])移除元素中一个或多个类样式名
contains(className)返回布尔值,判断指定的类名是否存在
id获取元素的id
firstElementChild第一个子元素节点(不兼容IE)
lastElementChild最后一个子元素节点(不兼容IE)
nextElementSibling下一个兄弟节点(不兼容IE)
previousElementSibling上一个兄弟节点(不兼容IE)
clientWidth边框内的宽度:包括了内容的宽度和panding,但不包含滚动条宽度
clientHeight边框内的高度
clientLeft内容左侧距离
clientTop内容顶部距离
scrollTop读取或设置元素滚动条到元素顶部的距离(元素的内容没有产生垂直方向的滚动条,那么它的scrollTop值为0)
scrollLeft读取或设置元素滚动条到元素左边的距离(元素的内容没有产生水平方向的滚动条,那么它的scrollLeft值为0)
6.4.2 常见方法
名称说明
appendChild(node)将节点拼接在当前节点内部的最后面
insertBefore(newNode, referenceNode)将节点拼接在当前节点内部的最前面
referenceNode表示父节点的指定子节点,如果传入null表示将newNode添加到父节点的内部最后面
removeChild(node)删除节点中的指定子节点
replaceChild(newNode, oldChild)将节点的指定子节点(oldChild)替换为新的节点(newNode)
getAttribute(name)获取节点指定的name属性
hasAttribute(name)判断节点是否存在指定的name属性
setAttribute(name,value)为节点添加指定的name属性并且值为value
6.4.4 示例

节点拼接

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>演示Element节点对象</title>
</head>
<body>
<table>
    <thead>
    <tr>
        <th><input type="checkbox" /></th>
        <th>商品编号</th>
        <th>商品简称</th>
        <th>单位</th>
        <th>规格</th>
        <th>商品分类</th>
        <th>采购单价</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00001</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00002</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00003</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00004</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    </tbody>
</table>
<script type="text/javascript">
    window.onload = function () {
        //移除第二个tr
        let tr = document.querySelector('table tr:nth-child(2)');
        tr.parentNode.removeChild(tr);
        
        //给最后一个tr的最后一个td添加一个属性data-id,值为4
        document.querySelector('table tr:last-child td:last-child').setAttribute('data-id','4');

        //给tbody再添加一个tr
        let trNode = document.createElement('tr');
        trNode.innerHTML = `
            <td><input type="checkbox" /></td>
            <td>00005</td>
            <td>青岛啤酒纯度8度</td>
            <td>青岛纯生</td>
            <td>箱</td>
            <td>600mlx24</td>
            <td>32.00</td>
            <td>
                <button>上架</button>
                <button>编辑</button>
                <button>删除</button>
                <button>一店一价</button>
            </td>
        `;
        document.querySelector('table tbody').appendChild(trNode);
    }
</script>
</body>
</html>

6.5 HTMLElement节点

HTMLElement节点参考链接: https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement

6.5.1 常见属性
名称说明
offsetWidth布局宽度:包含元素的边框、水平线上的内边距、竖直方向滚动条以及CSS设置的宽度的值
offsetHeight布局高度
offsetTop获取当前DOM节点元素距离浏览器顶部的距离,单位是像素
offsetLeft获取当前DOM节点元素距离浏览器左侧的距离,单位是像素
6.5.2 常见鼠标事件
名称说明
click单击
dbclick双击
mousedown按下
mouseup松开
mouseenter光标移入元素时触发
mouseleave光标移出元素时触发
mouseover光标移入元素时触发,进入子元素也会触发
mouseout光标移出元素时触发,离开子元素也会触发
mousemove光标在元素上移动时触发
6.5.3 常见键盘事件
名称说明
keydown键盘按下
keyup键盘松开
keypress键盘按下并产生字符时的事件(ctrl、shift之类的键不会触发)
6.5.4 特殊事件
名称说明
focus输入框获取焦点
blur输入框失去焦点
select内容选中
input输入框输入内容
change元素内容发生改变
6.5.5 示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>演示HTMLElement节点对象</title>
    <style type="text/css">
        table {
            border-collapse: collapse;
        }
        table.border th,table.border td {
            border: 1px solid black;
        }
    </style>
</head>
<body>
<table>
    <thead>
    <tr>
        <th><input type="checkbox" /></th>
        <th>商品编号</th>
        <th>商品简称</th>
        <th>单位</th>
        <th>规格</th>
        <th>商品分类</th>
        <th>采购单价</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00001</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00002</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00003</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox" /></td>
        <td>00004</td>
        <td>青岛啤酒纯度8度</td>
        <td>青岛纯生</td>
        <td></td>
        <td>600mlx24</td>
        <td>32.00</td>
        <td>
            <button>上架</button>
            <button>编辑</button>
            <button>删除</button>
            <button>一店一价</button>
        </td>
    </tr>
    </tbody>
</table>
<button class="border-btn">表格边框</button>
<script type="text/javascript">
    window.onload = function () {
        let table = document.querySelector('table');
        //点击“表格边框”按钮,实现添加或移除表格边框的样式
        document.querySelector('button.border-btn').addEventListener('click',e => {
            if(table.classList.contains('border')) {
                table.classList.remove('border');
            }else {
                table.classList.add('border');
            }
        });
    }
</script>
</body>
</html>

7. 表单验证(掌握)

输入元素参考链接: https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLInputElement

**表单元素参考链接:**https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLFormElement

7.1 获取输入元素值

  1. 使用元素value属性

7.2 表单对象验证事件与方法

类型名称说明
方法submit()提交表单
方法reset()重置表单
事件submit表单提交时执行,当事件执行函数返回false时,
会阻止表单向服务器提交数据,表示数据验证不通过
事件reset表单重置时执行
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>演示表单验证基础</title>
</head>
<body>
<form method="post">
    <label>
        <input type="text" name="account" placeholder="请填写账号" />
    </label>
    <button>普通按钮</button>
    <input type="submit" value="表单提交按钮" />
</form>
<script type="text/javascript">
    //普通按钮执行表单提交方法
    document.querySelector('button').addEventListener('click',e => {
        console.log('手动执行表单提交');
        document.querySelector('form').submit();
    });

    //表单提交事件
    document.querySelector('form').addEventListener('submit',e => {
        console.log('触发表单提交事件');
        //阻止表单提交(e.preventDefault()的作用是阻止默认的行为)
        e.preventDefault();
    });
</script>
</body>
</html>

7.3 正则表达式(重要)

**参考链接:**https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

7.3.1 什么是正则表达式

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。

7.3.2 js中创建正则表达式
let reg = /^[a-zA-Z\d_]{6,10}$/;	//快速创建正则表达式方式

let reg2 = new RegExp('^[a-zA-Z\d_]{6,10}$');	//通过对象创建正则表达式
7.3.3 字符元字符
字符含义
\转义字符,可以将特殊符号转移为普通字符,
例如+,代表一个’+‘号,\代表’'本身。特殊情况:\n代表一个换行符
^匹配字符串开始的位置,与后面紧邻的字符进行配合
$匹配字符串结束的位置,与前面紧邻的字符进行配合
*匹配前面的字符或者表达式出现0次或多次,等价于{0,}
+匹配前面的字符或者表达式出现一次或多次,等价于{1,}
?匹配前面的字符或者表达式出现零次或一次,等价于{0,1}
.匹配除换行符\n之外的任何单个字符
|或者的意思。例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’
()将表达式组合起来,括号中的内容可以被上面的特殊符号修饰
7.3.4 表达式元字符
字符含义
{n}匹配前面的字符或者表达式,指定匹配次数为n次
{n,}匹配前面的字符或者表达式,指定匹配次数至少为n次
{n,m}匹配前面的字符或者表达式,指定匹配次数至少n次,最多m次
[xyz]字符合集,匹配里面包含的任意一个字符。例如[abcd]代表abcd中的任意一个字符,也可以用-来进行范围约束,例如[a-z]、[0-9]、[A-z]、[A-z0-9]、[A-z0-9_]、[\u4e00-\u9fa5]
[^xyz]匹配不包含里面字符的其他任意一个字符。例如[^abcd]代表除了abcd以外的任意一个字符
\d匹配0-9中任意一个阿拉伯数字,相当于[0-9]。
\D匹配一个非阿拉伯数字,等价于[^0-9]
\f匹配一个换页符(U+000C)。
\n匹配一个换行符(U+000A)。
\r匹配一个回车符(U+000D)。
\s匹配一个空白字符,包括空格、制表符、换页符和换行符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
\S匹配一个非空白字符。等价于 [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
\t匹配一个水平制表符 (U+0009)。
\v匹配一个垂直制表符 (U+000B)。
\w匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]
\W匹配一个非单字字符。等价于 [^A-Za-z0-9_]
7.3.6 正则表达式方法
字符含义
exec查找字符串中满足规则的字符串,它返回一个数组(未匹配到则返回 null)。每次只匹配一个,其会返回lastIndex来表示下一个匹配的起始索引值,当我们再次执行exec时,自动从这里开始继续搜索,知道为null为止
test测试字符串是否匹配规则,它返回 true 或 false
7.3.7 高级搜索标志
字符含义
g全局搜索
i不区分大小写搜索
let str = 'a1c240eabc0abc1';
let result;
let reg = /[A-z0-9]{3}/;
//通过循环来查找所有能够匹配的字符串
while ((result = reg.exec(str)) !== null) {
    console.log(result);
}
let reg2 = /[A-z0-9]{3}/g;
while ((result = reg2.exec(str)) !== null) {
    console.log(result);
}
7.3.8 贪婪模式与非贪婪模式

贪婪模式的元字符包括:{n,}{n,m}?*+

贪婪模式的特性:匹配尽可能多的字符

非贪婪模式的特性:匹配尽量少的字符

在贪婪模式元字符后面加上?即可将其变为非贪婪模式:{n,}?{n,m}???*?+?

//贪婪模式
let str = 'd131adafdae';
let reg = /d\w+/;       //\w+将会匹配d之后所有的字符,有多少匹配多少
console.log(reg.exec(str));
let reg2 = /d\w+d/;     //虽然\w中包含有d,但是为了使整个表达式匹配成功,\w会让出最后一个匹配的d
console.log(reg2.exec(str));

//非贪婪模式
let reg3 = /d\w+?/;     //\w+?只会匹配d之后的1个字符
console.log(reg3.exec(str));
let reg4 = /d\w+?d/;     //尽可能少的匹配字符,为了让整个表达式匹配成功,不得不多匹配几个字符才能让后面的d匹配
console.log(reg4.exec(str));

7.4 表单验证示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>演示表单验证</title>
</head>
<body>
<form method="post">
    <label>
        <input type="text" name="account" autocomplete="off" placeholder="请填写账号" />
        <p class="tip"></p>
    </label>
    <label>
        <input type="password" name="pwd" autocomplete="off" placeholder="请填写密码" />
        <p class="tip"></p>
    </label>
    <input type="submit" value="表单提交按钮" />
</form>
<script type="text/javascript">
    //表单提交事件
    document.querySelector('form').addEventListener('submit',e => {
        //校验账号是否符合规则
        let accountValidate = false;
        let accountIpt = document.querySelector('input[name="account"]');
        let accountTip = accountIpt.nextSibling.nextSibling;
        let accountVal = accountIpt.value;
        //账号要求: 1.不能为空 2.6~10位字母或者数字
        let iptReg = /^[a-zA-Z0-9]{6,10}$/;
        if(accountVal.length === 0) {
            accountTip.innerHTML = '账号不能为空';
        }else if(!iptReg.test(accountVal)) {
            accountTip.innerHTML = '账号格式不正确,请输入6~10位字母或者数字';
        }else {
            accountTip.innerHTML = '';
            accountValidate = true;
        }

        //校验密码是否符合规则
        let pwdValidate = false;
        let pwdIpt = document.querySelector('input[name="pwd"]');
        let pwdTip = pwdIpt.nextSibling.nextSibling;
        let pwdVal = pwdIpt.value;
        //账号要求: 1.不能为空 2.6~10位字母或者数字或者下划线
        let pwdReg = /^\w{6,10}$/;
        if(pwdVal.length === 0) {
            pwdTip.innerHTML = '密码不能为空';
        }else if(!pwdReg.test(pwdVal)) {
            pwdTip.innerHTML = '密码格式不正确,请输入6~10位字母或者数字或者下划线';
        }else {
            pwdTip.innerHTML = '';
            pwdValidate = true;
        }
        //如果校验不通过,那么禁止提交表单
        if(!accountValidate || !pwdValidate) e.preventDefault();
    });
</script>
</body>
</html>

8.承诺 Promise

Promise 是异步编程的一种解决方案。简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息

参考链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

8.1 Promise的三种状态

待定(pending): 初始状态,既没有被兑现,也没有被拒绝

已兑现(fulfilled): 意味着操作成功完成

已拒绝(rejected): 意味着操作失败

8.2 Promise的特点

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected),它不会受到外界因素的影响

如果一个 promise 已经被兑现(fulfilled)或被拒绝(rejected),那么我们可以说它处于已敲定(settled)状态,一旦已敲定,就不会再被更改。

我们还会听到一个经常跟 promise 一起使用的术语:已决议(resolved),它表示 promise 已经处于已敲定(settled)状态,或者为了匹配另一个 promise 的状态被"锁定"了

8.3 Promise方法

方法名描述
then(onFulfilled, onRejected)添加兑现(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果
onFulfilled表示:当 Promise 变成已兑现(fulfilled)时调用的函数
onRejected表示:当 Promise 变成拒绝状态(rejected)时调用的函数
catch(onRejected)添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise,将以回调的返回值来resolve
finally加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)

因为then、catch、finally都会返回一个新的Promise对象,因此它们是可以串联使用的。

8.3 示例

8.3.1 普通示例
/**
  * 创建一个Promise对象
  * resolve:Promise逻辑执行成功时调用
  * reject:Promise逻辑执行失败时调用
  */
let divisionPromise = new Promise(function (resolve, reject) {
    let num = parseInt(prompt('请输入一个值,用于与100相除'));
    if(isNaN(num)) {
        reject('输入的不是数字');
    }else if(num === 0) {
        reject('除数不能为0');
    }else {
        let end = 100 / num;
        resolve(end);
    }
});
//添加兑现和拒绝的回调到当前Promise
divisionPromise.then(function (endNum) {
    alert(`除法成功,最终值为:${endNum}`);
},function (message) {
    alert(`除法失败:${message}`);
});
8.3.2 模拟数据统计
window.onload = function () {
    new Promise(resolve => {
        alert('下面进行一个数据统计,每个人说一个数:');
        resolve();
    })
        .then(() => {
            return new Promise((resolve, reject) => {
                let num = parseInt(prompt('我是张三,我说的数字是:'));
                isNaN(num) ? reject('输入的不是数字') : resolve(num);
            });
    	})
        .then((num) => {
            return new Promise((resolve, reject) => {
                let num2 = parseInt(prompt('我是李四,我说的数字是:'));
                isNaN(num2) ? reject('输入的不是数字') : alert(`两个数的总和是:${num + num2}`);
            });
        })
        .catch(message => {
            alert(message);
        })
        .finally(() => {
            alert('数据统计结束!');
        })
}
8.3.3 使用串联方式连续实现动画
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Promise连续动画</title>
    <style type="text/css">
        div {
            width: 200px;
            height: 200px;
            background-color: #17a2b8;
            position: absolute;
            top: 0;
            left: 0;
            transition: all 1s linear;
        }
        div.start {
            border-radius: 50%;
        }
        div.move-right {
            left: calc(100vw - 200px);
        }
        div.color {
            background-color: #c69500;
        }
        div.move-bottom-right {
            top: calc(100vh - 200px);
            left: 0;
        }
    </style>
</head>
<body>
<div></div>
<script type="text/javascript">
    window.onload = function () {
        let div = document.querySelector('div');
        new Promise(resolve => {
            setTimeout(() => {
                div.classList.add('start');
                resolve();
            },1500)
        })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('move-right');
                        resolve();
                    },1500);
                });
            })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('color');
                        resolve();
                    },1000);
                });
            })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('move-bottom-right');
                        resolve();
                    },1000);
                });
            })
    }
</script>
</body>
</html>

seInt(prompt(‘我是李四,我说的数字是:’));
isNaN(num2) ? reject(‘输入的不是数字’) : alert(两个数的总和是:${num + num2});
});
})
.catch(message => {
alert(message);
})
.finally(() => {
alert(‘数据统计结束!’);
})
}


#### 8.3.3 使用串联方式连续实现动画

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Promise连续动画</title>
    <style type="text/css">
        div {
            width: 200px;
            height: 200px;
            background-color: #17a2b8;
            position: absolute;
            top: 0;
            left: 0;
            transition: all 1s linear;
        }
        div.start {
            border-radius: 50%;
        }
        div.move-right {
            left: calc(100vw - 200px);
        }
        div.color {
            background-color: #c69500;
        }
        div.move-bottom-right {
            top: calc(100vh - 200px);
            left: 0;
        }
    </style>
</head>
<body>
<div></div>
<script type="text/javascript">
    window.onload = function () {
        let div = document.querySelector('div');
        new Promise(resolve => {
            setTimeout(() => {
                div.classList.add('start');
                resolve();
            },1500)
        })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('move-right');
                        resolve();
                    },1500);
                });
            })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('color');
                        resolve();
                    },1000);
                });
            })
            .then(() => {
                return new Promise(resolve => {
                    setTimeout(() => {
                        div.classList.add('move-bottom-right');
                        resolve();
                    },1000);
                });
            })
    }
</script>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值