javascript知识点汇总(基础很全,文章最后还有思维导图)

目录

前端规范: 

一、javascript基础

1.什么是js: 

2.主要功能: 

3.js最初的目的:

4.js应用场景

5.js和html、css的区别

二、js初次体验

js的书写位置

(1)写在标签上的,行内(不推荐使用)

(2)写在script标签中(常用)

(3)写在外部js文件中,在页面中引入(常用)

三、变量

1.什么是变量?

2.为什么要使用变量?

3.怎么去使用变量?

4.变量赋值

5.变量的命名规范(重点,需要背的)

四.js数据类型

(1)Number类型(数值)

(2)String类型(字符串类型单引号个双引号均可)

思考:

1.如何打印以下字符串:我是一个'正直'的人

2.单双引号在什么应用场景下使用?

3.字符串长度

4. 如何打印字符串:

5.字符串长度

6.字符串拼接

js中的一个小技巧:

Boolean类型

typeof查看变量类型

Undefined和Null类型

Object类型

字面量

js注释

五、数据类型的转换

转换成字符串

转成数值类型-----Number(变量)

转成布尔类型

js运算符

(1)算数运算符

重要知识点: ++a与a++区别?

(2)逻辑运算符

(3)关系运算符

重要的知识点:==与===的区别?

(4)赋值运算符

重要点: +=的意义?

运算符的优先级

六、表达式和语句

流程控制语句

· 分支结构 

总结:多分支中if else if  else和switch  case区别:

三元运算符

循环控制语句

七、数组

1.为什么要学习数组?

2.数组的概念

3.数组定义

4.如何创建数组?

5.如何获取数组元素

遍历数组

数组中新增元素

两道例题:

八、函数:

·定义:

·为什么要有函数:

·语法: 

函数的调用

·形参和实参

函数返回值

总结:

函数重载----c++

javascript----js

例题:

js垃圾回收机制

封装一个函数,求3个数中的最大值

作用域

例题:

作用域链

定义:

特点:

函数表达式

·函数定义两种方式

·匿名函数

·函数的自执行

·变量提升---转化过程

·函数有声明前置的

函数表达式没有声明前置

函数递归

定义:

特点:

技巧:

练习题:

·回调函数

自己练习的回调函数

九、js内置对象 

什么是内置对象?

js内置对象种类

Number对象

练习题:(document.write在浏览器中显示)

练习题

js内置对象 String对象

(1)length属性

(2)charAt

(3)indexOf

(4)lastIndexOf

(5)slice

(6)substring

(7)substr

(8)concat

(9)split

(10)replace

(11)toUpperCase() 

(12)toLowerCase() 

习题:

13)字符串遍历

js内置对象 Boolean对象

js内置对象 Math对象

习题:

isNaN

Date----日期对象

定时器**********

(1)间隔型定时器

 (2)延迟型定时器

本地时钟效果

js内置对象---Array对象

(1)数组可以用来存储一组数据(按照次序排列)---数组里可以是任意的数据类型

(2)如何创建:

(3)数组的访问

(4)如何去遍历一个数组

(5)数组有一个固有属性---length

(6)数组的方法

JSON对象

(1) 创建json对象

(2)访问json对象:

(3)方法中的this指向

(4)js天然的支持给对象动态的添加属性和方法

(5)访问json对象----进阶

(3)遍历json对象

· json对象应用场景

十、DOM编程

1. 什么是DOM

2.同一概念

3. js分为三块---ES5--js基础

(1)ECMAScript:

(2)DOM: 

(3)BOM: 

查找dom节点的方法

通过ID来获取节点---document.getElementById

节点类型:

节点名称:

父节点

所有的子节点

Body里

Script里

例题:元素类型的子节点获取

法一

法二

元素类型的子节点获取的属性:

1. 我就想获取元素类型的所有的子节点

2.children属性

3.子节点

4.兄弟节点

5.节点获取的方法

节点操作

(1)createElement

(2)innerHTML属性

(3)节点的挂载

(4)removeChild

(5)replaceChild

(6)cloneNode

(7)insertBefore

元素的属性操作

元素的偏移

 节点的style属性

通过js改变样式

元素的样式属性

运动特效练习:

思维导图:


前端规范: 

总文件夹内:html、css、img、js、index.html五个

·html文件夹:可n页,如found.html、person.html

·css文件夹:最多2个,style.css、common.css(公有样式,能复用于多个页面的样式抽离出来放这里)

·js文件夹:最多2个,script.js、common.js(公有js,能复用于多个页面的js抽离出来放这里)

·img文件夹:存放所有需要的图片

·外面放index.html也可以

一、javascript基础

1.什么是js: 

javascript是运行在客户端(浏览器,可预览)的编程语言

2.主要功能: 

用来给静态页(html网页)增加一些动态功能(比如轮播图、tab切换)

得能独立开发(面试)

3.js最初的目的:

为了处理表单的验证操作

4.js应用场景

(发展到现在几乎无所不能、什么都能做)

(1)网页特效

(2)服务端开发(Node.js)后台服务器

(3)桌面应用程序

(4)APP

(5)游戏开发(贪吃蛇、俄罗斯方块)

5.js和html、css的区别

(1)html: 提供网页的基本结构,和网页中的内容

(2)css: 用来美化了网页

(3)javascript:(绝对不是java,两码事)可以用来控制网页内容,给网页增加动态效果。

二、js初次体验

对比:css引入方式(三种)

(1)内部样式表(head标签里的style)

(2)内联样式表(直接在标签上写样式)

(3)外链式(link链接)

js的书写位置

(1)写在标签上的,行内(不推荐使用)

onclick-----点击事件

alert----弹出一个对话框

<!-- 1.行内 -->

       <span onclick="alert('淳淳')">加油</span>

(2)写在script标签中(常用)

 <script>

 </script>

重点:放在body结束标签上面(因为放到head里,js太大容易加载慢,导致后面的html都先不显示)

 <!-- 2.标签 -->

        <script>

            alert('淳淳')

        </script>

(3)写在外部js文件中,在页面中引入(常用)

<script src="js/script.js"></script>

注意:引用外部的js文件的script标签中不可以写js代码的

<!-- 3.外联 -->

        <script src="js/script.js"></script>

三、变量

1.什么是变量?

变量是计算机内存中存储数据的标识符,根据变量名获取到内存中存的数据

2.为什么要使用变量?

使用变量可以方便的获取或者修改内存中的数据

3.怎么去使用变量?

在js中一般用var关键字,去声明一个变量 var a;

4.变量赋值

// 声明变量

var a;

// 给变量赋值

a=1;

// 声明了多个变量,依次赋值(用逗号分隔)

var age,name,sex;

age=18;

name='yc';

// 同时声明多个变量并赋值

var userName='yy',userPassword=521;

// 变量在内存中的存储

var b=18;

5.变量的命名规范(重点,需要背的)

(1)由字母、数字、下划线、$符号组成,不能以数字开头。

(2)不能是关键字和保留字(未来可能成为关键字)例如: for、 while

(3)变量名是区分大小写的(两个相同的变量名,只要大小写的差异,也会被视为是两个不同的变量)

//变量名是区分大小写的

var a;

var A;

// 被视为两个不同的变量

(4)变量名要有意义(语义化)

        像a无语义,name译名字。

(5)遵守驼峰命名法。首字母小写,后面单词的首字母要大写;

例如:userName   userPassword

例题:下面哪些变量名不合法?

var 1; 不合法

var age18;合法

var $name; 合法

var _sex; 合法

var theworld;不规范

四.js数据类型

简单的数据类型(5个):Number  String  Boolean   Undefined   Null

复杂的数据类型(1个): Object(复杂的数据类型中包含Function函数类型了)

(1)Number类型(数值)

数值字面量:数值的固定值的表示法 110  20  50  60.5

(2)String类型(字符串类型单引号个双引号均可)

'abc'   "abc"

字符串的字面量,用单双引号都可以,个人习惯可以用单引不=规范。

思考:

1.如何打印以下字符串:我是一个'正直'的人

var person="我是一个‘正直’的人";

2.单双引号在什么应用场景下使用?

比如字符串中有双引号,那么外层要用单引号

比如字符串中有单引号,那么外层要用双引号

// 如下场景,字符串要用单引号

var person='<p class="box">盒子</p>';

// 如下场景,字符串要用双引号

var info="我是一个'正直'的人";

3.字符串长度

length属性(用来获取字符串的长度)

// 字符串有length的属性---获取字符串的长度

    var str='hello world';

    console.log(str.length);

4. 如何打印字符串:

