这是我在看尚硅谷的前端大神超哥视频时,所记录的笔记!
javaScript概述
JavaScript 是一种基于对象和事件驱动并具有安全性能的脚本语言 。
JavaScript 官方名称是 “ECMAScript” (ECMA是欧洲电脑商制造协会)。
JavaScript 特点:
由来
网景公司想在原来的静态页面的基础上添加一些动态的效果,让用户体验更好,所以让布兰登·艾奇着手开发此功能。这位牛人仅用10天时间,便写出了javaScript。
这里不多赘述,感兴趣的朋友可以搜索一下哟!
javaScript的Helloword
代码演示
<script>
alert("helloWord");
console.log("helloWord");
document.write("helloWord");
</script>
方式 一:在标签中写(不推荐 )
<a href="javascript:alert('太帅了!')">点我a>
<button onclick="alert('真帅!')">点一下button>
方式二:script标签中
<script type="text/javascript">
alert("真帅!");
</script>
方式三:外联js样式【写到外部的js文件,然后用script的src引入】推荐!!!
<script type="text/javascript" src="外部的js文件.js"></script>
注意:
script标签一旦用于 引用外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略。如果你还需要,则可以在创建一个新的script标签用于编写内部代码
<script src="one.js">alert("do")script>
如上,即使alert了,但不会有效果!
;
号结尾字面量:不可改变
1,2,3……n
变量
用var来 声明一个变量
注意:可以把字面量赋值给变量
var age =23;//变量
80 //字面量
局部变量
前提:idea需要设置ES6语法
建议都用let取定义局部变量(之前定义局部变量都是直接i=1),现在要let i =1
-例如:变量名、函数名、属性名都属于标识符
标识符命名规则: |
---|
1.标识符中可以含字母、数字、_、$ |
2.标识符不能以数字开头 |
3.标识符不能是ES中的关键字或保留字 |
4.标识符一般用驼峰命名 |
5.JS底层保存标识符实际上采用Unicode编码,所以 理论上讲,所有的 utf-8中含的内容都可以作为标识符 |
数据类型:字面量的类型
JS的6中数据类型
数据类型 | 释意 |
---|---|
String | 字符串 |
Number | 数值 |
Boolean | 布尔值 |
Null | 空值 |
Undefined | 未定义 |
Object | 对象 |
拓展:其中String Number Boolean Null Undefined
为基本数据类型,Object
属于引用数据类型
在JS中所有的数值都是Number
类型,包括整数和浮点数(小数)
Number.MAX_VALUE;
1.7976931348623157e+308
Number.MIN_VALUE //大于0的最小值
5e-324
如果使用Number表示的数字 超过了最大值,则会返回一个
Infinity
表示正无穷
-Infinity
表示负无穷
使用typeof检查Infinity也会返回number
NaN 是一个特殊的数字,表示Not A Number
使用typeof检查一个NaN也会返回number
拓展:typeof检查变量的类型
let i =1;//局部变量声明用let
alert(typeof i);//返回number
注意:
如果使用JS进行浮点运算,可能得到一个不精确的结果
所以,千万不要使用JS进行对精确要求比较高的运算
console.log((1/3)==(1-2/3));//这里会返回false,尽管数值都为1/3,尽量避免使用小数计算
布尔值只有两个,主要用来做逻辑判断
true
表示真
false
表示假
使用typeof检查一个布尔值,返回boolean
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>布尔值</title>
<script>
var bool =true;
console.log(bool);
console.log(typeof bool)
</script>
</head>
<body>
</body>
</html>
Null(空值)类型的值只有一个,就是null
null这个值专门用来表示一个为空的对象
使用typeof检查一个null值时,返回object
undefined(未定义)类型的值只有一个,就undefind
当声明一个变量,但是并不给变量赋值时,它的值就是undefined
使用typeof检查一个undefined时也是undefined
强制类型转换
– 指将一个数据类型强制转换为其他的数据类型
– 类型转换主要指,将其他的类型,转换为String、Number、Boolean
方式一:
调用被转换数据类型的toString()方法
该方法不会影响原变量,它会将转换的结果返回
但是注意:
null 和 undefined 这两个值没有toString()方法,如果调 用他们的方法会报错
方式二:
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>强制类型转换</title>
<script>
// 方式一:
var a =123;
a =a.toString();
console.log(typeof a);
console.log(a);
var b =true;
b =b.toString();
console.log(typeof b);
console.log(b);
//方式二:
a2 =String(a);
console.log( typeof a2);
console.log(a2);
var d =null;
d =String(d);
console.log(typeof d);
console.log(d);
</script>
</head>
<body>
</body>
</html>
转换方式一:使用Number()函数
类型 | 数字 |
---|---|
true | 1 |
false | 0 |
null | 0 |
undefined | 数字NaN |
转换方式二:
这种方式专门用来处理字符串,如果对非字符串使用parseInt()或parseFloat(),它会先将其转变为String类型,再操作
使用Boolean()函数
数字 ======》 布尔
字符串 ====》 布尔
其他类型
在JS中,
var a =0x10;
console.log(a); //16
var a =010;
console.log(a); // 8
var a =0b10;
console.log(a); //2
拓展:
如你想解析字符串为数字,"070"
,有些浏览器会当成8进制解析,有些则会当成10进制解析。为了避免你可能这里式10进制解析,那里又是8进制解析,我们在使用parseInt()时,一般指定进制。
格式如下:parseInt(参数,指定进制)
var a =070;
a =paseInt(a,10);//指定为10进制
a =paseInt(a,2);//指定2进制
代码实现
<html lang="en">
<head>
<meta charset="UTF-8">
<title>其他进制的数字title>
<script>
//16进制
var a ="0x70";
console.log(a);
//8进制
var b ="070";
console.log(b);
//2进制
var c ="0B10";//并不是所有浏览器就支持
console.log(c);
var str ="=====================";
console.log(str);
var d ="070";
d =parseInt(d,10);
console.log(d);
d =parseInt(d,8);
console.log(d)
d =parseInt(d,2);
console.log(d);
script>
head>
<body>
body>
html>
IDEA需要设置支持ES6语法,'use strict';
严格检查模式,预防javaScript的随意性导致的一些问题.
前提:idea需要设置支持ES6语法。
当对非Number类型的值进行运算时,会将这些值转换Number然后在运算
任何值和NaN做运算都得NaN
+
+可以对两个值进行加法运算,并将结果返回
如果对两个字符串进行加法运算,则会进行拼串处理:会将两个字符串拼接成一个字符串,并返回
任何的值和字符串做加法,都会先转换为字符串,然后再和字符串做拼串操作
-
-可以对两个值进行减法运算,并将结果返回
*
可以对两个值进行乘法运算
/
可以对两个值进行除法运算
注意:
我们可以利用这个特性做隐式的类型转换
可以通过为一个值 - 0 *1 /1
来将其转换为Number
原理和Number()函数一样,使用起来更简单
也可以利用任何的值和字符串做加法都会先转换为字符串,然后再和字符串做拼串操作
的特点,来进行隐式类型转换。
可以通过数字+""
来将其转换为字符串。原理也和String()函数
一样,使用起来更简单。
true | 1 |
---|---|
false | 0 |
null | 0 |
undefined | NaN |
一元运算符:只需要一个操作数
+
正号
不会对数字产生任何影响
-
负号
负号可以对数字进行符号的取反
注意:
对于非Number类型的值
它会将类型先转换为Number,然后在进行运算
可以对一个其他的数据类型使用+,来将其转换为Number
它的原理和Number()函数一样、
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>一元运算符</title>
<script>
var a =true;
a =-a;
console.log(a)//-1
var b ="123";
b =+b;
console.log(b);//123
var c =1 + +"2" +3+ +"4";
console.log(c)//10
</script>
</head>
<body>
</body>
</html>
++
a++
,与++a
++a
和a++
的值式不同的
++a
的值是变量的新值(自增后的值)a++
的值是变量的原值(自增前的值)--
--a
与a--
--a
还是a-
-都会立即使原变量自减1
--a
的值是变量的新值(自减后的值)a--
的值是变量的原值(自减前的值)JS中为我们提供了三种逻辑运算符
!
非
! 可以用来对一个值进行非运算
所谓非运算就是值对一个布尔值进行取反操作
如果对一个值进行两次取反,它将不会发生变化
如果对非布尔类型的元素进行取非,它将会转换为布尔值在取反
所以我们可以利用该特点,来将一个其他的数据类型转变为布尔类型
可以为一个任意数据类型取反两次,来将其转换为布尔值
原理和Boolean()函数一样
&&
与
&&可以对符号两侧的值进行与运算并返回结果
运算规则
JS中的”与“属于短路与
||
或
|| 可以对符号两侧的值进行或运算并返回结果
运算规则:
JS中的”或“属于短路的或
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>逻辑运算符</title>
<script>
true || alert("我是天下第一");
//因为第一个是true了,无论第二个是不是true,
// 结果都会放回true,所以它不会去管第二个值,
false && alert("我是天下第一");
//&& 这个是短路与, 一旦第一个值为false,就不回去管第二个值了
true && alert("我是天下第一");
//因为这个是第一个值且为true,它会去看第二个值,以来判断整段表达式
</script>
</head>
<body>
</body>
</html>
&& 与 || 非布尔值的情况
对于非布尔值进行与或运算时,会对其转换为布尔值,然后在运算,并且返回原值
与运算
如果第一个值时true,则必然返回第二个值
如果第一个值时false,则之间返回第一个值
或运算
// false false
//第一个为false了,不用看第二个直接返回第一个
var result = NaN && 0;
console.log(result)
var c =0 && NaN;
console.log(c)
// TRUE FALSE
// 第一个是正确的,那么整段逻辑表达式取决于第二个值,所以它会直接返回第二个值
var a =true && false;
console.log(a);
非数值的情况
在HTML中转义,用编码;
编码为10进制的数制
var a ="\u2620";//\为转义,u标明输出为unicode字符集
console.log(a);
在JS中用\u
,\
代表转义,u
指明输出的字符集
<h1 style="font-size: 1000px " align="center">☠h1>
想等运算符用来比较两个值是否相等,如果相等会返回true,否则返回false
使用==来做相等运算
不相等 !=
全等
不全等
拓展:
undefined
衍生自null
,所以这两个值做相等判断时,会返回true,所以我们在做变量值是否为NaN时,**不能用== 而是用isNaN()**函数语法:
条件表达式?语句1:语句2;
执行的流程:
条件运算符在执行时,首先对条件表达式进行求值
如果条件的表达式的求值结果是一个非布尔值,会将其 转换为布尔值然后再运算
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三元运算符</title>
<script>
var a = 10;
var b = 20;
var c = 50;
var max = a > b ? alert("a大") : alert("b大");
max = max > c ? max : c;
console.log(max);
//不建议,这么写
var max = a > b ? (a > c ? a : c) : (b > c ? b : c);
console.log(max);
</script>
</head>
<body>
</body>
</html>
就像数学中一样,在JS中运算符也有优先级
比如:先乘除,后加减
在JS中有一个运算符优先级的表,
在表中越靠上优先级越高,优先级越高越优先计算,如果优先级也有,则从左往右计算。
查看优先级:运算符优先级 - JavaScript | MDN (mozilla.org)
优先级 | 运算符类型 | 结合性 | 运算符 | 高低 |
---|---|---|---|---|
21 | 圆括号 | n/a(不相关) | ( … ) | 高 ↑ |
20 | 成员访问 | 从左到右 | … . … | |
需计算的成员访问 | 从左到右 | … [ … ] | ||
new(带参数列表) | n/a | new … ( … ) | ||
函数调用 | 从左到右 | … ( … ) | ||
可选链(Optional chaining) | 从左到右 | ?. | ||
19 | new(无参数列表) | 从右到左 | new … | |
18 | 后置递增 | n/a | … ++ | |
后置递减 | … – | |||
17 | 逻辑非 (!) | 从右到左 | ! … | |
按位非 (~) | ~ … | |||
一元加法 (+) | + … | |||
一元减法 (-) | - … | |||
前置递增 | ++ … | |||
前置递减 | – … | |||
typeof | typeof … | |||
void | void … | |||
delete | delete … | |||
await | await … | |||
16 | 幂 (**) | 从右到左 | … ** … | |
15 | 乘法 (*) | 从左到右 | … * … | |
除法 (/) | … / … | |||
取余 (%) | … % … | |||
14 | 加法 (+) | 从左到右 | … + … | |
减法 (-) | … - … | |||
13 | 按位左移 (<<) | 从左到右 | … << … | |
按位右移 (>>) | … >> … | |||
无符号右移 (>>>) | … >>> … | |||
12 | 小于 (<) | 从左到右 | … < … | |
小于等于 (<=) | … <= … | |||
大于 (>) | … > … | |||
大于等于 (>=) | … >= … | |||
in | … in … | |||
instanceof | … instanceof … | |||
11 | 相等 (==) | 从左到右 | … == … | |
不相等 (!=) | … != … | |||
全等 (===) | … === … | |||
不全等 (!==) | … !== … | |||
10 | 按位与 (&) | 从左到右 | … & … | |
9 | 按位异或 (^) | 从左到右 | … ^ … | |
8 | 按位或 (|) | 从左到右 | … | … | |
7 | 逻辑与 (&&) | 从左到右 | … && … | |
6 | 逻辑或 (||) | 从左到右 | … || … | |
5 | 空值合并 (??) | 从左到右 | … ?? … | |
4 | 条件(三元)运算符 | 从右到左 | … ? … : … | |
3 | 赋值 | 从右到左 | … = … | |
… += … | ||||
… -= … | ||||
… **= … | ||||
… *= … | ||||
… /= … | ||||
… %= … | ||||
… <<= … | ||||
… >>= … | ||||
… >>>= … | ||||
… &= … | ||||
… ^= … | ||||
… |= … | ||||
… &&= … | ||||
… ||= … | ||||
… ??= … | ||||
2 | yield | 从右到左 | yield … | |
yield* | yield* … | |||
1 | 逗号 / 序列 | 从左到右 | … , … | 低 |
图示
我们的程序由一条条语句构成的,语句是按照自上而下的顺序一条条执行。
在JS中可以使用{}来进行分组,它们要么都执行,要么都不执行。一个{}中的语句,我们称为一个代码块,在代码块后,不需要写;
了。
JS的代码块,只具有分组作用,没有其他用途(这里与java不一样)
与java中的if语法一样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>流程控制</title>
<script>
alert("请输入三个不相等的数字")
var imput1 =prompt("请输入第一个数值");//prompt 返回值 是String型
var imput2 =prompt("请输入第二个数值");
var imput3 =prompt("请输入第三个数值");
if(isNaN(imput1) || isNaN(imput1) ||isNaN(imput1)){
alert("数字为NaN")
}else {
if(imput1>imput2){
if(imput1>imput3){
alert(imput1);
}else {
alert(imput3);
}
}else{
if(imput2>imput3){
alert(imput2);
}else {
alert(imput3);
}
}
}
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>switchEx</title>
<script>
//方式一:与java一样
var score = 55;
switch (parseInt(score / 10)) {
case 10 :
case 9 :
case 8 :
case 7 :
case 6 :
console.log("及格");
break;
default:
console.log("不合格")
break;
}
//方式二:JS中独有
switch (true) {
case score >= 60: {
console.log("合格");
break;
}
default: {
console.log("不合格");
break;
}
}
</script>
</head>
<body>
</body>
</html>
var num =1;
while (num<=10){
document.write(num++ +"
");
//如果用javascipt的document.write("\n")输出到html内,只是一个换行符,并不能起到真正换行的作用。
}
var num =1;
do{
document.write(num++ +"
");
}while (num<=0);
for (var i = 100; i <1000 ; i++) {
var bai =parseInt(i/100);
var shi =parseInt((i-bai*100)/10);
var ge =i%10
if(bai*bai*bai+shi*shi*shi+ge*ge*ge == i){
console.log(i);
}
}
对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性
对象的分类:
内建对象
宿主对象
自定义对象
创建对象
var obj =new Object();
给对象属性赋值
obj.name ="李天启";
注意:
这个不像java中一样,不需要再上面定义,你直接.属性名
这样就可以定义。但这时没赋值的!
删除属性
delete obj.age;//删除对象属性
对象的属性名不强制要求遵守标识符的规范,意味着什么乱七八糟的名字都可以使用,但是我们使用还是要按照标识符规范去做。
如果要使用特殊的属性名,不能采用.属性名
的方式来操作,而是需要采用另一种方式:
语法:对象["属性名"]=属性值
obj[123] = 789;//1
obj["123"] = 456;//2
console.log(typeof obj["123"]);//其实1和2要说明的是同一个属性,它会自动类型转换为数字
注意:
使用[]
这种形式去操作属性,更加灵活,再[]
中可以直接传递一个变量,这样变量值是多少就会读取那个属性
var n ="I love You";
obj["I love You"] ="谢谢";
console.log(obj[n]);//输出谢谢
拓展:
in
运算符
语法:"属性名" in 对象
console.log( "name" in obj);
console.log( ["I love You"] in obj);
切记:
你在用in的时候要用""
括起来,如果它是字符串类的就不用了。
在JS的变量都是保存到栈内存中,基本数据类型的值直接在栈内存中存储,值与值之间是独立存在,修改一个变量不会影响其他变量
对象是保存到堆内存中的,没创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用时,当其中一个通过一个变量修改属性时,另一个也会受到影响。
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用时,当其中一个通过一个变量修改属性时,另一个也会受到影响。
使用对象字面量,可以在创建对象时,直接指定对象的属性
var obj ={};//对象字面量,这样写和new Object()这样,本质是一样的。
var obj1 ={name:"李白",
age:21,
sex:"男",
ability:{xingNeng:"超神"}
};
{属性名:属性值,属性名:属性值,属性名:属性值……}
对象字面量的属性名可以加引号也可以不加,建议不加;如果要使用一些特殊的名字,则必须加引号。
属性名和属性值是一组一组的名值堆结构
名和值之间使用:
连接,多个名值对之间用,
隔开
如果一个属性之后没有其他的属性了,就不要写,
函数
创建一个函数对象
可以将要封装的代码以字符串的形式传递给构造函数
封装到函数中的代码不会立即执行
函数中的代码会在函数调用的时候执行
调用函数语法:
函数对象();
当调用函数时,函数封装的代码会按照顺序执行
var fun =new Function ("console.log('这是我第一个函数');");//注意:log括号后要加上;,因为它是一个语句,只不过被封装了而已
fun();
注意:其实我们在开发的时候极少,甚至不使用这种利用构造函数创建一个函数
语法:
function 函数名([形参1,形参2,……形参N]){
语句……
}
//方式一:
var fun = new Function("console.log('这是我第一个函数');");//注意:log括号后要加上;,因为它是一个语句,只不过被封装了而已,一般不用
fun();
//方式二:
function fun2() {// 推荐
console.log("我要加油!")
}
fun2();
//方式三:
var fun3 = function(){
console.log("我是匿名函数");
};//这里是个赋值语句,所以要加分号
fun3();
,
隔开,声明形参就相当于在函数声明了对应的变量,但是并不赋值注意:
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数的参数</title>
<script>
function sum (a,b){
console.log("a="+a);
console.log("b="+b);
console.log(a+b);
}
sum(123,456);
sum(123);//因为b没有赋值,所以它是undefined,两者相加变成了NaN
sum(123,"abc");
sum(123,789,"abc",true);
sum(true,false);
</script>
</head>
<body>
</body>
</html>
return
来设置函数的返回值语法:
return 值
注意:
return后的值将会作为函数的执行结果返回,可以定义一个变量来接收该结果
函数返回声明result的值就是什么
return后的语句不会执行
如果函数中不写return,则会返回undefined
如果函数后不带值,也会返回undefined
return后的值可以是任意类型
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数的返回值</title>
<script>
function sum(a,b,c){
var d =a+b+c;
}
var result =sum(1,2,3);
console.log(result);//因为sum函数中没有写return,则result的结果将是undefined
function sum1(a,b,c){
var d =a+b+c;
return;
}
var result1 =sum(1,2,3);
console.log(result1);//因为return后不加任何值,将会返回undefined
function sum2(a,b,c){
var d =a+b+c;
return d;
}
var result3 =sum2(1,2,3);
console.log(result3);
//实参可以任何类型,可以是一个对象,也可以是一个函数
function sayHello(obj) {
console.log("我叫" + obj.name + ",来自" + obj.address);
}
sayHello(obj);
</script>
</head>
<body>
</body>
</html>
注意:
mianji()
// -调用函数
// -相当于使用函数的返回值
mianji
// -函数对象
// -相当于直接使用函数对象
==================================================
function fun1(){
return fun4();
}
fun1();
function fun4(){
console.log("我是fun4");
}
function fun(){
return fun4;
}
fun1()();//这里相当于直接调fun4
var a =fun1();
a();//这里于上面写法一样
(function (){
console.log("我是立即执行函数");
})();
(function (a,b){
console.log(a+b);
})(123,456);
call()和 apply()
这两个方法都是函数对象的方法,需要通过函数对象来调用
当对函数调用call()和apply()都会调用函数执行对象
在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this
call()方法可以将实参在对象之后依次传递
apply()方法需要将实参封装到一个数组中统一传递
实参的个数由函数的形参确定
this的情况:
var obj ={
name:"李天启",
sayName:function (){
console.log(obj.name);
}
}
obj.sayName();
==============================
var obj1 =new Object();
obj1.name="神";
obj1.sayName=function (){
console.log(obj1.name);
}
obj1.sayName();
解析器在调用函数时,每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就时this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象。
var name ="全局";
function fun(){
console.log(this.name);
}
var obj1 ={
name:"",
sayName:fun
}
var obj2 ={
name:"hah",
sayName: fun
}
fun();//全局 相当于window.fun();
obj1.sayName();
obj2.sayName();
在调用函数时,浏览器每次都会传递进两个隐含的参数
arguments
是一个类数组对象(不是数组),它可以通过索引来操作数据,也可以获取长度
在调用函数时,我们所传递的实参都会在argument中保存
arguments.length可以用来获取实参的长度
我们即使不定义形参,也可以通过argunments来使用实参,只不过比较麻烦
它里边有一个属性叫做callee
,这个属性对应一个函数对象,就是当前正在指向的函数的对象
function produceObject(name,age,gener){
var obj =new Object();
obj.name=name;
obj.age =age;
obj.gener=gener;
obj.sayName=function(){
console.log(this.name);
}
return obj;//将新对象返回
}
var obj =produceObject("孙悟空",21,"男");
var obj1 =produceObject("小狐狸",22,"女");
var obj2=produceObject("小红枣",20,"男");
obj.sayName();
obj1.sayName();
obj2.sayName();
构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的时构造函数习惯上首字母大写
构造函数的执行流程:
this的情况:
代码演示
function Person(name,age,sex){
this.name =name;
this.age =age;
this.sex =sex;
this.sayName =function (){
console.log(this.name);
};
}
var per =new Person("李天启",21,"男");
console.log(per);
console.log(per instanceof Person);
创建一个Person函数
在Person构造函数中,为每一个对象都添加了sayName方法,目前我们的方法是构造函数内部创建的,也就是构造函数每执行一次就会创建一个新方法,执行10000次就会创建10000个新方法,而10000个方法都是一模一样的,这是完全没有必要,完全可以使所有的对象共享一个方法
解决方法:把这个方法放在全局作用域中即可
代码演示
function Person(name,age,sex){
this.name =name;
this.age =age;
this.sex =sex;
this.sayName =function (){
console.log(this.name);
};
}
var per =new Person("李白",21,"男");
var per1 =new Person("杜甫",20,"女");
per.sayName();
per1.sayName();
console.log(per.sayName == per1.sayName);//false
//进阶:
function Person1(name,age,sex){
this.name =name;
this.age =age;
this.sex =sex;
this.sayName =fun;
}
function fun(){
console.log(this.name);
}
var per2 =new Person1("李天男",24,"男");
per2.sayName();
var per3 =new Person1("李天女",21,"女");
per3.sayName();
console.log(per2.sayName()==per3.sayName());//true
缺点:
原型prototype
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
这个属性对应着一个对象,这个对象就是我们所谓的原型对象
__proto__
来访问该属性原型对象相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一到原型对象中
当我们访问对象的一个属性或方法时,它会现在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如找到则直接使用
以后我们创建构造函数时,可以将这些对象的共有属性和方法,同意添加到构造函数的原型对象中,这一不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具备这些属性和方法了
若我们在网页中直接输出对象,那打印的是[Object Object]。所以我们可以在该类【原型对象】中,添加一份toString函数。
function Person(name,age, sex){
this.name =name;
this.age =age;
this.sex =sex;
}
Person.prototype.toString = function (){
return "Person[name:"+this.name+",age:"+this.age+",sex:"+this.sex+"]";
};
var per =new Person("李天启",21,"男");
var per1 =new Person("李白",20,"男");
alert(per);
alert(per1);
使用for in语句
语法:
for(var 变量 in 对象){
循环体//for...in对象中有几个属性,循环体就执行几次
}
代码演示
var obj ={
name:"李自在",
sex:"男",
age:21,
sayName:function (){
console.log(obj.name);
}
}
for (var n in obj) {
console.log(n);//输出属性名
console.log(obj[n]);//输出属性值
}
//切记不可obj.n === obj中没有n这个属性,会循环输出undefined
//obj["n"]也同上,但obj[n],这里的n就是变量。
就想人生活的时间常量会产生垃圾一样,程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢,使用我们需要一个垃圾回收的机制,来处理程序运行过程中产生的垃圾。
当一个对象没有仍和的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就想一个垃圾,这种对象过多占用大量的内存空间,导致程序运行变慢,使用这种垃圾必须进行清理。
在JS拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收操作,我们需要做得只是要将不再使用的对象设置为 Null即可。
class student {
constructor(name) {
this.name = name;
}
age = 10;
hell() {
alert("hello");
}
}
class xiaoming extends student{
constructor(name,grade) {
super(name);
this.grade =grade;
}
myGrade(){
alert("我是个大学生!");
}
}
var a=new xiaoming("xiaohong",1);
a.hell();
a.myGrade();
本质:其实还是利用了原型对象
作用域
作用域指一个变量作用的范围
在JS中一共有两种作用域
全局作用域
直接写在script标签中的JS代码,都在全局作用域
全局作用域在页面打开时创建,在页面关闭时销毁
在全局作用域中有一个全局对象window
在全局作用域中:
创建的变量都会作为window对象的属性保存
创建的函数都会走位window对象的方法保存
在全局作用域在的变量都是全局变量
变量的声明提前
使用var
关键字声明的变量,会在所有的代码执行之前杯声明(但不会被赋值),但是如果声明变量时,不是用var关键字,则变量不会被声明提前(局部变量一般用let【ES6】)
函数的声明被提前
使用函数声明形式创建的函数function 函数(){}
,它会在所有代码执行之前就被创建,所有我们可以在函数声明前调用函数
使用函数表达式创建的函数,不会被声明提前,使用不能在声明前调用
函数作用域
调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
每调用一次函数就会创建一个新的函数作用域,他们之间时相互独立
在函数作用域中可以访问到全局作用域的变量
当在函数作用域操作一个变量时,它会现在自身作用域中寻找,如果有就直接使用【就近原则】
如果没有就向上一级作用域中找,指导找到全局作用域,如果全局作用域中依然没有找到,就会报错ReferenceError
在函数中要访问全局变量可以使用window对象
注意:
var
关键字声明的变量,会在函数中所有的代码执行之前被声明var
声明的标量都会称为全局变量JS的数组和java中的数组基本一样,不同的是,java读取不存在的索引会报错,而它不会报错,而是返回undefined
设置和获取数组的长度
数组.length
尽量不要创建非连续的数组
修改length
向索引后一个位置添加值
//连续数组
var arr =new Array();
arr[0] =10;
arr[arr.length] =20;//向后添加一个元素
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[5]);//undefined
console.log(arr.length);//2
//不连续数组
var arr1 =new Array();
arr1[0] =30;
arr1[10] =5;
console.log(arr1[5]);
console.log(arr1.length);//11 最大索引加1
语法: var arr =[元素,元素,……];
//数组字面量创建【推荐使用】
var arr2 =[10,20,30];
//创建了长度为1,元素为10的数组
var arr2 =[10];
//创建了长度为10的数组
var arr3 =new Array(10);
//创建了长度为3,元素分别为10,20,30的元素
var arr4 =new Array(10,20,30);
可以是函数,对象,数字,字符串,null,undefined,数组等任意数据类型,哪怕混存也可以!
代码演示
//数组存储任意数据类型
var obj =new Object();
var arr5 =[true,undefined,null,"lalla",function (){},obj];
console.log(arr5);
// 二维数组
var arr6 =[[1,2,3],[4,5,6],[7,8,9]];
console.log(arr6[0]);
push()
var arr =[10,20,30];
arr.push(40,50,60);
console.log(arr);//10,20,30,40,50,60
console.log(arr.length);//6
pop()
var arr =[10,20,30];
arr.pop();
console.log(arr);
unshift()
var arr =[10,20,30];
arr.unshift(0);
console.log(arr);//0,10,20,30
console.log(arr.length);//3
shift()
var arr =[10,20,30];
arr.shift();
console.log(arr);//20,30
console.log(arr.length);//2
slice()
可以用来从数组中提取指定元素
该方法不会改变元素数组,而是将截取到的元素封装刀一个新数组中,并将该数组返回
参数:
3.索引可以传一个负数,如果传的是负数,那便从后往前计算
-1 倒数第一个
-2 倒数第二个
代码演示
var arr =[10,20,30,40,50];
var result =arr.slice(1);//如果只传一个索引值,那便会从1截取到后面所有(长度索引位置)
console.log(result);
var result1 =arr.slice(0,-2);//截取0位置到数组倒数第二个
console.log(result1);
var result2 =arr.slice(1,3);
console.log(result2);
splice()
可以用于删除数组中指定元素
使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回
参数:
var arr =[10,20,30,40,50];
arr.splice(0,2,503,911);
console.log(arr);
去重练习
var arr =[1,2,3,2,1,3,4,2,5];
for (var i = 0; i < arr.length; i++) {
for (var j = i+1; j < arr.length; j++) {
if(arr[i]==arr[j]){
arr.splice(j,1);
j--;
}
}
}
console.log(arr);
concat()
代码演示
var arr =["孙悟空","猪八戒","沙和尚"]
var arr1 =["牛魔王","铁扇公主","红孩儿"]
var result =arr.concat(arr1);//连接2个
console.log(result);
var arr2 =["超神","热血","战斗"];
result =arr.concat(arr1,arr2,"好好学习",999);//连接多个数组,并且加入元素
console.log(result);
join()
代码演示
var arr =["孙悟空","猪八戒","沙和尚"];
var result =arr.join("-");
console.log(result);
sort()
可以用来对数组中的元素进行排序,会影响原数组,默认会按照Unicode编码进行排序
即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,所以对数字排序时,可能会得到错误的结果
我们可以自己来指定排序的规则,我们可以在sort()添加一个回调函数,来指定排序规则,回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数,使用哪个元素不确定,但是肯定的是数组a一定排在数组b前边
技巧:如果需要升序排列,则返回a-b;如果需要降序排列,则返回b-a!
var arr =[12,1,52,123];
arr.sort(function (a, b) {
return a-b;
// if(a>b){
// return 1;
// }else if(a
// return -1;
// }else {
// return 0;
// }
})
console.log(arr);
for循环
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
forEach()
一般我们都是使用for循环去遍历数组,JS还未我们提供了一个方法,用来遍历数组forEach()
注意:这个方法值支持IE8以上浏览器,IE8及以下浏览器均不支持该方法,使用如果需要兼容IE8,则不要使用forEach。
在JS中使用Date对象来表示一个时间
//如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间
var date =new Date();
console.log(date);//Sun Nov 21 2021 11:36:41 GMT+0800 (中国标准时间)
//创建一个指定时间的对象
//需要在构造函数中传递一个时间的字符串作为参数
//日期格式:月份/日/年/ 时:分:秒
var date1 =new Date("1/13/1999 05:03:03");
console.log(date1);//Wed Jan 13 1999 05:03:03 GMT+0800 (中国标准时间)
//getDate()
//获取当前日期对象是几号
var date2 = date.getDate();
console.log(date2);
//getDay:获取当前日期对象是几号
//会返回一个0-6的值
//0 表示 周日
// 1 表示 周一
var day =date.getDay();
console.log(day);
//getMonth()
//获取当前时间对象的月份
//会返回一个0-11的值【所以我们在使用的时候一般给他加1】
// 0 表示 1月
// 1 表示 2月
//11 表示 12月
var month =date.getMonth();
console.log(month);
//getFullYear()
//从Date对象返回四位数字返回年份
var year =date.getFullYear();
console.log(year);
/*getTime()
获取当前日期对象的时间戳
-时间戳,指的是从格林威治标准时间的 1970年1月1日 0时0分0秒
到当前日期所花费的毫秒数(1秒=1000毫秒)
-计算机在底层保存时间都是使用时间戳
*/
var date4 =date.getTime();
console.log(date4);
//获取此代码运行时的时间戳
var date3 =Date.now();
console.log(date3);
abs()可以用来计算一个数的绝对值
console.log(Math.abs(-1));//1
ceil()可以对一个属进行向上取整,小数位只有有值就自动进1
console.log(Math.ceil(1.1));//2
floor()可以对一个数进行向下取整,小数部分会被舍掉
console.log(Math.floor(1.6));//1
round可以对一个数进行四舍五入
console.log(Math.round());//对一个数进行四舍五入
random()
Math.round(Nath.random()*X);
Math.round(Math.random()*(y-x)+x);
pow(x,y)返回x的y次幂
console.log(Math.pow(2,2));//4
sqrt()用于对一个开发运算进行
console.log(Math.sqrt(4));//2
基本数据类型:
String Numnber Boolean Null Undefined
引用数据类型:
Object
在JS中为我们提供了三个包装类,通过这是三个包装类科银酱基本数据类型转换为对象
String()
Number()
Boolean()
注意:我们在实际应用中不会使用基本数据类型的对象,如果使用了基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果。比如,你创建一个布尔值为false的对象,放进去判断,结果因为对象强转成布尔值时,为true;最后也运行出来了!
String底层使用字符数组存储的,使用数组有的,他一般也有!String的方法基本都不会对它原数组造成影响!
charAt()可以返回字符串中指定位置
var str ="Hello lizhiming";
console.log(str.length);//15
console.log(str.charAt(2));//与str[2]返回一样
charCodeAt()获取指定位置字符的字符编码(Unicode编码)
console.log(str.charCodeAt(0));//72
String.formaCharCode()可以根据字符编码去获取字符
var str1 =String.fromCharCode(72);//H
concat()
+号
差不多 var result =str.concat("你好","再见");
console.log(result)
indexof()
var str ="hello lizhiming";
var a =str.indexOf("h");
console.log(a);
var b =str.indexOf("h",3);//从索引三位置开始寻找
console.log(b);
lastIndexOf
slice()
可以从字符串截取指定内容
不会影响字符串,而是将截取到的内容返回
参数:
第一个:开始位置(包括)
第二个:结束位置(不包括)
也可以传递一个负数作为参数,负数的话将会从后变计算
substring()
var a = str.substring(0,5);
console.log(a);
substr()谨慎使用
用来截取字符串
参数:
ECMAscript没有对该方法进行标准化,因此反对使用它
拓展:substr与substring:
js中substr和substring都是截取字符串中子串,非常相近,可以有一个或两个参数。
语法:substr([start ,length]) 第一个字符的索引是0,start必选 length可选
substring([start , end]) 第一个字符的索引是0,start必选 end可选
相同点:当有一个参数时,两者的功能是一样的,返回从start指定的位置直到字符串结束的子串
var str = "hello Tony";
str.substr(6); //Tony
str.substring(6); //Tony
不同点:有两个参数时
(1)substr(start,length) 返回从start位置开始length长度的子串
“goodboy”.substr(1,6); //oodboy
【注】当length为0或者负数,返回空字符串
(2)substring(start,end) 返回从start位置开始到end位置的子串(不包含end)
“goodboy”.substring(1,6); //oodbo
【注】:
(1)substring 方法使用 start 和 end 两者中的较小值作为子字符串的起始点
(2)start 或 end 为 NaN 或者负数,那么将其替换为0
split()
正则表达式用于定义一些字符串的规则
语法:
var 变量 =new RegExp("正则表达式","匹配模式");
// 使用typeof检查正则对象,会返回object
var reg =new RegExp("a");
//这个正则表达式可以来检查一个字符串中是否含有a【严格区分大小写】
//在构造器中可以传递一个匹配模式作为第二个参数
//可以是
//i 忽略大小写
//g 全局匹配模式
正则表达式的方法:
test()
使用这个方法可以用来检查一个字符串是否符合正则表达式的规则
如果符合则返回true,否则返回false
reg.test(str)
var reg =new RegExp("a|b","i");
var boo =reg.test("B");
console.log(boo);
使用字面量来创建正则表达式
语法:var 变量 =/正则表达式/匹配模式
使用字面量的方式创建更加简单,但使用构造函数创建更加灵活。
[]
/*[]里的内容也是或的关系
[ab] == a| b
[a-z] 任意小写字母
[A-Z] 任意大写字母
[0-9] 任意数字
[A-z] 任意字母,忽略大小写
*/
var reg2 =/[0-9]/;
var boo2 =reg2.test("3854");
console.log(boo2);
[^]除了
var reg3 =/[^a-z]/;
var boo3 =reg3.test("3854");//true
var boo3 =reg3.test("a");//false
console.log(boo2);
console.log(boo3);
var reg4 =/a[ecd]g/;//aeg | acg| adg
split()
var str = "1a2b3c4d5f6g7h8j9k10";
var result =str.split(/[A-z]/);
console.log(result);
search()
serach()
只会查找第一个,即使设置全局匹配也没用var str ="hello zhen chun i love you";
var result =str.search(/[zc]h/);
console.log(result);
match()
match
只会找到第一个符合要求的内容,找到以后就停止检索match()
会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果。var str = "1a2b3c4d5f6g7h8j9k10";
var result =str.match(/[a-z]/gi);
console.log(result);
replace()
可以将字符串指定内容替换新的内容
参数
默认只会替换第一个,所以当你想全替换的时候,可以使用全局匹配
var str = "1a2a3c4a5a6A7A8a9a10";
var result =str.replace(/a/ig,",");//如果你没有传第二个参数进去,那就是undefined把a替换了!
console.log(result);
量词
通过量词可以设置一个内容出现的次数
量词只对它前边的一个内容起作用
{n}
至少出现n次
{m,n}
出现m到n次
{m,}
m次以上
+
至少一个,相当于{1,}
*
0个或多个,相当于{0,}
?
0个或1个,相当于{0,1}
var reg =/a{3}/;//至少出现3次
var str ="aaaa";
var result= reg.test(str);
console.log(result);
var reg1 =/a{1,3}/;//出现1次到3次
var str1 ="aaaa";
var result1= reg1.test(str1);
console.log(result1);
var reg3 =/a+/;//相当于{1,},一般用“x+”这种方式
var str3 ="aaaa";
var result3 =reg3.test(str3);
console.log(result3);
var reg4 =/a*/;//0个或多个
var str4 ="b";
var result4 =reg4.test(str4);
console.log(result4);//true
var reg5 =/a?/;//0个到1个
var str5 ="aaaaaaa";
var result5 =reg5.test(str5);
console.log(result5);
检查一个字符串的开头语结尾
^
表示开头
$
表示结束
var reg =/^a/;//a字开头
var str =“abaaabb”;
var result1 =reg.test(str);
console.log(result1);
var reg1 =/a$/;
var str1 ="bbbba";
var result2 =reg1.test(str1);
console.log(result2);
注意:如果在正则表达式同时使用^ $
则要求字符串必须完全符合正则表达式
var reg2 =/^a$/;//这种情况下下只有a才是true,aa都是false
var reg3 =/^a|a$/;//这种情况才是以a开头,以a结尾
var str2 ="a";
var result3 =reg2.test(str2);
console.log(result3);
\w
\W
\d
\D
\s
\S
\b
\B
var str =prompt("请输入")
str =str.replace(/^\s*| s*$/g,"");//去掉前尾空格
console.log(str);
DOM,全称Document Object Model 文档对象
JS通过DOM来对HTML文档进行操作。只要理解了DOM就可以随心所欲的操作WEB页面
文档
对象
模型
【这个是我看尚硅谷截取过来的图片,好评尚硅谷,如果有侵权,告知我删了哈!那个水印我不知道怎么去】
getElementById()
getElementsByTagName()
getElentsByName()
innerHTML
用于获取元素内部的HTML代码的,对于自结束的标签,这个属性没有意义
如果需要读取元素的节点属性,直接使用元素.属性名
eg:
注意:class属性不能采用这种方式,读取class属性时需要使用元素.className
getElementsByTagName()
childNodes
属性,表示当前节点的所有子节点
根据DOM,标签之间的空白也会当成文本节点
注意:在IE8及以下的浏览器中,不会将空白文档当成子节点,所以该属性在IE8中会返回4哥子元素而其他浏览器是9个
children
firstChild
firstElementChild
lastChild
通过具体的节点调用
parentNode
previousSibling
nextSibling
innerText
innerHTML
类似,不同的是它会自动将html去除previousElementSibling
body
body
的引用documentElement
html
根标签all
getElementByClassName()
class
属性获取一组元素节点对象querySelector()
getElementsByClassName()
,但是可以使用querySelector()
代替querySelectorAll()
代码实现
script>
window.onload=function (){
var all =document.all;
console.log(all.length);
var query =document.querySelector("#box div");
console.log(query.innerHTML);
var query1 =document.querySelectorAll("#box");
console.log(query1);
var de =document.documentElement;
console.log(de);
var body =document.body;
console.log(body);
};
removeChild()
删除子节点
confirm()
用于弹出一个带有确认和取消按钮的提示框,需要一个字符串作为参数,改字符串将会作为提示文字显示出来,如果用户点击确认会返回true,果果点击取消返回false
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加删除记录练习</title>
<link rel="stylesheet" type="text/css" href="css.css" />
<script type="text/javascript">
function deleteA(){
var tr = this.parentNode.parentNode;
//获取要删除的员工的名字
//var name = tr.getElementsByTagName("td")[0].innerHTML;
var name = tr.children[0].innerHTML;
//删除之前弹出一个提示框
/*
* confirm()用于弹出一个带有确认和取消按钮的提示框
* 需要一个字符串作为参数,该字符串将会作为提示文字显示出来
* 如果用户点击确认则会返回true,如果点击取消则返回false
*/
var flag = confirm("确认删除"+name+"吗?");
//如果用户点击确认
if(flag){
//删除tr
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 = deleteA;
}
var addEmpButton =document.getElementById("addEmpButton");
addEmpButton.onclick =function (){
var empName =document.getElementById("empName").value;
var email =document.getElementById("email").value;
var salary =document.getElementById("salary").value;
// var a =document.createElement("a");
// a.innerText ="Delete";
var tr =document.createElement("tr");
// var nameTd =document.createElement("td");
// var emailTd =document.createElement("td");
// var salaryTd =document.createElement("td");
// var aTd =document.createElement("td");
tr.innerHTML =""+empName+" "+
""+email+" "+
""+salary+" "+
"Delete ";
var a =tr.getElementsByTagName("a")[0];//哪怕只有一个元素,该方法也会返回一个集合
a.onclick =deleteA;
// var nameText =document.createTextNode(empName);
// var emailText =document.createTextNode(email);
// var salaryText =document.createTextNode(salary);
// var delText =document.createTextNode("delete");
//
//
// // a.appendChild(delText);上面有innerText
// a.href ="javascript:;";
// aTd.appendChild(a);
// nameTd.appendChild(nameText);
// emailTd.appendChild(emailText);
// salaryTd.appendChild(salaryText);
//
// tr.appendChild(nameTd);
// tr.appendChild(emailTd);
// tr.appendChild(salaryTd);
// tr.appendChild(aTd);
var employeeTable =document.getElementById("employeeTable");
var tbody =employeeTable.getElementsByTagName("tbody")[0];
tbody.appendChild(tr);
};
};
</script>
</head>
<body>
<table id="employeeTable">
<tr>
<th>Name</th>
<th>Email</th>
<th>Salary</th>
<th> </th>
</tr>
<tr>
<td>Tom</td>
<td>tom@tom.com</td>
<td>5000</td>
<td><a href="javascript:;">Delete</a></td>
</tr>
<tr>
<td>Jerry</td>
<td>jerry@sohu.com</td>
<td>8000</td>
<td><a href="deleteEmp?id=002">Delete</a></td>
</tr>
<tr>
<td>Bob</td>
<td>bob@tom.com</td>
<td>10000</td>
<td><a href="deleteEmp?id=003">Delete</a></td>
</tr>
</table>
<div id="formDiv">
<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">salary: </td>
<td class="inp">
<input type="text" name="salary" id="salary" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button id="addEmpButton" value="abc">
Submit
</button>
</td>
</tr>
</table>
</div>
</body>
</html>
注意:
for循环会在页面加载完成之后立即执行,而响应函数会在超链接被点击时才执行,当响应函数执行时,for循环早已执行完毕
通过JS修改的样式:
语法:元素.style.样式名 =样式值
注意:
-
,这种名称在JS中式不合法的,比如:background-colo
r需要将这种样式名改为驼峰命名法,去掉-
,然后将-
后的字母大写!important
,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效,所以尽量不要为样式添加!important<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>操作内联样式</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: red;
}
</style>
<script>
window.onload = function () {
var button = document.getElementById("button");
button.onclick = function () {
box.style.width = "300px";
box.style.height = "300px";
box.style.backgroundColor = "yellow";
};
var button1 = document.getElementById("button1");
button1.onclick = function () {
alert(box.style.width);
alert(box.style.height);
alert(box.style.backgroundColor);
};
};
</script>
</head>
<body>
<div id="box"></div>
<button id="button">点我一下</button>
<button id="button1">查看内联样式</button>
</body>
</html>
currentStyle
语法:元素.currentStyle.样式名
它可以用来读取当前正在显示的样式,如果当前元素没有设置该样式,则获取它的默认值
提示:只有IE支持,其他浏览器不支持
getComputedStyle() 推荐
这个方法来获取元素当前的样式,这个方法是window的方法,可以直接使用,需要两个参数
该方法会返回一个对象,对象中封装了当前元素对应的样式(属性),可以通过对象.样式名
来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值,比如:没有设置width,它不会获取到auto,而是一个长度,但是该方法不支持IE8及以下的浏览器
通过currentStyle
和和getComputedStyle()
读取到的样式都是只读的,不能修改,如果要修改必须通过style属性
自定义函数实现获取元素当前显示样本
定义一个函数,用来获取指定元素的当前的样式
参数:obj 要获取样式的元素
name 要获取的样式名
/**
* 这种思想常用来解决兼容性问题
* @param obj 对象
* @param name 字符串属性
* @returns {*}
*/
function getStyle(obj ,name){
if(window.getComputedStyle){
//这里最好加window. 因为不加的话,他就是变量,变量没找到会报错,下面就没有机会执行了,
// 要是属性的话,是undefined,就转false,去执行else,不会报错了。
return getComputedStyle(obj,null)[name];
}else {
return obj.currentStyle[name];
}
}
clientWidth clientHeight
这两个属性可以获取元素的可见宽度于高度,这些【包括后面的】属性都是不带px的,返回都是一个数字,可以直接进行计算,会获取元素的高度和宽度,包括内容区和内边距,这些属性都是只读的,不能修改。
offsetWidth offsetHeight
获取元素整个宽度和高度,包括内容区、内边距和边框
alert(box.offsetWidth);
offsetParent
可以用来获取当前元素是的定位父元素
var op =box.offsetParent
offsetLeft
当前元素相对于其定位父元素的水平
alert(box.offsetLest);
offsetTop
当前元素相对于其定位父元素的垂直偏移量
alert(box.offsetLeft)
scrollWitdth
scrollHeight
可以获取元素整个滚动区域的宽度和高度
alert(box.scrollWidth)
scrollLeft
可以获取水平滚动读条的距离
scrollTop
可以获取垂直滚动条滚动的距离
alert(box.scrollTop)
技巧:
scrollHeight -scrollTop == clientHeight
说明垂直滚动条到底了
scrollWidth - scrollLeft == clientWidth
说明水平滚动条到底了
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#box {
width: 300px;
height: 500px;
background-color: green;
overflow: auto;
}
</style>
<script>
/**
* 当垂直表单滚动到底时,使表单可选项可用
* onscroll
* 该事件会在元素滚动条滚动时触发
*/
window.onload = function () {
var box = document.getElementById("box");
var inputs = document.getElementsByTagName("input");
box.onscroll = function () {
if (box.scrollHeight - box.scrollTop == box.clientHeight) {
/**
* disabled属性设置一个元素是否可以
* 如果true,则表示禁用
* 如果使false,则表示启用
* @type {boolean}
*/
inputs[0].disabled = false;
inputs[1].disabled = false;
}
};
};
</script>
</head>
<body>
<div >
<h3>注册</h3>
<p id="box">年少轻狂的岁月沉淀下来的是哪些再也回不到的过去,而总让人感叹的则是未能珍惜而失去的那些,
但这些也恰恰是我们让你去体会的,因为年少轻狂的岁月,一生也只有一次。世间最珍贵的不是得不到或已失去的,而是现在能把握的。
我们生活在一个复杂又充满无奈的世界,身上背负着太多太多的责任和使命,
有时我们处理不当,就会不堪重负,难以忍受。最宽阔的是海洋,比海洋更宽阔的是天空,
比天空更宽阔的是人的胸怀。当你紧握双手,里面什么也没有,
当你打开双手,世界就在你手中。
年少轻狂的岁月沉淀下来的是哪些再也回不到的过去,而总让人感叹的则是未能珍惜而失去的那些,
但这些也恰恰是我们让你去体会的,因为年少轻狂的岁月,一生也只有一次。世间最珍贵的不是得不到或已失去的,而是现在能把握的。
我们生活在一个复杂又充满无奈的世界,身上背负着太多太多的责任和使命,
有时我们处理不当,就会不堪重负,难以忍受。最宽阔的是海洋,比海洋更宽阔的是天空,
比天空更宽阔的是人的胸怀。当你紧握双手,里面什么也没有,
当你打开双手,世界就在你手中。
年少轻狂的岁月沉淀下来的是哪些再也回不到的过去,而总让人感叹的则是未能珍惜而失去的那些,
但这些也恰恰是我们让你去体会的,因为年少轻狂的岁月,一生也只有一次。世间最珍贵的不是得不到或已失去的,而是现在能把握的。
我们生活在一个复杂又充满无奈的世界,身上背负着太多太多的责任和使命,
有时我们处理不当,就会不堪重负,难以忍受。最宽阔的是海洋,比海洋更宽阔的是天空,
比天空更宽阔的是人的胸怀。当你紧握双手,里面什么也没有,
当你打开双手,世界就在你手中。
</p>
</div>
<input type="checkbox" disabled="disabled"/>已阅读协议,我一定遵守
<input type="submit" value="注册" disabled="disabled" />
</body>
</html>
总结:
在写这个的时候,我常常发现一个问题:
getElementsByName
与getElementsByTagName
区别:
前者获得名字name属性;后者为标签名
代码实现
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件title>
head>
<body>
<button id="btn">我是一个按钮button>
<script>
var btn=document.getElementById("btn");
/*
可以为按钮的对应事件绑定处理函数的形式来响应事件
这样当事件被触发时,其对应的函数将会被调用
*/
//绑定一个单击事件
//想这种为单击事件绑定的函数,我们称为单击响应函数
btn.onclick =function (){
alert("你好帅!~~")
};
script>
body>
html>
注意:
浏览器在加载一个页面时,是按照自上而下的顺序加载的,读取到一行运行一行,如果将script标签写在页面是上面,在代码执行时,页面还没有加载,页面没有加载DOM对象会导致无法获取DOM 对象。
为了解决上述问题,可以引入onload
onload
事件会在整个页面加载完成之后才触发,为window绑定一个onload
事件,该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行的所有DOM对象加载完毕了!
事件对象
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标、键盘哪个键被按下、鼠标滚轮滚动 方向……
onmousemove
该事件将会在鼠标在元素中移动时被触发clientX
可以获取鼠标指针的水平位置clientY
可以获取鼠标指针的垂直坐标注意:
在IE8,响应函数被触发时,浏览器不会传递事件对象,在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件对象</title>
<style>
#agrsDiv {
width: 600px;
height: 500px;
border: solid;
}
#showDiv {
width: 600px;
height: 200px;
border: solid;
}
</style>
<script>
window.onload = function () {
var agrs = document.getElementById("agrsDiv");
var show = document.getElementById("showDiv");
agrs.onmousemove = function (event) {
event = event || window.event;
var x = event.clientX;
var y = event.clientY;
show.innerHTML = "x=" + x + ",y =" + y;
};
};
</script>
</head>
<body>
<div id="agrsDiv"></div>
<p></p>
<div id="showDiv"></div>
</body>
</html>
练习:div随鼠标移动
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
/*
* 开启box1的绝对定位
*/
position: absolute;
}
</style>
<script type="text/javascript">
window.onload = function(){
/*
* 使div可以跟随鼠标移动
*/
//获取box1
var box1 = document.getElementById("box1");
//绑定鼠标移动事件
document.onmousemove = function(event){
//解决兼容问题
event = event || window.event;
//获取滚动条滚动的距离
/*
* chrome认为浏览器的滚动条是body的,可以通过body.scrollTop来获取
* 火狐等浏览器认为浏览器的滚动条是html的,
*/
var st = document.body.scrollTop || document.documentElement.scrollTop;
var sl = document.body.scrollLeft || document.documentElement.scrollLeft;
//var st = document.documentElement.scrollTop;
//获取到鼠标的坐标
/*
* clientX和clientY
* 用于获取鼠标在当前的可见窗口的坐标
* div的偏移量,是相对于整个页面的
*
* pageX和pageY可以获取鼠标相对于当前页面的坐标
* 但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用
*/
var left = event.clientX;
var top = event.clientY;
//设置div的偏移量
box1.style.left = left + sl + "px";
box1.style.top = top + st + "px";
};
};
</script>
</head>
<body style="height: 1000px;width: 2000px;">
<div id="box1"></div>
</body>
</html>
注意点:
document.onmousemove =function (event){};
为什么给onmousemove绑定的对象是整个文档呢,因为他是相对于整个文档来移动的。经常会把这个东西绑定给div,但这是错的,一但你的鼠标离开div的范围,那div就不会跟着它移动了。所有这个时候,它只能斜向下方向移动,所有我们针对的是整个文档页面,即为document。
var st =document.body.scrollTop || document.documentElement.scrollTop;
var sl =document.body.scrollLeft || document.documentElement.scrollLeft;
如果你没有加这两个,因为div的偏移量时相对于整个页面来说,
而clientX和clientY的偏移是对当前可见页面来说的,
当实际页面比当前页面要大,就会出现滚条,当你滑动滚条时,div会出现于鼠标分离的情况,就因为这两件事物偏移所对应的对象所不同,所有你必须让div的移动加上滚条的移动,就实现了对当前可见窗的移动了。
所谓的冒泡指的就是事件向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
cancelBubble
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件的冒泡</title>
<style>
#box{
width: 500px;
height: 500px;
background-color: green;
}
span{
width: 200px;
height: 100px;
background-color: yellow;
}
</style>
<script>
window.onload =function (){
var box =document.getElementById("box");
box.onclick =function (event){
event = event||window.event;
alert("我是div函数");
event.cancelBubble =true;
};
var span =document.getElementById("spanBox");
span.onclick =function (event){
event = event||window.event;
alert("我是span函数");
event.cancelBubble =true;
};
document.body.onclick =function (){
alert("我是body函数");
};
};
</script>
</head>
<body>
<div id="box">我是div<span id="spanBox">我是span</span></div>
</body>
</html>
我们希望,只绑定一次事件,即可应用到多分元素上,即使元素是后添加的,我们可以尝试将其绑定给元素的共同祖先元素。
事件的委派指将事件统一绑定给元素的共同祖先,这样当后代元素的事件被触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
事件的委派是利用了冒泡,通过委派可以减少事件的绑定次数,挺高程序性能。
target
event中的target表示的触发事件的对象
代码演示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
window.onload = function(){
var u1 = document.getElementById("u1");
//点击按钮以后添加超链接
var btn01 = document.getElementById("btn01");
btn01.onclick = function(){
//创建一个li
var li = document.createElement("li");
li.innerHTML = "新建的超链接";
//将li添加到ul中
u1.appendChild(li);
};
/*
* 为每一个超链接都绑定一个单击响应函数
* 这里我们为每一个超链接都绑定了一个单击响应函数,这种操作比较麻烦,
* 而且这些操作只能为已有的超链接设置事件,而新添加的超链接必须重新绑定
*/
//获取所有的a
var allA = document.getElementsByTagName("a");
//遍历
/*for(var i=0 ; i
/*
* 我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的
* 我们可以尝试将其绑定给元素的共同的祖先元素
*
* 事件的委派
* - 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素
* 从而通过祖先元素的响应函数来处理事件。
* - 事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
*/
//为ul绑定一个单击响应函数
u1.onclick = function(event){
event = event || window.event;
/*
* target
* - event中的target表示的触发事件的对象
*/
//alert(event.target);
//如果触发事件的对象是我们期望的元素,则执行否则不执行
if(event.target.className == "link"){
alert("我是ul的单击响应函数");
}
};
};
</script>
</head>
<body>
<button id="btn01">添加超链接</button>
<ul id="u1" style="background-color: #bfa;">
<li>
<p>我是p元素</p>
</li>
<li><a href="javascript:;" class="link">超链接一</a></li>
<li><a href="javascript:;" class="link">超链接二</a></li>
<li><a href="javascript:;" class="link">超链接三</a></li>
</ul>
</body>
</html>
就目前而言,事件的绑定有三种
一:赋值绑定
window.onload = function () {
var button = document.getElementById("button");
button.onclick = function () {
alert(1);
};
button.onclick = function () {
alert(2);
};
};
这种方式后者会对前者进行覆盖,所以它只会弹出2
二:addEventListener
addEvebtListener()
通过这个方法也可以为元素绑定响应函数
参数:
false
var button = document.getElementById("button");
button.addEventListener("click", function () {
alert(1);
}, false);
button.addEventListener("click", function () {
alert(2);
}, false);
优点:
缺点:
attachEvent()
button.attachEvent("onclick",function (){
alert(1);
});
button.attachEvent("onclick",function (){
alert(2);
});
这个只有IE8及以下的时候采用,但我们考虑到兼容性问题,需要对浏览器做兼容-=》bind()函数
值得注意的是:
addEventListener()
想反定义一个函数,用来为指定元素绑定响应函数
addEventListener()
中的this,是绑定事件的对象
attachEvent()
中的this,是window
需要统一两个方法的this
/**
*
* @param obj 绑定事件的对象
* @param eventStr 事件的字符串(不要on)
* @param callback 回调函数
*/
function bind(obj,eventStr,callback){
if(obj.addEventListener){
//大部分浏览器
obj.addEventListener(eventStr,callback,false);
}else {
/**
* this是由谁调的方式决定
* callback().call(obj);
*/
//IE8及以下浏览器
obj.attachEvent("on"+eventStr,function (){
callback.call(obj);
});
}
}
关于事件的传播网景公司和微软有不同的理解
微软认为事件一个是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素传播,也就说事情应该再在冒泡阶段执行
网景公司认为事件应该时由外向内传播的,也就是当事件触发时,应该先触发当前元素最外层的祖先元素,然后再向内传播给后代元素
W3C综合了两个公司的方案,将事件传播分成了三个阶段
捕获阶段
目标阶段
冒泡阶段
注意:
如果希望在捕获阶段就触发事件,可以将addEventListener()
的第三个参数设置为true
IE8及以下的浏览器中没有捕获阶段
图示
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件的传播</title>
<style>
#box1{
height: 300px;
width: 300px;
background-color: yellow;
}
#box2{
height: 150px;
width: 150px;
background-color: green;
}
#box3{
height: 100px;
width: 100px;
background-color: red;
}
</style>
<script>
window.onload =function (){
var box1 =document.getElementById("box1");
var box2 =document.getElementById("box2");
var box3 =document.getElementById("box3");
bind(box1,"click",function (){
alert("我是box1");
});
bind(box2,"click",function (){
alert("我是box2");
});
bind(box3,"click",function (){
alert("我是box3");
});
};
function bind(obj,eventStr,callback){
if(obj.addEventListener){
//大部分浏览器
//这里如果你把obj去掉,那么调用addEventListener的就是window,
// 如果是window调用的话那就是顺序调用了,只有是这个事件调用才是符合事件的传播 obj.addEventListener(eventStr,callback,false);
}else {
/**
* this是由谁调的方式决定
* callback().call(obj);
*/
//IE8及以下浏览器
obj.attachEvent("on"+eventStr,function (){
callback.call(obj);
});
}
}
</script>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
</body>
</html>
注意:
这里如果你把obj
去掉,那么调用addEventListener
的就是window
,
如果是window
调用的话那就是顺序调用了,只有是这个事件调用才是符合事件的传播
拖曳的流程
onmousedown
onmousemove
onmouseup
鼠标位置问题:
//div的偏移量 鼠标.clientX-box.offsetLeft;
//div的偏移量 鼠标.clientY-box.offsetTop;
var ol =event.clientX -box.offsetLeft;
var ot =event.clientY -box.offsetTop;
var left =event.clientX-ol;
var top =event.clientY-ot;
box.style.left =left+"px";
box.style.top =top+"px";
注意:
当我们拖曳一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖曳功能异常,这个是浏览器所提供的默认行为,如果不希望发生这个行为,则可以通过return false
来取消默认行为
但是 这对IE8 不管用
针对IE8我们使用,捕获函数和释放捕获函数来解决
obj.setCapture&&obj.setCapture();//捕捉函数
obj.releaseCapture && obj.releaseCapture();//释放函数
拖曳代码演示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
#box2 {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 200px;
top: 200px;
}
</style>
<script type="text/javascript">
window.onload = function () {
/*
* 拖拽box1元素
* - 拖拽的流程
* 1.当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
* 2.当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
* 3.当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
*/
//获取box1
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var img1 = document.getElementById("img1");
//开启box1的拖拽
drag(box1);
//开启box2的
drag(box2);
drag(img1);
};
/*
* 提取一个专门用来设置拖拽的函数
* 参数:开启拖拽的元素
*/
function drag(obj) {
//当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
obj.onmousedown = function (event) {
//设置box1捕获所有鼠标按下的事件
/*
* setCapture()
* - 只有IE支持,但是在火狐中调用时不会报错,
* 而如果使用chrome调用,会报错
*/
/*if(box1.setCapture){
box1.setCapture();
}*/
obj.setCapture && obj.setCapture();
event = event || window.event;
//div的偏移量 鼠标.clentX - 元素.offsetLeft
//div的偏移量 鼠标.clentY - 元素.offsetTop
var ol = event.clientX - obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
//为document绑定一个onmousemove事件
document.onmousemove = function (event) {
event = event || window.event;
//当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
//获取鼠标的坐标
var left = event.clientX - ol;
var top = event.clientY - ot;
//修改box1的位置
obj.style.left = left + "px";
obj.style.top = top + "px";
};
//为document绑定一个鼠标松开事件
document.onmouseup = function () {
//当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
//取消document的onmousemove事件
document.onmousemove = null;
//取消document的onmouseup事件
document.onmouseup = null;
//当鼠标松开时,取消对事件的捕获
obj.releaseCapture && obj.releaseCapture();
};
/*
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
* 如果不希望发生这个行为,则可以通过return false来取消默认行为
*
* 但是这招对IE8不起作用
*/
return false;
};
}
</script>
</head>
<body>
我是一段文字
<div id="box1"></div>
<div id="box2"></div>
<img src="img/an.jpg" id="img1" style="position: absolute;"/>
</body>
</html>
DOMMouseScroll
注意该事件需要通过addEventListener()
函数来绑定
火狐不支持wheelDelta
这个属性,其对应用的是detail
这个属性来获取滚动的方向,向上滚动 -3
,向下滚动3
当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器的默认行为,一般用reture false
,来取消,但是火狐是用addEventListener()
,使用addEventListener()方法来绑定响应函数,取消默认行为不能使用return false
。需要使用event来取消默认行为event.preventDefault,但是IE8对此又不支持,如果调用会直接报错,所以我们一般这样写:
event.preventDefault && event.preventDefault()
onwheel
wheelDelta
来获取滚轮方向,当向上滚动时,其返回值为120
,向下滚动时,其返回值为-120
returen false
来取消浏览器滚条随滚条移动的情况。代码演示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
}
</style>
<script type="text/javascript">
window.onload = function(){
//获取id为box1的div
var box1 = document.getElementById("box1");
//为box1绑定一个鼠标滚轮滚动的事件
/*
* onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
* 但是火狐不支持该属性
*
* 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件
* 注意该事件需要通过addEventListener()函数来绑定
*/
box1.onmousewheel = function(event){
event = event || window.event;
//event.wheelDelta 可以获取鼠标滚轮滚动的方向
//向上滚 120 向下滚 -120
//wheelDelta这个值我们不看大小,只看正负
//alert(event.wheelDelta);
//wheelDelta这个属性火狐中不支持
//在火狐中使用event.detail来获取滚动的方向
//向上滚 -3 向下滚 3
//alert(event.detail);
/*
* 当鼠标滚轮向下滚动时,box1变长
* 当滚轮向上滚动时,box1变短
*/
//判断鼠标滚轮滚动的方向
if(event.wheelDelta > 0 || event.detail < 0){
//向上滚,box1变短
box1.style.height = box1.clientHeight - 10 + "px";
}else{
//向下滚,box1变长
box1.style.height = box1.clientHeight + 10 + "px";
}
/*
* 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
* 需要使用event来取消默认行为event.preventDefault();
* 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
*/
event.preventDefault && event.preventDefault();
/*
* 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,
* 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
*/
return false;
};
//为火狐绑定滚轮事件
bind(box1,"DOMMouseScroll",box1.onmousewheel);
};
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数
callback.call(obj);
});
}
}
</script>
</head>
<body style="height: 2000px;">
<div id="box1"></div>
</body>
</html>
键盘事件
onkeydown
onkeydown
来说如果一直按着某个按键不松手,则事件会被一直触发。onkeydown
连续触发时,第一次和第二次之间的间隔稍微长一点,其他的会变得非常快,这种设计是为了防止误操作的发生按键被松开onkeyup
键盘事件一般会绑定给一些可以获取焦点的对象或者是document
keyCode
获取按键的unicode编码
通过它可以判断哪个按键被按下
altKey
判断alt键是否被按下ctrlKey
判断ctrl键是否被按下shiftKeY
判断shift是否被按下练习:键盘移动div
向左的unicode是37
向上的unicode是38
向右的Unicode是39
向下的unicode是40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>键盘移动div</title>
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
border: solid;
position: absolute;
}
</style>
<script>
window.onload =function (){
/**
* 37向左
* 38向上
* 39向右
* 40向下
*/
var box =document.getElementById("box");
document.onkeydown =function (event){
event =event|| window.event;
var speed =10;
if(event.ctrlKey){
speed =50;
}
switch (event.keyCode) {
case 37:
box.style.left =box.offsetLeft -speed +"px";
break;
case 38:
box.style.top =box.offsetTop -speed+"px";
break;
case 39:
box.style.left =box.offsetLeft +speed+"px";
break;
case 40:
box.style.top =box.offsetTop+speed+"px";
break;
}
};
};
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>
BOM浏览器对象模型
BOM对象
Window
代表的使整个浏览器的窗口,同时window也是网页中的全局对象
Navigator
代表的是当前浏览器的信息,通过该对象可以识别不同的浏览器
Location
代表的是当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
History
代表的是浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时才有效
Screen
代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关信息
注意:这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可直接使用
Navigator
代表的是当前浏览器的信息,通过该对象可以识别不同的浏览器,由于历史原因,Navigator对象中大部分属性都已经不能帮助我们识别浏览器了。
一般我们只会使用userAgent
来判断浏览器的信息,userAgent是一个字符串,这个字符串中包含用来秒速浏览器信息的内容,不同的浏览器有不同的userAgent。(userAgent等价于浏览器)
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
在IE11中已经将微软和IE相关的表示都已经去除了,使用我们基本已经不能额通过userAgent来识别一个浏览器是否是IE了
但“技高一尺,魔高一丈”,我们现在虽然不能通过userAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息,比如**ActiveXObject
**
代码演示
var ua =navigator.userAgent;
console.log(ua);
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(Edge)")
}
这个只是初级的检测代码,在现在的开发过程中,也并没有起到作用,因为现在的Edge已经非常像Chrome了。
对象可以用来操作浏览器向前或向后翻转
length
属性,可以获取到当前访问的链接数量
back()
可以退回到上一个页面,作用和浏览器的回退按钮一样
forward()
可以跳转下一个页面,作用和浏览器的前进按钮一样
go()
可以用来跳转到指定的页面,需要一个整数作为参数
eg:
1:向前跳转一个页面,相当于forward()
2:向前跳转两个页面
-1:向后跳转一个页面,相当于back()
-2:向后跳转两个页面
代码演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>text1</title>
</head>
<body>
<a href="text2.html">去text2</a>
</body>
</html>
这个是test1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tex2</title>
<script>
window.onload =function (){
var butt =document.getElementsByTagName("button")[0];
butt.onclick =function (){
history.forward();
}
};
</script>
</head>
<body>
<a href="historyEx.html">回到history</a>
<button>向前</button>
</body>
</html>
这个是text2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>history</title>
<script>
window.onload = function () {
var butt = document.getElementsByTagName("button")[0];
butt.onclick = function () {
history.go(-2);
}
};
alert(history.length);
</script>
</head>
<body>
<button>后退</button>
</body>
</html>
这个是history
location
该对象封装了浏览器的地址栏信息
如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
如果直接将location属性修改为一个完整的路径,或相对路径
则我们页面会自动跳转到该路径,并且会生成相应的历史记录
location ="https://www.bilibili.com/";
location ="https://v.qq.com/"
assign()
用来跳转到其他页面,作用和直接修改location
一样
location.assign("https://v.qq.com/");
reload()
true
即可强制清除缓存,不加则默认为普通的刷新<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocationEx</title>
<script>
window.onload =function (){
var butt =document.getElementsByTagName("button")[0];
butt.onclick =function (){
// location ="https://www.bilibili.com/";
// location.assign("https://v.qq.com/");
location.reload(true);
};
};
</script>
</head>
<body>
<button>点一下</button>
<input type="text">
</body>
</html>
如果希望一段程序,每间隔一段时间执行一次,可以使用定时调用
setInterval()
定时调用,可以将一个函数,每隔一段时间执行一次
参数:
clearInterval()
此方法需要一个定时器标识作为参数,这样来关闭对应的定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定时器简介</title>
<script>
window.onload = function () {
var count = document.getElementById("count");
var num = 1;
var timer = setInterval(function () {
count.innerHTML = num++;
if (num == 11) {
clearInterval(timer)
}
}, 1000)
};
</script>
</head>
<body>
<h1 id="count"></h1>
</body>
</html>
clearInterval()注意点
其他注意点:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>定时器练习</title>
<script>
window.onload =function (){
//获取img1标签以便修改它的src属性,来达到换图片的效果
var img1 =document.getElementById("img1");
//将图片封装到数组里,方便我们切换图片
var imgArr =["./picture/1.JPG","./picture/2.bmp","./picture/3.bmp","./picture/4.png","./picture/5.jpg"];
//数组下标索引
var index =0;
//定义定时器的标识,以便关闭定时器,
// 如果你不在这里定义,而在按钮1中定义的话,按钮二范围内,它看不到这个标识
var timer;
//为butt1绑定单击响应函数
var butt1 =document.getElementById("butt1");
butt1.onclick =function (){
/**
* 目前,我们每点一次按钮,就会开启一个定时器
* 点击多次就会开启多个定时器,这就导致图片切换的速度过快
* 并且我们只能关闭最后一次定时器
*/
//在开启定时器之前,需要将当前元素上的其他定时器关闭
clearInterval(timer);
//开启一个定时器来自动切换图片
timer =setInterval(function (){
index++;
index =index%imgArr.length;//判断所以是否超过最大索引,将其置为0
//修改img1的src属性,达到切换效果
img1.src =imgArr[index];
},1000);
};
var butt2 =document.getElementById("butt2");
//为bttu2绑定一个单击响应函数
butt2.onclick =function (){
/*
clearInterval()可以接受任意参数
如果参数是一个有效的定时器的标识,则关闭该定时器
如果参数不是一个有效的标识,则什么也不做,也不会报错
*/
clearInterval(timer);
}
}
</script>
</head>
<body>
<img src="./picture/1.JPG" alt="图片" id="img1">
<br/><br/>
<button id="butt1">开始</button>
<button id="butt2">暂停</button>
</body>
</html>
造成它开始动的那一下,会有些卡动的解决方法,是因为让onkeyCode控制了速度,它有个防误碰机制,所以我们定义一个定时器来控制div移动的速度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>键盘移动div改进</title>
<style>
#box {
width: 100px;
height: 100px;
background-color: red;
border: solid;
position: absolute;
}
</style>
<script>
window.onload = function () {
var speed =10;
var dir =0;
//开启一个定时器来控制它移动的速度,不管它的方向,让onkeydown来只控制方向
setInterval(function (){
switch (dir) {
case 37:
box.style.left = box.offsetLeft - speed + "px";
break;
case 38:
box.style.top = box.offsetTop - speed + "px";
break;
case 39:
box.style.left = box.offsetLeft + speed + "px";
break;
case 40:
box.style.top = box.offsetTop + speed + "px";
break;
}
},30)
var box = document.getElementById("box");
document.onkeydown = function (event) {
event = event || window.event;
var speed = 10;
if (event.ctrlKey) {
speed = 50;
}
dir =event.keyCode;
};
document.onkeyup =function (){
dir =0;
speed =10;
}
};
</script>
</head>
<body>
<div id="box"></div>
</body>
</html>
延迟调用:setTimeout()
延迟调用一个函数不马上执行,而是隔一段时间后再执行,而且只会执行一次
延迟调用和定时调用的区别:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>延迟调用</title>
<script>
window.onload =function (){
var num =1;
var timer =setTimeout(function (){
console.log(num++);
},5000)
//使用clearTimeout来关闭一个延迟调用,因为这里关闭了,使用1不会出来
clearTimeout(timer);
};
</script>
</head>
<body>
</body>
</html>
按钮移动div
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按钮移动div</title>
<style>
*{
margin: 0;
padding: 0;
}
#box {
height: 100px;
width: 100px;
background-color: red;
border: solid;
position: absolute;
left: 0;
}
</style>
<script>
window.onload = function () {
var box = document.getElementById("box");
var butt = document.getElementsByTagName("button")[0];
var timer;
butt.onclick = function () {
clearInterval(timer);
timer = setInterval(function () {
var oldValue = parseInt(getStyle(box, "left"));
var newValue = oldValue + 10;
if(newValue>1600){
newValue =1600;
}
box.style.left = newValue + "px";
if (newValue >= 1600) {
clearTimeout(timer)
}
}, 30)
};
};
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
}
</script>
</head>
<body>
<button>点击按钮向右移动</button>
<br/><br/>
<div id="box"></div>
<div id="line" style="border: 1px solid;height: 10000px;width: 0px;position: absolute;left: 1600px; top: 0px"></div>
</body>
</html>
按钮移动div·进阶
但是这个方法现在也是有安全隐患的,定时器的变量是全局变量,他们共用这个定时器,当你想两个事件同时进行的话,那便办不到,原因是你开启第二个事件的定时器时,第一个就被关闭了。
/**
* 参数:
* @param obj 要执行动画的对象
* @param target 执行动画的目标位置
* @param speed 移动的速度(正数向右移动,负数向左移动)
*/
function move(obj,target,speed){
clearInterval(timer);
var current =parseInt(getStyle(obj,"left"));
/*
判断速度的正负值
如果从0向1600移动,speed为正
如果从1600向0移动,则speed为负
*/
if(current>target){
//此时速度应为赋值
speed =-speed;
}
timer =setInterval(function () {
var oldValue =parseInt(getStyle(obj,"left"));
var newValue =oldValue+speed;
//向左移动时,需要判断newValue是否小于target
//向右移动时,需要判断newValue是否大于target
if(speed<0 && newValue<target || speed>0 && newValue>target){
newValue =target;
}
obj.style.left =newValue+"px";
if(newValue ==1600){
clearInterval(timer)
}
},30)
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按钮移动div·进阶</title>
<style>
*{
margin: 0;
padding: 0;
}
#box{
left: 0;
height:100px ;
width: 100px;
position: absolute;
border: solid;
background-color: red;
}
</style>
<script>
var timer;
window.onload =function () {
var butt1 =document.getElementsByTagName("button")[0];
var butt2 =document.getElementsByTagName("button")[1];
var box =document.getElementById("box");
butt1.onclick = function () {
move(box,800,10);
};
butt2.onclick =function (){
move(box,0,10);
};
};
/**
* 参数:
* @param obj 要执行动画的对象
* @param target 执行动画的目标位置
* @param speed 移动的速度(正数向右移动,负数向左移动)
*/
function move(obj,target,speed){
clearInterval(timer);
var current =parseInt(getStyle(obj,"left"));
/*
判断速度的正负值
如果从0向1600移动,speed为正
如果从1600向0移动,则speed为负
*/
if(current>target){
//此时速度应为赋值
speed =-speed;
}
timer =setInterval(function () {
var oldValue =parseInt(getStyle(obj,"left"));
var newValue =oldValue+speed;
//向左移动时,需要判断newValue是否小于target
//向右移动时,需要判断newValue是否大于target
if(speed<0 && newValue<target || speed>0 && newValue>target){
newValue =target;
}
obj.style.left =newValue+"px";
if(newValue ==1600){
clearInterval(timer)
}
},30)
}
function getStyle(obj,name) {
if(window.getComputedStyle){
return getComputedStyle(obj,null)[name];
}else {
return obj.currentStyle[name];
}
}
</script>
</head>
<body>
<button id="butt1">点击按钮向右移动</button>
<button id="butt2">点击按钮向左移动</button>
<br/><br/>
<div id="box"></div>
<div id="line" style="border: 1px solid;height: 10000px;width: 0px;position: absolute;left: 1600px; top: 0px"></div>
</body>
</html>
按钮变换div
这里的obj.timer避免了上处的安全隐患,且加入了回调函数,让此方法变得更加灵活,且将方向也作为形参传进去,让此方法适应性增强!
function getStyle(obj,name) {
if(window.getComputedStyle){
return getComputedStyle(obj,null)[name];
}else {
return obj.currentStyle[name];
}
}
/**
* 参数
* @param obj 要执行动画的对象
* @param dir 要执行动画的样式;比如:left top width height
* @param target 执行动画的目标位置
* @param speed 移动的速度
* @param callback 回调函数,这个函数将会再动画执行完毕以后执行
*/
function move(obj,dir,target,speed,callback){
//关闭上一个定时器
clearInterval(obj.timer);
var current =parseInt(getStyle(obj,dir));
if(current>target){
speed =-speed;
}
obj.timer =setInterval(function (){
var oldValue =parseInt(getStyle(obj,dir));
var newValue =oldValue+speed;
if(speed<0 && newValue<target ||speed>0 && newValue>target){
newValue =target;
}
obj.style[dir] =newValue +"px";
if(newValue ==target){
clearInterval(obj.timer);
callback && callback();
}
},30)
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按钮演播divtitle>
<style>
*{
margin: 0;
padding: 0;
}
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
left: 0;
border: solid;
}
#box2{
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 0;
top:300px;
border: solid;
}
style>
<script src="tool.js">script>
<script>
window.onload =function () {
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var butt1 = document.getElementById("butt1");
var butt2 = document.getElementById("butt2");
var butt3 = document.getElementById("butt3");
var butt4 = document.getElementById("butt4");
butt1.onclick = function () {
move(box1, "left", 1600, 20);
}
butt2.onclick = function () {
move(box1, "left", 0, 10);
}
butt3.onclick = function () {
move(box2, "left", 1600, 10);
}
butt4.onclick = function () {
move(box2, "width", 1600, 10, function () {
move(box2, "height", 800, 10, function () {
move(box2, "top", 0, 10, function () {
move(box2, "width", 100, 10, function () {
confirm("漂亮吧!");
});
});
});
});
};
};
script>
head>
<body>
<button id="butt1">点击按钮以后box1向右移动button>
<button id="butt2">点击按钮以后box1向左移动button>
<button id="butt3">点击按钮以后box2向右移动button>
<button id="butt4">测试按钮button>
<br /><br />
<div id="box1">div>
<div id="box2">div>
<div id="line" style="position: absolute;width: 0;height: 1600px;left: 1600px;border: solid;top:0">div>
body>
html>
目前,这个,我还不是很会!
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
/*
* 设置outer的样式
*/
#outer{
/*设置宽和高*/
width: 520px;
height: 333px;
/*居中*/
margin: 50px auto;
/*设置背景颜色*/
background-color: greenyellow;
/*设置padding*/
padding: 10px 0;
/*开启相对定位*/
position: relative;
/*裁剪溢出的内容*/
overflow: hidden;
}
/*设置imgList*/
#imgList{
/*去除项目符号*/
list-style: none;
/*设置ul的宽度*/
/*width: 2600px;*/
/*开启绝对定位*/
position: absolute;
/*设置偏移量*/
/*
* 每向左移动520px,就会显示到下一张图片
*/
left: 0px;
}
/*设置图片中的li*/
#imgList li{
/*设置浮动*/
float: left;
/*设置左右外边距*/
margin: 0 10px;
}
/*设置导航按钮*/
#navDiv{
/*开启绝对定位*/
position: absolute;
/*设置位置*/
bottom: 15px;
/*设置left值
outer宽度 520
navDiv宽度 25*5 = 125
520 - 125 = 395/2 = 197.5
* */
/*left: 197px;*/
}
#navDiv a{
/*设置超链接浮动*/
float: left;
/*设置超链接的宽和高*/
width: 15px;
height: 15px;
/*设置背景颜色*/
background-color: red;
/*设置左右外边距*/
margin: 0 5px;
/*设置透明*/
opacity: 0.5;
/*兼容IE8透明*/
filter: alpha(opacity=50);
}
/*设置鼠标移入的效果*/
#navDiv a:hover{
background-color: black;
}
style>
<script type="text/javascript" src="js/tools.js">script>
<script type="text/javascript">
window.onload = function(){
//获取imgList
var imgList = document.getElementById("imgList");
//获取页面中所有的img标签
var imgArr = document.getElementsByTagName("img");
//设置imgList的宽度
imgList.style.width = 520*imgArr.length+"px";
/*设置导航按钮居中*/
//获取navDiv
var navDiv = document.getElementById("navDiv");
//获取outer
var outer = document.getElementById("outer");
//设置navDiv的left值
navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth)/2 + "px";
//默认显示图片的索引
var index = 0;
//获取所有的a
var allA = document.getElementsByTagName("a");
//设置默认选中的效果
allA[index].style.backgroundColor = "black";
/*
点击超链接切换到指定的图片
点击第一个超链接,显示第一个图片
点击第二个超链接,显示第二个图片
* */
//为所有的超链接都绑定单击响应函数
for(var i=0; i<allA.length ; i++){
//为每一个超链接都添加一个num属性
allA[i].num = i;
//为超链接绑定单击响应函数
allA[i].onclick = function(){
//关闭自动切换的定时器
clearInterval(timer);
//获取点击超链接的索引,并将其设置为index
index = this.num;
//切换图片
/*
* 第一张 0 0
* 第二张 1 -520
* 第三张 2 -1040
*/
//imgList.style.left = -520*index + "px";
//设置选中的a
setA();
//使用move函数来切换图片
move(imgList , "left" , -520*index , 20 , function(){
//动画执行完毕,开启自动切换
autoChange();
});
};
}
//开启自动切换图片
autoChange();
//创建一个方法用来设置选中的a
function setA(){
//判断当前索引是否是最后一张图片
if(index >= imgArr.length - 1){
//则将index设置为0
index = 0;
//此时显示的最后一张图片,而最后一张图片和第一张是一摸一样
//通过CSS将最后一张切换成第一张
imgList.style.left = 0;
}
//遍历所有a,并将它们的背景颜色设置为红色
for(var i=0 ; i<allA.length ; i++){
allA[i].style.backgroundColor = "";
}
//将选中的a设置为黑色
allA[index].style.backgroundColor = "black";
};
//定义一个自动切换的定时器的标识
var timer;
//创建一个函数,用来开启自动切换图片
function autoChange(){
//开启一个定时器,用来定时去切换图片
timer = setInterval(function(){
//使索引自增
index++;
//判断index的值
index %= imgArr.length;
//执行动画,切换图片
move(imgList , "left" , -520*index , 20 , function(){
//修改导航按钮
setA();
});
},3000);
}
};
script>
head>
<body>
<div id="outer">
<ul id="imgList">
<li><img src="img/1.jpg"/>li>
<li><img src="img/2.jpg"/>li>
<li><img src="img/3.jpg"/>li>
<li><img src="img/4.jpg"/>li>
<li><img src="img/5.jpg"/>li>
<li><img src="img/1.jpg"/>li>
ul>
<div id="navDiv">
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
<a href="javascript:;">a>
div>
div>
body>
html>
类CSS修改
box.style.width ="300px";
通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面,这样的执行的性能是比较差,而且这种形式当我们要修改多个样式时,也不太方便
box.className += " b2";
我们可以通过修改元素的class属性来简介的修改样式,这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器渲染页面一次,性能比较好,并且这种方式,可以让表现和行为进一步分离。
方式三:提取方法
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
* 参数:
* obj 要添加class属性的元素
* cn 要添加的class值
*
*/
function addClass(obj , cn){
//检查obj中是否含有cn
if(!hasClass(obj , cn)){
obj.className += " "+cn;
}
}
/*
* 判断一个元素中是否含有指定的class属性值
* 如果有该class,则返回true,没有则返回false
*
*/
function hasClass(obj , cn){
//判断obj中有没有cn class
//创建一个正则表达式
//var reg = /\bb2\b/;
var reg = new RegExp("\\b"+cn+"\\b");
return reg.test(obj.className);
}
/*
* 删除一个元素中的指定的class属性
*/
function removeClass(obj , cn){
//创建一个正则表达式
var reg = new RegExp("\\b"+cn+"\\b");
//删除class
obj.className = obj.className.replace(reg , "");
}
/*
* toggleClass可以用来切换一个类
* 如果元素中具有该类,则删除
* 如果元素中没有该类,则添加
*/
function toggleClass(obj , cn){
//判断obj中是否含有cn
if(hasClass(obj , cn)){
//有,则删除
removeClass(obj , cn);
}else{
//没有,则添加
addClass(obj , cn);
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>类的操作title>
<style>
*{
margin: 0;
padding: 0;
}
.b1{
height: 100px;
width: 100px;
background-color: red;
border: solid;
}
.b2{
height: 300px;
width: 300px;
border: solid;
}
style>
<script>
window.onload =function () {
var box =document.getElementById("box");
var butt =document.getElementById("butt1");
box.className +=" b2";
butt.onclick =function (){
// box.style.width ="300px";
//方式二:
// box.className +=" b2";
// addClass(box,"b2");
// removeClass(box,"b2");
toggleClass(box,"b2");
};
};
function addClass(obj,cn){
if(!hasClass(obj,cn)){
obj.className += " "+cn;
}
}
function hasClass(obj,cn) {
var reg =new RegExp("\\b"+cn+"\\b");
return reg.test(obj.className);
}
function removeClass(obj,cn) {
var reg =new RegExp("\\b"+cn+"\\b");
obj.className =obj.className.replace(reg,"");
}
function toggleClass(obj,cn){
if(hasClass(obj,cn)){
removeClass(obj,cn)
}else {
addClass(obj,cn);
}
}
script>
head>
<body>
<button id="butt1">点击修改div的类button>
<br/><br/>
<div class="b1" id="box">div>
body>
html>
JS中的对象只有JS自己认识,其他的语言都不认识,JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON再开发中主要用来数据的交互
JSON
javaScript Object Notation JS 对象表示法
JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,不然就会报错!其他的和JS语法一致!
JSON中允许的值 |
---|
1.字符串 |
2.数 组 |
3.布尔值 |
4. null |
5.对 象 |
6.数 组 |
创建JSON对象
var arr ='[1,2,3,"hello",true]';
var obj2 ='{"arr":[1,2,3]}';
var obj ='[{"name":"李白","age":18,"gender":"男",{"name":"美美","age":18,"gender":"女"}]';
转换
将JSON字符串转换为JS中的对象,再JS中,为我们提供了一个工具类,就叫JSON,这个对象 可以帮助我们将JSON转换JS对象,也可以将一个JS对象转换为JSON
JSON.parse()
var obj ='[{"name":"李白","age":18,"gender":"男"},{"name":"美美","age":18,"gender":"女"}]';
var jsObj =JSON.parse(obj);
console.log(jsObj);
JSON.stringify()
var obj3 ={name:"李白",age:18,sex:"男"};
var str =JSON.stringify(obj3);
console.log(str);
值得注意的是:
JSON这个对象在IE7及以下的浏览器中不支持,所以再这些浏览器中调用时会报错。
eval()
eval()
执行的字符串中含有{}
,它会将{}
当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()eval()
这个函数的功能十分强大,可以直接执行一个字符串的JS代码,但是在开发中尽量不要使用,首先它的执行性能比较差,然后它害具有安全隐患。那要怎么去兼容IE7及以下的浏览器呢!
直接引进JSON文件!~
这是我看尚硅谷视频时所做的笔记,希望对大家有所帮助!谢谢!