本文主要是介绍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类型
- 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
重要知识点: ++a与a++区别?
前置++ ++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替换成greenarr6[1]='green';arr6[4]='grey';console.log(arr6)
两道例题:
//1.求一组数中的所有数的和,和平均值//10 20 30 ----- 60 ---- 20var arr9=[10,20,30];//计数器思想var sum=0;for(var i=0;i<arr9.length;i++){sum+=arr9[i]}console.log(sum);//60var 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;//undefinedconsole.log(a+b+c);//9+undefined ----NaN}sum(4,5);//实参//js中允许形参和实参不对等//当形参多于实参//形参多于实参无意义function sum(a,b,c){//形参//形参本质就是声明了一个局部变量var c;//undefinedconsole.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;//假设最大值为aif(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;//假设我的最大值aif(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);//undefinedvar g=1;//变量提升转化步骤var g;console.log(g);//undefinedg=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){ //阶乘停止的条件肯定就是1return 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){ //阶乘停止的条件肯定就是1return 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.48var b=3.4;console.log(b.toFixed(2));//3.40//isNaN函数----用来判断当前所输入的内容是否是一个数字console.log(isNaN(9));//falseconsole.log(isNaN(NaN));//true//如果是数字isNaN的返回值是false//如果是字母isNaN的返回值是true
练习题:(document.write在浏览器中显示)
document.write(isNaN('123'));//falsedocument.write(isNaN(-1.23));//falsedocument.write(isNaN(5-2));//falsedocument.write(isNaN('hello'));//truedocument.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);//29console.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'));//hconsole.log(str.charAt('1'));//econsole.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));//helconsole.log(str);//返回值是原来的hello,不受影响console.log(str.slice(1));//ello,只传了一个参数就会把后面的全部截取出来,e和llo//substringconsole.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()
----转成小写
//toUpperCasevar str='hello';console.log(str.toUpperCase());//无参数但有()才是方法//toLowerCaseconsole.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
//Booleanvar 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));//4console.log(Math.ceil(-3.14));//-3//floor---向下取整console.log(Math.floor(3.14));//3console.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--需要实例化 newvar 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-4clearInterval(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(){//引入htmlvar oDiv=document.getElementById('div1');//定义最后给div显示的字符串var timestring;//Date--需要实例化 newvar 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+1setInterval(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'));//1console.log(arr.indexOf('c'));//2console.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 3console.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一个Array(new的这个过程就是实例化的过程)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( )
//创建单体对象jisovar obj={};//创建了一个空的单体对象jisoconsole.log(obj);//Object__proto__: Objectconsole.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);//undefinedconsole.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(标签名),返回值是大写的字符串
//返回节点类型nodeTypeconsole.log(oDiv.nodeType);//nodeType返回值1是指元素节点//返回节点名称nodeNameconsole.log(oDiv.nodeName);//返回值为大写字符串DIVconsole.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里
//获取父节点parentNodeconsole.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后面//创建一个avar 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];//用父节点对象.insertBeforeoUl.insertBefore(newLi,targetLi);//找目标节点法2var 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);//div1console.log(oDiv.class);//undefined//获取元素的class属性,不能.class,id是他已有属性,class不是//理由:遍历oDiv所有固有属性,没有class,叫className,也没有自定义的my-attrfor(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);//redconsole.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---设定为20msvar 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>
思维导图:
这篇关于javascript知识点汇总(基础很全,文章最后还有思维导图)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!