alert-----具有阻塞性(不推荐)

alert('琪琪')

console.log()-----在控制台中打印(一般选用)

5.字符串长度

var str='hello world';

console.log(str.length);

注意:空格也表示一个字符------如上的字符串编号从0开始,编号为0-10,长度是11。

6.字符串拼接

字符串拼接用加号+进行连接

例题:

console.log(11+11);     //数值+数值     22

console.log('hello'+'world');  //  'helloworld'

console.log('100'+'100');   // '100100'

console.log('11'+11);  //字符串和数值进行+,无论顺序(要把数值类型转成字符串,然后再进行字符串拼接) ‘1111’

console.log(+'4'); // +一个字符串 (把字符串转成数值) 4

console.log(11+11); 

console.log('hello'+'world'); 

console.log('100'+'100'); 

console.log('11'+11); 

console.log(+'4'); 

  • js中的一个小技巧:

通过控制台(右键浏览器页面打开检查,然后点console)可以查看数据类型是什么,

(比如

蓝色:表示数值类型

灰色/黑色颜色:表示的是字符串类)

Boolean类型

字面量:true和false,  区分大小写

计算机内部存储: true-------1    false----0  (涉及到计算时如:true+false=1)

//Boolean类型

        var k=true;

        console.log(typeof k);

typeof查看变量类型

Undefined和Null类型

  1. undefined表示一个声明了但是没有赋值的变量,变量只声明但没有赋值,默认就是undefined
// undefined-----只声明变量但没有赋值

        var student;

        console.log(student);

(2)Null表示一个空,变量的值如果想设为空,必须手动设置(清理js的垃圾机制)

//手动设置

    var a=null;

Object类型

定义:对象(复杂的数据类型)

{ }---花括号表示对象

[ ]----方括号表示数组

·typeof ----一个操作符:获取变量的类型

var num=22;//数值类型

console.log(typeof num);//number

var num=22;

console.log(typeof num);

var a='18',b=true,c={},d=[];

console.log(typeof a,b,c,d);

字面量

(直接能表示出来的):在源代码中一个固定值的表示法

数值字面量: 8  99 20.5

字符串字面量:  '大前端'    ‘阿里云学院’

布尔字面量: true   false

  • js注释

单行注释   ctrl+/

用来描述我们一行或多行代码的作用

多行块级注释 /*   */

五、数据类型的转换

转换成字符串

1.转换成字符串类型(带to的一般是方法)

// 转换成字符串的方法  toString()

        var num=5;

        console.log(num.toString());

2.拼接字符串的方式 +

console.log(num+'');

num+'', 当+两边

一个操作符是字符串类型,

一个操作符是其他类型的时候,

会先把其他类型的转成字符串,再进行字符串的拼接,最后会返回给我们一个字符串

转成数值类型-----Number(变量)

(1)Number( )

Number( )可以把任意值转换成数值,如果要转换的字符串中有一个不是数值的字符串,返回NaN

NaN-----not a  number    不是一个数字(我们不知道它究竟是什么)

var a='1x23';

console.log(Number(a));

(2)parseInt( )----整型

var num1=parseInt("12.3abc");

console.log(num1)

(3)parseFloat( )----浮点型

var num3=parseFloat("12");

console.log(num3)

parseInt( )与parseFloat( )区别

parseInt()---如果第一个字符是数字会解析,直到遇到非数字结束

parseFloat()-----会解析第一个小数点.遇到第二个小数点.或者非数字结束

(特点:如果解析的内容里只有整数,解析成整数)

转成布尔类型

Boolean()

var a=Boolean(0);

console.log(a);

console.log(typeof a);

哪些情况为false

0、‘’空的字符串、null、undefined、NaN----------------五种情况会转换成false

其他情况都会转成true

  • js运算符

(1)算数运算符

+ -  *(乘)  /(除) %(取余数)

一元运算符:只有一个操作数的运算符  num++

二元运算符: 两个操作数的运算符  5+6

重要知识点: ++aa++区别?

前置++        ++num    先加1再赋值   

后置++        num++    先赋值再加1

var numA=5;

console.log(num1=numA++,numA);

var numB=5;

console.log(num1=++numB,numB);

(2)逻辑运算符

&&----与    一假为假(两个操作数同时为true,结果为true,否则就为false)

||----或    一真为真(两个操作数有一个为true,结果就是true,否则就为false)

!----非    取反(操作数为true,结果就是false)

var a=1,b=0;

console.log(a&&b,a||b,!a,!b);

var a=Boolean(1),b=Boolean(0);

console.log(a&&b,a||b,!a,!b);

(3)关系运算符

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

重要的知识点:=====的区别?

== 只进行值的比较

=== 严格意义上的相等 (类型和值同时相等,则相等)

var a=  '55'==55;

console.log(a);

var b=  '55'===55;

console.log(b);

(4)赋值运算符

=    +=    -=    *=    /=    %=

重要点: +=的意义?

var a+=5;

var a=a+5;

运算符的优先级

优先级从高到低1>2>3>4>5>6>7

1. ()优先级最高-----小括号在js中提升优先级

2.  一元运算符 ++  --  !

3.算术运算符 先*  /  %  后+ -

4.关系运算符 >  >= < <=

5.相等运算符==  !=   ===  !==

6.逻辑运算符 先&&   后||

7.赋值运算符= += -=

六、表达式和语句

表达式:一个表达式可以产生一个值,有可能是运算、函数调用、有可能是字面量。

(表达式可以放在任何需要值的地方)

语句:理解为这就是一个行为,循环语句和条件判断语句(最典型的),一个程序有很多语句组成,一般情况下,会分隔成一条一条语句;

  • 流程控制语句

(程序分三种基本结构)

1. 顺序结果(从上到下执行的代码就是顺序结构)---程序所默认的

2. 分支结构(根据不同的情况,执行对应的代码)

3. 循环结构---重复做一件事

· 分支结构 

if----单分支

var a=10;

if(a==10){

    console.log('hello');

}

判断小括号里的条件表达式的真假,如果为真,执行或括号中的程序;

如果为假,程序就会跳过花括号,继续向下执行

if  else----双分支

if(a==10){

    console.log('相等');

   }

else{

    console.log('不相等');

   }

判断小括号里的条件表达式的真假,如果为真,执行第一个花括号中的程序;

如果为假,执行第二个花括号中的程序;

if   else if   else------多分支(应用场景---分数转换:<60=E、60-70 =D、70-80 =C、80-90 =B、90-100 =A)

if(a<10){

    console.log('第一条分支');

    }

    else if(a==10){

    console.log('第二条分支');

    }

    else{

    console.log('第三条分支');

    }

多分支  switch  case

switch(name){

    case '张三':

    //....

    break;



    case '李四':

    //....

    break;



    case '王五':

    //....

    break;



    default:

    //.....

    break;

    }

注意事项:  设置的表达式name就是变量名(name通常指的就是一个变量),随后表达式的值会和结构中的每个case值进行比较,如果匹配上了,则执行该分支的代码,用break来阻止代码向下一分支执行

  • 总结:多分支中if else if  else和switch  case区别:

if else if  else    -----区间判断(分数转换)

switch  case ------具体值的判断

  • 三元运算符

条件表达式? 第一条分支: 第二条分支

本质就是if else双分支流程控制语句

//是否年满18岁,满足的话--成年人    如果不满足----未成年人

        var age=18;

        console.log(age>=18?'成年人':'未成年人')
  • 循环控制语句

while循环 -----不推荐使用

while(判断条件){

        循环代码

}

 // while循环

        var i=0;

        while(i<10){

            i++;

            console.log(i)

        }

推荐使用for循环

for(初始化; 条件;  增量){

    循环代码

}

//for循环

        for(var i=0; i<10; i++){

            if(i==3){

                continue;

            }

            console.log(i)

        }



        for(var i=0; i<10; i++){

            if(i==3){

                break;

            }

            console.log(i)

        }

一个=叫赋值

两个==叫比较

for循环里的break---跳出循环体,执行下边的的代码

continue-------跳出当前循环体,进入下一次循环

&& 是与运算表达式,可以理解为当 && 前面的值为真时,执行 && 后面的表达式,

 && 前面的表达式为假时,返回false
|| 或运算表达式,可以理解为当 || 前面的值为假时,执行|| 后面的表达式。

 || 前面的表达式为真时,直接返回前面的表达式。

七、数组

1.为什么要学习数组?

之前学习的数据类型,只能存储一个值(Number/String),

我们想存储班级中所有学生的姓名,此时该如何存储?

2.数组的概念

