前端学习心得笔记之三(JavaScript篇)

 

前言

JavaScript一种运行在客户端(浏览器)上的解释性弱语言,是前端的重中之重,在计算机刚刚兴起的那个时代,这个由十天仓促编成的语言发展到现在也是令人吹嘘。

基础语法

文件引用

在一个单独的js文件中也可以编写JavaScript代码,然后在HTML文件使用script标签进行引用以下为演示

main.html

main.js

alert(“hello,world”)

注意:外部JavaScript会是代码更加有序,更易于复用,且没有了脚本的混合,HTML也会更加易读,是个好的习惯。

但是引用之后,script标签中间无需写代码,否则会被忽略

输出

使用JavaScript向页面输出一句话。

注意:如果输入的内容写的是标签,也会被解析成网页元素。

结束符

作用:使用英文的“;”表示语句结束

实际情况:实际开发中,可写可不写,浏览器可以自动推断语句的结束位置

现状:在实际开发中,越来越多的人主张,书写JavaScript代码时省略结束符

约定:为了统一,结束符要么每句都写,要么每句的不写

所有直觉性的“当然应该加分号”都是保守的,未经深入思考的草率结论,所有Vue.js的代码全部不带分号。

——尤雨溪

即使语句末尾的分号不是必需的,也应该加上。记着加分号有助于防止省略造成的问题,比如可以避免输入内容不完整。此外,加分号也便于开发者通过删除空行来压缩代码(如果没有结尾的分号,只删除空行,则会导致语法错误)。加分号也有助于在某些情况下提升性能,因为解析器会尝试在合适的位置补上分号以纠正语法错误。

——《JavaScript高级程序设计》

 

 

控制台输出

向控制台输出一句话

输入

prompt语句

作用:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

弹出窗口输出

使用JavaScript向弹出窗口输出一句话,如下

注释

单行注释://注释内容

多行注释:/*注释内容*/

单行注释:快捷键为ctrl+/

多行注释:其内容均会被注释,快捷键为shift+alt+a

字面量

在计算机科学中,字面量(literal)是在计算机中描述 事/物

比如:

      我们的工资是: 1000  //此时1000就是  数字字面量

      程序员    //字符串字面量

      还有接下来要学习的 [] 数组字面量  {}  对象字面量  等等 

变量

声明变量:

要想使用变量,首先需要创建变量(称之为声明变量或者定义变量)

语法:let  变量名

声明变量有两部分构成:声明关键字、变量名(标识)

let是声明关键词

上图的代码可以直接简化为:

let age = 18
alert(age)

声明多个变量(但是提倡声明变量时,一个一个变量声明,为了更好的可读性):

变量命名规则:

  1. 不能用关键字
  2. 只能使用下划线、字母、数组、$组成,且数字不能开头
  3. 字母严格区分大小写,如Age和age是不同的变量

规范(建议使用)

1、起名要有意义

2、遵守小驼峰命名法

     第一个首字母小写,后面每个单词首字母大写。例:userNAme

因为按照惯例,ECMAscript标识符使用驼峰大小写形式,即第一个单词的首字母小写,后面每个单词的首字母大写。

这种写法并不是强制性的,但因为这种形式跟ECMAScript内置函数和对象的命名方式一致,所以算得上是最佳实践。

变量扩展:let和var区别:

在较旧的JavaScript,使用关键字var来声明变量,而不是let

var现在一般不再使用它,只是我们还能在老版程序中看到它。

let为了解决var的一些问题。

var声明:

  1. 可以先使用再声明(不合理)

不会报错,之后声明underfined,即声明变量中没有值

  1. var 声明过的变量可以重复声明(不合理)
  2. 比如变量提升、全局变量、没有块级作用域等等

数组

数组(Array)——一种将一组数据存储在单个变量名下的方式

语法:let   arr = [ ]

JavaScript中数组的使用方法与其他语言的用法相一致。

操作数组:

修改语法:arr[下标] = 数值

增加语法:利用push向数组中添加元素(数据)

1、数组.push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度

2、arr.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度

删除语法:

1、数组.pop()方法从数组中删除最后一个元素,并返回该元素的值

2、数组.splice()方法   删除指定元素,返回该元素的值

