1.JavaScript基础
1.1.JavaScript简介
JavaScript是一种脚本语言,是直接在浏览器运行的
如果要写JavaScript就需要在
1.2.JavaScript常用常用输出语法
alert();用来在窗口显示信息
console.log()用来在控制台输出一个信息
document.write(); document--文档在网页里面一个网页就是一个文档 document就是网页
document.write();在网页里面输出一个信息
1.3.JavaScript的编写位置
- 在script标签里面
- 将js代码直接编写在外部的文件中 通过script标签引入
- 写在标签里面
javascript
<button onclick="alert('你点我干嘛')">点我</button>
<a hrtf="javascript:;">我是一个超链接<a>
1.4.JavaScript 的基语法 变量类型的 基础操作等
- 注释&变量
// 单行注释
/*多行注释*/
let a=100;
count b=30;
使用let来赋值一个变量
使用const来赋值一个常量
> JavaScript是弱类型的语言 对变量的定义比较简单
- MDN的使用
https://developer.mozilla.org/zh-CN/ 网址是这个 参考文档
- 标识符
在JavaScript中 所有的可以自主命名的内容都是标识符
比如:变量名 函数名 类名
标识符命名规则:
只能由 字母 数字 和下划线开头 不能以数字开头
不能使用关键字命名
不建议使用JavaScript中的内置函数名
标识符遵驼峰命名法
- 字符串:string
JavaScript 中的数据类型
let len="hello";
模板字符串 使用反单引号来创建 好处是可以换行 在模板字符串中可以嵌入变量
例如:
let a=`我是模板字符串
我可以换行
还能够保留格式`;
let name='张三';
a=`${name}是法外 狂徒`;
alert(a);
变量的语法:
- 数值
在所有的JavaScript中所有的整数和小数都是属于数值 都是属于number类型
使用typeof()可以用来检查变量的类型
在js中不要使用太大的数字计算 原因是计算的数值不够精确 通常情况下 在后端对数据进行精确的计算
let a = 12;\
let num =100;
console.log(num/2.3);
-
布尔类型
boolean 是用来做逻辑判断 就是用来判断是真还是假
let b = ture;
let c = false;
布尔值可以从来表示世界上的一切事物
-
空值和未定义
null 表示空值
undefined 表示未定义 当我们定义一个变量但是未赋值时 就是undefined
let a = null;
let b =undefined;//千万不要这么做
在JavaScript中所有的东西都是由这些数据类型构成的
1.5.变量和值的内存结构
同堆和栈
1.6.类型转换
-
其他类型转字符串
调用被转换类型的tostring()方法 let a =123; b=a.toString(); 调用string函数将其他类型转换为string c = String(a);
-
数值的类型转换
如果字符串为合法的数字则转换为数字 如果不是合法的数字就为 let a='123'; console.log(a,typeof a); b=Number(a); console.log(b,typeof b); 布尔值转数字 true 转换为 1 false 转换为 0 null转换为0 undefined 转换为1 parseInt();将一个值解析为number( 会从左往右将所有合法的数字转换为数字) let a='123r345'; let c='123.345'; b=parseInt(a); d=parseINt(c);//会取整数位 console.log(b); parseFloat();将一个字符串解析为一个小数 隐式数字类型的转换:可以通过对一个值+0 -0 *1的方法来对一个值进行数字类型的转换 隐式数字类型的转换:可以在一个值的前面加一个+号 来对一个值进行数字类类型的转换
-
布尔值的转换
使用Boolean()函数将其他类型的值转化为布尔值 对于数字来说除了0 和null 和NaN都是true 对于字符串来说 除了空号和false都是true a='';转换为boll值是false 对一个值进行两次取反 可以将一个值转换为布尔值
1.7. 算数运算符
通过运算符可以对一个值或者多个值进行运算
-
算数运算符
+ - * / 求幂运算 ** let a =123; b= a**10;//a的10次方 c= a**0.5;//a的平方根 console.log(b); console.log(c); % 取模两个数相除取余 字符串拼接 d='aaa'+'hha';
-
拼串
let a =123; //将a转换为字符串 let a= a+'';
任何类型在于字符串拼串的是时候类型都会变成字符串类型
通过对一个任意值加上一个空串的形式可以将任意一个值转换为字符串
-
自增自减
自增:++
自减:- -
-
赋值运算
将一个值赋值给一个变量
console.log(3**3);
-
逻辑运算 console.log(3**3);
! 逻辑非 (!!a 可以对a进行布尔值的转换)
&& 逻辑和
|| 逻辑或
-
关系运算符
如果关系成立就返回true 否则返回 false
如果是true和false浏览器会先把他们转换成为数字
如果是字符串或者是其他的类型浏览器也会先把他们转换成数字在进行比较
任何值和null比结果都是false
let a=10>7;
1.8相等和全等
/*
* 相等运算符
* ==
* - 相等运算符用来比较两个值是否相等
* - 相等运算符会对值进行自动的类型转换,
* 如果比较的两个值的类型不同,会将其转换为相同的类型然后再比较
* 通常情况下,不同类型都会转换为Number然后再比较
* null 和 undefined 做相等比较时,会返回true
*
* === (全等)
* - 全等用来检查两个值是否全等
* - 全等运算不会发生自动的类型转换,
* 如果两个值的类型不同,直接返回false
* - null和undefined做全等比较时,返回false
*
* != (不相等)
* - 比较两个值是否不相等
* - 如果不相等返回true,相等返回false
* - 会做自动类型转换,将两个值转换为相同的类型然后再比较
*
*
* !== (不全等)
* - 比较两个值是否不全等
* - 如果不全等返回true,全等返回false
* - 不会做自动的类型转换,如果两个值的类型不同,直接返回true
*
* */
// console.log(10 == 10); // true
// console.log(10 == "10"); // true
// console.log(true == "1"); // true
// console.log(true == "true"); // false
// console.log(null == 0); // false
// console.log(null == undefined); // true
// console.log(null >= 0); // false
// console.log(10 === '10'); // false
// console.log(true === '1'); // false
// console.log(null === undefined); // false
// NaN不和任何值相等,包括它自己
// console.log(NaN == NaN);
// console.log(NaN === NaN);
let a = NaN;
// 检查一个值是否是NaN时,需要使用函数 isNaN()
// console.log(isNaN(a));
1.9 条件运算符(三元运算)
* 条件运算符(三元运算符,三目运算符)
- 语法:
条件表达式 ? 语句1 : 语句2
- 执行流程:
条件运算符在执行时,会先对条件表达式进行求值判断,
如果判断结果为true,则执行语句1
如果判断结果为false,则执行语句2
1.10运算符的优先级
1.11.基础知识总结
类型转换
- 类型转换指将其他的类型转换为number、string、boolean
- 转化为string
显式类型转换
1.调用toString()方法
- 例子:
let a = 10;
a = a.toString()
- 问题:
不适用于 null 和 undefined
2.调用String()函数
- 例子:
let a = 10;
a = String(a);
- 原理:
对于有toString()值,也是调用toString()
对于没有toString()的null和undefined,直接转换为 'null'和'undefined'
隐式类型转换 *****
1.为任意值加上一个空串,即可将其转换为字符串
- 例子:
let a = 10;
a = a + '';
- 原理:
原理同String()函数
- 转化为number
显式类型转换
1. 使用Number()函数
- 例子:
let a = '10';
a = Number(a);
- 不同的情况:
字符串
- 如果一个字符串是合法的数字,则直接转换为对应的数字
如果不合法则转换为NaN
如果是空串或空格串,则转换为0
布尔值:
true --> 1
false --> 0
null --> 0
undefined --> NaN
2. 专门用来转换字符串的两个函数:
parseInt()
- 将一个字符串解析为一个整数
parseFloat()
- 将一个字符串解析为小数
隐式类型转换 *****
1. 使用一元的+来将一个任意值转换为数字
- 例子:
let a = '10';
a = +a;
- 原理:
同Number()函数
- 转化为boolean
显式类型转换
1. 使用Boolean()函数来进行转换
例子:
let a = 123;
a = Boolean(a);
情况:
会转换为false的情况:
0、NaN、null、undefined、false、''
隐式类型转换 *****
2. 为任意值取两次反,来将其转换为布尔值
例子:
let a = 123;
a = !!a;
原理:
同Boolean()函数
运算符
- 运算符也称为操作符,可以对一个或多个值进行各种运算或操作
- 算术运算符
+ 加法运算符
- 减法运算符
* 乘法运算符
/ 除法运算符
** 幂运算符 (新增的)
% 模运算符
注意:
除了字符串的加法,其余类型的值进行算术运算时,
都会转换为数值然后再运算
- 一元运算符
+ 正号
- 负号
注意:
使用±号,会发生类型转换(数值)
- 自增自减运算符
自增
a++(后++)
- a++会使变量立即自增1,并返回变量自增前的值(原值)
++a(前++)
- ++a会使变量立即自增1,并返回变量自增后的值(新值)
自减:
a--(后--)
- a--会使变量立即自减1,并返回变量自减前的值(原值)
--a(前--)
- --a会使变量立即自减1,并返回变量自减后的值(新值)
- 赋值运算符
=
将符号右侧的值赋值给左侧变量
+=
a += x 等价于 a = a + x
-=
*=
/=
**=
%=
- 逻辑运算符
!(逻辑非)
- 逻辑非用来对一个值进行取反,true变false,false变true
- 非布尔值会转换为布尔值然后取反
&&(逻辑与)
- 与运算是找false的,只要有false就会返回false
- 与运算是短路的与,如果第一个值是false,则不看第二个值
- 非布尔值运算时,会返回原值
- 如果第一个值是false,则直接返回第一个值,
如果第一个值为true,则返回第二个值
||(逻辑或)
- 或运算是找true的,有true就返回true,没有返回false
- 或运算是短路的或,如果第一个值是true,则不看第二个值
- 非布尔值运算时,会返回原值
- 如果第一个值是true,则返回第一个值
如果第一个值是false,则返回第二个值
- 关系运算符
- 关系运算赋用来比较两个值之间大小等于的关系
如果关系成立,返回true,否则返回false
>
>=
<
<=
- 规则同数学运算
let a = 10;
5 < a < 20 错的
a > 5 && a < 20 正确
2.JavaScript正式
2.1代码块
在js中使用代码块来对代码来进行分组
一对大括号就是一组代码块
注意:在代码块中申明的变量只能在代码块中使用
使用var来申明变量在代码块外面也能够使用
{
let a = 10;
}
{
var a1=20;
}
2.2 流程控制语句
代码的执行就是由上到下的顺序执行的,这样的会会引起一些问题 所以我们使用一些流程控制语句来对我们的程序进行流程控制
-
if语句
语法 if(条件表达式)
语法
如果满足条件就执行语句,如果不满足条件就不执行下面的语句
- if else 语句
2.3垃圾回收
2.3函数
function fn( 参数1 ,参数2,…){
函数体
return ;
}
2.3补充 箭头函数
箭头函数就是函数的一种简洁的写法
-
箭头函数语法
([参数列表])=> 返回值;
function sum(a,b){
retutn a+b;
}
//------使用箭头函数表达----
let sum=([a,b])=>a+b;
2.4方法
任何值都能成为对象的属性
如果一个对象的属性是方法 我们称这个函数是这个对象的方法
- 两种书写方法
let obj={
tese:function(){
alert('我是obj中的函数');
}
tese2:function(){
alert('我是obj中的函数2');
}
}
let obj2={
tese() {
alert('我是obj2中的函数');
}
tese2 () {
alert('我是obj2中的函数2');
}
}
//调用obj的tese方法
obj.tese();
2.4作用域
作用域就是变量的作用范围
-
全局作用域
所有的写在script标签里面的内容都是全局作用域
全局作用域在页面开始的时候开始 在网页结束时销毁
全局作用域中定义的变量是全局变量 定义的函数是全局函数
全局变量和全局函数 在任意位置都能被访问到
全局作用域中有一个全局变量window window代表的是浏览器
使用var申明的变量都会作为window的属性保存
let存放的对象函数不是window的属性和方法
-
变量的提升
在js中使用var创建的变量在程序执行前都会被创建 但是不会赋值
使用function开头的也会被提升会提前执行 所以在js中 在函数被申明前就可以被调用
//var a= 10;a会被提前创建但是不会被赋值 console.log(a); var a=10; //函数申明 function fn(){ alert("会提前被执行"); } var function fn2(){ alert('dgfadg'); }
2.5小结
2.5.1对象
对象是一个复合数据类型 在对象中库存储其他的数据 是一个数据的容器
1.内建对象:
- 由于ES标准所规定的对象 object function String Boolean NUmber 。。。
2.宿主对象:
- 有js运行所提供的对象 window console document
3.自定义对象
- 由开发人员自己定义的对象
-
创建对象
let obj = object(); let obj = new object(); let obj = {};
-
在对象中添加属性
对象.属性名=属性值; 对象['属性名']=属性值; let obj=object(); obj.name='zhansan'; obj['name']='lisi';
-
提取对象的属性
语法: 对象.属性名; 对象.['属性名']; obj.name; obj.['name'];
-
删除对象中的属性
delete 对象.属性名; delete 对象.['属性名']; delete obj.name; delete obj.['name'];
-
创建对象时 直接指定对象中的属性
语法: { 属性名:属性值, 属性名:属性值, 属性名:属性值, 属性名:属性值 } { name:"zhansna", id:13344, }
-
方法(method)
对象的属性值可以是任意类型,也可以是一个函数
如果对象的属性值是一个函数,这个函数我们称为对象的方法函数和方法没有本质的区别,就是称呼的不同
-
in 运算符
就是用来检查对象中是否含有某个属性
'属性值' in 对象
-
for in
枚举对象中的属性
//语法: for(let 变量 in 对象){ 语句。。。。; } let student= { name:"张三", id:1234, class:1 } for(let i in student){ alert(i); }
-
可变类型
对象就是一个可变类型 对象中存储的属性值都可以被修改
如果修改的是对象的属性 那么指向该对象的的变量都会受到影响//obj 和obj2 指向的都是同一个对象 let obj ={name:"swk"}; let obj2=obj; obj2.name='zbj'; console.log(obj.name); console.log(obj2.name); function fn(a){ a.name='shs'; } fn(obj); console.log(obj.name);
2.5.2函数(function)
函数也是一个对象 函数可以用来存储代码 在需要的时候对其进行调用
-
创建函数
//函数申明 function 函数名 ([形参1],[形参2],.....){ 语句; } //函数表达式: let 函数名= function([形参1],[形参2],.......){ 语句; } //立即执行函数 (function(){ 语句....; })(); (function(a,b){ 语句...; })(a的值,b的值);
-
函数调用
函数调用就是将函数中的代码执行
语法:函数对象
-
参数
- 形式参数:在定义函数时,在函数中可以定义数量不等的参
定义形参就相当于在函数中声明了变量但是没有赋值
- 实际参数:可以在函数中传递实际参数
实际参数会赋值给对应的给形式参数
- JS不会检查实参的类型和数量
- 可以传递任意类型的值作为参数
- 可以传递任意数量的值作为参数
等于形参数量 --> 一一对应
小于形参数量 --> 没有的就是undefined
大于形参数量 --> 多了的不用
-
返回值
- 返回值是函数的执行结果,通过return关键字来设置返回值
- 语法:
return 值; - 注意:
1.任何值都可以成为函数的返回值
2.return后不跟值或不写return,相当于return undefined;
3.return一旦执行,函数直接结束
-
递归
函数自己调用自己叫做递归
递归要满足两个条件
1.基线条件 递归停止的条件
2.递归条件 如何对问题进行拆分
//创建一个函数 求任意数的阶乘 function jieCheng(num){}
2.6作用域
作用域就是变量的区域
-
全局作用域
在页面加载的时候创建在 在页面关闭的时候销毁
开发时很少在全局作用域声明变量
全局作用域有一个全局对象window
-
局部作用域
2.7 函数作用域
函数每次调用都会产生一个新的作用域
作用域与作用域之间是相互独立的
在函数作用域中声明的变量是局部变量只能在作用域中使用
2.8 作用域链
当我们访问一个变量的时候 如果当前的作用域有点的时候就会用的是当前的变量 如果当前的作用域没有的话就去上一级去找 找到了就直接使用 如果没找到就再去上一级找 依次类推如果还是没有就报错
let a=10;
function fn(){
let a=20;
console.log(a);
}
2.9 this
在调用函数时 浏览器没次都会向函数中传递一个参数这个参数的名字叫做this
this 指向的是一个对象
vat name ='全局name';
var obj1={
name:'obj1name'
}
var obj2={
name:'obj2name;'
}
function fn(){
console.log(this.name);
}
obj1.fn();
2.10 工厂方法创建对象
function people(name,age,sex,address){
let obj={};
obj.name=name;
obj.age=age;
obj.sex=sex;
obj.address=address;
obj.sayname=function(){
alert('"大家好我是${this.name}"')
}
return obj;
}
let sek=people('fhh',19,'nan','fjasldkjflas');
sek.sayname;
2.11 构造函数来创建对象
构造函数的流程
- 创建一个新的对象
- 将这个新的对象设置为函数中的this
- 执行函数中的代码
- 将新建的对象返回
构造函数是专门用来创建对象的函数
构造函数的定义方式和普通函数没有区别
唯一不同的是在于构造函数的首字母要大写 一个函数如果直接调用就是普通函数 如果使用new就是一个构造函数e
function Person(name,age) {
this.name=name;
this.age=age;
this.sayname=function () {
alert('大家好我是'+this.name);
}
}
let per1=new Person('张三',10);
let per2=new Person('李四',10);
per1.sayname();
per2.sayname();
每一个对象都有一个sayname方法但是这些sayname的功能都是一样的
而创建很多就会占用很多的内存 实际上完全可以所有的对象都共用一个sayname方法
-
instanceof
用来检查一个对象是不是一个类的实例
console.log(对象 instanceof 类) console.log(per instamceof Person);
2.12 原型
原型就是一个公共的区域 可以把一些大家都需要用到的的一些方法和属性放到这里 可以节省内存 如果对象有该方法或者属性,就会替换掉原型内的属性和方法
1.定义类时:独有的属性和方法 在构造函数中通过this来添加
2.公共的方法和属性 在构造函数时 通过外部原型来添加
3.当我们使用对象的属性和方法时候 首先在对象中找 然后在从原型中找 最后在原型中的原型中找
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWsMKC2n-1649314181892)(C:\Users\WYQ\AppData\Roaming\Typora\typora-user-images\image-20211129145643818.png)]
function Person(name,age) {
this.name=name;
this.age=age;
}
//向原型中添加sayname方法
Person.prototype.sayname=function(){
alert('大家好我是'+this.name);
}
let per1=new Person('张三',10);
per1.sayname();
2.13 属性和方法
属性就是表示事物的数据(身高,体重 姓名等等)
方法就是表示事物的功能(跑 跳 飞 讲话等等)
2.14 原型链
- hasOwnProperty:用来检查一个属性是否存在于对象自身中
- object 是所有原型的原型
function Person(name,age) {
this.name=name;
this.age=age;
}
Person.prototype.test='公共属性';
let per=new Person('战三',10);
console.log(per.name);
console.log('test' in per);
//检查name是否在per中
console.log(per.hasOwnProperty('name'));
//检查test是否在per的原型中
console.log(per.__proto__.hasOwnProperty('test'));
2.15 对象的分类
- 内建对象 由es标准所规定的对象 object function string Boolean
- 宿主对象 有js运行环境所提供的对象 Windows console document
- 自定义对象 由开发人员自己定义的对象
3.JavaScript 方法概念
3.1数组(Array)
数组也是一个对象 数组用来存储一组有序的数据
数组中存储的数据成为元素 数组中的每一个元素 会根据存取的顺序保存在内存中
数组中的每一个元素都有一个唯一的索引
-
创建数组对象
let arr =new Array(); let arr=[]
-
向数组中添加元素
arr[0]=0; arr[1]=1; console.log(arr);
-
读取数组中的元素
console.log(arr[1]);
-
length 用来获取数组中元素的数量()
这种属于是非连续的数组 1-99的位置虽然没有值但是位置被占用了 在开发中建议不要使用
let arr=new Array(); arr[0]=0; arr[100]=100; console.log(arr.length);
-
向数组的最后一位添加元素
arr[arr.length]=值;
-
二维数组
let a=[[1,1,1,],[2,2,2]];
-
数组的遍历
let arr=[1,2,1,2]; for (let a=0;a<arr.length;a++){ console.log(arr[a]); } for (let i=arr.length;i>=0;i--){ console.log(arr[i]); } for (let i in arr) { console.log(i); }
-
push()向数组中添加一个或者多个元素
let arr=[1,2,1,2]; arr.push(12,15555); let a=arr.push(3333); console.log(a);
-
unshift() 向数组中添加一个或者多个元素 从前面的元素开始加
arr.unshift(333); let a=arr.unshift(222);
-
pop()删除数组中最后一个元素返回被删除的元素
let a=arr.pop(); console.log(a);
-
shift 删除数组中的第一个元素
arr.shift(); let a=arr.shift();
-
slice() 用来截取数组 可以拿到数组中的部分元素
slice(起始位置索引,结束位置索引) 截取的元素中不包括结束位置的元素
slice(1,-1) -1表示倒数第一个元素
let arr=[1,2,3,4,5,6]; let arr1=arr.slice(0,3); console.log(arr1);
-
splice()
删除替换数组中的元素
splice(删除元素的起始位置,删除的数量) 返回值是被删除的元素
splice(删除元素的起始位置,删除的数量,替换值1,替换值2…)
splice(2,0,222) 在指定的位置插入新的元素
let arr=[1,2,3,4,5,6]; arr.splice(0,2); console.log(arr); arr.splice(0,2,22222,33333); console.log(arr); arr.splice(2,0,666666); console.log(arr);
-
练习 数组去重
let arr=[1,2,3,1,2,3,4,5,6]; for (let a=0;a<=arr.length;a++){ for (let b=a+1;b<arr.length;b++){ if (arr[a]===arr[b]){ arr.splice(b,1); } } } console.log(arr);
-
forEach
该方法需要一个函数作为参数
像这种是由我们定义但是不由我们调用的函数叫做回调函数
forEach() 的回调函数共有三个参数
1.当前被遍历的元素
2.当前遍历元素的索引
3.当前正在被遍历的数组对象
let arr=[9,8,7,6,5,4,3,2,1]; arr.forEach(function (element,index,array) { console.log(index, element,array); })
-
concat 拼接数组
let arr=[9,8,7,6,5,4,3,2,1]; let arr2=[22,33,22,5,8,9,4]; console.log(arr.concat(arr2));
-
indexof 返回元素在数组中的位置
找到了就返回元素索引 如果没找到就返回-1
参数 1 :数组中的元素
参数 2 : 参数的起始位置
let arr=[9,8,7,6,5,4,3,2,1]; let arr2=[22,33,22,5,8,9,4]; console.log(arr.indexOf(4)); let arr=[9,8,7,6,5,4,3,2,1]; let arr2=[]; if (arr2.indexOf(arr)===-1){ arr2.push(arr) } console.log(arr2);
-
lastindexof 返回元素最后一次出现的位置 从后往前找的
找不到就返回-1效果和index一样
-
join 将数组中的所有元素连接为一个字符串
参数 可以传递连接符 默认为‘,’
let arr=[9,8,7,6,5,4,3,2,1]; console.log(arr.join('.'));
-
reverse 对数组进行反转
对原数组有影响
let arr=[9,8,7,6,5,4,3,2,1]; console.log(arr.reverse());
-
sort 对数组进行排序的
对原数组有影响
使用sort对数字排序的时候会把数字抓换成字符编码值来排序
let arr=[9,8,7,6,5,4,3,2,1]; arr.sort(); console.log(arr); //使用回调函数的方法来指定排序的规则 升序排序 arr.sort(function(a,b){ return a-b; }) //降序排列 all.sort(function(a,b){ return b-a; }) //乱序排列 arr.sort(function(a,b){ return Math.random()-Math.random(); })
-
数组的快速排序
let arr=[]; for (let a=0;a<100;a++){ arr.push(Math.round(Math.random()*100)) ; } console.log(arr); function quick(array) { if (array.length<2){ return array; } //获取一个随机的index let index=Math.floor(Math.random()*array.length); let left=[]; let right=[]; let min=[array[index]]; for (let i=1;i<array.length;i++){ //判断基准值是不是自己 if (i===index){ continue; } if (array[i]<min){ left.push(array[i]); }else { right.push(array[i]); } } return quick(left).concat(min,quick(right)); } let a=quick(arr); console.log(a);
3.2.math
math 里面存放的数学对象
3.2.1math的常用的函数
-
abs
对一个数求绝对值
-
floor
对一个数进行向下取整
-
ceil
对一个数进行向上取整
-
round
对一个数进行四舍五入
-
max
最大值
-
min
最小值
-
pow(X,Y)
x的y次幂
-
sqrt()
对一个数进行开放
-
random()
用来生成一个随机数 0-1
生成一个0-x的随机数
Math.round((Math.random)*x);
生成一个x-y之间的随机数
Maht.round(Math.random()*(y-x))+x;
3.3.date
日期类
//创建一个表示当前日期的对象
let a=new Date();
console.log(a);
//创建一个表示指定日期的对象
月 日 年 时 分 秒
let a=new Date('3/2/2019 14:11:11');
3.3.1 常用的方法
-
getDay() 获取当前的日期是周几 返回值是0-6 0 是周日
let a=new Date(); let arr=['周日','周一','周二','周三','周四','周五','周六']; console.log(arr[a.getDay()]);
-
getDate () 获取当前的日期
-
getMonth() 获取当前的月份 0-11 0 表示一月
-
getFullyear() 获取完整的年
-
getTime() 用来获取当前对象的时间 时间戳是1970 1 1 获取的是从1970年开始到现在所过了多少毫秒 在计算机的底层所有的时间都是由时间戳的形式存储
3.4.字符串方法
字符串本质上就是一个字符数组
在操作字符串的时候就跟操作字符数组一样
-
length 获取字符串的长度
-
concat 连接字符串
let a='ddddd'; a.concat('ehhehehe');
-
charAt() 根据索引获取字符串中的字符
-
charCodeAt()获取指定字符的字符编码
-
String.fromCharCode() 根据编码返回字符
-
indexOf() 查找字符串总是否有指定的字符编码 返回值是true 和 falst
-
slice() 用来从一个字符串中截取一个子串
两个参数 一个是起始的位置 一个是结束位置 包括开始但是不包括结束
str='12346'; str.slice(6,8);
-
split(); 根据指定的字符把字符串拆分
let str='123465'; let str2=split('3');
-
toLowerCase() 大写转小写
-
toUpperCase() 小写转大写
-
trim() 去除空格 只去除开始和结束的空格 中间的空格不去除
let str=' 11 '; str.trim();
3.5 字符串的解构赋值
let arr=[1,2,3,4,5,6];
let [a,b,c]=arr;//就是把arr 中的值依次赋值给a,b,c
//结果是
a=1 b=2 c=3
//----------------------------------
let arr=[1,2,3,4,5,6];
let [a,b,...c]=arr;
//z这个是把1给a 2给b 后面的都给c
结果是a=1 b=2 c=[3,4,5,6];
//-----------------------------------
let arr=[1,2,3,4,5,6];
[arr[1],arr[2]]=[arr[2],arr[1]];
结果是交换arr[1]和arr[2] 的值
3.5.闭包
概念:就是能访问到外部函数的内部函数、
用途:闭包的作用就是用来藏起来一些不希望被别人看到的东西
闭包的构成:1.必须要有函数的嵌套
2.内部函数必须要返回外部函数的变量
3.必须将内部函数作为返回值返回
生命周期:外部函数调用时闭包就产生了 外部函数每调用一次 当外部函数被回收的时候就消失了
function outer() {
//定义一个变量 记录函数的执行的次数
let times=0;
//创建一个函数 每次调用时 都会打印函数的次数
function inner() {
times++;
alert(times);
}
//将inner 作为函数的返回值
return inner;
}
let a=outer();
a=null;
4.DOM(查询)
dom是文档对象模型DOM中提供了大量的对象 来让我们通过js来操作网页
-
document 对象表示的是整个网页 通过document来获取网页的对象
let id=document.getElementById('id'); id.innerHTML='ddadfasd';
4.1事件
事件就是用户和网页的交互瞬间 例如鼠标点击 键盘按下
我们通过响应用户的事件来对用户进行交互
可以通过为指定对象的事件属性设置响应函数的形式来处理事件
let btn=document.getelementbyid('id');
btn.onclick=function(){
alert('哈哈哈');
}
4.3文档加载
由于前端的代码都是从前往后执行的 如果把script标签写在前面可能会导致html标签还没被读取完毕就开始js js就检测不到
解决方法1:把script标签写在body后面
解决方法2:window.οnlοad=function(){}
-
window.onload=function(){ let id=document.getElementById('id'); id.innerHTML='ddadfasd'; }
4.4 DOM查询
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>DOM查询</title>
<style>
*{
margin: 0;
padding: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: yellowgreen;
margin: 10px;
}
</style>
<script>
/*
如何获取到我们想要对象?
* */
window.onload = function () {
// 当我们点击按钮时,可以获取到box1
// 获取按钮btn01
let btn01 = document.getElementById('btn01');
// 为btn01绑定一个单击响应函数
btn01.onclick = function () {
/*
* document.getElementById()
* - 根据id获取一个元素节点对象
* */
// 获取到id为box1的div
let box1 = document.getElementById('box1');
// alert(box1);
box1.innerHTML = '我是box1中的文字';
};
// 当点击按钮2时可以获取到所有的class为item的li
// 获取到按钮2的对象
let btn02 = document.getElementById('btn02');
btn02.onclick = function () {
/*
* document.getElementsByClassName()
* - 根据class属性值获取一组元素
* */
// 获取class为item的元素
// let items = document.getElementsByClassName('item');
// document.getElementsByTagName() 根据标签名来获取一组元素节点对象
let items = document.getElementsByTagName('li');
// 遍历items
for(let i=0; i<items.length; i++){
alert(items[i].innerHTML);
}
};
// 获取btn03
let btn03 = document.getElementById('btn03');
btn03.onclick = function () {
/*
* getElementsXxx一系列总会返回一个类数组对象
* */
// let divs = document.getElementsByTagName('div');
// alert(divs.length);
// document.getElementsByTagName('*') 用来获取页面中的所有元素
// let all = document.getElementsByTagName('*');
// for(let i=0; i<all.length; i++){
// alert(all[i]);
// }
/*
* document.getElementsByName()
* - 根据name属性值获取一组元素节点对象
* (主要用来对付表单项)
*
* */
let um = document.getElementsByName('username')[0];
let genders = document.getElementsByName('gender');
// alert(um);
// innerHTML用来获取或设置标签内部的HTML代码
for(let i=0; i<genders.length; i++){
// 读取一个对象的属性值 value
/*
* 读取哪个属性就.哪个
* 特殊的就是 class属性,需要通过 className来获取
* classList 返回的是当前类所有class的列表,可以通过索引来获取具体的class
* */
alert(genders[i].classList[0]);
}
};
// 为btn04绑定单击响应函数
let btn04 = document.getElementById('btn04');
btn04.onclick = function () {
// 获取name为username的input
let um = document.getElementsByName('username')[0];
// 修改对象的属性 对象.属性 = 值
// alert(um.value);
um.value = '今天天气真不错!';
};
};
</script>
</head>
<body>
<button id="btn01">按钮一</button>
<button id="btn02">按钮二</button>
<button id="btn03">按钮三</button>
<button id="btn04">按钮四</button>
<div id="box1"></div>
<ul>
<li class="item">列表1</li>
<li class="item">列表2</li>
<li class="item">列表3</li>
<li class="item">列表4</li>
</ul>
<form action="#">
用户名:<input type="text" name="username"> <br>
性别:<input class="hello abc bcd" type="radio" name="gender" value="male">男
<input class="hello abc bcd" type="radio" name="gender" value="female">女
</form>
</body>
</html>
window.onload = function () {
/*
* 在document提供了一些直接获取元素的方法
* document.body 获取到页面的body元素
* document.documentElement 获取页面中html根元素
* */
// let body = document.getElementsByTagName('body')[0];
// alert(document.all.length);
// alert(document.body);
// alert(document.documentElement);
/*
document.querySelector()
- 根据CSS选择器来获取一个元素节点
- 需要一个选择器的字符串作为参数,会根据选择器去页面中获取元素
该方法只会返回符合条件的第一个元素
querySelectorAll()
- 根据CSS选择器返回所有符合条件的元素节点
*/
let div = document.querySelector('div[title]');
// alert(div);
// div.innerHTML = '这是被我找到的div';
let item = document.querySelector('.item');
// alert(items);
item.innerHTML = '我变了!';
let items = document.querySelectorAll('.item');
alert(items.length);
};
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#box1{
background-color: tomato;
}
#p1{
background-color: skyblue;
}
</style>
<script>
window.onload = function () {
// 为btn01绑定一个单击响应函数
document.getElementById('btn01').onclick = function () {
// let p = document.querySelectorAll('#box1 p');
// alert(p.length);
// 获取id为box1的元素
let box1 = document.getElementById('box1');
// 获取box1中的所有p元素
let p = box1.getElementsByTagName('p');
for(let i=0; i<p.length; i++){
p[i].innerHTML += '哈哈~';
}
};
// 为btn02绑定一个单击响应函数
document.getElementById('btn02').onclick = function () {
// 获取box1
let box1 = document.getElementById('box1');
// 获取box1的所有子节点
//childNodes 表示当前元素的所有子节点
// 空白的文本节点也会被当成子节点返回
let cns = box1.childNodes;
// children 用来获取当前元素的所有子元素
let cr = box1.children;
alert(cr.length);
// for(let i=0; i<cns.length; i++){
// alert(cns[i]);
// }
};
document.getElementById('btn03').onclick = function () {
let box1 = document.getElementById('box1');
// firstChild 用来获取当前元素的第一个子节点
// firstElementChild 用来获取第一个子元素
let fc = box1.firstChild;
let fec = box1.firstElementChild;
// box1.lastChild 最后一个子节点
// box1.lastElementChild 最后一个子元素
alert(fec);
};
document.getElementById('btn04').onclick = function () {
// 获取id为p1的元素的父节点
let p1 = document.getElementById('p1');
// parentNode 用来获取当前元素的父节点(通常都是元素)
// alert(p1.parentNode);
// previousSibling 获取当前节点的前一个兄弟节点
// previousElementSibling 获取当前节点上一个兄弟元素
// nextSibling 获取下一个兄弟节点
// nextElementSibling 获取下一个兄弟元素
let ps = p1.previousSibling;
let pes = p1.previousElementSibling;
alert(pes.innerHTML);
};
document.getElementById('btn05').onclick = function () {
// 读取标签内部的html代码
let p1 = document.getElementById('p1');
// innerHTML 表示标签内部的HTML代码(包含标签的)
// alert(p1.innerHTML);
// innerText 表示标签内部的文本内容(不含标签)
// alert(p1.innerText);
// alert(p1.textContent);
// <p id="p1">段落2</p>
let text = p1.firstChild;
// alert(text.nodeValue);
alert(p1.firstChild.nodeValue);
};
};
</script>
</head>
<body>
<button id="btn01">按钮1</button>
<button id="btn02">按钮2</button>
<button id="btn03">按钮3</button>
<button id="btn04">按钮4</button>
<button id="btn05">按钮5</button>
<div id="box1">
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
</div>
<div>
<p>段落1</p>
<p id="p1">段落2</p>
<p>段落3</p>
</div>
</body>
</html>
-
练习切换图片
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> *{ margin: 0; padding: 0; } .wb{ width:500px; margin:0 auto; margin-top: 50px; padding: 10px; background-color: yellow; text-align: center; } </style> <script> window.onload=function(){ let but01=document.getElementById('but01'); let but02=document.getElementById('but02'); let img=document.getElementsByTagName('img')[0]; let imgarr=['img/1.jpg','img/2.jpg','img/3.jpg','img/4.jpg','img/5.jpg']; let index=0; let info=document.getElementById('info'); but01.onclick=function(){ index--; if(index<0){ index=imgarr.length-1; } info.innerHTML='当前第'+(index+1)+'张'+'一共'+imgarr.length+'张'; img.src=imgarr[index]; } but02.onclick=function(){ index++; if(index>imgarr.length-1){ index=0; } info.innerHTML='当前第'+(index+1)+'张'+'一共'+imgarr.length+'张'; img.src=imgarr[index]; } } </script> </head> <body> <div class="wb"> <p id="info">当前第几章 总共几张</p> <img src="img/1.jpg" > <button type="button" id="but01">上一张</button> <button type="button" id="but02">下一张</button> </div> </body> </html>
``` <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #box1{ background-color: tomato; } #p1{ background-color: skyblue; } </style> <script> window.onload = function () { // 为btn01绑定一个单击响应函数 document.getElementById('btn01').onclick = function () { // let p = document.querySelectorAll('#box1 p'); // alert(p.length); // 获取id为box1的元素 let box1 = document.getElementById('box1'); // 获取box1中的所有p元素 let p = box1.getElementsByTagName('p'); for(let i=0; i<p.length; i++){ p[i].innerHTML += '哈哈~'; } }; // 为btn02绑定一个单击响应函数 document.getElementById('btn02').onclick = function () { // 获取box1 let box1 = document.getElementById('box1'); // 获取box1的所有子节点 //childNodes 表示当前元素的所有子节点 // 空白的文本节点也会被当成子节点返回 let cns = box1.childNodes; // children 用来获取当前元素的所有子元素 let cr = box1.children; alert(cr.length); // for(let i=0; i<cns.length; i++){ // alert(cns[i]); // } }; ``` ```
document.getElementById('btn03').onclick = function () { let box1 = document.getElementById('box1'); // firstChild 用来获取当前元素的第一个子节点 // firstElementChild 用来获取第一个子元素 let fc = box1.firstChild; let fec = box1.firstElementChild; // box1.lastChild 最后一个子节点 // box1.lastElementChild 最后一个子元素alert(fec); }; document.getElementById('btn04').onclick = function () { // 获取id为p1的元素的父节点 let p1 = document.getElementById('p1'); // parentNode 用来获取当前元素的父节点(通常都是元素) // alert(p1.parentNode); // previousSibling 获取当前节点的前一个兄弟节点 // previousElementSibling 获取当前节点上一个兄弟元素 // nextSibling 获取下一个兄弟节点 // nextElementSibling 获取下一个兄弟元素 let ps = p1.previousSibling; let pes = p1.previousElementSibling; alert(pes.innerHTML); }; document.getElementById('btn05').onclick = function () { // 读取标签内部的html代码 let p1 = document.getElementById('p1'); // innerHTML 表示标签内部的HTML代码(包含标签的) // alert(p1.innerHTML); // innerText 表示标签内部的文本内容(不含标签) // alert(p1.innerText); // alert(p1.textContent); // <p id="p1">段落2</p> let text = p1.firstChild; // alert(text.nodeValue); alert(p1.firstChild.nodeValue); }; };
按钮1
按钮2
按钮3
按钮4
按钮5
<div id="box1"> <p>段落1</p> <p>段落2</p> <p>段落3</p> </div> <div> <p>段落1</p> <p id="p1">段落2</p> <p>段落3</p> </div>
```
4.5DOM小结
-
节点
网页里面的所有的东西都是节点
常用的节点
文档节点:document(整个网页)
元素节点:element(div body h1)
文本节点:text(标签中的文字)
属性节点:attribute(标签中的属性)
-
DOM查询
查询是指在网页中获取网页中指定的节点
通过document对象查询
-
DOM查询常用方法
- 通过document对象查询 - document.getElementById() - 根据id获取一个元素节点对象 - document.getElementsByClassName() - 根据class属性值获取一组元素节点对象 - document.getElementsByTagName() - 根据标签名获取一组元素节点对象 - document.getElementsByTagName('*') - 获取页面中的所有元素 - document.getElementsByName() - 根据元素的name属性获取一组元素节点对象(主要用于表单项) - document.querySelector() - 根据选择器字符串获取符合条件的第一个元素 - document.querySelectorAll() - 根据选择器字符串获取符合条件的所有元素 - document.documentElement - 获取页面的根元素 (html) - document.body - 获取页面的body元素
4.6 element 常用方法
- 通过element进行查询
- element.getElementsByTagName()
- 根据标签名获取元素中的指定的后代元素
- element.childNodes
- 获取当前元素的所有子节点
- element.children
- 获取当前元素的所有子元素
- element.firstChild
- 获取第一个子节点
- element.firstElementChild
- 获取第一个子元素
- element.lastCwi个兄弟节点
- element.nextElementSibling
- 获取后一个兄弟元素
4.7 元素属性
- 元素的中的属性:
- 如何读取元素的属性:
元素.属性名
例子:
ele.name
ele.value
ele.id
ele.className
- 如何设置:
元素.属性名 = 属性值
例子:
ele.name = xx
ele.value = xxx
ele.id = xxx
ele.className = xx
- 其他属性:
innerHTML 内部的HTML代码,带标签
innerText 内部的文本内容,不带标签
- 读取一个标签内部的文本:
<span>哈哈</span>
span.innerHTML
span.innerText
span.firstChild.nodeValue
span.textContent
4.8DOM 小练习
全选 啥啥啥的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
input{
border-radius: 10px;
}
</style>
<script type="text/javascript">
window.onload=function(){
let all=document.getElementById('checkedAllBtn');
let notall=document.getElementById('checkedNoBtn');
let fx=document.getElementById('checkedRevBtn');
let tj=document.getElementById('sendBtn');
let qx=document.getElementById('checkedAllBox');
let items=document.getElementsByName('items');
//全选
all.onclick=function(){
for(let i=0;i<items.length;i++){
items[i].checked=true;
}
//大全选状态
qx.checked=true;
}
//全不选
notall.onclick=function(){
for(let i=0;i<items.length;i++){
items[i].checked=false;
}
qx.checked=false;
}
//反选
fx.onclick=function(){
for(let i=0;i<items.length;i++){
if(items[i].checked===true){
items[i].checked=false;
}else{
items[i].checked=true;
}
}
}
//提交
tj.onclick=function(){
for(let i=0;i<items.length;i++){
if(items[i].checked===true){
alert(items[i].value);
}
}
}
//全选全不选
qx.onclick=function(){
if(qx.checked){
for(let i=0;i<items.length;i++){
items[i].checked=true;
}
}else{
for(let i=0;i<items.length;i++){
items[i].checked=false;
}
}
}
//小全选同步大全选
// for(let i=0;i<items.length;i++){
// items[i].οnclick=function(){
// let pd=true;
// for(let j=0;j<items.length;j++){
// if(items[j].checked===false){
// pd=false;
// }
// }
// qx.checked=pd;
// }
// }
//方法二 判断所有选中的items 是不是和总的items的个数一样
for(let i=0;i<items.length;i++){
items[i].onclick=function(){
//获取所有选中的items
let xz=document.querySelectorAll('[name=items]:checked');
qx.checked=(xz.length===items.length);
}
}
}
</script>
</head>
<body>
<form method="post" action="">
你爱好的运动是?<input type="checkbox" id="checkedAllBox">全选/全不选
<br>
<input type="checkbox" name="items" value="足球">足球
<input type="checkbox" name="items" value="篮球">篮球
<input type="checkbox" name="items" value="羽毛球">羽毛球
<input type="checkbox" name="items" value="乒乓球">乒乓球
<br>
<input type="button" id="checkedAllBtn" value="全 选">
<input type="button" id="checkedNoBtn" value="全不选">
<input type="button" id="checkedRevBtn" value="反 选">
<input type="button" id="sendBtn" value="提 交">
</form>
</body>
</html>
5.DOM(增删改)
5.1 创建对象
创建对象 然后在对象中添加文字 把对象插入到对应的节点
- createElement(‘li’);通过标签名称来新建
let newli=document.createElement('li');
- 添加元素appendChild()
let list=document.getElementById('list');
let newli=document.createElement('li');
list.appendChild(newli);
- 创建一个文本子节点document.createTextNode(‘d’);
//创建一个文本节点
let text=document.createTextNode('ddddd');
newli.appendChild(text);
- 通过insertAdjacentHtml来添加
list.insertAdjacentHTML('beforeend','<li>新的元素<li>')
5.2删除对象
- removeChild() 删除子节点
list.removeChild(newli);
- parentNode() 父节点
通过父节点来删除自己
li1.parentNode.removeChild(li1);
- remove() 自己把自己删除
li1.remove();
5.3 小结
- DOM的增删改
- 创建元素
- document.createElement(标签名)
- 创建一个新的元素
- document.createTextNode(文本内容)
- 创建一个新的文本节点
- 插入元素
- 父节点.appendChild(子节点)
- 向父节点中插入一个子节点
- 元素.insertAdjacentElement('位置', 元素);
- 向元素的指定位置插入子元素
- 元素.insertAdjacentHTML('位置', 'HTML代码');
- 向元素的指定位置插入HTML代码
- 元素.insertAdjacentText('位置', '文本内容');
- 向元素的指定位置插入文本内容
- 位置需要传递一个字符串作为参数:
'beforebegin' 开始标签前,成为当前元素的前一个兄弟元素
'afterbegin' 开始标签后,成为当前元素的第一个子元素
'beforeend' 结束标签前,成为当前元素的最后一个子元素
'afterend' 结束标签后,成为当前元素的后一个兄弟元素
- 父节点.replaceChild(新节点, 旧节点)
- 使用新节点替换旧节点
- 父节点.insertBefore(新节点, 旧节点)
- 将新节点插入到旧节点的前边
- 复制节点
- 节点.cloneNode()
- 对节点进行浅复制(只复制节点本身)
- 节点.cloneNode(true)
- 对节点进行深复制(复制节点本身及所有的后代节点)
- 删除元素
- 子节点.parentNode.removeChild(子节点)
- 子节点.remove()
- this
- 根据函数的调用方式不同,this的值也不同:
1.以函数形式调用,this是window
2.以方法的形式调用,this是调用方法的对象
3.以构造函数的形式调用,this是新建的对象
4.以call和apply的形式调用,this是它们的第一个参数
5.箭头函数中的this由它外层作用域决定
6.事件的回调函数中,this是绑定事件的对象
- 默认行为
- 默认行为指当事件触发时元素默认会做的事情
比如:点击超链接后页面会发生跳转,点击表单的提交按钮后页面发生跳转 ...
- 有时默认行为会影响到正常功能,需要将其取消,只需要在事件的响应函数中return false即可取消
- 例子:
link.onclick = function(){
...
return false;
};
6.js对css的操作
-
对象.style
元素.style.样式名=样式值;
这种方法就是直接搞成了内联样式 只能修改一次 会立即执行
样式名中带有’-’ 的之间是改成是驼峰命名法
box1.style.backgrouind-color=‘’;
修改为
box1.style.backgroundColor=‘’;例如: box1.style.width='100px';//修改box1的宽度 也可以 let width=100; box1.style.width=width+'px'; 样式名中带有'-' 的之间是改成是驼峰命名法 box1.style.backgrouind-color=''; 修改为 box1.style.backgroundColor='';
-
获取样式
通过style来读取样式也指定读取内联样式
getComputedStyle(对象,‘伪元素’)
获取的是对象的所有的样式 如果要获取某一个样式之间后面加. 样式名称
通过getComputedStyle()获取的都是有单位的 如果要使用纯数据要只取有效单位
getComputedStyle(box).color console.log(getComputedStyle(box).width); console.log(parseInt(getComputedStyle(box).width));
clientHeight clientWidth 用来获取盒子的内部大小
内部大小是指 内容区加上内边距
console.log(box.clientHeight);
offsetHeight 用来获取盒子可见框的大小
内容区 内边距 边框
box.offsetHeight box.offsetWidth
offsetParent 获取当前定位的父元素
offsetLeft 获取当前元素相对于定位的父元素的相对左侧偏移量
offsetRIght 获取当前元素相对定位的父元素的右侧偏移量
offsetTOp 同上
scrollHeight()scrollWidth()获取元素滚动区域的大小
scrollTop()垂直滚动条的距离
scrollTop 垂直滚动条的滚动的距离
scrollLeft 水平滚动条滚动的距离
当 scrollHeight - scrollTop === clientHeight 说明垂直滚动条到底了
当 scrollWidth - scrollLeft === clientWidth 说明水平滚动条到底了//练习 滚动条滚动到底表名用户已经阅读协议 <script> window.onload=function () { //获取input 检测滚动条是否被 let info=document.getElementById('info'); let input=document.getElementsByTagName('input'); info.onscroll=function () { if(info.scrollHeight-info.scrollTop===info.clientHeight){ input[0].disabled=false; input[1].disabled=false; } } } </script>
6.2 事件对象
当事件的响应函数触发时,浏览器都会传递一个对象作为回调函数的实参,
这个实参就是事件对象,事件对象中存储了所有当前事件相关的信息,
比如:事件是谁触发、触发时哪个按键被按下、触发时鼠标的坐标…
显示鼠标坐标位置
<script>
window.onload=function () {
let box1=document.getElementById('box1');
let box2=document.getElementById('box2');
box1.onmouseover=function (event) {
let x=event.clientX;
let y=event.clientY;
box2.innerHTML='x='+x+'y='+y;
}
}
</script>
6.3 事件冒泡
冒泡是指 当某个事件被触发时 祖先元素的同类型事件也会被触发
冒泡和只和结构有关 (只和HTML有关)与样式无关(与css无关)
要取消事件的冒泡需要用到事件对象
只需将事件对象的 cancelBubble 属性设置true,即可取消冒泡
也可以通过 事件的对象 stopPropagation() 方法来停止冒泡
/*
* 冒泡(bubble)
* - 冒泡指的是事件的向上传导,当元素上的某个事件被触发时,
* 其祖先元素上的相同事件也会同时被触发
* - 冒泡的存在在大部分情况都是有利的,简化我们的开发
* - 冒泡的发生只和结构有关,和元素的位置无关
- 要取消事件的冒泡需要用到事件对象
只需将事件对象的 cancelBubble 属性设置true,即可取消冒泡
也可以通过 事件的对象 stopPropagation() 方法来停止冒泡
* */
// 分别为body box1 和 s1绑定单击响应函数
let s1 = document.getElementById('s1');
s1.onclick = function (event) {
// event.cancelBubble = true;
// 停止事件的冒泡
// event.stopPropagation();
alert('我是s1上的单击响应函数!');
};
let box1 = document.getElementById('box1');
box1.onclick = function (event) {
event.stopPropagation();
alert('我是box1上的单击响应函数!');
};
document.body.onclick = function () {
alert('我是body上的单击响应函数!');
};
6.3事件的绑定与事件的传播
可以通过 addEventListener() 来为元素设置响应函数
参数:
1.要绑定的事件,需要一个事件的字符串作为参数(不要on)
2.事件的回调函数
3.是否在捕获阶段触发事件,需要一个布尔值
true 会发生事件的捕获
false 不会(默认值)
* 可以通过 addEventListener() 来为元素设置响应函数
* 参数:
* 1.要绑定的事件,需要一个事件的字符串作为参数(不要on)
* 2.事件的回调函数
* 3.是否在捕获阶段触发事件,需要一个布尔值
* true 会发生事件的捕获
* false 不会(默认值)
*
* 通过该方式所绑定的事件不会互相干扰,可以为同一个事件绑定多个响应函数
* 事件触发时,函数会按照绑定的顺序执行
*
* removeEventListener()可以用来移除一个事件的响应函数
* - 移除时的参数必须和设置时的一模一样
*
-
事件的捕获与传播
/* * 关于事件的传播微软公司和网景公司有着不同的理解: * 微软认为,事件应该是由内向外传播, * 也就是先触发后代元素上的事件,在触发祖先元素的事件(事件的冒泡) * 网景认为,事件应该是由外向内传播 * 先触发祖先元素的上的事件,在触发后代元素的事件(事件的捕获) * W3C将两种理念进行整合,将事件分为了三个阶段: * 1.事件的捕获 * - 从最外层元素(window)向目标元素进行事件的捕获 * 2.目标元素 * - 事件捕获到目标元素,捕获停止 * 3.事件的冒泡 * - 从目标元素开始,向外层元素进行事件的冒泡 * - 默认情况下,事件是在冒泡阶触发的 * */
-
事件的委派
在事件中有一个属性叫做target他表示的是事件触发的对象
targer还有一个属性叫做tagName 表示的是事件触发的对象名
小结
通过JS去操作CSS: - 操作内联样式 - 属性:style - 读取样式: 元素.style.样式名 - 设置样式: 元素.style.样式名 = 样式值 - 注意: 1.通过style属性所读取和设置的样式都是内联样式 2.所以通过它所设置的样式通常会立即生效 3.如果样式名不符合标识符的规范,需要对样式名就行修改: 去掉-,-后的字母大写 background-color ==> backgroundColor border-left-width ==> borderLeftWidth - 获取当前的生效的样式 getComputedStyle() - 参数: 1.要获取样式的元素 2.要获取的伪类(没有可以不写) - 返回值: 一个对象,对象中包含了当前元素所有生效的样式 - 注意: 该方法获取的样式全都是只读的,无法修改 - 其他的样式相关的属性: clientWidth clientHeight - 获取的是内容区和内边距的总大小 offsetWidth offsetHeight - 获取的是内容区、内边距和边框的总大小 offsetParent - 获取当前元素的定位父元素 - 离当前元素最近的开启了定位的祖先元素,如果所有的祖先都没有开启定位 则返回body offsetLeft offsetTop - 当前元素距离其定位父元素的距离 scrollHeight scrollWidth - 获取元素滚动区域的大小 注意: 1.以上属性都是只读属性,无法修改 2.以上属性所获取的值都是不带单位的值,可以直接参与运算 scrollTop scrollLeft - 获取(设置)垂直和水平滚动条滚动的距离 - 判断滚动条滚动到底: - 垂直: scrollHeight - scrollTop === clientHeight - 水平: scrollWidht - scrollLeft === clientWidth 事件(Event) - 事件对象: - 当事件的回调函数被调用时,浏览器每次都会传递一个对象作为参数 这个对象就是事件对象。 - 事件对象中存储了事件相关的一切信息: 事件触发时,哪个鼠标按键被按下、 哪个键盘上的按键被按下、 鼠标滚轮滚动的方向.. - 要获取事件对象,只需在事件的回调函数中定义一个形参即可 - 事件的冒泡(bubble) - 冒泡指事件的向上传导, 子元素上事件触发时,会同时导致其祖先元素上的同类事件也被触发 - 冒泡的存在简化了代码的编写 - 但是有时我们不希望冒泡的存在,可以通过事件对象来取消冒泡: 1.通过cancelBubble属性来取消冒泡 event.cancelBubble = true; 2.通过stopPropagation()方法来取消冒泡 event.stopPropagation(); - 事件的传播 - 事件的传播分成了三个阶段: 1.事件的捕获 - 指事件从最外层元素开始向内部元素进行事件的捕获 - 默认情况下,捕获阶段不会触发事件 - 如果希望在捕获时触发事件,可以将addEventListener()的第三个参数设置为true 2.目标元素(触发事件的元素) - 捕获到达目标元素停止 3.事件的冒泡 - 从目标元素开始向外层元素进行事件的冒泡 - 默认情况下,冒泡时事件会被触发 - addEventListener() - 为元素添加事件的响应函数 - 参数: 1.要绑定的事件的字符串(不要on) 2.事件的回调函数 3.是否在捕获阶段触发事件,默认为false // https://developer.mozilla.org/en-US/docs/Web/Events - removeEventListener() - 移除元素上的指定的事件
-
小练习---- 拖拽
//当鼠标按下的时候 (function () { // 创建一个变量,来保存当前被拖拽的元素 let dragEle = null; // 创建两个变量,存储偏移量 let left, top; // 将鼠标按下的事件绑定给document document.addEventListener('mousedown', function (event) { // 如果触发事件的元素含有 drag 类,则可以进行拖拽 if(event.target.classList.contains('drag')){ event.preventDefault(); dragEle = event.target; left = event.clientX - dragEle.offsetLeft; top = event.clientY - dragEle.offsetTop; } }); // 给document绑定鼠标移动的事件 document.addEventListener('mousemove', function (event) { if(dragEle){ // 鼠标移动事件,改变被拖拽元素的位置 dragEle.style.left = event.clientX - left + 'px'; dragEle.style.top = event.clientY - top + 'px'; } }); // 给document绑定鼠标松开的事件 document.addEventListener('mouseup', function (event) { // 将dragEle设置为null dragEle = null; }); })();
6.4 修改元素的class
一个一个的修改元素的样式太麻烦 我们可以把要修改的样式写在一个class里面 然后通过修改元素的class来修改元素的样式
使用classlist 来对元素的class来进行操作
常用的方法 remove add replace替换
toggle 切换 有多个类的话就切换 没有就不切换
contains 检查一个元素是不是包含某类
let button=document.getElementById('button'); let box1=document.getElementsByClassName('box1'); button.addEventListener('click',function () { box1.classList.replace('box1','box2') })
6.5 鼠标事件
-
右键菜单事件 contextmenu
document.addEventListener('contextmenu', function (event) { // event.preventDefault(); // console.log('你点了右键了~'); // }); }
-
鼠标滚轮事件wheel
document.addEventListener('wheel', function (event) { // console.log('我滚了~~'); // event.deltaY 获取滚轮的垂直滚动的方向 // console.log(event.deltaY); // if(event.deltaY > 0){ // console.log('向下滚~~'); // }else{ // console.log('向上滚~~'); // } /* event.deltaX 滚轮的水平滚动方向 * */ console.log(event.deltaX); });
-
6.6键盘事件
-
keydown keyup keypress
event.key 能够看出用户按下的是哪个键
event.ctrlkey 能够判断用户是否同时按下了Ctrl和其他键
6.7定时器
-
steTImeout() 在指定的时间后调用函数
SetTimeOut(函数,时间);
-
clearTimeout() 用来关闭定时器
-
setInterVar(函数,时间);每隔一段时间就开始调用、
会有一个返回值 可以使用一个参数timer来接受这个返回值
-
clearInterval(定时器) 关闭定时器
//从1到10的定时器
<script>
let num=0;
let hh=document.getElementsByTagName('h1')[0];
let timer=setInterval(function (event) {
num++;
hh.innerHTML=num;
if(num===10){
clearInterval(timer);
}
},10);
</script>
贪吃蛇游戏
7.BOM
BOM 浏览器对象模型 通过BOM可以操作浏览器
7.1BOM对象
-
window
代表的是浏览器窗口
-
history(历史)
代表的是浏览器的历史记录(向前 向后翻页的)
-
location
代表的是浏览器的地址栏
-
Navigator
代表的是浏览器的信息
-
screen
代表的是设备屏幕的信息
<script>
/*
* BOM(浏览器对象模型)
* - BOM中为我们提供了一组对象,用来完成对浏览器的各种操作
* - BOM对象:
* Window
* - 代表的是浏览器窗口
* History
* - 代表的是浏览器的历史记录
* Location
* - 代表的是浏览器的地址栏
* Navigator
* - 代表浏览器的信息
* Screen
* - 代表的是设备屏幕信息
*
* - BOM对象都是window对象的属性,所以可以直接访问
*
* */
// alert(location);
// alert(window.history);
window.onload = function () {
let btn01 = document.getElementById('btn01');
btn01.addEventListener('click', function () {
/*
* History 表示浏览器的历史记录
* - 由于隐私的原因,History无法访问具体的历史记录
* - 只能用来控制浏览器向前向后翻页
* history.length
* - 当前访问的页面的数量
* history.forward();
* - 切换到前边访问的网址
* history.back();
* - 相当于浏览器的回退按钮
* history.go()
* - 跳转到指定的历史记录
* */
// alert(history.length);
// history.forward();
// history.back();
// history.go(2);
// history.go(-1);
/*
location
- location表示浏览器地址栏信息
- 如果直接读取location,则可以获取到地址栏的信息
- 如果修改location的值,则浏览器会自动跳转到新的地址
- 通过这种方式跳转页面,会留下历史记录,可以通过回退按钮回退
- assign()
- 用来跳转地址,和直接修改location是一样的
- replace()
- 用来跳转地址,它不会产生历史记录,无法通过回退按钮回退
- reload()
- 用来重新加载网页,相当于网页的刷新按钮
* */
// alert(location.port);
// location = 'https://www.baidu.com';
// location.assign('https://www.jd.com');
// location.replace('https://www.jd.com');
// location.reload(true);
});
};
</script>
7.2 Navigator
代表浏览器的信息 ,通过Navigator来识别不同的浏览器
主要是用来识别ie
<script>
document.getElementById('btn01').addEventListener('click', function () {
/*
* Navigator
* - 代表浏览器的信息,通过Navigator来识别出不同的浏览器
* - 在 Navigator 中大部分属性都没有什么使用价值
* - userAgent 返回的是一个字符串,
* 用来表示浏览器的信息
*
* - Chrome
* Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
* - Firefox
* Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
*
* - IE
* Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
* Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
*
* - IE11
* Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
* */
var ua = navigator.userAgent;
console.log(ua);
if (ua.indexOf('Firefox') !== -1) {
alert('你是火狐~~');
} else if (ua.indexOf('Chrome') !== -1) {
alert('你是Chrome');
} else if (ua.indexOf('MSIE') !== -1) {
alert('你是IE');
}
});
</script>
如何判断ie
<script>
document.getElementById('btn01').addEventListener('click', function () {
/*
* Navigator
* - 代表浏览器的信息,通过Navigator来识别出不同的浏览器
* - 在 Navigator 中大部分属性都没有什么使用价值
* - userAgent 返回的是一个字符串,
* 用来表示浏览器的信息
*
* - Chrome
* Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
* - Firefox
* Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
*
* - IE
* Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
* Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
*
* - IE11
* Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
* */
var ua = navigator.userAgent;
// console.log(ua);
// if(ua.indexOf('Firefox') !== -1){
// alert('你是火狐~~');
// }else if(ua.indexOf('Chrome') !== -1){
// alert('你是Chrome');
// }else if(ua.indexOf('MSIE') !== -1){
// alert('你是IE');
// }
if('ActiveXObject' in window){
alert('你是IE!');
}else if(ua.indexOf('Firefox') !== -1){
alert('你是火狐~~');
}else if(ua.indexOf('Chrome') !== -1){
alert('你是Chrome');
}
// alert(!!window.ActiveXObject);
});
</script>
8.正则表达式
正则表达式就是一个规则 让计算机可以根据这个规则来做一些事情
8.3创建正则表达式
new RegExp(‘正则表达式’,‘匹配规则’)
方法二:字面量 语法:/正则/匹配模式
/*
* 量词
* {m} 正好出现m次
* {m,n} 出现m到n次
* {m,} 至少出现m次
* + 至少1次,等价于 {1,}
* ? 0-1次,等价于 {0,1}
* * 0-多次,等价于 {0,}
* */
<script>
//检查一个字符串中是否含有a
let re = /a/;
//检查一个字符串中是否含有aa
re = /aa/;
/*
* 量词
* {m} 正好出现m次
* {m,n} 出现m到n次
* {m,} 至少出现m次
* + 至少1次,等价于 {1,}
* ? 0-1次,等价于 {0,1}
* * 0-多次,等价于 {0,}
* */
//检查一个字符串中是否含有aaaa
re = /a{4}/;
re = /ab{4}c/;
re = /ab{1,3}c/;
re = /ab{1,}c/;
re = /(ab){2}c/;
re = /ab+c/;
re = /ab?c/;
re = /ab*c/;
alert(re.test('abc'));
</script>
8.3 正则语法
匹配模式:i: 忽略大小学 g全局匹配
| 表示或 * [] 中的内容都表示或 * [a-z] 表示任意的小写字母 * [A-Z] 表示任意的大写字母 * [a-zA-Z] 任意字母 * [0-9] 任意数字 * [^ ] 表示除了结尾 $表示结束 . 表示任意字符 * \. 表示 . * \w 任意单词字符,相当于[A-Za-z0-9_] * \W 除了单词字符,相当于[^A-Za-z0-9_] * \d 任意数字,相当于[0-9] * \D 除了数字,相当于[^0-9] * \s 空格 * \S 除了空格
* 创建正则表达式来检查一个字符串是否是一个合法的手机号码
*
* 1 3 67890145
* 以1开头 3-9 任意数字9个结尾
* ^1 [3-9] [0-9]{9}$
*
* */
let phoneReg = /^1[3-9][0-9]{9}$/;
str = '11678901451';
phoneReg = /1[3-9][0-9]{9}/;
str = 'hello13716578901dasdasdasd';
alert(phoneReg.test(str));
//创建一个正则表示邮箱
[a-zA-Z]{1,}/. (\w{1,})* @ [a-zA-A-]{1,} (\.[a-z]{2,5}){1,2}$i
8.4 字符串方法 结合正则表达式
-
search()搜索字符串中是否有指定的字符串
返回值是字符串中第一次出现的位置 可以传递一个正则表达式过去
let srt='ddddd'; srt.search('dd'); --检查str中是否含有'dd' --通过正则表达式来找字符串 str.search(/^1[3-9][0-9]{9}$/)
-
split() 把一个字符串拆分成一个数组
let str='d1d1d1d1d1d1'; str.split('1'); --根据正则表达式来拆 str.split(/a[bd]c/i);
-
replace() 替换
参数:正则表达式,新的内容
使用哈哈哈 来替换电话号码 let str='ddddh哈哈哈155232222222'; str.replace(/^1[3-9][0-9]{9}$/g,'哈哈哈');
-
match() 提取 将符合正则表达式的内容提取出来
参数是一个正则表达式 返回值是一个数组
将字符串中的所有电话号码取出来 let str='ddddd155231234'; let new=str.match(/^1[3-9][0-9]{9}$/g);