所谓数组,就是将多个元素(通常指同一类型)按照一定顺序排列放到一个集合中,

我们通常把这个集合称为数组

3.数组定义

数组是一个有序(数组有索引值,下标(从0开始))列表,

可以在数组中存放任意的数据,并且数组的长度可以动态调整

4.如何创建数组?

(1)通过字面量的方式创建数组

·创建了一个空的数组

var arr1 = [ ]

·创建了一个包含3个数值的数组,多个数组项以逗号分隔

var arr2 = [10,3,6]

·创建一个包含2个字符串的数组

var arr3 = ['a','c']

·可以通过数组的固有的属性length获取数组的长度

console.log(arr2.length);

·可以设置length属性改变数组中元素的个数

arr2.length=0;

//创建了一个空的数组

      var arr1 = [ ]

//创建了一个包含3个数值的数组,多个数组项以逗号分隔

      var arr2 = [10,3,6]

//创建一个包含2个字符串的数组

      var arr3 = ['a','c']

//可以通过数组的固有的属性length获取数组的长度

      console.log(arr2.length);

//可以设置length属性改变数组中元素的个数

      arr2.length=0;

      console.log(arr2.length);

5.如何获取数组元素

数组的取值

//格式:   数组名[下标]    下标又称为索引

//功能:获取数组对应下标的那个值,如果不存在,则返回undefined

//创建了一个空的数组

      var arr1 = [ ]

//创建了一个包含3个数值的数组,多个数组项以逗号分隔

      var arr2 = [10,3,6]

//创建一个包含2个字符串的数组

      var arr3 = ['a','c']

//可以通过数组的固有的属性length获取数组的长度

      console.log(arr2.length);

//可以设置length属性改变数组中元素的个数

      arr2.length=0;

      console.log(arr2.length);

遍历数组

遍历: 遍及所有,对数组的每一个元素都访问一次,就叫做遍历

通过for循环语句。遍历出数组的每一项

//如何遍历一个数组---正向遍历

     var arr4=['a',2,false,'hello'];

     for(var i=0;i<arr4.length; i++){

            console.log(arr4[i])

     }

//数组的反向遍历

     for(var i=arr4.length-1;i>=0;i--){

            console.log(arr4[i])

     }

数组中新增元素

数组的赋值

//格式:  数组名[下标/索引]=值;

//如果下标有对应的值,会把原来的值覆盖,如果下标的值不存在,会给数组新增一个元素

//数组新增元素

        var arr6=['pink','yellow','orange','purple'];

//把yellow替换成green

        arr6[1]='green';

        arr6[4]='grey';

        console.log(arr6)

两道例题:

//1.求一组数中的所有数的和,和平均值

        //10 20 30   -----  60    ----   20

        var arr9=[10,20,30];

        //计数器思想

        var sum=0;

        for(var i=0;i<arr9.length;i++){

            sum+=arr9[i]

        }

        console.log(sum);//60

        var avg=sum/arr9.length;

        console.log(avg);

//2.将字符串数组用|进行分割

        var arry=['赵云','张飞','关羽','吕布'];

        var str=arry[0];

        var sep="|";

        //为了避免第一个名字前面有|,把第一名字从数组中取出来,赋值给str,然后再用|去链接其他名字

        for(var i=1;i<arry.length;i++){

            str+=sep+arry[i];

        }

        console.log(str);

八、函数:

·定义:

可以重复执行的代码块

·为什么要有函数

部分代码使用次数可能会很多,所以我们要封装起来,需要的时候调用就可;

·语法

声明函数

//function   函数声明的标识符;   test函数名;   花括号标示的是函数体

function test( ){

    //函数体

}

函数的调用

函数名加小括号,标示函数的调用

//声明函数

     function test(){//未声明仅调用

            console.log(1);

     }

//函数名+()------表示函数调用

     test();

·形参和实参

形参:在小括号中传入的参数,形参的本质是声明了一个局部变量

实参:函数调用时候传入的参数。

//形参和实参

     function sum(a,b,c){//形参

          //形参本质就是声明了一个局部变量

          var c;//undefined

          console.log(a+b+c);//9+undefined  ----NaN

     }

     sum(4,5);//实参

//js中允许形参和实参不对等

//当形参多于实参//形参多于实参无意义

           function sum(a,b,c){//形参

               //形参本质就是声明了一个局部变量

               var c;//undefined

               console.log(a+b+c);//9+undefined  ----NaN

              }

           sum(4,5);//实参//显示NaN

//当实参多于形参//实参个数多余形参-----多传入的那个实参(传丢了)但是不会报错

           function sum(a,b){

               console.log(a+b);

           }

           sum(4,5,6);//显示9

//实参只能传给形参---但是形参绝对不允许传给实参的-----单向传递

//企业中开发----最好实参和形参一一对等
  • 函数返回值

函数运行后的结果外部需要使用的时候,我们不能直接给与,需要通过return返回

总结:

函数内部,return后面的值就是返回值

·函数执行完毕,会不会留点什么,取决于有没有返回值

如果函数内部没有return语句,默认返回undefined

如果函数内部有return语句,但是后边没有值,那么也返回undefined

function sum1(c,d){

var e=c*d;

return e;//函数返回值的执行结果返回给了函数调用本身

console.log('返回值');//return后面的代码无法执行,return直接跳出了当前的函数体

}

var res=sum1(6,9);

console.log(res);//54
  • 函数重载----c++

重载函数是函数中的一种特殊情况,为了方便使用,c++允许在同一范围中声明几个功能类似的同名函数,

但是这些同名函数的形参有要求,形参必须不同(参数个数、类型、顺序),

也就是说用一个函数实现不同的功能,这种模式就叫做函数重载

  • javascript----js

js中是没有函数重载的概念,只要函数名相同,后面会覆盖前面

arguments----当作函数重载-----应用场景:

当传入的形参个数不确定的这种情况下,

arguments----相当于是一个类似数组(有索引值)--但不是真正的数组

//arguments传入参数个数不确定的时候用

function sun(){

     var sn=0;

     for(var i=0;i<arguments.length;i++){

         sn+=arguments[i];//累加求和

     }

     return sn;

}

console.log(sun(3,5,7,80,45))

例题:

//封装函数

    function getMax(a,b,c){

            var max=a;//假设最大值为a

            if(b>max){

                max=b;

            }

            if(c>max){

                max=c;

            }

            return max;

    }

    var res=getMax(4,2,9);

    console.log(res);//9
  • js垃圾回收机制

找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,

因为开销比较大,所以垃圾回收机制就会在一定的时间间隔执行

--标记清除  var a=null;  (现代浏览器都使用标记清除算法)js底层已经帮咱们处理好

---引用计数:低版本的ie(6、7)

  • 封装一个函数,求3个数中的最大值

// 封装函数,求3个数中的最大值

        function getMax(a,b,c){

            var max=a;//假设我的最大值a

            if(b>max){//假设不成立

                max=b;

            }

            if(c>max){

                max=c;

            }

            return max;

        }

        var res=getMax(4,2,9);

        console.log(res);//9
  • 作用域

定义:js代码的作用范围

·全局作用域--------作用script标签对里的作用域

·局部作用域----------在函数体内的作用域

·全局变量----------作用script标签对里的变量就叫做全局变量

·局部变量--------在函数体内的变量

·常量---------js中本身没有常量的概念 (在js中把变量全部大写,就会被认为是常量,习惯)

var PI=3.1415926;

        // PI----常量

例题:

 

  • 作用域链

定义:

当局部作用域找不到相应的变量的时候,会跳到全局作用域,这个过程就像链条一样,因此叫做作用域链

特点:

从上到下,从里到外

作用域的跳转是和当前函数声明环境有关和调用是没有关系的

var n=9;

function a(){

            var n=7;

            b();

        }

function b(){

            console.log(n);//

        }

a();//9
  • 函数表达式

·函数定义两种方式

1.函数声明------调用: 函数名+()

// 函数声明

        function test(){

            console.log('name');

        }

        test();

2.函数表达式------调用:  变量名+() 

//函数表达式

        //函数表达式后面的赋值语句是一个匿名函数

        var txt=function(){

            console.log(1);

        }

        //函数表达式调用 ---变量名+()

        txt();

·匿名函数

----没有名字的函数

·函数的自执行

--------函数表达式后边直接跟上小括号

·变量提升---转化过程

//变量提升---开始时并未赋值,只是初始化了一下变量

        console.log(g);//undefined

        var g=1;

        //变量提升转化步骤

        var g;

        console.log(g);//undefined

        g=1;

·函数有声明前置的

//函数有声明前置

        student()

        function student(){

            console.log('我是一名好学生');

        }

//函数表达式没有声明前置

        var k=function(){

            console.log('xixixi');

        }

        k();

调用可放在函数声明的前面

函数表达式没有声明前置

·匿名函数自执行

//匿名函数自执行

        var numbe=function(){

            console.log('world');

        }();

        // 表达式后直接跟着的()----表示函数调用

//匿名函数自执行

        (function(){

            var m=20;

            console.log(m);

        })();

        //为什么要括起来?

        /*

        1.封闭作用域,把原本的全局作用域包装成了局部作用域

        2.避免了全局变量污染

        3.失效的变量会被销毁,不会一直驻扎在内存中

        4.提升js引擎的执行效率

        5.同时实现把函数声明,转换成函数表达式,所以后面能跟小括号

        */
  • 函数递归

定义:

函数自身的调用

特点:

(1)自己调用自己

(2)有停止条件(出口)

(3)先递再归的过程

技巧:

(1)先写一层递归

(2)再找递归出口(停止条件)

递归:最麻烦的方法: 自己画一个内存调用图

//递归

function test(n){

            if(n>3){

                test(--n);

            }

            console.log(n);

        }

        test(5);

练习题:

//实现4的阶乘

//实现阶乘和计算相关,通常return返回值

//特点:(1)自己调用自己(2)有停止条件(出口)(3)先递再归的过程

function jiecheng(n){

    if(n==1){ 

        //阶乘停止的条件肯定就是1

        return 1;          

    }

    //n*自己调用自己的阶乘(我们可以在里面进行--n,每次都减一)

    return n*jiecheng(--n);

}

var res=jiecheng(4);

console.log(res);

·回调函数

回调的英文callback

定义:把函数作为参数

//实现4的阶乘

//实现阶乘和计算相关,通常return返回值

//特点:(1)自己调用自己(2)有停止条件(出口)(3)先递再归的过程

function jiecheng(n){

    if(n==1){ 

        //阶乘停止的条件肯定就是1

        return 1;          

    }

    //n*自己调用自己的阶乘(我们可以在里面进行--n,每次都减一)

    return n*jiecheng(--n);

}

var res=jiecheng(4);

console.log(res);

自己练习的回调函数

//回调函数

        function a(n){

            console.log(n);

        }

        function b(m){

            var num=100;

            m(num);//实现局部变量的传递

        }

        b(a);

九、js内置对象 

什么是内置对象?

js语言的设计者为了方便我们开发需要,提供很多封装好的对象直接供开发者使用,这些有js本身提供的对象,就称为内置对象

js内置对象种类

Number          String               Boolean           Array 

Date(日期对象)  Math(数学函数)  RegExp(正则) Events(事件) Functions(函数)

Number对象

Number('5');

parseInt()

parseFloat()

toFixed---数值对象.toFixed(n)---保留小数点后n位

isNaN函数----用来判断当前所输入的内容是否是一个数字

console.log(isNaN(9));//false

console.log(isNaN(NaN));//true

//如果是数字isNaN的返回值是false

//如果是字母、非数字isNaN的返回值是true

var a=3.475;

        //数值对象.toFixed(n)---保留小数点后n位

        //特点: 四舍五入  位数不够用0补齐

        console.log(a.toFixed(2));//3.48

        var b=3.4;

        console.log(b.toFixed(2));//3.40



        //isNaN函数----用来判断当前所输入的内容是否是一个数字

        console.log(isNaN(9));//false

        console.log(isNaN(NaN));//true

        //如果是数字isNaN的返回值是false

        //如果是字母isNaN的返回值是true

练习题:(document.write在浏览器中显示

document.write(isNaN('123'));//false

document.write(isNaN(-1.23));//false

document.write(isNaN(5-2));//false

document.write(isNaN('hello'));//true

document.write(isNaN('2020-02-18'));//true

练习题

//写一个函数,返回参数的平方和

        function sumSquares(){

            var sum=0;

            for(var i=0;i<arguments.length;i++){

                sum+=arguments[i]*arguments[i];

            }

            return sum;

        }

        var result1=sumSquares(2,3,4,6,7);

        var result2=sumSquares(1,3);

        console.log(result1);//29

        console.log(result2);//10

 

js内置对象 String对象

(1)length属性

(2)charAt

----获取指定位置的(索引)的字符  索引值从0开始

如果索引值越界,返回空的字符串

(3)indexOf

---返回指定字符串首次出现对应索引值

如果找不到返回-1

(4)lastIndexOf

----返回指定字符串最后一次出现对应索引值· String

//字符串/数组下标从0开始

//对象

var str='hello';

// length--属性

console.log(str.length);//5

//charAt给下标查找字符

console.log(str.charAt('0'));//h

console.log(str.charAt('1'));//e

console.log(str.charAt('6'));//冒了--返回一个空的字符串

//indexOf给字符查找下标

console.log(str.indexOf('l'));//2

//lastIndexOf给字符查找下标

console.log(str.lastIndexOf('l'));//3

//字符串截取

(5)slice

----极其推荐使用

字符串的截取   传入两个参数(第一个参数:起始位置    第二个参数:结束位置)

特点:含头不含尾

返回值是截取之后的字符串,原始字符串不会受影响

如果你只传入一个参数,会把其余全部截取出来

(6)substring

---用法与slice相同 (不推荐使用)

(7)substr

-----不推荐(第一个参数:起始位置    第二个参数:截取的长度)

var str='hello';

//字符串截取

//slice--字符串截取,传入两个参数(第一个参数:起始位置;第二个参数:结束位置)

//特点:含头不含尾

console.log(str.slice(0,3));//hel

console.log(str);//返回值是原来的hello,不受影响

console.log(str.slice(1));//ello,只传了一个参数就会把后面的全部截取出来,e和llo

//substring

console.log(str.substring(0,3));//hel

//slice和substring用法及效果类似,但推荐slice,不推荐substring和substr

//substring(第一个参数:起始位置;第二个参数:截取长度)

console.log(str.substr(2,3));//llo

(8)concat

---字符串的拼接  特点:谁调用谁在前  +也可以实现字符串拼接

(9)split

----根据指定字符把字符串拆分成数组,返回值就是一个数组

把字符串转成字符串数组,只有这一个办法,所以split方法十分重要

(10)replace

----表示的就是字符串的替换,----找到第一个匹配的字符就会停止

-----第一个参数传正则表达式(换成正则表达式就会替换)

里面需要传入两个参数

(参数1--------替换的目标字符串或正则表达式对象)

(参数2------替换字符串)

//concat--字符串拼接(特点:谁调用谁在前)

var str='hello';

var str2=' world';

console.log(str.concat(str2));

//split--字符串拆分成字符串数组,返回值就是一个数组--字符串转成字符串数组的唯一办法

var str3="h,e,l,l,o";

var str4="h*e*l*l*o";

console.log(str3.split(','));

console.log(str4.split('*'));//可以不传逗号传别的,但如果不传就会把逗号也转成数组里的字符

//replace--表示字符串的替换--找到第一个匹配的字符就会停止

//第一个参数传正则表达式(换成正则表达式就会替换)

//里面需要传入两个参数,第一个参数:需要换的字符;第二个参数:换成的字符。

console.log(str3.replace(',','*'));

console.log(str3.replace(/,/g,'*')); //g全局匹配,正则写法(var reg=/a/g;)

(11)toUpperCase() 

  ----转成大写

(12)toLowerCase() 

   ----转成小写

//toUpperCase

var str='hello';

console.log(str.toUpperCase());//无参数但有()才是方法

//toLowerCase

console.log(str.toLowerCase());

习题:

 //自己封装一个方法,把字符串前n转成大写;

function toUpper(str,n){

    str1=str.slice(0,n);

    str2=str.slice(n);//不用str2=str.slice(n,str.length);

    str1=str1.toUpperCase();

    return str=str1+str2;

}

console.log(toUpper('hello',2));//HEllo

13)字符串遍历

正向

反向

 //自己封装一个方法,把字符串前n转成大写;

function toUpper(str,n){

    str1=str.slice(0,n);

    str2=str.slice(n);//不用str2=str.slice(n,str.length);

    str1=str1.toUpperCase();

    return str=str1+str2;

}

console.log(toUpper('hello',2));//HEllo

js内置对象 Boolean对象

Boolean

toString

//Boolean

var a=true;

console.log(a.toString());//字符串true

//把参数转成布尔

console.log(Boolean('h'));//数值true

js内置对象 Math对象

静态对象---不需要我们实例化(new---新创建)的对象

(1)Math.PI

 (2) ceil-----向上取整

(3)floor----向下取整

(4)round---四舍五入

(5)abs----取绝对值

(6)random---随机数

(7)sqrt---求平方根

//Math.PI---圆周率

console.log(Math.PI);

//ceil---向上取整

console.log(Math.ceil(3.14));//4

console.log(Math.ceil(-3.14));//-3

//floor---向下取整

console.log(Math.floor(3.14));//3

console.log(Math.floor(-3.14));//-4

//round---四舍五入

console.log(Math.round(3.47));

console.log(Math.round(3.77));

//abs---取绝对值

console.log(Math.abs(-3.77));

//random---随机数(取0到1之间的小数,包含0,不包含1)

console.log(Math.random());//括号里不用给数

//sqrt---求平方根

console.log(Math.sqrt(9));

console.log(Math.sqrt(4));

习题:

//封装一个函数,产生a,b之间的随机数(整数)[a,b]

function getRandom(a,b){

    //先产生一个ran随机数[0,1)

    ran=Math.random();

    n=b-a+1;//个整数

    c=a+n*ran;//[a,a+n)

    random=Math.floor(c)//[a,a+n]中的整数

    return random;

}

console.log(getRandom(2,5))

//化简版

function getRandom(a,b){

    return Math.floor(a+(b-a+1)*Math.random());

}

console.log(getRandom(2,5));

 

isNaN

------记忆是十分简单的

isNaN()-----这个函数用于检测其参数是否是非数字值

如果不是NaN,返回值是false,说明是个数字

如果是NaN,返回值是true,说明是个字母

isNaN(Number(str.charAt(i))

//过滤掉字符串中的数值类型的字符

        //isNaN做

        var str2="adh55ba2sd55c525sdff11dv545";

        function filter(a){

            var tmp=’’;

            var arr = a.split('');//把字符拆出来

            for(var i=0;i<arr.length;i++){//判断数组里每一项是否为数字

                if( (isNaN(Number(arr[i]))) == true){

                    tmp+=arr[i];//不是数字加到串里

                }

            }

            return tmp;

        }

        var res=filter(str2);

        console.log(res)

Date----日期对象

new一个构造函数或者一个类(高级js课程中---面向对象编程思想oop)(实例化的过程)

//new Date就是我生成了一个对象,这个对象就是日期对象

var oDate=new Date( );

//getTime-----获取时间戳(1970年的1月1日到现在毫秒数)

//Date--需要实例化 new

var oDate=new Date();

//getTime---获取时间戳(1970年的1月1日到现在的毫秒数)

console.log(oDate.getTime());//这些方法都没有参数

//getFullYear----获取年

//getMonth---获取月

//getDate----获取日

//getDay-----获取星期

//getHours----获取小时

//getMinutes---获取分钟

//getSeconds---获取秒

var oDate=new Date();

//getFullYear---获取年

console.log(oDate.getFullYear());

//getMonth---获取月

console.log(oDate.getMonth()+1);//用的时候加一=现在月

//getDate---获取日

console.log(oDate.getDate());

//getDay---获取星期几

console.log(oDate.getDay());

//getHours---获取小时

console.log(oDate.getHours());

//getMinutes---获取分钟

console.log(oDate.getMinutes());

//getSeconds---获取秒

console.log(oDate.getSeconds());

定时器**********

(1)间隔型定时器

    setInterval

清空间隔型定时器  clearInterval(时间句柄)

 (2)延迟型定时器

    setTimeout

清空延迟型定时器  clearTimeout(时间句柄)

定时器特点:------先等待再执行

//定时器//特点:先等待再执行

//间隔型定时器setInterval(函数,间隔时间)

/*setInterval(function(){//回调函数

    console.log('hello');

},1000)*/

    //清空间隔型定时器

    //timer的返回值是定时器的编号(时间句柄)

    var i=0;

    var timer=setInterval(function(){

        if(i++==5){

            //i++==5时,输出1-5,i=0,然后从1开始输出

            //++i==5时,输出1-4

            clearInterval(timer);

        }else{

            console.log(i);

        }

    },1000)

    console.log('timer:'+timer);



//延迟型定时器

var timer2=setTimeout(function(){

    console.log("延迟了")

},2000);//隔两秒出现“延迟了”,不是每两秒,只出现一次

//关闭延迟型定时器

clearTimeout(timer2);

console.log('timer2:'+timer2);

本地时钟效果

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>本地时钟效果</title>

    <style>

        #div1{

            font-size: 40px;

            color: blue;

        }

    </style>

</head>

<body>

    <div id="div1">

        10:22:21

    </div>

    <script>

        //解决空白的问题

        dingyi();

        //引入的定义值

        function dingyi(){

            //引入html

            var oDiv=document.getElementById('div1');

            //定义最后给div显示的字符串

            var timestring;

            //Date--需要实例化 new

            var oDate=new Date(); 

            //getMinutes---获取分钟

            var minutes=oDate.getMinutes();

            //getHours---获取小时

            var hours=oDate.getHours();

            //getSeconds---获取秒

            var seconds=oDate.getSeconds();

            timestring=zero(hours)+':'+zero(minutes)+':'+zero(seconds);

            console.log(timestring);

            oDiv.innerHTML = timestring;

        }

        //定时器:每秒(1000)给seconds+1

        setInterval(dingyi,1000);

        // 个位数时补零

        function zero(a){

            if(a<10){

                return "0"+a;

            }

            return a;

        }

    </script>

</body>

</html>

js内置对象---Array对象

(1)数组可以用来存储一组数据(按照次序排列)---数组里可以是任意的数据类型

(2)如何创建:

1.字面量方式创建----var arr=[ 1,2,3];----推荐使用---因为简单

2.Array的构造函数方式创建-----实例化一个数组对象------不推荐使用(了解即可)

var arr1 = new Array('a','b',1);

(3)数组的访问

数组名[下标]------数组的下标也叫作数组的索引值,索引一般都是从0开始

(4)如何去遍历一个数组

正向遍历

fot(var i=0;i<arr.length;i++){

    console.log(arr[i]);// 1 2 3

}

反向遍历

fot(var i=arr.length-1;i>=0;i--){

    console.log(arr[i]); //3 2 1

}

(5)数组有一个固有属性---length

*******  属性是不带()

*******  方法是带()

(6)数组的方法

1. indexOf-----方法可以返回数组中某个指定的元素位置--找不到就返回-1

2. push方法-----入栈---给数组追加(从后面添加)元素,可以同时添加多个元素

3. unshift方法----给数组追加(从前面添加)元素,可以同时添加多个元素

4. pop方法----删除数组中的最后一个元素(没参数)

5. shift方法-----删除数组中的第一个元素(没参数)

6. ***  slice方法-----数组的截取  参数1:起始位置   参数2:结束位置

特点: 含头不含尾---返回截取之后的新的数组

这个方法不会影响原来的数组

//indexOf-----方法可以返回数组中某个指定的元素位置--找不到就返回-1

//字面量方式创建

var arr=['a','b','c'];

console.log(arr.indexOf('b'));//1

console.log(arr.indexOf('c'));//2

console.log(arr.indexOf('n'));//-1

//push--入栈---给数组追加(从后面添加)元素,可以同时添加多个元素

arr.push('d','e','f');

console.log(arr);

//unshift方法----给数组追加(从前面添加)元素,可以同时添加多个元素

arr.unshift(1,2,3);

console.log(arr);

//pop方法----删除数组中的最后一个元素(没参数)

arr.pop();

console.log(arr);

//shift方法-----删除数组中的第一个元素(没参数)

arr.shift();

console.log(arr);//[2, 3, "a", "b", "c", "d", "e"]

//slice方法-----数组的截取  参数1:起始位置   参数2:结束位置

//特点: 含头不含尾---返回截取之后的新的数组

//这个方法不会影响原来的数组

var res=arr.slice(0,2);

console.log(res);//返回截取之后的新数组 2 3

console.log(arr);//这个方法不会影响我们的原始数组

7. concat----表示数组拼接 ----谁调用谁在前

这个方法不会影响原来的数组

8. join---方法用于把数组中的所有元素根据,连接成字符串(把数组转成字符串)

split-----把字符串转成字符串数组

//concat----表示数组拼接 ----谁调用谁在前

var arr=['a','b','c'];

var arr1=['hello','world'];

var res=arr.concat(arr1);

console.log(res);

console.log(arr);

console.log(arr1);//这个方法不会影响原来的数组

//join---方法用于把数组中的所有元素根据,连接成字符串(把数组转成字符串)

var res=arr1.join('*');//这种是常见的

console.log(res);

var res=arr1.join();//默认值;

console.log(res);

var res=arr1.join('');//空字符串,就会连上

console.log(res);

9. reverse方法----数组元素进行反转(翻转)

10. sort方法----底层就是冒泡排序-----每一次取出两个元素进行比较

----sort方法我们要再数组中使用,一定要用回调函数

-------会改变原数组

//resever(数组元素进行反转(翻转))

var arr1=[5,2,8,15,18,25,28];

console.log(arr1.reverse());

//sort排序(底层就是冒泡排序)

var arr2=[1,5,6,8,2,7,3];

var res=arr1.sort();//比每个数的第一位的大小,像2拿2,18拿1,35哪3比。

var res2=arr2.sort();//全个位数才能正常从小到大

console.log(res);

console.log(res2);

   //sort加回调

    arr1.sort(function(a,b){

        console.log(a,b);

        console.log(a-b);

        return a-b//从小到大排列

        //return b-a;//从大到小排列

        

    })

    console.log(arr1);

11.  splice方法---终极神器

删除-----参数1:起始位置  参数2:删除个数  参数3:新增加的元素

//splic删除

var arr=[2,3,'a','b','c','d','e'];

var res=arr.splice(3,2);//第一个参数:起始字符;第二个参数:长度

console.log(res);

console.log(arr);//可以改变原始数组

//splic修改

console.log(arr.splice(3,2,'元素1','元素2'));//第一个参数:起始字符;第二个参数:长度;之后为修改成的

console.log(arr);

//spilc新增

//第一个参数:起始位置

//第二个参数:删除元素的个数

//第三个参数:新增加的

var res=arr.splice(1,0,'元素3');//第二个参数为0零时,不删除只增加

console.log(res);

console.log(arr);

JSON对象

定义:  轻量级的数据交换格式,我们称之为js对象的表示法

---单体对象、对象字面量

---单体对象(json对象写完之后就固定死了,不会再变了

应用场景: 一般情况下,前台向后台发送ajax异步请求,后台向前台发送一个json格式数据

数组(就不叫单体对象)-----new一个Arraynew的这个过程就是实例化的过程)new的这个东西叫做类

我们可以通过Array再去实例化一个对象

//new实例化一个数组

var arr1=Arrray(1,2,3);

//通过Array再去实例化一个对象

var arr2 = new Array('a','b','c');

//对于上述情况就不叫做单体对象,因为每new一次都会形成一个新的数据

//所以给我们一种创建的这个对象好像是动态

(1) 创建json对象

var obj={ };//创建了一个空的json对象

json对象的数据格式  {K:v, k:v} 由多个k:v对组成(键:值)

var obj2={

    name: 'lulu',

    age: 50,

    say:function(){//方法

        alert('xdd');

    }

};

(2)访问json对象

--访问属性-----属性    对象.属性名

obj2.name

--访问json方法---对象.方法名()

obj2.say( )

//创建单体对象jiso

    var obj={};//创建了一个空的单体对象jiso

    console.log(obj);//Object__proto__: Object

    console.log(typeof obj);//object



//json对象的数据格式{K:v,k:v}由多个 键(属性、方法):值 对组成

    var obj2={

        name:'chunchun淳淳',//name:属性

        age: 21,//age:属性

        say:function(){//say:方法

            alert('淳淳');

        }

    };

//后台给的键值对前端如何访问//访问json对象

        //访问属性(name/age):对象.属性名

        console.log(obj2.name);

        console.log(obj2.age);

        //访问方法(say:function()):对象.方法名

        obj2.say();

(3)方法中的this指向

哪个对象调用了this所在的成员方法,那么this就指向哪个对象

say:function(){//say:方法

            alert('淳淳');

            console.log(this.name);//方法中的this指向对象

        }

(4)js天然的支持给对象动态的添加属性和方法

//js动态添加属性和方法

    obj2.sex='男';//动态添加属性

    obj2.speak=function(){

        console.log(this.sex);

    }

    console.log(obj2);

    obj2.speak();

    </script>

(5)访问json对象----进阶

var attr='name';

console.log(obj2.attr);//会不会找到lulu----不会找到  undefined

比如我现在想找到name属性,但是它现在是个变量,也就是name属性名是个变量

思考问题方式:

如果程序把attr当作变量,就会输出

但是如果程序把attr当作属性,就不会输出

console.log(obj2[attr]);//这个时候程序就把它当作变量,来处理就会输出(与obj2['name']等价的)

------属性   对象['属性名']

------方法   对象['方法名']();

中括号里边可以是变量,打点调用后边不可以是变量

//访问json对象---进阶

var attr='name';//自己定义了一个变量,存了一个

console.log(obj2.attr);//会不会输出name:'chunchun淳淳'//不会输出

//说明程序把attr当成属性了

//---进阶

console.log(obj2[attr]);//说明程序把attr当成变量了,就会输出,与obj2['name']等价

console.log(obj2['name']);//不加单引号程序就会把它当成变量

console.log(obj2['speak']);

obj2['speak']();//访问方法

(3)遍历json对象

for in

for(var attr in obj2){

   console.log(attr);//attr  每次遍历的是属性名

   //如何遍历属性值?

   // console.log(obj2.attr);//这样写不可以---undefined

   console.log(obj2[attr]);//每次遍历的属性值

}

//遍历json对象

for(var attr in obj2){

    //如何遍历属性名?

    console.log(attr);//attr 每次遍历的是属性名

    //如何遍历属性值?

    console.log(obj2.attr);//undefined

    console.log(obj2[attr]);//每次遍历的是属性值

}

· json对象应用场景

(1)存储数据

(2)组件传递参数

(3)后台向前台返回的数据通常都是json格式的

十、DOM编程

1. 什么是DOM

document(文档-----指document对象)   object(对象)    model  (模型)

定义了js操作html文档的接口和规范

可以把整个的document文档看作是一颗倒栽的树

2.同一概念

标签==元素(html阶段)==节点==对象(js阶段)

以后把html标签都统称为dom节点

3. js分为三块---ES5--js基础

(1)ECMAScript:

javascript的语法标准

(2)DOM: 

js操作网页上的元素的API(方法)

(3)BOM: 

js操作浏览器部分功能的API(方法)-----比如前进、后退、刷新、查看浏览的地址、查看历史

   

查找dom节点的方法

通过ID来获取节点---document.getElementById

//DOM全称指document:文档,指document对象;object:对象;model:模型;

    //根据元素id来获取节点

    var oDiv=document.getElementById('div1');

    console.log(oDiv);

    //改变背景颜色--js改变样式

    //通过:节点对象.style.属性名='属性值'

    oDiv.style.background='pink';

节点类型:

返回节点类型nodeType

节点名称:

返回节点名称nodeName(标签名),返回值是大写的字符串 

//返回节点类型nodeType

    console.log(oDiv.nodeType);//nodeType返回值1是指元素节点

    //返回节点名称nodeName

    console.log(oDiv.nodeName);//返回值为大写字符串DIV

    console.log(oDiv.nodeName.toLowerCase());//转小写

    if(oDiv.nodeName.toLowerCase()==='div'){//时做什么事

        oDiv.style.fontSize='18px';

        oDiv.style.color='blue';

    }

  

父节点

---parentNode------返回当前节点对象的父节点

所有的子节点

----childNodes-----特点:包含文本和注释节点

childNodes-返回值不是数组-----本质上是集合类型,类数组(有数组的下标和可遍历的特点,但是没有数组的一系列方法)

Body里

<div id="div1">

        <li>1</li>

        <li>2</li>

    </div>

    <!-- 空白的字符也算一个文本节点 -->

    <div id="div2">

        <li>1</li>

        <!-- 注释 -->

        <li>2</li>

    </div>

Script里

//获取父节点parentNode

    console.log(oDiv.parentNode);//body

    //获取所有的子节点

    console.log(oDiv.childNodes);//包含文本和注释节点//5个节点,li前面的换行产生的叫text,也是一个节点

    var oDiv2=document.getElementById('div2');

    console.log(oDiv2.childNodes); //7个节点

例题:元素类型的子节点获取

法一

//我就想获取元素类型的所有子节点

        //先获取节点对象

        var oDiv=document.getElementById('div1');

        //console.log(oDiv)

        function getChild(div){

            var child=[];

            for(var i=0;i<div.childNodes.length;i++){

                if(div.childNodes[i].nodeType==1){

                    child.push(div.childNodes[i]);

                }

            }

            return child;

        }

        console.log(getChild(oDiv))

法二

//我就想获取元素类型的所有需要的子节点

        //先获取节点对象

        var oDiv=document.getElementById('div1');

        //console.log(oDiv)

        function getChild(obj){

            //获取所有子节点

            var achilds=obj.childNodes;

            var child=[];

            //简单方法建立数组,不用push,去遍历然后依次赋值

            for(var i=0;i<achilds.length;i++){

                child[i]=achilds[i];//可以通过直接赋值,把集合转成数组

            }

            for(var i=0;i<child.length;i++){

                if(child[i].nodeType !== 1){

                        child.splice(i--,1);

                        //i--;//可以直接放上面

                }

            }

            return child;

        }

        console.log(getChild(oDiv))

元素类型的子节点获取的属性:

1. 我就想获取元素类型的所有的子节点

2.children属性

-----返回元素类型的子节点----返回值也是集合类型

3.子节点

firstElementChild---第一个元素类型的子节点

想获取最后一个元素类型的子节点----lastElementChild

//children属性---直接获取元素类型子节点

        var oDiv=document.getElementById('div1');

        console.log(oDiv.children);//返回值也是集合类型

        //获取第一个元素类型子节点//两种办法

        console.log(oDiv.children[0]);

        console.log(oDiv.firstElementChild);

        //获取最后一个元素类型子节点//两种办法

        console.log(oDiv.children[oDiv.children.length-1]);

        console.log(oDiv.lastElementChild);

4.兄弟节点

previousElementSibling(获取前面一个兄弟节点)

nextElementSibling(获取后面一个兄弟节点)

//获取兄弟节点

        var oli=oDiv.children[1];//先获取一个节点

        console.log(oli);

        console.log(oli.previousElementSibling);//节点的前一个节点

        console.log(oli.nextElementSibling);//节点的后一个节点

5.节点获取的方法

1)通过标签获取  getElementsByTagName---浏览器兼容性特别好-----返回值--集合类型---只要是类数组,就可以通过下标访问

//通过下标访问---得到节点对象

节点对象.getElementsByTagName('p')

特点:基于节点对象,获取到下边所有的p节点(后代)

    <div>

        <p>1</p>

        <p>2</p>

        <p>3</p>

    </div>

    <p>4</p>

//getElementsByTagName---通过标签获取节点对象

        //返回值--集合类型---只要是类数组,就可以通过下标访问

        console.log(document.getElementsByTagName('p')[0]);// <p>1</p>

        console.log(document.getElementsByTagName('p')[3]);// <p>4</p>

        //通过下标访问---得到节点对象



<div id="div2">

        <ul>

            <p>1</p>

            <p>2</p>

            <p>3</p>

        </ul>

    </div>

    <p>4</p>

//找到ul的办法

        console.log(document.getElementById('div2').children[0]);

        //找到ul里p的办法

        console.log(document.getElementById('div2').children[0].children);

            //或:节点对象.getElementsByTagName('p')

            //特点:基于节点对象,获取到下边所有p节点(后代)

            console.log(document.getElementById('div2').getElementsByTagName('p'));

(2)getElementsByClassName---返回值--集合类型---通过类名获取---浏览器兼容性特别好

(3)getElementById---浏览器兼容性特别好

(4)querySelectorAll----参数是选择器(css选择器) -------低版本ie浏览器是不支持的(其余浏览器支持)

(5)querySelector----参数是选择器(css选择器)--------返回值是第一个具体的节点对象(浏览器兼容问题同上)

<div id="div2">

        <ul>

            <p>1</p>

            <p>2</p>

            <p>3</p>

        </ul>

    </div>

    <span class="sp1">1</span>

    <span class="sp1">2</span>

    <div class="aaa">

        <ul>

            <li>

                <p>1</p>

                <p>2</p>

            </li>

            <li class="bbb">

                <p>3</p>

                <p>4</p>

            </li>

            <li>

                <p>5</p>

                <p>6</p>

            </li>

        </ul>

    </div>

//getElementsByClassName,通过类名获取,返回值:集合类型(浏览器兼容性特别好)

      console.log(document.getElementsByClassName('sp1'));//HTMLCollection [span.sp1]

      //返回具体的节点对象

      console.log(document.getElementsByClassName('sp1')[1]);//<span class="sp1">2</span>

        

//getElementsById,浏览器兼容性特别好

        

//querySelectorAll参数是css选择器

        //返回值是集合类型

        console.log(document.querySelectorAll('.aaa ul li p'));//[p, p, p, p, p, p]

        console.log(document.querySelectorAll('.aaa ul li.bbb p'));//[p, p]

        

//querySelector----参数是选择器(css选择器)  

        //返回值是一个具体的节点对象

        console.log(document.querySelector('.aaa ul li p'));//<p>1</p>

        console.log(document.querySelector('.aaa ul li.bbb p'));//<p>3</p>

6.  classList属性

--length   返回class属性的个数

--add()------追加class方法

---remove()------删除class方法

----toggle()----切换class方法----讲事件

<div id="div2">

        <ul>

            <p>1</p>

            <p>2</p>

            <p>3</p>

        </ul>

    </div>

    <span class="sp1">1</span>

    <span class="sp1">2</span>

    <div class="aaa">

        <ul>

            <li>

                <p>1</p>

                <p>2</p>

            </li>

            <li class="bbb">

                <p>3</p>

                <p>4</p>

            </li>

            <li>

                <p>5</p>

                <p>6</p>

            </li>

        </ul>

    </div>

//classList属性

     var oDiv=document.getElementsByClassName('aaa')[0];

     console.log(oDiv);//<div class="ccc">...</div>

     console.log(oDiv.classList.value);//aaa

//add()------追加class方法

     oDiv.classList.add('ccc');

//remove()------删除class方法

     oDiv.classList.remove('aaa');

节点操作

(1)createElement

-----节点的创建

var newDiv=document.createElement('div');---创建了一个div标签,但是只是存储到内存中,还未挂载到页面上

(2)innerHTML属性

: 没有赋值语句,表示获取; 如果有赋值语句,表示的是设置

        newDiv.innerHTML='hello';//设置文本

        console.log(newDiv.innerHTML);//获取文本

(3)节点的挂载

---在body最后追加(父节点的对象.appendChild(子节点)----》表示节点的追加)

            <ul>

        <li></li>

    </ul>

    <p id='p1'>p1</p>

    <p id='p2'>p2</p>

    <div class="div1">

        <p>p3</p>

    </div>

    <ul>

        <li>1</li>

        <li>2</li>

        <li>3</li>

    </ul>



//节点的创建

        var newDiv=document.createElement('div');

        console.log(newDiv);

        //设置节点文本

        //innerHTML属性:没有赋值语句,表示获取;如果有赋值语句,表示的是设置

        newDiv.innerHTML='hello';//设置文本

        console.log(newDiv.innerHTML);//获取文本

    //节点的挂载---在body最后追加

        //父节点的对象.appendChild(子节点)---表示节点的追加

        document.body.appendChild(newDiv);//在body里script后面

        //创建一个a

            var newA=document.createElement('div');

            newA.innerHTML='淳淳';

            //挂载

            document.getElementsByTagName('li')[0].appendChild(newA);

(4)removeChild

--移除节点(父节点的对象.removeChild(被移除的节点))

(5)replaceChild

---替换节点 父节点的对象.replaceChild(新创建的节点,目标节点)

(6)cloneNode

   参数默认的是false,  克隆节点本身,不包含后代;  如果传入的参数是true--包含后代

(7)insertBefore

   父节点的对象.insertBefore(新插入的节点,目标节点)

    <ul>

        <li></li>

    </ul>

    <p id='p1'>p1</p>

    <p id='p2'>p2</p>

    <div class="div1">

        <p>p3</p>

    </div>

    <ul>

        <li>1</li>

        <li>2</li>

        <li>3</li>

    </ul>