语法:arr.splice(start,deleteCount)

arr.splice(起始位置(下标),删除几个元素)

 

常量

使用const声明的变量称之为“常量”

使用场景:当某个变量永远不会改变的时候,就可以使用const来声明,而不是let。

其命名规范与变量一致。

注意:常量不允许重新赋值,并且声明的时候必须赋值(初始化)

即:不需要重新赋值的数据使用const

严格模式

ECMAScript增加了严格模式(strict mode)的概念。严格模式是一种不同的JavaScript解析和执行模型,ECMAScript 3 的一些不规范写法在这种模式下会被处理,对于不安全的活动将抛出错误。要对整个脚本启动严格模式,在脚本开头加上这一行:

“use strict“;

     它是一个预处理指令。任何支持的JavaScript引擎看到它都会切换到严格模式。选择这种语法形式的目的不破坏ECMAScript 3 语法。

     也可以单独指定一个函数在严格模式下执行,只要把这个预处理指令放到函数体开头即可:

function doSomething(){
“use strict”;
//函数体
}

所以现代浏览器都支持严格模式

 

 

数据类型

JavaScript数据类型整体分为两大类:

     基本数据类型

     引用数据类型

其中基本数据类型一共有5种基本数据类型:

     字符串型(string)

     数字型(number)

     布尔型(boolean)

     undefined型(undefined)

     null型(null)

引用数据类型

     对象(object)

因为JavaScript是一门弱数据类型的计算机语言,所以其数据类型的定义没有java和C语言等强数据类型的计算机语言那么的规范

例如:

let num = “你好”  //这里定义了一个num变量

num  =  14   //直接修改,系统不会报错

 但是在Java中:

int  num  =  14   //就是定义了一个数字类型的变量。无法修改

注意:NaN是一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。

并且NaN是粘性的。任何对NaN的操作都会返回NaN

并且如果让NaN === NaN  ,返回结果为false

字符串类型

