JavaScript学习笔记
1.JavaScript的输入输出
- 输出
js自上往下执行
<!-- js代码需要编写到script标签中 -->
<script>
// 控制浏览器弹出一个警告框
alert("hello world");
// 让计算机在页面中输出一个内容
//可以在body中写入一个内容
document.write("mea");
// 向控制台输出一个内容
console.log("在浏览器控制台出现");
- 输入
prompt()可以弹出一个提示框,该提示框中会带有一个文本框
用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数
该字符串将会作为提示框的提升文字
用户输入的内容将会作为函数的返回值(返回值类型为String)返回,可以定义一个变量来接收该内容
var score= prompt("请输入小明的成绩");
2.JavaScript的编写位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="keywords" content="HTML5,前端,css3">
<meta name="description" content="这是一个不错的网站">
<!-- 可以将js代码编写到外部js文件中,然后通过script标签引入
写到外部文件中可以在不同的页面中同时引入,也可以利用到浏览器的缓存机制
-->
<!-- scrip标签一旦用于引入外部文件,就不能在编写代码了
即使编写了浏览器也会忽略
如果需要则可以再创建一个新的script标签用于编写内部代码
-->
<script src="scripttest.js"></script>
<title>Document</title>
<style>
</style>
<script>
// 可以在head部分写JavaScript代码
alert("我是内部的js代码");
</script>
</head>
<body>
<!-- 可以将JavaScript代码编写到标签的onclick属性中,当我们点击按钮时,js代码才执行
虽然可以写在标签的属性中,但是他们属于结构和行为耦合,不方便维护,不推荐使用
-->
<button οnclick="alert('不要点我')">点击</button>
<!-- 可以将js代码写在超链接的href属性中,这样当点击超链接时,会执行js代码 -->
<a href="javascript:alert('点了也没有用');">点我吧</a>
</body>
</html>
3.JavaScript的基本语法
-
JS中严格区分大小写
-
JS每一条语句以分号(;)结尾
如果不写分号,浏览器会自动添加,但是会消耗一些系统资源
-
JS中会忽略多个空格和换行,所以我们可以利用空格和换行
-
JS中使用var关键字来说明一个变量,不可改变的值叫字面量,如1,2,3,”hello”都叫字面量
var a=100;
-
JS中标识符命名规则和C语言类似,一般常用驼峰命名法
4.JavaScript的基本数据类型
数据类型指的是字面量的类型
在JS中一共有六种数据类型
- String 字符串
- Number 数值
- Boolean 布尔值
- Null 空值
- Underfined 未定义
- Object 对象
1.String
在JS中字符串需要使用引号引起来
使用单引号或双引号都可以,但是不要混用
引号不能嵌套,双引号不能放双引号,单引号不能放单引号
JavaScript的转义字符和C语言的一样
2.Number
包括整数和浮点数
可以用typeof来检查一个变量的类型
typeof 变量
a="123"
console(typeof a)
JS中表示的数字的最大值:Number.MAX_VALUE
如果Number表示的数字超过最大值,则会返回一个Infinity(正无穷)
使用typeof 检查也是返回Number
NaNcy是一个特殊的数字,表示Not A Number
使用typeof检查一个NaN也会返回number
Number.MIN_VALUE 大于0的最小数
JS中整数的运算基本可以保证精确
如果使用JS进行浮点数运算,可能得到一个不精确的结果,所以千万不要使用JS进行对精确度要求比较高的运算
var c=0.1+0.2
console.log(c)
//结果:0.30000000000000004
3.Boolean
和Java一样只有true和false
4.Null和Undefind
Null(空值)类型的值只有一个,就是null
null这个值专门用来一个为空的对象
使用typeof检查一个null值,会返回object
var a=null;
console.log(null)
//null
Undefind(未定义)类型的值只有一个,就undefind
当声明一个变量,但是并不给变量赋值,它的值就是undefined
使用typeof 检查一个undefined时也会返回undefined
var b;
console.log(b)
//undefined
5.Object
5.强制类型转化
强制类型转化
类型转换主要指将其他的数据类型转换为String Number Boolean
1.转换为String
方法一:
调用被转换数据类型的toString()方法
该方法不会影响到原变量,它会将转换的结果返回
但是注意:null和undefined这两个值没有toString方法,如果调用他们的方法,会报错
方法二:
调用String()函数
使用String()函数做强制类型转换时,
对于Number和Boolean实际上就是调用toString()
但是对于null和undefined,就不会调用toString()方法
它会将null直接转换为“null”
将undefined直接转换为“underfined”
2.转换为Number
方法一:
使用Number()函数
- 字符串转为数字
- 如果是纯数字的字符串,则直接 将其转换为数字
- 如果字符串中有非数字的内容,则转换为NaN
- 如果字符串是一个空串或是一个全是空格的字符串,则转换为0
- 布尔转为数字
- true转为1
- false转为2
- null转为数字0
- undefined转为NaN
方法二:
专门对付字符串
parseInt():把一个字符串转换为一个整数
var a="123";
console.log(parseInt(a)); //123
var b="123.34px";
console.log(parseInt(b)); //123
var c="123a34";
console.log(parseInt(c)); //123
parseFloat():可以获得有效的小数(不一定获得的就是浮点数)
var a="123";
console.log(parseFloat(a)); #123
var b="123.34px";
console.log(parseFloat(b));#123.34
var c="123a34";
console.log(parseFloat(c));#123
var d="123.456.789px"
console.log(parseFloat(d))#123.456
如果对非String使用parseInt()或parseFloat()
它会先将其转换为String,然后在操作
var a=123.98;
console.log(parseInt(a)); //123
var b=true;
console.log(parseInt(b)); //nan
3.转换为Boolean
将其他的数据类型转换为Boolean
方法一:使用Boolean()函数
数字—>布尔值
除了0和nan是false,其他的都是true
字符串—>布尔值
除了空串是false,其他的都是true
null和undefined都会转换为false
对象也会转换为true
方法二:可以为任意的数据类型做两次非运算,即可将其转换为布尔值
6.进制表示
-
在JS中,如果需要表示16进制的数字,则需要以0x开头
-
需要表示8进制的数字,则需要以0开头
-
如果要表示2进制的数字,则需要以0b开头(但不是所有的浏览器都支持)
-
像“070”这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析,可以在parseInt()中传递一个第二个参数,来指定数字的进制
var a="070"; console.log(parseInt(a,10)); //70 console.log(parseInt(a,8)); //56
7.运算符
对于所有的所有的算数运算符,非Number类型的值进行运算时,会将这些值转换为Number然后进行运算(和字符串进行+比较特殊,会拼接得到字符串)
1.+运算符
- 对两个数字进行加法运算
- 任何值(非字符串)和NaN做运算都得NaN
- 如果和字符串进行+运算,会返回一个由两个值拼接成的字符串
2.-运算符
var a="100";
var b=1;
console.log(a-b); //99
var a="100abc";
var b=1;
console.log(a-b); //NaN
3.*运算符
var a="100";
var b=1;
console.log(a-b); //200
4./运算符
var a=1;
var b=null;
console.log(a/b); //Infinity
5.%运算符
var a=10;
console.log(a%0); //NaN
var a=10;
console.log(a%3); //1
6.技巧
方法一:
任何值做 – * /运算都会自动转换为Number,我们可以利用这一特点做隐式的类型转换
可以通过为一个值 -0 *1 、1来将其转换为Number
原理和Number()函数一样,使用起来更加简单
方法二:
对于非数字类型,可以用一元运算符+,它会先转换为Number,然后再运算
8.非布尔值的与或非运算
-
与(&&)运算
如果第一个值为true,则必然返回第二个值
如果第一个值为false,则直接返回第一个值
-
或(||)运算
如果第一个值为true,则直接返回第一个值
如果第一个值为false,则返回第二个值
9.关系运算符
数值的关系比较和C语言一样,要注意NaN对任意值都是false
非数值的情况
- 对于非数值进行比较时,会将其转换为数字然后比较
- 如果符号两侧的值都是字符串时,不会将转换为数字进行比较,而是按照strcmp的方式比较
- 所以,在比较两个字符串型的数字时,一定到转型
10.相等运算符(==)
当使用==来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型再比较
NaN不和任何值相等,包括他本身,可以用isNaN()函数来判断一个值是否为NaN
undefined衍生自null,比较返回true
11.全等(===)
===
全等用来判断两个值是否全等,它和全等类似,不同的是它不会做自动类型转换,如果两个类型不等,直接返回false
12.控制结构
控制结构和C语言一样
13.break
break关键字可以用来退出switch或循环语句
不能在在if语句中使用break和continue
break关键帧,会立刻终止离它最近的那个循环语句
可以为循环语句创建一个label,来标识当前的循环
label:循环语句
使用break语句时,可以在break后跟一个label
这样break将会结束指定的循环,而不是最近的
outer:
for(var i=0;i<5;i++){
console.log("外层循环"+i);
for (var j=0;j<5;j++){
break outer;
console.log("内层循环"+j);
}
} //外层循环0
14.对象
-
内建对象
由ES标准定义的对象,在任何的ES的实现都可以使用
比如:Math String Number Function Object
-
宿主对象
由JS的运行环境提供的对象,目前来说主要指的由浏览器提供的对象
比如BOM DOM
-
自定义对象
由开发人员创建的对象
15.对象的创建
对象属性的添加,删除,修改和python一样
var obj= new Object();
obj.name="tom";
obj.sex="male";
obj.age=18;
console.log(obj); //{name: 'tom', sex: 'male', age: 18}
console.log(obj.hello); //undefined
16.属性名和属性值
如果要使用特殊的属性名,不能采用.的方式来操作
需要使用另一种方法:
语法:对象[“属性名”]=属性值
读取时也需要采用这种方法
var obj= new Object();
obj["123"]=789;
console.log(obj["123"]) //789
使用[]这种形式去操作属性,更加灵活
在[]中可以直接传递一个变量,主要变量值是多少就会读取那个属性
var obj= new Object();
var test="name";
obj.name="tom";
obj.sex="male";
obj.age=18;
console.log(obj[test]); //tom
test="sex";
console.log(obj[test]); //male
对象的属性值可以是任何的数据类型,也可以是个函数
var obj= new Object();
obj.name="tom";
obj.sex="male";
obj.age=18;
obj.sayName=function(){
console.log(obj.name);
};
obj.sayName(); //执行函数 tom
17.基本数据类型和引用数据类型的区别
基本数据类型
String Number Boolean Null Undefined
引用数据类型
Object
JS中的变量都是保存到栈内存中的
基本数据类型的值直接在栈内存中存储
值与值之间是独立存在,修改一个变量不会影响其他的变量
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间
而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用
当一个通过变量修改属性时,另一个也会受到影响
var obj1= new Object();
obj1.name="tom";
var obj2= new Object();
obj2=obj1;
obj1.name="nancy";
console.log(obj2.name); //nancy
var obj1= new Object();
obj1.name="tom";
var obj2= new Object();
obj2=obj1;
obj2=null;
console.log(obj2); //null
console.log(obj1); //{name: 'tom'}
var obj1= new Object();
obj1.name="tom";
var obj2= new Object();
obj2.name="nancy";
console.log(obj1==obj2); //false
当比较两个基本数据类型的值时,就是比较值
而比较两个引用数据类型时,它是比较的对象的内存地址
如果两个对象是一模一样的,但是地址不同,她也会返回false
18.对象字面量
使用对象字面量,可以在创建对象时,直接指定对象中的属性
语法:{属性名:属性值,属性名:属性值…}
对象字面量的属性名可以加引号也可以不加,建议不加
如果要使用一些特殊的名字,则必须加引号
var obj1={name:"tom",sex:"man",age:18}; //最后一个键值对就不用加,了
属性名和属性值是一组键值对结构
名和值之间使用:连接,多个键值对之间使用,隔开
19.函数定义
函数也是一个对象
-
使用函数声明来创建一个函数
语法:
function 函数名([形参1,形参2…形参N])
function fun1(){ console.log("这是我的第一个函数"); } fun1(); //调用函数,这是我的第一个函数
-
使用函数表达式来创建一个函数
语法:
var 函数名 = function([形参1,形参2…形参N])
var fun2=function(){ console.log("我是匿名函数中封装的代码"); }; fun2(); //我是匿名函数中封装的代码
20.函数的参数
函数的实参和形参对应和书写和C语言一样,但是调用函数时对参数的检查并不严格
- 调用函数时解析器不会检查实参的类型,所以要注意是否有可能会接收非法的参数,必要时需要对参数进行类型检查
- 函数的实参可以是任意的数据类型
function sum(a,b){
console.log(a+b);
}
sum(1,2); //3
sum(123,"hello"); //123hello
sum(true,false); //1
-
调用函数时,解析器也不会检查实参的数量
多余参数不会被赋值
如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
function sum(a,b){
console.log(a+b);
}
sum(123); //nan
sum(1,2,"hello",true); //3
sum('hello',2,true,2); //hello2
- 当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递
var ob1={name:"tom",sex:"male",age:18};
function fun1(obj){
console.log("名字:"+ob1.name+"年龄:"+ob1.age+"性别:"+ob1.sex);
}
fun1(ob1); //名字:tom年龄:18性别:male
- 参数也可以是函数
var ob1={name:"jike",sex:"male",age:18};
function fun1(obj){
console.log("名字:"+ob1.name+"年龄:"+ob1.age+"性别:"+ob1.sex);
return 0;
}
function fun2(fun){
fun(ob1);
}
// 这个相当于直接使用函数对象
fun2(fun1) //名字:jike年龄:18性别:male
/* fun2(fun1(ob1))
* 调用函数
* 相当于使用的函数的返回值
* 即fun2(0)
*/
21.函数的返回值
用return返回
- 在函数中return后的语句都不会执行,使用return可以结束整个函数
- 如果return语句后不跟任何值就相当于返回一个undefined
- 如果函数不写return,则也会返回一个undefined
- return后可以跟任意类型的值,可以是一个对象,也可以是一个函数
function fun3(){
// 在函数内部再声明一个函数
function fun4(){
return 10;
}
// 返回函数对象
// return fun4;
// 这个是返回函数返回值
return fun4()
}
a=fun3();
console.log(a); //10
function fun3(){
// 在函数内部再声明一个函数
function fun4(){
console.log("fun4函数");
}
return fun4;
}
a=fun3();
a(); //fun4函数
22.立即执行函数
立即执行函数
函数定义完,立即被调用,这种叫做叫做立即执行函数
立即执行函数往往只会执行一次
//立即执行函数,不带参数
(function(){
alert("我是一个匿名函数");
})();
//立即执行函数,带参数
(function(a,b){
console.log("a="+a); //a=11
console.log("b="+b); //b=22
})(11,22);
23.全局作用域和函数作用域
-
全局作用域
直接编写在Script标签中的JS 代码,都在全局作用域
全局作用域在页面打开时创建,在页面关闭时销毁
在全局作用域中有一个全局对象window
它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
在全局作用域中
创建的变量都会被作为window对象的属性保存
创建的函数都会作为window对象的方法保存
全局作用域中的变量都是全局变量,在页面的任意部分都可以访问到
-
局部作用域
调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
如果没有则向上一级作用域中寻找,直到找到全局作用域
如果全局作用域中依然没有找到,则会报错ReferenceError
在函数中访问全局变量可以使用window对象
var a=10; var fun2=function() { console.log(a); }; fun2(); //10
a=33; // 在函数中,不使用var声明的变量都会成为全局变量 function fun1(){ a=10; d=100; } fun1(); //在执行后,会改变全局变量a的数值,也会产生全局变量d,当然一定要执行函数 console.log(a); //10 console.log(d); //100
24.变量和函数的提前声明
-
变量的声明提前
使用var关键字声明的变量,会在所有的代码执行前被声明,但是不会赋值
var a; console.log(a); //undfined a=10; console.log(a); //a
但是如果声明变量时不使用var关键字,则变量不会被声明提前
a;
console.log(a); //报错 a is not definedat
a=10;
console.log(a);
-
函数的声明提前
使用函数声明形式创建的函数function 函数名(){},它会在所有的代码执行之前就被创建,所以可以在函数声明前来调用函数
fun1(); //声明前调用
function fun1(){
console.log("声明前调用");
}
使用函数表达式创建的函数不会被声明提前,所以不能在声明前调用
fun2(); //Uncaught TypeError: fun2 is not a function
var fun2=function() {
console.log("函数调用");
};
fun2(); //正确位置
-
在函数作用域也有声明提前的特性
使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
函数声明也会在函数中所有的代码执行之前执行
function fun3(){ fun4(); function fun4(){ alert("im fun4"); }; };
25.this
解析器在调用函数每次都会向函数内部传递一个隐含的参数,
这个隐含的参数就是this,this指向的是一个对象
这个对象我们称为函数执行的上下文对象
根据函数的调用方式的不同,this会指向不同的对象
- 以函数的形式调用时,this永远都是window
- 以方法调用时,this就是调用方法的那个对象
- 以构建函数的形式调用时,this是新创建的那个对象
- 使用call和apply调用时,this是指定的那个对象
var name="window的name";
function fun1(){
console.log(this.name);
}
fun1(); //window的name
obj1={
name:"tom",
sayName:fun1
};
obj1.sayName(); //tom
obj2={
name:"nancy",
sayName:fun1
};
obj2.sayName(); //nancy
26.使用工厂方法创建对象
就是类似于Java的类构建函数
function creatperson(name,age,gender){
var obj= new Object();
obj.name=name;
obj.age=age;
obj.gender=gender;
obj.sayName=function(){
console.log(this.name);
};
return obj;
}
var obj1=creatperson("tom",18,"man");
var obj2=creatperson("nancy",19,"female");
console.log(obj1); //{name: 'tom', age: 18, gender: 'man', sayName: ƒ}
console.log(obj2); //{name: 'nancy', age: 19, gender: 'female', sayName: ƒ}
使用工厂方法创建的对象,使用的构建函数都是Object
所以创建的对象都是Object这个类型
导致我们无法区分多种不同类型的对象
27.构造函数
构造函数的执行流程:
- 立刻创建一个新的对象
- 将新的对象设置为函数中this,在构建函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
function Person(name,sex){
this.name=name;
this.sex=sex;
}
var per1=new Person("tom","man");
console.log(per1); //Person {name: 'tom', sex: 'man'}
function pig(name,sex){
this.name=name;
this.sex=sex;
}
var pig1= new pig("nancy","female");
console.log(pig1); //pig {name: "nancy" sex: "female"}
和Java,python一样可以用instanceof来检查一个对象是否是指定类的实例
语法:
对象 instanceof 构造函数类名
28.原型对象
在对象中直接添加方法的办法,每次创建的方法都是不同的,会极大的浪费资源
为此,我们可以将对象共有的属性和方法放进原型对象prototype
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
这个属性对应一个对象,这个对象就是我们所谓的原型对象
如果函数作为普通函数,调用prototype没有任何作用
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性
指向该构造函数的原型对象,我们可以通过–proto–来访问该属性,
- 原型对象就相当于一个公共的区域,所有同一类的实例都可以访问到这个原型对象
我们可以将对象中共有的内容,统一设置到原型对象中。
- 当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
function Person(name,sex){
this.name=name;
this.sex=sex;
};
Person.prototype.sayHello=function(){
console.log(this.name+"hello");
};
var per1=new Person("tom","man");
per1.sayHello(); //tomhello
var per2=new Person("hhh","man");
per2.sayHello(); //hhhhello
console.log(per1.sayHello==per2.sayHello); //true
function Person(name,sex){
this.name=name;
this.sex=sex;
};
Person.prototype.sayHello=function(){
console.log(this.name+"hello");
};
var per1=new Person("tom","man");
var per2=new Person("hhh","man");
// 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log("sayHello" in per1); //true
// 可以使用对象的hasOwnProperty()来检查对象自身是否含有该属性
// 使用该方法只有对象自身 中含有属性时,才会返回true
console.log(per1.hasOwnProperty("name")); //true
原型对象也是对象,所以他也有原型
当我们使用一个对象的属性或方法时,会先在自身中寻找
自身如果有,则直接使用,如果没有则去原型中寻找,如果原型对象有,则使用
如果没有则去原型的原型中寻找,直到找到Object对象的原型
Object的原型没有原型,如果在Object中依然没有找到,则返回undefined
29.toString()
一样在prototype里面设置
function Person(name,sex){
this.name=name;
this.sex=sex;
Person.prototype.sayHello=function(){
console.log(this.name+"hello");
};
Person.prototype.toString=function(){
console.log("这是"+this.name+"的tostring方法");
};
};
var per1=new Person("tom","man");
var per2=new Person("hhh","man");
per1.toString(); //这是tom的tostring方法
per2.toString(); //这是hhh的tostring方法
30.数组
JS数组本身是特殊的
对象
,没有负索引
//创建数组
var arr1= new Array(10); //创建一个长度为10的空数组
var arr2=[1,2,3,4,5];
var arr3=new Array(10,20,30); //创建[10,20,30]
//读取数组中的元素也C语言一样
//如果读取不存在的索引,不会报错而是返回undefined
//可以有非连续数组
var arr3= new Array();
arr3[0]=1;
arr3[1]=2;
arr3[5]=10;
console.log(arr3); //非连续数组的打印 [1, 2,,,, 10]
//获取数组的长度
语法:数组.length
对于连续的数组,使用length可以获取到数组的长度
对于非连续的数组,使用length会获得到数组的最大的索引+1 ,尽量不要创建非连续的数组
//修改length。
如果修改的length大于原长度,则多出部分会空出来
如果修改的length小于原长度,则多出来的元素会被删除
var arr2=[1,2,3,4,5];
arr2.length=2;
console.log(arr2); //[1, 2]
//数组中的元素可以是任意的数据类型,也可以是对象或函数
var arr4=["tom",123,true,null];
console.log(arr4); //['tom', 123, true, null]
31.数组的常用方法
-
push()
该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
可以将要添加的元素作为方法的参数传递
-
pop()
该方法可以删除数组的最后一个元素,并返回被删除的元素
-
unshift()
向数组开头添加添加一个或多个元素,并返回新的数组长度
-
shift()
可以删除数组的第一个元素,并将被删除的元素作为返回值
var arr=[1,2,3,4,5,6];
res1=arr.push(7,8,9);
console.log(res1); //9
console.log(arr); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
res2=arr.pop(9);
console.log(res2); //9
console.log(arr); //[1, 2, 3, 4, 5, 6, 7, 8]
res3=arr.unshift(9,10,11);
console.log(res3); //11
console.log(arr); //[9, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8]
res4=arr.shift();
console.log(res4); //9
console.log(arr); // [10, 11, 1, 2, 3, 4, 5, 6, 7, 8]
-
slice()
可以用来从数组中提取指定元素
该方法不会改变元素数组,而是将截取的元素封装到一个新的数组中返回
参数:
截取开始的位置的索引,包含开始索引
截取结束的位置的索引,不包括结束索引
第二个参数可以省略不写,此时会截取从开始往后的所有元素
var arr=[1,2,3,4,5,6]; var res=arr.slice(1,4); console.log(res); //[2, 3, 4] res=arr.slice(1,); console.log(res); //[2,,3,4,5,6]
-
splice()
可以用来删除数组中指定的元素
使用splice()会影响原数组,会将指定元素从原数组中删除
并将被删除的元素作为返回值
参数:
第一个,开始位置的索引
第二个,表示删除的数量
第三个及以后,可以传递新的元素,这些元素将会自动插入到开始位置索引前面
var arr=[1,2,3,4,5,6]; var res=arr.splice(1,2); console.log(res); //[2,3] console.log(arr); //[1,4,5,6] arr.splice(0,0,"new1","new2"); console.log(arr); // ['new1', 'new2', 1, 4, 5, 6]
-
concat()
可以连接两个或多个数组,并将新的数组返回
该方法不会对原数组产生影响
var arr1=[1,2]; var arr2=[3,4]; var arr3=arr1.concat(arr2,"tom",true); console.log(arr3); // [1, 2, 3, 4, 'tom', true]
-
join():
该方法可以将数组转换为一个字符串
该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
可以指定一个字符串作为参数,这个字符串将会作为数组元素的连接符,如果不指定连接符,则默认使用,作为连接符
var arr1=[1,2]; console.log(arr1.join()); //"1,2" console.log(typeof arr1.join()); //string console.log(arr1.join("~___~ ")); //1~___~ 2
-
reverse()
数组的反转,影响原数组
var arr1=[1,2]; arr1.reverse(); console.log(arr1); //[2,1]
-
sort()
可以对数组中的元素进行排序
也会影响原数组,默认会按照Unicode编码进行排序
即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序
所以对数字进行排序时,可能会得到错误的结果
可以自己来指定排序的规则,在sort()添加一个回调函数,来指定排序规则,回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数
使用哪个元素不确定,但是肯定的是在数组中a一定在b前面
如果返回一个大于0的值,则元素会交换位置
如果返回一个小于0的值,则元素位置不变
如果返回一个0,则认为两个元素相等,也不交换位置
var arr=[9,2,12,78,2,1];
arr.sort(function(a,b){
//升序排列
return a-b; // [1, 2, 2, 9, 12, 78]
});
console.log(arr);
arr.sort(function(a,b){
//降序排列
return b-a;
});
console.log(arr); //[78, 12, 9, 2, 2, 1]
arr.sort();
console.log(arr); // [1, 12, 2, 2, 78, 9]
32.数组的forEach()方法
forEach()方法需要一个函数作为参数
像这种函数,由我们创建但是不由我们调用的,我们称为回调函数
数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历的元素以实参的形式传递回来,我们可以来定义形参,来读取这些内容
浏览器会在回调函数中传递三个参数:
- 第一个参数:当前正在遍历的元素
- 第二个参数,就是当前正在遍历的元素的索引
- 第三个参数,就是正在遍历的数组
var arr=[1,2,3,4,5,6];
arr.forEach(function(value,index,obj){
console.log("我是第"+value+"个"+"元素:"+value);
});
该方法只支持IE8以上浏览器,移动端也可以使用
33.call和apply
这两个方法都是函数对象的方法,需要通过函数对象来调用
当函数调用call()和apply()都会调用函数执行
在调用call()和apply()可以将一个对象指定为第一个参数
此时这个对象将会成为函数执行时的this
call()方法可以将实参在对象之后依次传递
apply()方法需要将实参封装到一个数组中统一传递
var obj1={
name:"tom",
sex:"male",
syaName:function(){
console.log(this.name);
}
};
var obj2={
name:"nancy",
sex:"female",
syaName:function(){
console.log(this.name);
}
};
function fun(a,b){
console.log("a="+a);
console.log("b="+b);
}
fun.call(obj1,2,3); //a=2 b=3
fun.apply(obj1,[2,3]); //a=2 b=3
obj1.syaName.call(obj2); //nancy
34.arguments
在调用函数时,浏览器每次都会传递两个隐含的参数:
-
函数的上下文对象this
-
封装实参的对象arguments
arguments是一个类数组对象,她也可以通过索引来操作数据,也可以获取长度
在调用函数时,我们所传递的实参都会在arguments中保存
我们即使不定义形参,也可以通过arguments来使用实参
只不过比较麻烦 arguments[0]:表示第一个实参 arguments[1]:表示第二个实参
它里面有一个属性叫做callee,这个属性对于一个函数对象,就是当前正在指向的函数的对象
function fun(a,b){ console.log(arguments[0]); console.log(arguments[1]); console.log(arguments.length); console.log(arguments.callee==fun); }; fun("hello",123); //hello 123 2 true
35.Date
在JS中使用Date对象来表示一个时间
// 创建一个date对象
// 如果直接使用构建函数创建一个Date对象,则会封装当前代码执行的时间
var d1=new Date();
// 创建一个指定的时间对象
// 需要在构建函数中传递一个表示时间的字符串作为参数
// 日期的格式 月份/日/年 时:分:秒
var d2= new Date("4/16/1960 14:59:00");
// getDate():获取当前日期对象是几号
var d3=d2.getDate();
console.log(d3);
// getDay():获取当前日期对象是周几,会返回一个0~6的值 0表示周日 1表示周一....
var day=d1.getDay()
console.log(day); //16
// getMonth():获取当前对象的月份,会返回一个0~11的值 0表示1月,1表示2月
var month=d1.getMonth();
console.log(month); //6
// getFullYear():获取当前日期对象的年份
var year=d1.getFullYear();
console.log(year); //2022
// getTime():获取当前日期对象的时间戳,从格林尼治时间1970年1月1日0时0分0秒到当前日期的毫秒数
// 计算机底层在保存时间使用都是时间戳
var time=d2.getTime(d1);
console.log(time); //-306435660000,因为是东八区的时间,所以是负
//Date.now() 获取当前的时间戳
36.math
Js中的Math函数的使用和Java,python一样
Math.ceil(1.2); //向上取整,小数值只要有值就自动进一 2
Math.floor(1.2); //向下取整,小数部分舍掉 1
console.log( Math.round(1.5)); //对一个数四舍五入取整 2
37.包装类
和Java一样,JS为我们提供了三个包装类,通过包装类可以将基本数据类型的数据转换为对象
String()
-可以将字符串转换为String对象
Number()
-可以将数字转换为Number对象
Boolean()
-可以将布尔值转换为Boolean对象
但是,在实际应用中不会使用基本数据类型的对象,如果使用基本数据类型的对象,在做一些比较时可能带来不可预期的结果
方法和属性能添加给对象,不能添加给基本数据类型
当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法,调用以后,再将其转换为基本数据类型
38.正则表达式
正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式,来检查一个字符串是否符合规则,或者将字符串中符合规则的内容提取出来。
// 语法 :var 变量 = new RegExp("正则表达式","匹配模式");
// 使用typeof 检查正则对象,会返回object
// 构造函数中可以传递一个匹配模式作为第二个参数,
// 可以是:i:忽略大小写 g:全局匹配模式
var reg= new RegExp("a"); //检查字符串中是否含有a
var str1="abcd";
// 正则表达式的方法:
// test():使用这个方法可以用来检查一个字符串是否符合正则表达式的规则
// 如果符合返回true,否则返回false
res=reg.test(str1);
console.log(res); //true
var reg1= new RegExp("a","i"); //忽略大小写的模式
var str2="Abc";
res=reg1.test(str2);
console.log(res); //true
1.正则语法
//使用字面量创建正则表达式
//语法:var 变量=/正则表达式/匹配模式;
//使用字面量的方式创建更加简单
//使用构造函数创建更加灵活
reg=/a/i;
//创建一个正则表达式,检查一个字符串中是否有a或b
//语法:使用|表示或者的意思
reg=/a|b/;
//[]里面的内容也是或的关系,[ab]=a|b
//[a-z]:任意小写字母
//[A-Z]:任意大写字母
//[A-z]:任意字母
//检查一个字符串中是否含有abc 或adc 或aec
reg=/a[bde]c/;
//[^~]:字符串中是否除了~还有内容
var reg= /[^ab]/;
var str1="ab";
var str2="abc";
console.log(reg.test(str1)); //false
console.log(reg.test(str2)); //true
// 创建一个正则表达式检查一个字符串中是否含有几个特定元素
//量词 通过量词可以设置一个内容出现的次数,量词只对它前面的一个内容起作用
//{n}正好出现{n}次
//{m,n}出现m-n次
//{m,} m次以上
//+ 至少一个,相当于{1,}
//* 0个或多个,相当于{0,}
// ? 0个或一个,相当于{0,1}
var reg1=/a{3}/;
str1="aaabc";
console.log(reg1.test(str1)); //true
var reg2=/(ab){3}/;
str2="abababc";
console.log(reg2.test(str2)); //true
var reg3=/ab?c/;
console.log(reg3.test("abbc")); //false
// 检查一个字符串的开头结尾
// ^ 表示开头 /^a/ 匹配开头的a
// $ 表示结尾 /a$/ 匹配结尾的a
// 如果在正则表达式中同时使用^ $则要求字符串必须要完全符合正则表达式
reg=/^a$/;
console.log(reg.test("a")); //true
console.log(reg.test("aba")); //false
// 检查手机号的规则
//1.以1开头
//2.第二位3-9任意数字
//3.三位以后任意数字9个
var phoneReg=/^1[3-9][0-9]{9}$/;
console.log(phoneReg.test("16662445644")); //true
console.log(phoneReg.test("abds16662445644")); //false
var phoneReg2=/1[3-9][0-9]{9}/;
console.log(phoneReg2.test("abds16662445644")); //true,^$同时使用的必要性
/* 检查一个是否含有特殊字符
在正则表达式中使用\作为转义字符
\.表示.
\\表示\
使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,要使用\需要使用\\来代替
\w:任意字母,数字,_ 相当于[A-z0-9_]
\W:除了字母,数字,_ 相当于[^A-z0-9_]
\d:任意的数字 [0-9]
\D:除了数字[^0-9]
\s:空格
\S:除了空格
\b:单词边界
\B:除了单词边界
*/
var reg1=/\W/;
console.log(reg1.test("1111&&")); //true
// 创建一个正则表达式检查一个字符串中是否含有单词child
reg2=/child/;
console.log(reg2.test("hello children")); //true
reg3=/\bchild/;
console.log(reg3.test("hello children")); //true
reg4=/\bchild\b/
console.log(reg4.test("hello children")); //false
reg5=/\bchild\b/
console.log(reg5.test("hello child ren")); //true
//去除开头结尾的空格
var str1=" he llo ";
reg=/^\s*|\s*$/g;
console.log(str1.replace(reg,""));
/*
电子邮件
hell .nihao @ abc .com.cn
任意字母数字下划线 .任意字母数字下划线 @ 任意字母数字 .任意字母(2-5位) .任意字母
\w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}){1,2}
*/
var reg= /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
console.log(reg.test("hello.mei@163.com")); //true
console.log(reg.test("hui@qq.com")); //true
2.字符串和正则表达式
-
split()
可以将一个字符串拆分为一个数字
方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串
var reg= /[A-z]/; var str="1a2c3b4nb5"; console.log(str.split(reg)); //['1', '2', '3', '4', '', '5']
-
search()
可以搜索字符串中是否有指定内容
可以接受一个正则表达式作为参数,然后会根据正则表达式去搜索字符串
无法设置全局查找
var reg= /a[de]c/; var str="hello adc hello aec"; var res=str.search(reg); console.log(res); //6
-
match()
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就会停止搜索,可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
可以为一个正则表达式设置多个匹配模式,且顺序无所谓
match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
var reg= /[A-z]/g; var str="1bi35477*7&&&&&&eer%"; var res=str.match(reg); console.log(res); // ['b', 'i', 'e', 'e', 'r']
-
replace()
可以将字符串中指定内容替换为新的内容
参数:
- 被替换的内容,可以接受一个正则表达式作为参数
- 新的内容
- 默认只会替换第一个
var reg= /[A-z]/ig; var str="1b2b33h45ji8O0i"; var res=str.replace(reg,"[替换]"); console.log(res); //1[替换]2[替换]33[替换]45[替换][替换]8[替换]0[替换]
39.DOM简介
DOM:Document Object Model 文档对象模型
-
JS通过DOM来来对HTMl文档进行操作,只要理解了DoMain就可以操作web页面
-
文档
文档表示的就是整个的HTML网页文档
-
对象
对象表示将网页中的每一个部分都转换为了一个对象
-
模型
使用模型来表示对象之间的关系,方便我们获取对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="scripttest.js"></script>
<title>Document</title>
</head>
<body>
<button id="btn">我是一个按钮</button>
<script>
/* 浏览器已经为我们提供文档节点对象,整个对象是window属性
可以在页面直接使用,文档节点代表的是整个网页 */
// 获取到button对象
var btn=document.getElementById("btn");
// 运行就修改按钮的文字
//获取元素内部的HTML代码
btn.innerHTML="i'm a Button";
//innerText:该属性可以获取到元素内部的文本内容,会去掉HTML标签
</script>
</body>
</html>
40.事件
事件就是用户和浏览器之间的交互行为
我们可以在事件对应的属性中设置一个js代码,这样当事件被触发时,这些代码将会执行(不方便维护,不推荐)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="scripttest.js"></script>
<title>Document</title>
</head>
<body>
<button id="btn">我是一个按钮</button>
<script>
/*
可以为按钮的对应事件绑定处理函数的形式来响应事件
这样当事件被触发时,其对应的函数将会被调用
*/
// 绑定一个单击事件:按钮单击改变内部文字
// 像这种为单击事件绑定的函数,称为单击响应函数
var btn=document.getElementById("btn");
btn.οnclick=function(){
btn.innerHTML="i'm a button";
};
</script>
</body>
</html>
41.文档的加载
浏览器在加载一个页面时,是按照自上而下的顺序加载的
读取到一行就运行一行,如果将script标签写到页面的上边
在代码执行时,页面还没有加载
把js代码写在head,而不是标签后面需要onload
onload事件会在整个页面加载完成才会触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="scripttest.js"></script>
<title>Document</title>
<script>
// 为window绑定一个onload事件
//该事件对应的响应函数将会在页面加载完成之后执行
//这样可以确保我们的代码执行时所有的DoM对象已经加载完成了
window.οnlοad=function(){
var btn=document.getElementById("btn");
btn.οnclick=function(){
btn.innerHTML="i'm a button";
};
};
</script>
</head>
<body>
<button id="btn">我是一个按钮</button>
</body>
</html>
42.Dom查询
获取元素节点
-
通过document对象
-
getElemntById():通过
id
属性获取
一个
元素节点 -
getElementsByTagName():通过
标签
名获取
一组
元素节点对象 会返回一个类数组对象,所有查询到的元素都会封装到对象中
-
getElementsByName():通过
name
属性获取
一组
元素节点对象
//tips: 如果需要读取元素节点属性,可以直接使用元素.属性值 如:元素.id ;元素.name;元素.value 注意:class属性不能采用这种方式 读取class属性时需要使用元素.className
-
-
获取元素节点的子节点
通过具体的元素节点调用
-
getElementsByTagName()
方法,返回当前节点的指定标签名后代节点
-
childNodes
属性,表示当前节点的所有子节点
childNodes属性会获取包括文本节点在内的所有节点
根据DOM标签间空白也会当成文本节点,所以空白也会当成文本节点
-
children
属性,可以获取当前元素的所有子
元素
-
firstChild
属性,表示当前节点的第一个
子节点
-
firstElementChild
属性,表示当前元素的第一个子元素
-
lastChild
属性,表示当前节点的最后一个
子节点
-
lastElementChild
属性,表示当前元素的最后一个子元素
-
-
获取父节点和兄弟节点
通过具体的节点调用
和前一个一样,都有对应的获取元素属性
-
parentNode
属性,表示当前节点的父节点
-
previousSibling
属性,表示当前节点的前一个兄弟节点
-
nextSibling
属性,表示当前节点的后一个兄弟节点
-
-
DOM其他的查询
// 获取body标签 var body=document.body; // 获取HTML根标签 var html=document.documentElement; // 获取页面所有元素 var all=document.getElementsByTagName("*"); // 根据元素的class属性值查询一组元素节点 var box1=document.getElementsByClassName("box1"); /* document.querySelector() 需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象 使用该方法总会返回唯一一个元素,如果满足条件的元素有多个,那么他只会返回第一个 */ // 获取.box1类下的唯一div var div=document.querySelector(".box1 div"); /* document.querySelectorAll() 该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回 即使符合条件的元素只有一个,它也会返回数组 */
43.dom图片切换案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<style>
.outer{
width: 800px;
margin: 0 auto;
padding: 40px;
background-color: aqua;
text-align: center;
}
img{
width: 750px;
margin: 0 auto;
background-size:contain;
}
</style>
<script>
/*
要切换图片就是要修改img标签的src属性
*/
// 分别为两个按钮绑定单击响应函数
window.onload=function(){
// 获取img标签,页面只有一个元素直接用索引
var img=document.getElementsByTagName("img")[0];
// 创建一个数组,用来保存图片的路径
var imgarr=["image/meabanner1.jfif","image/meabanner2.jfif","image/meabaner3.jfif"];
// 创建一个变量,来保存当前正在显示的图片的索引
var index=0;
// 设置id为info的p元素
var info=document.getElementById("info");
// 设置提示文字
info.innerHTML="一共"+imgarr.length+"张图片,当前第"+(index+1)+"张";
var pre=document.getElementById("pre");
var next=document.getElementById("next");
pre.onclick=function(){
/*
切换图片就是修改img的src属性
要修改一个元素的属性:元素.属性=属性值
*/
// 切换到上一张,索引自减
index--;
// 判断index是否小于0
if(index<0){
index=imgarr.length-1;
}
img.src=imgarr[index];
// 每次点击按钮,重新设置文字
info.innerHTML="一共"+imgarr.length+"张图片,当前第"+(index+1)+"张";
};
next.onclick=function(){
index++;
// 判断index是否大于最大索引值
if(index>imgarr.length-1){
index=0;
}
img.src=imgarr[index];
// 每次点击按钮,重新设置文字
info.innerHTML="一共"+imgarr.length+"张图片,当前第"+(index+1)+"张";
};
};
</script>
</head>
<body>
<div class="outer">
<p id="info"></p>
<img src="image/meabanner1.jfif" alt="">
<button id="pre">上一张</button>
<button id="next">下一张</button>
</div>
</body>
</html>
44.提交选择练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<style>
</style>
<script>
window.οnlοad=function(){
/*
全选按钮
点击按钮以后,四个多选框都被选中
*/
// 1.#checkedallbtn
// 为id为checkedallbtn的按钮绑定一个单击响应函数
var checkedallbtn=document.getElementById("checkedallbtn");
// 提取所有的选项元素对象
var items=document.getElementsByName("items");
checkedallbtn.οnclick=function(){
// 获取四个多选框items
// 遍历items
for (i=0;i<items.length;i++){
// 通过多选框的checked属性获取或设置多选框的选中状态
items[i].checked=true;
}
}
// 2.全不选
var checkedNobtn=document.getElementById("checkedNobtn");
checkedNobtn.οnclick=function(){
for(i=0;i<items.length;i++){
items[i].checked=false;
}
}
// 3.反选
var checkedrevbtn=document.getElementById("checkedrevbtn");
checkedrevbtn.οnclick=function(){
for (i=0;i<items.length;i++){
if(items[i].checked){
items[i].checked=false;
}
else{
items[i].checked=true;
}
}
}
// 4.提交,将所有选中的value弹出
var sendbtn=document.getElementById("sendbtn");
sendbtn.οnclick=function(){
for(i=0;i<items.length;i++){
if(items[i].checked){
alert(items[i].value);
}
}
}
};
</script>
</head>
<body>
<form action="" method="post">
你喜好的运动是?<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" value="全选" id="checkedallbtn">
<input type="button" value="全不选" id="checkedNobtn">
<input type="button" value="反选" id="checkedrevbtn">
<input type="button" value="提交" id="sendbtn" >
</form>
</body>
</html>
45.DOM增删改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
.outer{
margin: 0 auto;
width: 400px;
height: 200px;
font-size: 20px;
border: 5px solid black;
}
.outer ul{
display: flex;
}
ul li{
margin-top: 50px;
margin-left: 20px;
width: 50px;
height: 30px;
background-color: #bfa;
}
</style>
<script>
window.οnlοad=function(){
// 为列表添加一个广州节点
// 1.创建一个li元素节点
/*
document.createElement()
可以用于创建一个文本节点对象
它需要一个标签名作为参数,将会根据该标签名创建元素节点对象
并将创建好的对象作为返回值返回
*/
var li1=document.createElement("li");
// 2.创建广州文本节点
/*
document.createTextNode()
可以用来创建一个文本节点对象
需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
*/
var gztext1=document.createTextNode("广州");
// 3.将gztext设置li的子节点
/*
appendChild()
向一个父节点中添加一个新的子节点
用法:父节点.appendChild(子节点)
*/
li1.appendChild(gztext1);
// 4.获取city节点
var city=document.getElementById("city");
// 5.把新节点添加进city
city.appendChild(li1);
// 在北京节点前面插入一个河内节点
// 1.获取北京的节点
var bj=city.firstElementChild;
// 2.创建一个河内节点
var li2=document.createElement("li");
var heneitext=document.createTextNode("河内");
li2.appendChild(heneitext);
// 2.北京节点前面插入一个广州节点
/*
insertBefore()
可以在指定的子节点前插入新的子节点
语法:父节点.insertBefore(新节点,旧节点)
*/
city.insertBefore(li2,bj);
// 把北京节点替换成广州节点
/*
replaceChild();
可以使用指定的子节点替换已有的子节点
语法:父节点.replaceChild(新节点,旧节点)
旧节点会消失
*/
city.replaceChild(li1,bj);
// 删除上海节点
var shai=li1.nextElementSibling;
/*
removeChild()
可以删除一个子节点
语法:父节点.removeChild(子节点)
或者:子节点.parentNode.removeChild(子节点)(常用便捷)
*/
shai.parentNode.removeChild(shai);
// 向列表添加香港节点(通过innerhtml实现):// city.innerHTML+="<li>香港</li>";
/*
使用innerHtml也可以完成DOM的增删改的相关操作
一般会把把前面的和这种结合使用
*/
var li3=document.createElement("li");
li3.innerHTML="香港";
city.appendChild(li3);
};
</script>
</head>
<body>
<div class="outer">
<p>你喜欢哪个城市?</p>
<ul id="city">
<li>北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
</div>
</body>
</html>
(原始未修改的页面)
(JavaScript运行后的界面)
46.表单添加删除练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#employeeTable{
width: 50%;
border: 1px solid black;
margin: 0 auto;
border-collapse: collapse;
}
#employeeTable td,th{
border: 1px solid black;
text-align: center;
}
#fromdiv{
width: 50%;
margin: 0 auto;
}
</style>
<script>
var delA=function(){
// 点击超链接以后删除超链接所在的那行
// 1.获取当前tr
var tr=this.parentNode.parentNode;
// 2.弹出删除提示
var name=tr.firstElementChild.innerHTML;
/*
confirm()用于弹出一个带有确定和取消按钮的提示框
需要一个字符串作为参数作为提示文字
如果点击确定返回true ,点击取消返回false
*/
var flag=confirm("是否要删除"+name+"的记录");
if(flag){
tr.parentNode.removeChild(tr);
}
/*
点击超链接以后,超链接会跳转页面,这个是超链接的默认行为
但是此时我们不希望出现默认行为,可以在响应函数的最后return false来取消默认行为
*/
return false;
}
window.onload=function(){
/*
点击超链接以后,删除一个员工的信息
*/
// 获取所有的超链接
var allA=document.getElementsByTagName("a");
// 为每一个超链接都绑定一个单击响应函数
for(var i=0;i<allA.length;i++){
allA[i].onclick=delA;
}
/*
添加员工的功能
点击按钮以后,将员工的信息添加到表格中
*/
// 为提交按钮绑定一个单击响应函数
var addEmpBUtton=document.getElementById("addEmpBUtton");
addEmpBUtton.onclick=function(){
// 添加用户的员工信息
var name=document.getElementById("empName").value;
var email=document.getElementById("email").value;
var income=document.getElementById("income").value;
// 创建tr和子节点
var tr=document.createElement("tr");
var nametd=document.createElement("td");
var emailtd=document.createElement("td");
var incometd=document.createElement("td");
var atd=document.createElement("td");
var a=document.createElement("a");
// 创建文本节点
var nametext=document.createTextNode(name);
var emailtext=document.createTextNode(email);
var incometext=document.createTextNode(income);
var deltext=document.createTextNode("删除这个节点");
//为a标签添加href属性
a.href="#";
// 为a绑定单击响应函数
a.onclick=delA;
//设置对应的子节点
nametd.appendChild(nametext);
emailtd.appendChild(emailtext);
incometd.appendChild(incometext);
a.appendChild(deltext);
atd.appendChild(a);
tr.appendChild(nametd);
tr.append(emailtd);
tr.appendChild(incometd);
tr.appendChild(atd);
// 获取table
var employeeTable=document.getElementById("employeeTable");
employeeTable.appendChild(tr);
}
};
</script>
</head>
<body>
<table id="employeeTable">
<tr>
<th>Name</th>
<th>Email</th>
<th>income</th>
<th> </th>
</tr>
<tr>
<td>Tom</td>
<td>Ton@13.com</td>
<td>5000</td>
<td><a href="#">删除该记录</a></td>
</tr>
<tr>
<td>jike</td>
<td>jiek@13.com</td>
<td>15000</td>
<td><a href="#">删除该记录</a></td>
</tr>
<tr>
<td>jimmy</td>
<td>jimmy@13.com</td>
<td>51000</td>
<td><a href="#">删除该记录</a></td>
</tr>
</table>
<div id="fromdiv">
<h4>添加新员工</h4>
<table>
<tr>
<td class=" word">name:</td>
<td class="inp">
<input type="text" name="empName" id="empName">
</td>
</tr>
<tr>
<td class="word">Email:</td>
<td class="inp">
<input type="text" name="email" id="email">
</td>
</tr>
<tr>
<td class="word">income:</td>
<td class="inp">
<input type="text" name="income" id="income">
</td>
</tr>
<tr>
<td>
<button id="addEmpBUtton" value="abc">
Submit
</button>
</td>
</tr>
</table>
</div>
</body>
</html>
改进
var addEmpBUtton=document.getElementById("addEmpBUtton");
addEmpBUtton.οnclick=function(){
// 添加用户的员工信息
var name=document.getElementById("empName").value;
var email=document.getElementById("email").value;
var income=document.getElementById("income").value;
// 创建tr和子节点
var tr=document.createElement("tr");
tr.innerHTML="<td>"+name+"</td>"+
"<td>"+email+"</td>"+income+
"<td><a href='#'>删除这个节点</a></td>";
var a=tr.getElementsByTagName("a")[0];
a.οnclick=delA;
// 获取table
var employeeTable=document.getElementById("employeeTable");
var tbody=employeeTable.getElementsByTagName("tbody")[0];
tbody.appendChild(tr);
}
47.循环和单击响应函数执行顺序问题
var allA=document.getElementsByTagName("a");
// 为每一个超链接都绑定一个单击响应函数
for(var i=0;i<allA.length;i++){
/*
for循环会在页面加载完成之后立即执行
而响应函数会在超链接被点击时才执行
当响应函数执行时,for循环早已执行完毕
*/
alert("for循环正在执行"+i);
allA[i].onclick=function(){
alert("响应函数正在执行"+i);
return false;
}
}
(刷新执行的情况)
48.操作和读取内联样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 300px;
height: 300px;
background-color: red !important;
}
</style>
<script>
window.οnlοad=function(){
/*
通过JS改变元素的样式:
语法:元素.style.样式名=样式值;
注意:如果CSS的样式名含有-
这种名称在JS中是不合法的比如:background-color
需要将这种样式名修改为驼峰命名法
去掉-,然后将-后字母大写
通过style设置的样式都是内联样式
而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
但是如果在样式表中写了!important,则此时样式会有最高的优先级
即使通过JS也不能覆盖该样式,所以将会导致JS修改样式失效
所以尽量不要为样式添加!important
*/
var box1=document.getElementById("box1");
var btn01=document.getElementById("btn01");
var btn02=document.getElementById("btn02");
btn01.οnclick=function(){
box1.style.width="600px";
box1.style.height="600px";
box1.style.backgroundColor="aqua";
}
btn02.οnclick=function(){
/*
读取box1的样式
语法:元素.style.样式名
通过style属性和读取的都是内联样式
无法读取样式表中的样式
*/
alert(box1.style.width);
}
};
</script>
</head>
<body>
<button id="btn01">点我一下</button>
<button id="btn02">读取样式</button>
<br>
<div id="box1"></div>
</body>
</html>
49.获取元素的样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 300px;
height: 300px;
background-color: red ;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
var btn01=document.getElementById("btn01");
var btn02=document.getElementById("btn02");
btn01.onclick=function(){
box1.style.width="600px";
box1.style.height="600px";
box1.style.backgroundColor="aqua";
}
btn02.onclick=function(){
/*
getComputedStyle()这个方法来获取元素当前的样式
这个方法是window的方法,可以直接使用
需要两个参数
第一个:要获取样式的元素
第二个:可以传递一个伪元素,一般都传null
该方法会返回一个对象,对象中封装当前元素对应的样式
可以通过对象.样式名来读取样式
如果获取的样式没有设置,则会获取到真实的值,而不是默认值
比如:没有设置width,它不会获取到auto,而是一个长度
*/
var obj=getComputedStyle(box1,null);
alert(obj.width);
alert(obj.height);
alert(obj.backgroundColor);
}
};
</script>
</head>
<body>
<button id="btn01">点我一下</button>
<button id="btn02">读取样式</button>
<br>
<div id="box1"></div>
</body>
</html>
(会自动读取当前页面的样式)
//自定义兼容IE8获取属性方法
function getStyle(obj,name){
if(window.getComputedStyle){
// 正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj,null)[name];
}
else{
// IE8的方法,没有getComputedStyle()方法
return obj.currentStyle[name];
}
}
50.其他样式相关的属性
clientWidth clientHeght
这两个属性可以获取元素的可见宽度和高度
这些属性都是不带px的返回的都是一个数字,可以直接进行计算
会获取元素宽度和高度,包括内容去和内边距
这些属性都是只读的,不能修改
offsetParent
可以用来获取当前元素的定位父元素
会获取到离当前元素最近的开启了定位的祖先元素
如果所有的祖先元素都没有开启定位,则返回body
offsetLeft
当前元素相对于其定位元素的水平偏移量
offsetTop
当前元素相对于其定位元素的垂直偏移量
scrollLeft
可以获取水平滚动条滚动的距离
scrollTop
可以获取垂直滚动条滚动的距离
当满足scrollHeight-scrollTop==clientHeight
说明垂直滚动条滚动到底了
当满足scrollWidth-scrollLeft==clientWidth
说明水平滚动条滚动到底了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
p{
width: 200px;
height: 300px;
background-color: beige;
overflow: auto;
}
</style>
<script>
window.οnlοad=function(){
/*
当垂直滚动条滚动到底时使表单项可用
onscroll:该事件会在元素的滚动条滚动时触发
*/
var info=document.getElementById("info");
var inputs=document.getElementsByTagName("input");
info.οnscrοll=function(){
// 判断垂直滚动条是否滚动到底
if(Math.ceil( info.scrollHeight)-Math.ceil(info.scrollTop)<=info.clientHeight){
/*
disabled属性可以设置一个元素是否禁用
如果设置为true,元素禁用
如果设置为false,则元素可用
*/
inputs[0].disabled=false;
inputs[1].disabled=false;
}
};
};
</script>
</head>
<body>
<h3>欢迎尊敬的用户注册</h3>
<p id="info">
只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!只有阅读完后才能注册!!!!
</p>
<input type="checkbox" disabled="disabled">我已仔细阅读协议,一定遵守
<input type="submit" value="注册" disabled="disabled">
</body>
</html>
51.事件对象
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数。
在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标 键盘哪个按键被按下,鼠标滚轮滚动的方向…
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#input{
width: 300px;
height: 100px;
border: 2px solid black;
}
#out{
width: 300px;
height: 100px;
margin-top: 50px;
border: 2px solid black;
}
</style>
<script>
window.onload=function(){
/*
当鼠标在input中移动时,在out中显示鼠标的坐标
*/
var input=document.getElementById("input");
var out=document.getElementById("out");
// onmousemove:该事件将会在鼠标在元素中移动时被触发
input.onmousemove=function(event){
var x=event.clientX;
var y=event.clientY;
// clientX clentY:鼠标的水平坐标,鼠标的垂直坐标
out.innerHTML="x="+x+",y="+y;
}
};
</script>
</head>
<body>
<div id="input"></div>
<div id="out"></div>
</body>
</html>
52.跟随页面滚动的方块练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
height: 100px;
width: 100px;
background-color: aqua;
position: absolute;
}
</style>
<script>
window.οnlοad=function(){
var box1=document.getElementById("box1");
document.οnmοusemοve=function(event){
// 解决兼容性问题使用两个获取方式
// 获取滚动条滚动的距离
var st=document.body.scrollTop||document.documentElement.scrollTop;
var sl=document.body.scrollLeft||document.documentElement.scrollLeft;
var x=event.clientX;
var y=event.clientY;
box1.style.left=x+sl+"px";
box1.style.top=y+st+"px";
}
};
</script>
</head>
<body style="height:10000px; width: 2000px;">
<div id="box1"></div>
</body>
</html>
(可以在拖动滚动条之后使用)
53.事件的冒泡
事件的冒泡:所谓的冒泡就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
在开发中大部分冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
height: 300px;
width:300px;
background-color: aqua;
}
span{
height: 90px;
height: 50px;
background-color: #bfa;
}
</style>
<script>
window.οnlοad=function(){
var div=document.getElementById("box1");
div.οnclick=function(){
alert("div被触发");
};
var span=document.getElementById("span");
span.οnclick=function(){
alert("span被触发");
};
var body=document.getElementById("body");
body.οnclick=function(){
alert("body被触发");
};
};
</script>
</head>
<body id="body">
<div id="box1">我是div
<span id="span">我是span</span>
</div>
</body>
</html>
(给span的同类单击事件也会触发它的父级(div)和祖先(body))
var span=document.getElementById("span");
span.οnclick=function(event){
// 取消冒泡
// 可以将事件对象的cancelBubble设置为true,即可取消冒泡
alert("span被触发");
event.cancelBubble=true;
};
(点击span不再触发div和body,但是其他未取消的依旧冒泡)
54.事件的委派
事件的委派指的是将事件统一绑定给元素的共同祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
ul{
background-color: #bfa;
}
</style>
<script>
window.οnlοad=function(){
var button=document.getElementsByTagName("button")[0];
button.οnclick=function () {
var newli=document.createElement("li");
newli.innerHTML="<a href='#' class='link'>新加的链接</a>";
ul.appendChild(newli);
}
var ul=document.getElementsByTagName("ul")[0];
var li=document.getElementsByTagName("li");
// 为ul绑定一个单击响应函数
ul.οnclick=function(event){
/*
target:event中的target表示的触发事件的对象
*/
// 如果触发事件的对象是我们期望的元素,则执行否则不执行
if(event.target.className=="link")
alert("我是ul的单击响应函数");
}
li.οnclick=function(){}
};
</script>
</head>
<body >
<button>新加链接</button>
<ul>
<li ><a href="#" class="link">link1</a></li>
<li><a href="#" class="link">link2</a></li>
<li><a href="#" class="link">link3</a></li>
</ul>
</body>
</html>
(只有点击链接部分才会触发,新建的也可以)
55.事件的绑定
使用对象.事件=函数的形式绑定响应函数
它只能同时为一个元素的一个事件绑定一个响应函数
不能绑定多个,如果绑定多个,则后面的会覆盖前面的
addEventListener()
通过这个方法也可以为元素绑定响应函数
参数:
1.事件的字符串,不要on
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
</style>
<script>
window.οnlοad=function(){
var button=document.getElementsByTagName("button")[0];
button.addEventListener("click",function(){
alert("响应1");
},false);
button.addEventListener("click",function(){
alert("响应2");
},false);
button.addEventListener("click",function(){
alert("响应3");
},false);
};
</script>
</head>
<body >
<button>按钮</button>
</body>
</html>
56.拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
#box2{
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
top: 300px;
left: 500px;
}
</style>
<script>
window.οnlοad=function(){
var box1=document.getElementById("box1");
box1.οnmοusedοwn=function(event){
// 解决拖拽时鼠标只能在左上角的问题,实现box1的拖拽方向和鼠标一致
// div的偏移量鼠标.clentX-元素.offsetLeft
// div的偏移量鼠标.clentY-元素.offsetTop
var ol=event.clientX-box1.offsetLeft;
var ot=event.clientY-box1.offsetTop;
document.οnmοusemοve=function(event){
var left=event.clientX-ol;
var top=event.clientY-ot;
box1.style.left=left+"px";
box1.style.top=top+"px";
};
};
//
box1.οnmοuseup=function(){
document.οnmοusemοve=null;
}
/*
当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容
此时会导致拖拽功能的异常,这个是浏览器提供的默认行为
如果不需要发生这个行为,则可以通过return false来取消默认行为
*/
return false
};
</script>
</head>
<body >
<p>我是一个文字</p>
<div id="box2"></div>
<div id="box1"></div>
</body>
</html>
57.滚轮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
min-height: 10px;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
box1.onwheel=function(event){
if(event.wheelDelta>0){
box1.style.height=box1.clientHeight-10+"px";
}
else{
box1.style.height=box1.clientHeight+10+"px";
}
/*
当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动
这是浏览器的默认样式
*/
return false;
}
};
</script>
</head>
<body >
<div id="box1"></div>
</body>
</html>
58.按键事件
键盘事件:
onkeydown
按键被按下
对于onkeydown来说如果一直按着某个按键不松手,则事件一直触发
对于onkeydownl连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常块
这种设计是为了防止误操作的发生
onkeyup
按键被松开
键盘对象一般都会绑定给一些可以获取到焦点的对象或者document
可以通过key属性来判断按键的编码,也可以keycode来获取按键的编码
//event.key=="a"||event.keyCode==95
除了keycode,事件对象中还提供了几个属性
altKey
ctrkey
shiftKey
这三个用来判断alt ctrl 和shift是否被按下,如果按下则返回true,否则返回false
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
</style>
<script>
window.οnlοad=function(){
var input=document.getElementById("input");
input.οnkeydοwn=function(event){
var reg1=/[0-9]/g;
if(reg1.test(event.key)){
/*
在文本框中不能输入数字
*/
// 在文本框中输入内容,属于onkeydown的默认行为
// 如果在onkeydown中取消了默认行为,则输入的内容不会出现在文本框中
return false;
}
};
};
</script>
</head>
<body >
<input type="text" id="input" value="不能输入数字">
</body>
</html>
(尝试输入数字但不可以输入)
59.鼠标控制div移动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
var speed=20;
document.onkeydown=function(event){
switch(event.key){
case 'a':
//向右
box1.style.left=box1.offsetLeft-speed+'px';
break;
case 'd':
box1.style.left=box1.offsetLeft+speed+'px';
break;
case 'w':
box1.style.top=box1.offsetTop-speed+'px';
break;
case 's':
box1.style.top=box1.offsetTop+speed+'px';
break;
}
}
};
</script>
</head>
<body >
<div id="box1"></div>
</body>
</html>
60.BOM
BOM:浏览器对象
BOM可以使我们通过JS来操作浏览器
在BOM为我们提供了一组对象,用来完成对浏览器的操作
BOM对象
window:
-代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navgator:
-代表的当前浏览器的信息,通过该对象可以识别不同的浏览器
Location:
-代表当前浏览器的地址栏信息,通过location可以获取地址栏信息,或者操作浏览器跳转界面
History:
-代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
由于隐式原因,该对象不能获取具体的历史记录,只能操作浏览器向前或向后翻页而且该操作只在当次访问时有效
Screen:
-代表用户的屏幕的信息,通过该对象可以获取用户的显示器的信息
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用
1.Navgator
通过该对象可以识别不同的浏览器
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息
可以通过IE浏览器中特有的对象,来判断浏览器的信息。比如:ActiveXObje
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
</style>
<script>
window.οnlοad=function(){
var ua=window.navigator.userAgent;
if(/firefox/i.test(ua)){
alert("你是火狐");
}
else if(/chrome/i.test(ua)){
alert("你是chrome");
}
else if(/msie/i.test(ua)){
alert("你是IE");
}
else if('ActiveXObject' in window){
alert("你是IE11");
}
};
</script>
</head>
<body >
</body>
</html>
(edge使用chrome内核)
2.History
操作浏览器向前或向后翻页
length
属性,可以获取当前访问的链接数量
back()
方法,可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward()
方法,可以跳转下一个页面,作用和浏览器的前进按钮一样
go()
方法,可以用来跳转到指定的页面
它需要一个整数作为参数
n:表示向前跳转n个页面
-n:表示向后跳转n个页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
</style>
<script>
window.οnlοad=function(){
alert(window.history.length);
};
</script>
</head>
<body >
<h1>History</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>TEST01</h1>
<a href="test02.html">去test02</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>TEST02</h1>
<a href="forjs.html">去History页面</a>
</body>
</html>
(test01->test02->forjs,最终在forjs页面显示的页面数)
3.Location
该对象封装了浏览器的地址栏的信息
如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
如果直接将location属性修改为一个完整的路径,或相对路径
则我们页面会自动跳转到该路径,并生成相应的历史记录
// window.location="https://www.baidu.com/?tn=15007414_pg";
aissgn()
方法,用来跳转到其他的页面,作用直接修改location一样
reload()
// window.location.reload();
方法,用于重新加载当前页面
如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面
//window.location.reload(true);
replace()
可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
不会生成历史记录,不能使用回退按钮回退
4.window的定时调用
如果希望一段程序,可以每间隔一段时间执行一次,可以使用定时调用
setInterval()
定时调用,可以将一个函数,每隔一段时间执行一次
参数:
1.回调函数,该函数每隔一段时间被调用一次
2.每次调用间隔的时间单位是毫秒
返回值:
返回一个Number类型的数据
这个数字用来作为定时器的唯一标识
clearInterval():
可以用来关闭一个定时器
方法中需要一个定时器的吧iOS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
h1{
font-size: 50px;
}
</style>
<script>
window.οnlοad=function(){
var h1=document.getElementsByTagName("h1")[0];
var num=1;
var timer=setInterval(function(){
h1.innerHTML=num++;
if(num==11){
//关闭定时器
clearInterval(timer);
}
},1000);
};
</script>
</head>
<body >
<h1></h1>
</body>
</html>
(定时器实现计时)
61.定时切换图片练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<style>
.outer{
width: 800px;
margin: 0 auto;
padding: 40px;
background-color: aqua;
text-align: center;
}
img{
width: 750px;
margin: 0 auto;
background-size:contain;
display: block;
}
</style>
<script>
/*
要切换图片就是要修改img标签的src属性
*/
// 分别为两个按钮绑定单击响应函数
window.onload=function(){
// 获取img标签,页面只有一个元素直接用索引
var img=document.getElementsByTagName("img")[0];
// 创建一个数组,用来保存图片的路径
var imgarr=["image/meabanner1.jfif","image/meabanner2.jfif","image/meabaner3.jfif"];
// 创建一个变量,来保存当前正在显示的图片的索引
var timer;
var btn1=document.getElementById("kaishi");
var btn2=document.getElementById("jieshu");
var index=0;
/*
目前,我们每点击一次按键,就会一个定时器
点击多次就会多个定时器,这导致图片的切换速度过快
并且我们只会关闭最后一次的定时器
*/
btn1.onclick=function(){
//在开启定时器之前,需要将当前元素上的其他定时器关闭
clearInterval(timer);
// 开启一个定时器,来自动切换图片
timer=setInterval(function(){
index++;
if(index>=imgarr.length){
index=0;
}
img.src=imgarr[index];
},1000);
}
btn2.onclick=function(){
/*
clearInterval()可以接收任意参数
如果参数是一个有效的定时器的标识,则停止对应的定时器
如果参数不是一个有效的标识,则什么也不做
*/
clearInterval(timer);
}
};
</script>
</head>
<body>
<div class="outer">
<p id="info"></p>
<img src="image/meabanner1.jfif" alt="">
<button id="kaishi">开始</button>
<button id="jieshu">结束</button>
</div>
</body>
</html>
(点击按钮控制图片自动播放,按结束停止)
62.丝滑的div移动
方向和速度分开控制,onkeydown控制方向,定时器控制速度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<title>Document</title>
<script src="scripttest.js"></script>
<style>
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script>
window.οnlοad=function(){
var box1=document.getElementById("box1");
// dir代表方向
var dir;
var speed=20;
setInterval(function(){
switch(dir){
case 'a':
//向右
box1.style.left=box1.offsetLeft-speed+'px';
break;
case 'd':
box1.style.left=box1.offsetLeft+speed+'px';
break;
case 'w':
box1.style.top=box1.offsetTop-speed+'px';
break;
case 's':
box1.style.top=box1.offsetTop+speed+'px';
break;
}
}
,30);
document.οnkeydοwn=function(event){
// 当用户按了CTRL以后,速度加快
if(event.ctrlKey){
speed=50;
}
// 使dir等于按键的值
dir=event.key;
}
document.οnkeyup=function(){
// 当按键松开时,div不在移动
dir=0;
}
};
</script>
</head>
<body >
<div id="box1"></div>
</body>
</html>
63.延时调用
//延时调用:一个函数不马上执行,而是隔一段时间再执行,而且只会执行一次
//延时调用和定时调用的区别:定时调用会执行多次,而延时调用只会执行一次
var tiem=setTimeout(function(){
console.log("3秒后出现");
},3000)
// 使用clearTimeout()来关闭一个延时调用
clearTimeout(tiem);
//延时调用和定时调用实际上是可以相互替代的,在开发中可以根据需要去选择
64.动态轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="index.css">
<title>Js轮播图</title>
<script src="scripttest.js"></script>
</head>
<body>
<div class="lunbo">
<div class="content">
<ul id="item">
<li class="item">
<a href="#"><img src="image/京东轮播图/1.jpg" alt=""></a>
</li>
<li class="item">
<a href="#"><img src="image/京东轮播图/2.jpg" alt=""></a>
</li>
<li class="item">
<a href="#"><img src="image/京东轮播图/3.jpg" alt=""></a>
</li>
<li class="item">
<a href="#"><img src="image/京东轮播图/4.jpg" alt=""></a>
</li>
<li class="item">
<a href="#"><img src="image/京东轮播图/5.jpg" alt=""></a>
</li>
</ul>
<div id="btn-left"></div>
<div id="btn-right"></div>
<ul id="circle">
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
</div>
</body>
</html>
a{
list-style: none;
}
li{
list-style: none;
}
.lunbo{
width: 100%;
}
.content{
width: 590px;
height: 470px;
margin: 20px auto;
position: relative;
}
#item{
width: 100%;
height: 100%;
}
.item{
position: absolute;
opacity: 0;
transition: all 1s;
}
/*
被选中时激活显示图片
*/
.item.active{
opacity:1;
}
img{
width: 100%;
}
#btn-left{
width: 30px;
height: 69px;
font-size: 30px;
color: white;
background-color:rgba(0,0,0,0.4);
line-height: 69px;
padding-left:5px;
z-index: 10;/*始终显示在图片的上层*/
position: absolute;
left: 0;
top: 50%;
transform: translateY(-60%);/*使按钮向上偏移居中对齐*/
cursor: pointer;
opacity: 0;/*平时隐藏*/
}
.lunbo:hover #btn-left{
/*鼠标滑入,显示图标*/
opacity: 1;
}
#btn-right{
width: 26px;
height: 69px;
font-size: 30px;
color: white;
background-color:rgba(0,0,0,0.4);
line-height: 69px;
padding-left: 5px;
z-index: 10;
position: absolute;
right: 0;
top: 50%;
cursor: pointer;
opacity: 0;
transform: translateY(-60%);
}
.lunbo:hover #btn-right{
opacity: 1;
}
#circle{
height: 20px;
display: flex;
position: absolute;
bottom: 35px;
right: 25px;
}
.circle{
width: 10px;
height: 10px;
border-radius: 10px;
border: 2px solid white;
background: rgba(0,0,0,0.4);
cursor: pointer;
margin: 5px;
}
/* circle里面的白色 */
.white{
background-color: #FFFFFF;
}
window.onload=function(){
var items=document.getElementsByClassName("item");
var circles=document.getElementsByClassName("circle");
var leftBtn=document.getElementById("btn-left");
var rightBtn=document.getElementById("btn-right");
var content=document.querySelector('.content');
// 为了第一次执行右切换函数时,index++等于0,保证第一张图第一个出现而不是第二张出现
var index=-1;
var timer=null;
//为下方圆圈加上对应的数字标识
var clearclass=function(){
for(var i=0;i<items.length;i++){
items[i].className="item";
circles[i].className="circle";
// setAttribute() 方法添加指定的属性,并为其赋指定的值。
/*为下方的圆圈加上num的数据,并加上对应的值(0~4) */
circles[i].setAttribute("num",i);
}
}
/*只显示一个class*/
/*
修改对应的图片的类名
修改对应的下方圆环类名
*/
function move(){
clearclass();
items[index].className="item active";
circles[index].className="circle white";
}
//点击右边按钮切换下一张图片
rightBtn.onclick=function(){
if(index<items.length-1){
index++;
}
else{
index=0;
}
move();
}
//点击左边按钮切换上一张图片
leftBtn.onclick=function(){
if(index<items.length&&index>0){
index--;
}
else{
index=items.length-1;
}
move();
}
//开始定时器,点击右边按钮,实现轮播
timer=setInterval(function(){
rightBtn.onclick();
},1500)
//点击圆点时,跳转到对应图片
for(var i=0;i<circles.length;i++){
circles[i].addEventListener("click",function(){
var point_index=this.getAttribute("num");
index=point_index;
move();
})
}
//鼠标移入清除定时器,并开启一个三秒的定时器,使慢慢转动
content.onmouseover=function(){
clearInterval(timer);
timer=setInterval(function(){
rightBtn.onclick();
},3000)
}
//鼠标移出又开启定时器
content.onmouseleave=function(){
clearInterval(timer);
timer=setInterval(function(){
rightBtn.onclick();
},1500)
}
}
https://live.csdn.net/v/190490
65.类的操作
和上面的轮播图类似,通过加减元素的类属性来实现快速修改属性,不用再通过style去逐一修改
66.JSON
JS中读写只有JS自己认识,其他的语言都不认识
JSON就是一个特殊的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
JSON Javascript Object Notation JS对象表示法
JSON和JS的对象的格式一样,只不过JSON字符串中的属性名必须加双引号
JSON分类:
1.对象{}
2.数组[]
JSON中允许的值
1.字符串
2.数值
3.布尔值
4.对象
5.null
6.数组
//JSON字符串
var obj='{"name":"tom","age":18}';
var arr='[1,2,3,"hello",true]';
var arr2='[{"name":"tom","age":18},{"name":"tom","age":18}]'
var obj2='{"arr":[1,2,3]}';
//将JSON字符串转换为JS中的对象
在JS中,为我们提供了一个工具类,就叫JSON
这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON对象
/*
json--->js对象
JSON.parse()
-可以将JSON字符串转换为JS对象
-它需要一个JSON字符串作为参数,会将该字符串转换为js对象
*/
var o=JSON.parse(obj);
/*
js对象--->JSON
JSON.stringify()
-可以将JS对象转换为JSON字符串
-它需要一个JS对象串作为参数,会返回一个JSON字符串
*/
eval()
这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
如果使用eval()执行的字符串中含有{},它会将{}当成代码块
如果不希望将其当成代码块解析,则需要在字符串前后加上()
这个函数的功能很强大,但是开发中尽量不要使用,首先执行性能比较差,然后它还具有安全隐患
var str='{"name":"tom","age":18}';
var obj=eval("("+str+")");
console.log(obj); //{name: 'tom', age: 18}转换成了js对象
nter;
opacity: 0;
transform: translateY(-60%);
}
.lunbo:hover #btn-right{
opacity: 1;
}
#circle{
height: 20px;
display: flex;
position: absolute;
bottom: 35px;
right: 25px;
}
.circle{
width: 10px;
height: 10px;
border-radius: 10px;
border: 2px solid white;
background: rgba(0,0,0,0.4);
cursor: pointer;
margin: 5px;
}
/* circle里面的白色 */
.white{
background-color: #FFFFFF;
}
```javascript
window.onload=function(){
var items=document.getElementsByClassName("item");
var circles=document.getElementsByClassName("circle");
var leftBtn=document.getElementById("btn-left");
var rightBtn=document.getElementById("btn-right");
var content=document.querySelector('.content');
// 为了第一次执行右切换函数时,index++等于0,保证第一张图第一个出现而不是第二张出现
var index=-1;
var timer=null;
//为下方圆圈加上对应的数字标识
var clearclass=function(){
for(var i=0;i<items.length;i++){
items[i].className="item";
circles[i].className="circle";
// setAttribute() 方法添加指定的属性,并为其赋指定的值。
/*为下方的圆圈加上num的数据,并加上对应的值(0~4) */
circles[i].setAttribute("num",i);
}
}
/*只显示一个class*/
/*
修改对应的图片的类名
修改对应的下方圆环类名
*/
function move(){
clearclass();
items[index].className="item active";
circles[index].className="circle white";
}
//点击右边按钮切换下一张图片
rightBtn.onclick=function(){
if(index<items.length-1){
index++;
}
else{
index=0;
}
move();
}
//点击左边按钮切换上一张图片
leftBtn.onclick=function(){
if(index<items.length&&index>0){
index--;
}
else{
index=items.length-1;
}
move();
}
//开始定时器,点击右边按钮,实现轮播
timer=setInterval(function(){
rightBtn.onclick();
},1500)
//点击圆点时,跳转到对应图片
for(var i=0;i<circles.length;i++){
circles[i].addEventListener("click",function(){
var point_index=this.getAttribute("num");
index=point_index;
move();
})
}
//鼠标移入清除定时器,并开启一个三秒的定时器,使慢慢转动
content.onmouseover=function(){
clearInterval(timer);
timer=setInterval(function(){
rightBtn.onclick();
},3000)
}
//鼠标移出又开启定时器
content.onmouseleave=function(){
clearInterval(timer);
timer=setInterval(function(){
rightBtn.onclick();
},1500)
}
}
[外链图片转存中…(img-sjpJxSZQ-1647670560099)]
65.类的操作
和上面的轮播图类似,通过加减元素的类属性来实现快速修改属性,不用再通过style去逐一修改
66.JSON
JS中读写只有JS自己认识,其他的语言都不认识
JSON就是一个特殊的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
JSON Javascript Object Notation JS对象表示法
JSON和JS的对象的格式一样,只不过JSON字符串中的属性名必须加双引号
JSON分类:
1.对象{}
2.数组[]
JSON中允许的值
1.字符串
2.数值
3.布尔值
4.对象
5.null
6.数组
//JSON字符串
var obj='{"name":"tom","age":18}';
var arr='[1,2,3,"hello",true]';
var arr2='[{"name":"tom","age":18},{"name":"tom","age":18}]'
var obj2='{"arr":[1,2,3]}';
//将JSON字符串转换为JS中的对象
在JS中,为我们提供了一个工具类,就叫JSON
这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON对象
/*
json--->js对象
JSON.parse()
-可以将JSON字符串转换为JS对象
-它需要一个JSON字符串作为参数,会将该字符串转换为js对象
*/
var o=JSON.parse(obj);
/*
js对象--->JSON
JSON.stringify()
-可以将JS对象转换为JSON字符串
-它需要一个JS对象串作为参数,会返回一个JSON字符串
*/
eval()
这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
如果使用eval()执行的字符串中含有{},它会将{}当成代码块
如果不希望将其当成代码块解析,则需要在字符串前后加上()
这个函数的功能很强大,但是开发中尽量不要使用,首先执行性能比较差,然后它还具有安全隐患
var str='{"name":"tom","age":18}';
var obj=eval("("+str+")");
console.log(obj); //{name: 'tom', age: 18}转换成了js对象