//removeChild删除节点

        var op=document.getElementById('p1');

        console.log(op);

        //document.body.removeChild(op);

        //推荐写法

        op.parentNode.removeChild(op);



        //replaceChild替换节点

        var oNewSpan=document.createElement('span');

        oNewSpan.innerHTML='这是span标签';

        var op2=document.getElementById('p2');

        //开始替换

        op2.parentElement.replaceChild(oNewSpan,op2);



        //cloneNode--克隆节点

        var oDiv=document.getElementsByClassName('div1')[0];

        console.log(oDiv);

        console.log(oDiv.cloneNode(true));//默认false不包含属性及后代,如果时true包含属性及后代

        document.body.appendChild(oDiv.cloneNode(true));

        

        //inserBefore在谁之前插入

        var newLi=document.createElement('li');//创建了一个新的节点

        newLi.innerHTML='inserBefore在谁之前插入' //给新的节点加文本

        

        //找目标节点

        var oUl=document.getElementsByTagName('ul')[1];

        var targetLi=oUl.children[1];

        //用父节点对象.insertBefore

        oUl.insertBefore(newLi,targetLi);

            //找目标节点法2

            var oUl=document.getElementsByTagName('ul')[1].children[1];

            console.log(oUl);

            oUl.parentNode.insertBefore(newLi,oUl);

元素的属性操作

getAttribute----标签属性的获取---id  class属性能够获取到     自定义属性也可以获取到

setAttribute----标签属性的设置---里面传两个参数(第一个参数是属性名,第二个参数是要设置的属性值)

reoveAttribute---移除属性

属性的打点操作-----获取节点中已有的属性,id  className   获取不到自定义属性

<div id="div1" class="class0" my-attr="zidingyi">淳淳</div>

    <script>

        //getAttribute---获取属性

            var oDiv=document.getElementById('div1');

            console.log(oDiv.getAttribute('id'));

            console.log(oDiv.getAttribute('class'));

            //自定义属性是可以获取的

            console.log(oDiv.getAttribute('my-attr'));

        //setAttribute---属性的设置

            oDiv.setAttribute('my-attr','genggaidezdy');

            oDiv.setAttribute('class','genggaidec');

        //removeAttribute---移除属性

            oDiv.removeAttribute('my-attr');



        //属性的打点操作

        console.log(oDiv.id);//div1

        console.log(oDiv.class);//undefined

        //获取元素的class属性,不能.class,id是他已有属性,class不是

            //理由:遍历oDiv所有固有属性,没有class,叫className,也没有自定义的my-attr

            for(var attr in oDiv){

                console.log(attr);

            }
        console.log(oDiv.className);//才行
        //设置类名

        oDiv.className='DDD';

        //属性的清空(和移除等价),用处特别少

        oDiv.className='';

    </script>

元素的偏移

offsetParent------具有定位属性的父元素----如果当前上层没找到定位属性,就逐层向上查找,直到找到body为止

offsetLeft-----左侧(x轴)的偏移-----获取的相对于offsetParent的x轴的偏移

offsetTop----顶部(y轴)的偏移-----获取的相对于offsetParent的y轴的偏移

改变一个盒子的位置有两种方式:

(1)用margin

(2)用position定位

 // offsetLeft,offsetTop这连个属性不能赋值

<style>

        *{

            margin: 0;

            padding: 0;

        }

        #div{

            width: 300px;

            height: 300px;

            background: #f0f0f0;

            position: relative;

            padding-top: 50px;

        }

        #div ul{

            width: 200px;

            height: 200px;

            background: pink;

        }

        #div ul p{

            width: 100px;

            height: 100px;

            background: yellow;

            margin-left: 50px;

            position: absolute;

            left: 50px;

        }

    </style>

</head>

<body>

    <div id="div">

        <ul>

            <p></p>

        </ul>

    </div>

    <script>

        var op=document.getElementsByTagName('p')[0];

        //offsetParent---具有定位属性的父元素

        console.log(op.offsetParent);//如果它外层元素没有position: relative;显示body,如果有,显示有的元素//div

        //offsetLeft---获取相对于offsetParent的x轴偏移,只能获取,不能赋值

        console.log(op.offsetLeft);//只有改op的margin和left,数值才变;改父亲的margin和left,数值不变;//改父亲的parding,当子没定位时,数值改变。

        //offsetTop---获取相对于offsetParent的y轴偏移,同上

        console.log(op.offsetTop);

    </script>

</body>

 节点的style属性

通过js改变样式

第一种方式:通过修改标签的class属性,来改变样式----推荐

第二种方式:修改元素的style属性---节点对象.style.属性名='属性值';  (把样式直接加到标签上)内联样式(优先级高)

在写静态页面时绝对不允许把样式写在标签上

//注意:如果出现中划线,改成驼峰法   别忘加单位

元素的样式属性

getComputedStyle---能获取内部样式表里的样式

通过对象.style能获取到内联样式,获取不到内部样式表里的样式

元素可视区的宽度和高度----数值类型的

(1)clientWidth(content+padding)   clientHeight(content+padding)   

(2)offsetWidth---元素占位(盒模型)的宽度  (content+padding+border)

(3)浏览器窗口的宽和高

window.innerWidth

window.innerHeight

<style>

        #oop{

            background: red;

            font-size: 30px;

            padding: 20px;

            border: 10px solid pink;

        }

    </style>

</head>

<body>

    <div id='oop' style="width: 100px;height: 400px;">淳淳</div>



    <script>

        var opp=document.getElementById('oop');

        console.log(opp.style.width);//100px---字符串类型

        console.log(opp.style.height);//400px---字符串类型

        console.log(opp.style.background);//

        console.log(opp.style.fontSize);//

        //getComputedStyle---获取内部样式表里的样式

        console.log(getComputedStyle(opp).background);//red

        console.log(getComputedStyle(opp).fontSize);//30px---字符串类型

        

        //clientWidth--元素可视区的宽度和高度,数值类型的(content+padding)

        console.log(opp.clientWidth);//140--数值类型的,没单位

        console.log(opp.clientHeight);//440--数值类型的,没单位

        //offsetWidth---元素占位(盒模型)的宽度  (content+padding+border)

        console.log(opp.offsetWidth);//160--数值类型的,没单位

        //浏览器窗口的宽和高

        console.log(window.innerWidth,window.innerHeight);//527 694--数值类型的,没单位

    </script>

(4)元素滚动条的偏移距离

scrollLeft   scrollTop(常用)---内容卷上去的高度

overflow:hidden;-----直接把超出的元素隐藏,不再显示

overflow: auto;-----内容没有超出不显示滚动条,当内容过多超出了,就显示滚动条

(5)页面滚动条的偏移---页面卷上去的高度

document.body.scrollTop|| document.documentElement.scrollTop

(6)事件---节点对象.οnclick=事件处理函数

btn.οnclick=function(){

}

<style>

        *{

            padding: 0;

            margin: 0;

        }

        #oop{

            background: wheat;

            font-size: 20px;

            color: blue;

            border: 10px solid hotpink;

            overflow: auto;

            text-align: center;

        }

        #btn{

            position: fixed;

            right: 20px;

            bottom: 20px;

        }

    </style>

</head>

<body style="height: 2000px;background-color: pink;">

    <button id="btn">点我</button>

    <div id='oop' style="width: 210px;height: 400px;">

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

        淳淳LOVE学习<br>

    </div>



    <script>

        var opp=document.getElementById('oop');

        //页面滚动条的偏移距离

        //scrollTop--元素滚动条的偏移距离

        var btn=document.getElementById('btn');

        btn.onclick=function(){

            console.log(opp.scrollTop);//偏移等于页面卷上去的高度

            console.log(document.body.scrollTop||document.documentElement.scrollTop);

        }

    </script>

运动特效练习:

<title>运动特效</title>

    <style>

        *{

            padding: 0;

            margin: 0;

        }

        #div1{

            width: 100px;

            height: 100px;

            background: red;

            position: absolute;

            left:100px;

            top:50px;

        }

        .start-line{

            width: 0;

            height: 300px;

            border-left: 1px solid #000;

            position: absolute;

            left:100px;

            top:0;

        }

        .end-line{

            width: 0;

            height: 300px;

            border-left: 1px solid #000;

            position: absolute;

            left:800px;

            top:0;

        }

    </style>

</head>

<body>

    <button id="btn1">点击运动</button>

    <div class="start-line"></div>

    <div class="end-line"></div>

    <!-- 动画原则:执行动画的元素必须是脱离文档流 -->

    <div id="div1"></div>

    <script>

        // 屏幕有一个刷新频率,用1s除,基本上控制20-30ms---设定为20ms

    

        var hz=document.getElementById('div1');

        var btn=document.getElementById('btn1');

        btn.onclick=function(){

            var timer=setInterval(function(){ 

                if(hz.offsetLeft >= 800 || timer != 1){ //点多次按钮就会开多个定时器,速度叠加,所以开了一定要关闭,加了多个定时器也都要关闭

                    clearInterval(timer);

                }else{

                    hz.style.left=hz.offsetLeft+ 5 +'px';

                }

            },20)

        }

    </script>

</body>

思维导图:

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值