通过单引号(’   ’)、双引号(“  ”)或反引号(`)包裹的数据都叫做字符串,单引号和双引号没有本质上的区别,推荐使用单引号。

注意事项:

console.log(11)   //所打印的11是数字类型(偏蓝色)

console.log(`11`)  //所打印的11是字符串类型(偏黑色)

模板字符串

使用场景:拼接字符串和变量

在没有模板字符串之前,要拼接字符串比较麻烦

语法:`  `(反引号)

     内容拼接变量时,用${ }包住变量

布尔类型(boolean)

表示肯定或否定时在计算机中对应的时布尔类型数据。

它有两个固定的值true和false,表示肯定的数据用true(真),表示否定的数据用false(假)

未定义类型(underdined)

未定义时比较特殊的类型,只有一个值underfined。

什么情况出现未定义类型?

只声明变量,不赋值的情况下,变量的默认值为underfined,一般很少【直接】为某个变量赋值为underfined。

使用场景:

我们开发中经常声明一个变量,等待传送过来的数据。

如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是underfined,就能判断用户是否有数据传递过来

空类型(null)

JavaScript中的null仅仅是一个代表“无“、”空“或”值未知“的特殊值

null和underfined的区别:

     underfined表示没有赋值

     null表示赋值了,但是内容为空

官方解释:把null作为尚未创建的对象(即:将来会有个变量里面存放的是一个对象,但是对象还没创建好,就先给个null)

typeof运算符

使用typeof操作符可以用来检查一个变量的数据类型

console.log(typeof 123);
console.log(typeof "Hello,World!");
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof null);

注意:JavaScript中的特殊的数字

number类型用来表示整数和浮点数,最常用的功能就是用来表示10进制的整数和浮点数。

number表示的数字大小是有限的,如果超过了范围,则会返回infinity

  • 最大值:+1.7976931348623157e+308
  • 最小值:-1.7976931348623157e+308
  • 0以上的最小值:5e-324

    即:infinity:正无穷

    -infinity:负无穷

    NaN:非法数字(Not A Number)

    其他进制:

    二进制:0b开头表示二进制,但是,并不是所有的浏览器都支持

    八进制:0开头表示八进制

    十六进制:0x开头表示十六进制

    注意:使用typeof检查一个number类型的数据时(包括NaN和infinity),会返回“number”

    语法进阶

    类型转换

    隐式转换

    某些运算符被执行时,系统内部会自动将数据类型进行转换,这种转换称为隐式转换。

    规则:+ 号两边只要一个是字符串,都会另外一个转成字符串

         在实际运算中,除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型

    缺点:转换类型不明确,靠经验才能总结

    小技巧:

         +号可以在运算之外作为正号解析将字符串型转换成数字型

         任何数据和字符串相加结果都是字符串

    显式转换

    编写程序时过度依靠系统内部的隐式转换时不严格的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常需要对数据进行显式转换。

    转换为数据类型

    Number(数据)

         转成数字类型

         如果字符串内容里有非数字,转换失败时结果为NaN(Not a Number)即不是一个数字

         NaN也是number类型的数据,代表非数字

    parseInt(数据)

    只保留整数

    parseFloat(数据)

    可以保留小数

     

    比较运算符

    “==“比较运算符有隐式转换,把”2“转换为2,并且双引号只判断值

    console.log(2 == “2”)   //true

    “===“全等,判断 值  和数据类型都一样才行  所以在JavaScript中”===“较为常用。

    逻辑运算符

    语句

    if语句

    if语句有三种使用:单分支、双分支、多分支

    单分支使用语法:

    括号内的条件为true时,进入大括号里执行代码

    小括号内的结果若不是布尔类型时,会发生隐式转换为布尔类型

    如果大括号只有一个语句,大括号可以省略……

    利用三元运算符执行满足条件的语句

    ?与:配合使用

    语法:

    switch语句

    找到跟小括号里面的数据全等的case值,并执行里面对应的代码

    若没有全等 === 的则执行default里的代码

    例:数据若跟值2全等,则执行代码2

    注意:

    1、switch  case语句一般用于等值判断,不适合于区间判断

    2、switch  case语句一般需要配合break关键字使用 ,没有break会造成case穿透。

    上图为经典的case穿透

    while循环

    循环三要素:循环的本质是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。

    所以,循环三要素如下:

    1. 变量起始值
    2. 终止条件(没有终止条件,循环就一直执行,会造成死循环)
    3. 变量变化量(用自增或自减)

    for循环

    for循环与while循环的区别

         当如果明确了循环的次数的时候推荐使用for循环

         等不明确循环的次数的时候推荐使用while循环

    函数

    函数命名规范

         和变量命名基本一致

         尽量小驼峰命名法

         前缀应该为动词

    函数传参:

    function  函数名(参数列表){

    函数体}

    当实参多于形参的时候,多出的实参无效

    当形参少于实参的时候,函数会自动填上underfined

    函数返回值“

    函数是被设计为执行特定任务的代码块,在执行完特定任务之后,把任务的结果给我们。

    缺点:把计算后的结果处理方式写死了,内部处理了。

    解决:把处理结果返回给调用者

    有返回值(return)的函数

         当调用某个函数后,这个函数会返回一个结果出来,如果return后面不接数据或者函数内不写return,函数的返回值是underfined

    匿名函数

    没有名字的函数,无法直接使用。

    使用方式:1、函数表达式2、直接执行函数

    函数表达式:将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将这个称为函数表达式

    实例如下:

    与具名函数的区别在于具名函数可以在任意位置调用,但是函数表达式必须先声明后调用。

    立即执行函数:

    场景:为了避免全局变量之间的污染

    语法:必须加分号

    对象

    对象(object):JavaScript里面的一种数据类型

    可以理解为一种无序的数据集合,注意数组是有序的数据集合

    用来描述某个事物,例如描述一个人

         人有姓名、年龄、性别等等信息,还有吃饭睡觉打代码等功能

         如果用多个变量保存则比较分散,用对象比较统一

    对象使用

    属性:信息或者叫特征(名词)。比如 手机尺寸、颜色、重量等等

    方法:功能或叫行为(动词)。比如 手机打电话、发短信、玩游戏

    属性:数据描述性的信息称之为属性,如人的性命、身高、年龄、性别等,一般是名词性的。

    属性都是成对出现的,包括属性名和值,它们之间使用英文“:“分隔

    多个属性之间使用英文,分隔

    属性就是依附在对象上的变量(外面是变量,对象内是属性)

    属性名可以使用双引号(“ “)或单引号(’ ’),一般情况下省略,除非名称遇到特殊符号如空格、中横线等等

    增删改查:

    1、查:声明对象,并添加了若干属性后,可以使用 . 获得对象中属性对应的值,pink老师称之为属性访问。

    (1)语法:对象名.属性

    (2)语法:对象名[‘属性’]

    2、改与增:语法为对象名 .属性 = 新值

    对象中的方法:数据行为性的信息

    1. 方法是由方法名和函数两部分构成,它们之间使用“ :“分隔
    2. 多个属性之间使用英文,分隔
    3. 方法是依附在对象中的函数
    4. 方法名可以使用“ “或‘ ’,一般情况下省略,除非名称遇到特殊符号如空格、下划线、中横线等等

    遍历对象

    为什么在以上案例中不能使用“obj.k“?因为在遍历时,将‘uname’、‘age’存入变量k中,注意存入变量k中的键是带有单引号的,obj.k就相当是obj.’uname’,所以会报错。要使用obj[k]

    Web API

    声明变量:var(不考虑)、let和const

    const优先,尽量使用const,原因如下:

    1. const语义化更好
    2. 很多变量我们声明的时候就知道他不会被更改了,那为什么不用const
    3. 实际开发中,比如react框架,基本使用const

    而且:有了变量先给const,如果发现它后面是要被修改的,再改为let

    作用与分类

    作用:就是使用js去操作html和浏览器

    分类:DOM(文档对象模型)、BOM(浏览器对象模型)

    WebAPIs:是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)

    DOM(Document  Object  Model——文档对象模型)是用来呈现以及与任意HTML或XML文档交互的API。即:DOM是浏览器提供的一套专门用来操作网页内容的功能。

    DOM树:将文档以树状结构直观的表现出来,我们称之为文档树或者DOM树。下面是具体解释DOM中的一些基本的名词。

    文档(document):一个页面就是一个文档。

    元素(element):页面中的所有标签都是元素。

    节点(node):页面中所有的内容在文档树中都是节点(如元素节点,文本节点,注释节点等等)。在DOM中,所有的节点都会被看作是对象,这些对象拥有自己的属性和方法。

    并且,元素是节点的一种类型,所有的元素都是节点,但节点不一定是元素

    描述网页内容关系的名词

    作用:文档树直观的体现了标签与标签之间的关系

     

    DOM对象:浏览器根据html标签生成的js对象

         所有的标签属性都可以在这个对象上面找到

         修改这个对象的属性会自动映射到标签身上

    在HTML中,div是一个标签,但在js里面,div以及所有引进进去的标签都是对象。

    展开后可以发现div对象里面有很多的属性。

    所以:DOM的核心就是把内容当对象来处理的

    document是什么?

    是DOM里提供的一个对象,网页所有内容都在document里面。

    获取DOM标签

    一、通过CSS选择器获取

    1、选择匹配的第一个元素

    语法:

    参数:包含一个或多个有效的CSS选择器 字符串

    返回值:CSS选择器匹配的第一个元素,一个HTMLElement对象。

    CSS选择器外必须加引号

    2、选择匹配的多个元素

    语法:

    参数:包含一个或多个有效的CSS选择器 字符串

    返回值:CSS选择器匹配的NodeList 对象集合

    例如:

    但是通过CSS选择器得到的是一个伪数组:

         有长度有索引号的数组

         但是没有pop() push()等数组方法

    想要得到里面的每一个对象,则需要遍历(for)的方式获得

    注意:哪怕只要一个元素,通过querySelectAll()获取过来的也是一个伪数组,里面只要一个元素而已。

    3、其他获取DOM元素方法(了解)

    操作元素内容

    目标:能够修改元素的文本更好内容

         DOM对象都是根据标签生生成的,所以操作标签,本质上就是操作DOM对象。

         类名需要加点

    方法:1、元素.innerText属性

         将文本内容添加/更新任意标签位置

         显示纯文本,不解析标签

     

    2、元素.innerHTML属性

         将文本内容添加/更新到任意标签位置

         会解析标签,多标签建议使用模板字符

    操作元素属性

    1、操作元素常用属性

    还可以通过js设置/修改标签元素属性,比如通过src更换 图片

    最常见的属性比如:href、title、src等等

    语法:

    2、操作元素样式属性

    (1)通过style属性操作CSS

    语法:

    举例:

    注意:1、修改样式通过style属性引出

    2、如果属性有-连接符,需要转换为小驼峰命名法,否则-连接符会被识别为减号

    3、赋值的时候,需要的时候不要忘记加CSS单位

    并且,因为这种方法是通过style行内样式控制元素样式,所以权重较高。

    (2)操作类名(className)操作CSS

    如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于CSS类名的形式。

    语法:

    注意:由于class是关键字,所以使用className去代替

    className是使用新值换旧值,如果需要添加一个类,需要保留之前的类名。

    (3)通过classList操作类控制CSS(经常使用)

    为了解决className容易覆盖以前的类名,我们可以通过classList方式追加和删除类名

    语法:

    类名不需要加点

    重点提一下toggle,toggle会判断是否含有该类名,如果有就删掉,没有就加上。

    操作attribute属性

    attribute属性也是一个统称,它是指HTML标签的属性,在程序中对attribute属性的操作会直接反映到HTML标签中。attribute属性不仅可以操作元素的内置属性,还可以操作元素的自定义属性。

    语法格式如下:

    element.setAttribute(‘属性’,‘值’)

    案例如下:

    attribute还可以获取到自定义属性。

    语法格式为:element.getAttribute(‘属性’);

     

     

    移除属性:

    通过元素对象的removeAttribute方法可以移除属性

    语法格式为:element.removeAttribute(‘属性’)

    操作表单元素属性

    表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框。

    获取:DOM对象.属性名

    设置:DOM对象.属性名 = 新值

    注意:inner 是双标签之间的空间  value 只存在于input单标签,在这里innerHTML是拿不到内容的,要用value

    表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示 。如果为true 代表添加了该属性 如果是false代表移除了该属性。

    比如:disabled、checked、selected

    自定义属性

    标准属性:标签天生自带的属性,比如class 、id、title等等,可以直接使用点语法操作比如:disabled、checked、selected

    自定义属性:在html5中推出来的专门的data-自定义属性

    在标签上一律以data-开头

    在DOM对象上一律以dataset对象方式获取

     

    定时器-间歇函数

    目标:能够使用定时器函数重复执行代码

    定时器函数(setInterval)可以开启和关闭定时器

    在指定的时间间隔内重复执行,根据时间间隔执行,不清除则永远重复执行。

    1、开始定时器

    作用:每隔一段时间调用这个函数,间隔时间单位是毫秒

    注:一秒等于1000毫秒

    例如:

    1. 函数名字不需要加括号
    2. 定时器返回的是一个id数字

    关闭定时器:

    必须赋值,使用let的原因是后面可能会变化

    定时器的累加效果

    box.onmouseover = function () {
       timer=setInterval(function () {
            height+=1;
            console.log(height);
    },1000)
    };
    

    导致最后打印的速度“越来越快“

    原理:每停留在box上一次,就会产生一个定时器去执行height+1这个程序。

    只有一个定时器:每隔1秒打印一次height。

    第二次停留时,有两个定时器:每隔1秒有两个定时器去做这件事

     

    简单的例子:

    你点击一次按钮,相当于叫一个人过去,每隔1秒把打印一下;你点两次,就相当于让两个人去干同样的事情,都是每隔1秒打印一次,但是,假设过了1秒,第一个人过去打印了,第二个人也会过去打印,但是他们都是在同时进行的,会有叠加,就相当于每隔1秒打印多于原来两倍的速度。

     

    累加问题的解决:先清除、后累加。先清除之前的定时器,然后再添加定时器

     

    box.onmouseover = function () {
        clearInterval(timer);
        /*先清除后设置*/
        timer=setInterval(function () {
            height+=1;
            console.log(height);
        },1000)
    };
    • 事件监听

      发展史:

      DOM  L0  : 是DOM的发展的第一个版本;L : level

      DOM  L1 :DOM级别1于1998年10月1日成为W3C推荐标准

      DOM L2  :使用addEventListener注册事件

      DOM L3 :  DOM级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型。

      目标:能够给DOM元素添加事件监听

      什么是事件?

           事件是在编程时系统内发生的动作或者发生的事情

           比如用户在网页上单击一个按钮

      什么是事件监听?

      就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称之为 绑定事件或者注册事件,比如鼠标经过显示下拉菜单,比如点击可以播放轮播图等等。

      语法:

      事件监听三要素:

      事件源:那个DOM元素被事件触发了,要获取DOM元素

      事件类型:用什么方式触发,比如鼠标点击click、鼠标经过mouseover等

      事件调用的函数:要做什么事

      举例说明:

      注意:1、事件类型要加引号

      2、函数是点击之后再去执行,每次点击都会执行一次

      事件类型

      鼠标事件

      click  鼠标点击

      mouseenter  鼠标经过(示例如下:)

      mouseleave   鼠标离开()

      焦点事件(表单获得光标):

      focus  获得焦点

      bius  失去焦点

      键盘事件(键盘触发):

      Keydown  键盘按下触发

      Keyup  键盘抬起触发

       

      文本事件(表单输入触发):

      input  用户输入事件

      事件对象

      事件对象里面有事件触发时的相关信息

      使用场景:

      可以判断用户按下哪个键,比如按下回车键可以发布新闻

      可以判断鼠标点击了哪个元素,从而做相应的操作

      语法:

      在事件绑定的回调函数的第一个参数就是事件对象

      一般命名为event、ev、e

      部分常用属性

      type:获取当前的事件类型

      clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置

      offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置

      key:用户按下的键盘键的值

      环境对象(this)

      指的是函数内部特殊的变量this,它代表着当前函数运行时所处的环境

      并且每个函数里面都有this环境对象,普通函数里面this指向的是window

      this指向的粗略规则:谁调用函数,函数里面的this就是谁

      回调函数

      如果将函数A作为参数来传递给另外一个函数的时候,这个函数就是回调函数。

       

       

      DOM事件流

      事件流指的是事件完整执行过程中的流动路径

      事件流分为事件捕获和事件冒泡,事件捕获指的是事件流传播的顺序应该是从DOM树的根节点一直到发生事件的节点;事件冒泡是指事件流从发生事件的节点到DOM树的根节点。

      事件捕获代码:

      addEvenListenter第三个参数传入true代表是捕获阶段触发(很少使用)

      若传入false代表冒泡阶段触发,默认就是false

      并且若是用L0事件(onclick)监听,则只有冒泡阶段,没有捕获

      阻止事件冒泡:

      因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素

      语法:

      注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效。

      示例:

      解绑事件

      L0语法,移除事件属性方式注册的事件,格式如下:

      对象.onclick = null;

      移除事件监听方式注册的事件,语法格式如下:

      对象.detaEvent(type,callback);

      对象.removeEventListener(type,callback);

      事件委托

      事件委托(事件代理)也是如此,其原理是将子节点对应的事件注册給父节点,然后利用事件冒泡的原理影响到每个子节点。当子节点触发事件时,会执行注册在父节点上的事件

      优点:减少注册次数,可以提高程序性能

      原理:事件委托其实是利用事件冒泡的特点

      示例如下:

       

      阻止默认行为

      在HTML中,有些元素自身拥有一些默认行为。例如,使用标签创建的超链接被单击后,浏览器会自动跳转到href属性设置的URL地址;点击表单的提交(submit)按钮后,浏览器会自动将表单提交。但是当表单信息有误的时候,我们将阻止这种默认行为的发生。

      其他事件

      页面加载事件

      加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

      使用场景:

      有时我们需要等页面资源全部处理完了做一些事情

      load事件:监听整个页面资源给window加

      DOMContentLoaded事件:

      给document加

      无需等待样式表、图像等完全加载

      元素滚动事件:

      滚动条在滚动的时候持续触发

      事件名:srcoll

      监听整个页面滚动:

      当需要监视滚动了多少像素的时候,就需要用到scrollTop方法。

      案例:让用户下拉到指定的像素时,显示左横栏。

      页面滚动事件-滚动到指定的坐标

      scrollTo()方法可把内容滚动到指定的坐标

      语法:元素.scroolTo(x,y)

      页面尺寸事件

      会在窗口尺寸改变的时候触发事件:resize

      检测屏幕宽度

      获取元素宽高

      1、获取宽高:

      获取元素的可见部分宽高(不包含边框,margin,滚动条等)

      clientWidth和clientHeight

      2、获取元素宽高

      offsetWidth和offsetHeight

      获取元素的自身宽高、包含元素自身设置的宽高、padding、border

      获取出来的是数值,方便计算

      注意:获取的是可视宽高,如果盒子是隐藏的,获取的结果是0

      获取位置:获取元素距离自己定位父级元素的左、上距离

      offsetLeft和offsetTop注意是只读属性

      总结:

      节点

      网页中的所有内容在文档树中都是节点,即元素、属性、文本等都属于节点,当利用DOM进行网页开发时,通过节点操作可以更加灵活地实现网页中的交互效果。

      节点又三个常用属性:nodeName(节点名称)、nodeValue(节点值)、nodeType(节点类型)

      nodeName:用于获取节点名称,返回全大写形式,如返回的是DIV

      nodeValue:用于获取节点值,一般适用于文本、注释类型的节点。

      nodeType:用于获取数字表示的节点类型,如1表示元素节点。节点类型有很多种,常见的如上图红色所示。

      节点操作

      获取父节点的方法为使用parentNode属性获取当前节点的父节点,如果当前节点没有父节点,parentNode属性会返回null。通过parentNode获取父节点的语法如下:

      node.parentNode

      获取子节点

      获取兄弟节点

      可以使用previousSibling属性和nextSibling属性获取当前节点的上一个兄弟节点和下一个兄弟节点,进而获取到元素节点、文本节点等内容。

      若没有兄弟节点,就返回null

      如果想要获得兄弟元素节点,则可以返回使用nextElementSibiling,属性返回当前元素的下一个兄弟元素节点,使用previousElementSibLing属性返回当前元素的上一个兄弟元素。则返回null。

      创建并添加节点

      创建节点:

      使用document对象的createElement()方法可以创建元素节点,因为该方法创建的节点是页面中原本不存在的,所有也被称为动态节点。

      createElement()在使用时,只需将标签名作为参数传入即可,语法结构如下:

      document.createElement(‘div’);

      const div = document.createElement(‘div’);

      console.log(div);           //结果为

      添加节点:

      节点创建后,我们需要根据实际的开发需求将节点添加到文档中的指定位置。DOM中提供了appendChild()方法和insertBefore()方法用于添加节点。

      父元素.appendChild(插入的元素)//插在父元素的最后一个子元素后面

      父元素.insertBefore()方法示例如下:

      在特殊情况下,我们新增节点,按照如下操作:

           复制一个原有的节点

           把复制的节点放入到指定的元素内部

      克隆节点:

      cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值

           若为true,则代表克隆时会包含后代节点一起克隆

           若为false,则代表克隆时不包含后代节点;默认为false

      移除节点:

      在DOM中,可以通过removeChild()方法将一个父节点的指定子节点移除,语法如下:

      注:如不存在父子关系则删除不成功

      删除节点和隐藏节点(display:none)有区别的:隐藏节点还是存在的,但是删除,则从html中删除节点。

      M端事件:

      移动端也有自己独特的地方。比如触屏事件touch(也称触摸事件),Android和IOS都有。

           触屏事件touch(也称触摸事情),Android和IOS都有。

           touch对象代表一个触摸点。触摸点可能时一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

           常见的触屏事件如下:

       

      BOM

      浏览器对象模型(Browser  Object  Model,BOM)是浏览器提供的用于JavaScript于浏览器窗口进行交互的一系列对象。在BOM中,顶级对象是window,表示浏览器窗口,其他对象都是window对象的属性。BOM没有统一的标准,每个浏览器都有自己对BOM的实现方法,因此BOM的兼容性较差。

      延时函数:

      setTimeout(函数,要延迟的时间)

      setTimeout仅仅只执行一次,所以可以理解为就是把一段代码延迟执行。

       清除延时函数

      JS执行机制

      JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。

      这是因为JavaScript这门脚本语言诞生的使命所致——JavaScript时为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。

      单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

      为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web  Wprker标准,允许JavaScript脚本创建多个线程。于是,JS中出现了同步和异步。

      他们的本质区别:这条流水线上各个流程的执行顺序不同。

      同步任务

      同步任务都在主线程上执行,形成一个执行栈。

      异步任务

      JS的异步是通过回调函数实现的。

      一般而言,异步任务有以下三种类型:

      1. 普通事件,如click、resize等等
      2. 资源加载,如load、error等等
      3. 定时器,包括setInterval、setTimeout等等

      异步任务相关添加到任务队列中(任务队列也称为消息队列)

       

       

      执行机制:

      1. 先执行执行栈中的同步任务。
      2. 异步任务放入任务队列中。
      3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取renw1队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

       

      由于主线程不断的重复获得任务、执行任务、在获取任务、再执行,所以这种机制被称为事件循环(event  loop)

       

      BOM对象

      window对象

      location 的数据类型是对象,他拆分并保存了URL地址的各个组成部分

      常用属性和方法:

      href属性获取完整的URL地址,对其赋值时用于地址的跳转

      hash属性获取地址中的哈希值,符号#后面部分

      console.log(location.hash)

      reload方法用来刷新当前页面,传入参数true时表示强制刷新

      navigator对象

      该对象主要记录了浏览器自身的相关信息

      history对象

      主要管理历史记录,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等

      JS高阶方法

      本地存储

      随着互联网的快速发展,基于网页的应用越来越普通,同时也变的越来越复杂,为了满足各种各样的需求。会经常在本地存储大量的数据,HTML5规范提出了相关解决方案

      1. 数据存储在用户浏览器中
      2. 设置、读取方便、甚至页面刷新不丢失数据
      3. 容量较大、sessionStorage和localstorage约5M左右

      常见的使用场景:

      页面刷新的时候数据不刷新

      localStorage

      作用:可以将数据永远存储在本地(用户的电脑),除非手动删除,否则关闭页面也会存在

      特性:可以多窗口(页面)共享(同一浏览器可以共享)

      以键值对的形式存储使用

      存储方式:localStorage.setItem(“键”,“值”)

      本地存储只能存储字符串数据类型

      sessionStorage

      特性:生命周期为关闭浏览器窗口

      在同一个窗口(页面下数据可以共享)

      以键值对的形式存储使用

      用法跟localStorage基本相同

      复杂数据类型存储方法:

      JSON.stringify(复杂数据类型)

       

      正则表达式

      正则表达式(Regular  Expression)是用于匹配字符串中字符组合的模式。

      在JavaScript中,正则表达式也是对象。

      通常用来查找、替换那些符号正则表达式的文本,许多语言都支持正则表达式。

      正则表达式在JavaScript中的使用场景:

      例如验证表单:用户名表单只能输入英文字母、数字或者下划线,昵称输入框中可以输入中文(匹配)

      过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等。

      正则的使用:

      1. 定义规则
      2. 查找

      定义正则表达式语法:

      判断是否有符合规则的字符串:

      test()方法,用来查看正则表达式与指定的字符串是否匹配

      语法:

      返回的是true,否则false

      检索(查找)符合规则的字符串:

      exec()方法在一个指定字符串中执行一个搜索匹配

      语法:

      返回的是数组,否则为null

      元字符

      普通字符:

      大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。

      元字符(特殊字符)

      是一些具有特殊含义的字符,可以极大提高灵活性和强大的匹配功能。

      比如:规定用户只能输入英文26个英文字母,普通字符的话abcdefg……

      但是换成元字符写法:[a-z]

      分类:边界符、量词、字符类

      边界符:正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

      量词:表示重复次数

      用来设定某个模式出现的次数

        • 1.01 节 作用域

        了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免全局变量污染。

        作用域规定了变量能够被访问的“范围”,离开了这个范围,变量便不能被访问。

        分为:局部作用域,全局作用域

        函数作用域:

        在函数内部声明的变量只能在函数内部被访问,外部无法直接访问

        函数执行完毕后,变量实际是被回收了的。

        块作用域:

        在JavaScript中使用{}包裹的代码称之为代码块,代码块内部声明的变量外部将有可能无法被访问

        1. let声明的变量会产生块作用域,var不会产生块作用域
        2. const声明的常量也会产生块作用域
        3. 不同代码块直接的变量无法互相访问
        4. 推荐使用let或const

        全局作用域: