JavaScript简介
概述
JavaScript负责页面中的的行为。
它是一门运行在浏览器端的脚本语言。
javascript和java的一些区别:
- javascript是一个解释性语言,java是编译解释性语言
- javascript是一个弱势语言,Java是一个强势语言
- 在页面上引入的方式不同javascript代表用
<script>
引入,Java代码<%>
- JS是基于对象,Java是面向对象。
JavaScript组成
1 | EcMAScript + BOM + DOM |
JavaScript与Html的结合方式
- Javascript与HTML的结合方式有三种:
- 可以编写到标签的指定属性中
- 可以编写到script标签中
- 通过标签将其引入
- script标签一旦用于引入外部文件了,就不能在编写代码了
- 即使编写了浏览器也会忽略 ,如果需要则可以在创建一个新的script标签用于编写内部代码
采用事件来调用,代码写在字符串中
1
2
3<button onclick = "alert('大家好')">点击</button>
<button onclick="alert('hello');">我是按钮</button>
<a href="javascript:alert('aaa');">超链接</a>- 采用定义函数的方式: 用function来定义函数
1
function fun(){ alert('你好')} ;
- 采用外部js文件,利用script引入
1
2
3
4
5
6// 可以将代码编写到外部的js文件中,然后通过标签将其引入
<script type="text/javascript" src="文件路径"></script>
<script type="text/javascript">
//编写js代码
</script>
基本语法
JS严格区分大小写
JS中每条语句以分号(
;
)结尾如果不写分号,浏览器会自动添加,但是会消耗一些系统资源而且有些时候,浏览器会加错分号,所以在开发中分号必须写
JS中会自动忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化。
输出语句
- 该语句会在浏览器窗口中弹出一个警告框
1 | alert("要输出的内容"); |
- 该内容将会被写到body标签中,并在页面中显示
1 | document.write("要输出的内容"); |
- 该内容会被写到开发者工具的控制台中
1 | console.log("要输出的内容"); |
函数声明
- js函数声明不需要
;
分号,但是赋值语句要加;
分号
1 | function functionName(arg0, arg1, arg2) { |
注释
- 单行注释
1 | //注释内容 |
- 多行注释
1 | /* |
字面量
字面量实际上就是一些固定的值,比如
1 2 3 4 true false null NaN "hello"
字面量都是不可以改变的。
由于字面量不是很方便使用,所以在JS中很少直接使用字面量
变量
变量可以用来保存字面量,并且可以保存任意的字面量
一般都是通过变量来使用字面量,而不直接使用字面量,而且也可以通过变量来对字面量进行一个描述
使用var关键字来声明一个变量
1
var a;
为变量赋值
1
a = 1;
声明和赋值同时进行
1
var a = 456;
标识符
在JS中所有的可以自主命名的内容,都可以认为是一个标识符,是标识符就应该遵守标识符的规范。
比如:变量名、函数名、属性名
规范:
- 标识符中可以含有
字母
、数字
、_
、$
- 标识符不能以数字开头
- 标识符不能是JS中的关键字和保留字
- 标识符一般采用驼峰命名法 :xxxYyyZzz
- 标识符中可以含有
六种数据类型
- JS中一共分成六种数据类型 5个基本数据类型+object,typeof运算符检查数据类型
数据类型 | 说明 |
---|---|
String | 字符串 |
Number | 数值 |
Boolean | 布尔值 |
Null | 空值 |
Undefined | 未定义 |
Object | 对象 |
String 字符串
JS中的字符串需要使用
引号
引起来,双引号或单引号都行, 在字符串中使用\
作为转义字符1
2
3
4
5\' ==> '
\" ==> "
\n ==> 换行
\t ==> 制表符
\\ ==> \使用
typeof
运算符检查字符串时,会返回"string"
Number 数值
JS中所有的整数和浮点数都是Number类型
最大能表示的值:
Number.MAX_VALUE =1.7976931348623157e+308
特殊的数字:能赋值给变量
- Infinity 正无穷
a = Infinity
,能赋值 - -Infinity 负无穷 NaN 非法数字(Not A Number)
- Infinity 正无穷
其他进制的数字的表示:
0b开头
表示二进制,但是不是所有的浏览器都支持0 开头
表示八进制0x 开头
表示十六进制
使用typeof检查一个Number类型的数据时,会返回”number” ,(包括NaN 和 Infinity)
Boolean 布尔值
- 布尔值主要用来进行逻辑判断,布尔值只有两个
true
逻辑的真false
逻辑的假
- 使用typeof检查一个布尔值时,会返回”boolean”
Null 空值
空值专门用来表示为空的对象,Null类型的值只有一个
null
使用typeof检查一个Null类型的值时会返回”object”
Undefined 未定义
如果声明一个变量但是没有为变量赋值此时变量的值就是undefined
该类型的值只有一个 undefined
使用typeof检查一个Undefined类型的值时,会返回”undefined”
引用数据类型
- Object 对象
类型转换
- 类型转换就是指将其他的数据类型,转换为String Number 或 Boolean
转换为String
强制类型转换:toString()方法
调用被转换数据的toString()方法
注意:这个方法不适用于null和undefined ,由于这两个类型的数据中没有方法,所以调用toString()时会报错
1
2var a = 123;
a = a.toString();
强制类型转换:String()函数
例子:
1
2var a = 123;
a = String(a);原理:
- 对于Number Boolean String都会调用他们的toString()方法来将其转换为字符串
- **对于null值,直接转换为字符串”null”**。
- 对于undefined直接转换为字符串”undefined”
隐式的类型转换
为任意的数据类型
+""
原理:和String()函数一样
例子:
1
2var a = true;
a = a + "";
转换为Number
强制类型转换:调用Number()函数
例子:
1
2var s = "123";
s = Number(s);
字符串 > 数字
- 如果字符串是一个合法的数字,则直接转换为对应的数字
- 如果字符串是一个非法的数字,则转换为NaN
- 如果是一个空串或纯空格的字符串,则转换为0
布尔值 > 数字
- true转换为1
- false转换为0
空值 > 数字
- null转换为0
未定义 > 数字
- undefined 转换为NaN
强制类型转换:parseXXX
调用
parseInt()
或parseFloat()
这两个函数专门用来将一个字符串转换为数字的
如果对非String使用parseInt()或parseFloat(),它会先将其转换为String然后在操作
parseInt()
可以将一个字符串中的有效的整数位提取出来,并转换为Number
例子:
1
2var a = "123.456px";
a = parseInt(a); //123如果需要可以在parseInt()中指定一个第二个参数可选。给解析的数字指定进制。该值介于 2 ~ 36 之间。
1
var result = parseInt("11", 2); //返回 3 (2+1);
parseFloat()可以将一个字符串中的有效的小数位提取出来,并转换为Number
1
2var a = "123.456px";
a = parseFloat(a); //123.456
隐式的类型转换:
使用一元的
+
来进行隐式的类型转换原理:和Number()函数一样
例子:
1
2var a = "123";
a = +a;
转换为布尔值
强制类型转换: 使用Boolean()函数
例子:
1
2var s = "false";
s = Boolean(s); //true
- 字符串 > 布尔
- 除了空串其余全是true
- 数值 > 布尔
- 除了0和NaN其余的全是true
- null、undefined > 布尔
- 都是false
- 对象 > 布尔
- 都是true
隐式类型转换
为任意的数据类型做两次非运算,即可将其转换为布尔值
例子:
1
2var a = "hello";
a = !!a; //true
运算符
- 运算符也称为操作符
- 通过运算符可以对一个或多个值进行运算或操作
typeof运算符
- 用来检查一个变量的数据类型
- 语法:
typeof 变量
- 它会返回一个用于描述类型的字符串作为结果
算数运算符
+
: 对两个值进行加法运算并返回结果-
: 对两个值进行减法运算并返回结果*
: 对两个值进行乘法运算并返回结果/
: 对两个值进行除法运算并返回结果%
: 对两个值进行取余运算并返回结果除了加法以外,对非Number类型的值进行运算时,都会先转换为Number然后在做运算。
而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。
任何值和字符串做加法,都会先转换为字符串,然后再拼串
一元运算符
- 一元运算符只需要一个操作数
一元的+
就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字
例子:
1
2var a = true;
a = +a;
一元的-
对于JS的减法运算,整体规则是当运算符两边的运算元不为Number时,通过ToNumber()把值转换成Number再计算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//Number(直接相减)
console.log(5 - 2); //3
console.log(1 - 3); //-2
//String(转化为Number后相减)
console.log(3 - "1"); //2
console.log("7" - 2); //5
console.log(2 - "7"); //-5
console.log("2" - 7); //-5
console.log("7" - "2"); //5
console.log("2" - "7"); //-5
console.log("abc" - 1); //NaN
//Boolean(转换后true为1,false为+0)
console.log(4 - true); //3
console.log(true - false); //1
//undefined(undefined转换后为NaN)
console.log(1 - undefined); //NaN
console.log(undefined - 1); //NaN
//Null(null转换后为+0)
console.log(1 - null); //1
console.log(null - 1); //-1Object类型
由于Object为复杂类型,做减法运算时,要先调用内置的valueOf()转化为Number类型后再做运算1
2
3
4
5
6
7
8//Object
console.log(1 - []); //1
console.log(1 - {}); //NaN
console.log({} - 1); //NaN
console.log([] - []); //0
console.log({} - {}); //NaN
console.log({} - []); //NaN
console.log([] - {}); //NaN一元运算
1
2
3
4console.log(-1); //-1
console.log(-[]); //-0
console.log(-{}); //NaN
console.log(-'1'); //-1
自增
- 自增可以使变量在原值的基础上自增1 ,自增可以使用 前++(++a)后++(a++)
- 无论是++a 还是 a++都会立即使原变量自增1
- 不同的是++a和a++的值是不同的,
++a
的值是变量的新值(自增后的值)a++
的值是变量的原值(自增前的值)
自减
- 自减可以使变量在原值的基础上自减1, 自减可以使用 前(–a)后(a–)
- 无论是a 还是 a都会立即使原变量自减1
- 不同的是a和a的值是不同的,
--a
的值是变量的新值(自减后的值)a--
的值是变量的原值(自减前的值)
~运算(按位取反)
- 规则
1 | result = ~ [数字] |
~
运算符查看表达式的二进制表示形式的值,并执行位非运算,表达式中的任何一位为 1,则结果中的该位变为 0。表达式中的任何一位为 0,则结果中的该位变为 1。
- 实例
1 | var temp = ~5; |
~【数字】,所以~运算符后面的类型要转换为Number。
1 | /** |
- 扩展~~
1 | console.log(~~true); //-1 |
~~运算在****的基础上再做一次操作
逻辑运算符
!
非运算可以对一个布尔值进行取反,true变false false边true- 当对非布尔值使用!时,会先将其转换为布尔值然后再取反
- 我们可以利用!来将其他的数据类型转换为布尔值
&&
可以对符号两侧的值进行与运算只有两端的值都为true时,才会返回true。只要有一个false就会返回false。
如果第一个值是false,则不再检查第二个值
对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
规则:
- 如果第一个值为false,则返回第一个值
- 2.如果第一个值为true,则返回第二个值
||
可以对符号两侧的值进行或运算- 只有两端都是false时,才会返回false。只要有一个true,就会返回true。
- 如果第一个值是true,则不再检查第二个值
- 对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
- 规则:
- 如果第一个值为true,则返回第一个值
- 如果第一个值为false,则返回第二个值
赋值运算符
=
可以将符号右侧的值赋值给左侧变量+=
1 | a += 5 相当于 a = a+5 |
-=
1 | a -= 5 相当于 a = a-5 |
*=
1 | a *= 5 相当于 a = a*5 |
/=
1 | a /= 5 相当于 a = a/5 |
%=
1 | a %= 5 相当于 a = a%5 |
关系运算符
关系运算符用来比较两个值之间的大小关系的 ,
- 如果关系成立则返回true,关系不成立则返回false。
- 如果比较的两个值是非数值,会将其转换为Number然后再比较。
- 如果比较的两个值都是字符串,此时会比较字符串的Unicode编码,而不会转换为Number。
=
<
<=
相等运算符
==
相等,判断左右两个值是否相等,如果相等返回true,如果不等返回false- 相等会自动对两个值进行类型转换,如果对不同的类型进行比较,会将其转换为相同的类型然后再比较,转换后相等它也会返回true,null == undifined
!=
不等,判断左右两个值是否不等,如果不等则返回true,如果相等则返回false- 不等也会做自动的类型转换。
===
全等,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换,如果两个值的类型不同,则直接返回false!==
不全等,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回true- 特殊的值: null和undefined
- 由于undefined衍生自null,所以null == undefined 会返回true。但是 null === undefined 会返回false。
- NaN不与任何值相等,包括它自身 NaN == NaN //false
- 判断一个值是否是NaN 使用isNaN()函数
三元运算符:
?
- 语法:
条件表达式?语句1:语句2;
- 执行流程:
- 先对条件表达式求值判断,
- 如果判断结果为true,则执行语句1,并返回执行结果
- 如果判断结果为false,则执行语句2,并返回执行结果
- 语法:
优先级
- 和数学中一样,JS中的运算符也是具有优先级的, 比如 先乘除 后加减 先与 后或
- 具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,
- 优先级越高的越优先计算,优先级相同的,从左往右计算。
- 优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。
下面的表将所有运算符按照优先级的不同从高(20)到低(1)排列。
流程控制语句
程序都是自上向下的顺序执行的, 通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序。
条件分支语句
if语句
语法一:
1 | if(条件表达式){ |
1 | 执行流程: |
语法二:
1 | if(条件表达式){ |
1 | 执行流程: |
语法三:
1 | if(条件表达式){ |
1 | 执行流程 |
switch语句
语法:
1 | switch(条件表达式){ |
1 | 执行流程: |
循环语句
通过循环语句可以反复执行某些语句多次
while循环
语法:
1 | while(条件表达式){ |
do…while循环
语法:
1 | do{ |
和while的区别
- while:先判断后执行
- do…while: 先执行后判断
- do…while可以确保循环体至少执行一次。
for循环
语法:
1 | for(①初始化表达式 ; ②条件表达式 ; ④更新表达式){ |
死循环
1 | while (true) {} |
对象(Object)
对象是JS中的引用数据类型 对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性
使用typeof检查一个对象时,会返回object
对象的分类
内建对象
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object….
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
宿主对象
- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
- 比如 BOM DOM
- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
自定义对象
- 由开发人员自己创建的对象
创建对象
方式一:
1 | var obj = new Object(); |
方式二:
1 | var obj = {}; |
向对象中添加属性
- 语法:
1 | 对象.属性名 = 属性值; |
读取对象中的属性
- 语法:
1 | 对象.属性名 |
删除对象中的属性
语法:
1 | delete 对象.属性名; |
方法(method)
可以将一个函数设置为一个对象的属性,当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。
调用的区别
- 对象.方法名();
- 函数名() 直接调用
遍历
使用in检查对象中是否含有指定属性
语法:
1
2
3
4"属性名" in 对象
如果在对象中含有该属性,则返回true
如果没有则返回false
循环遍历对象自身的和继承的可枚举属性(不含Symbol属性).1
2
3
4
5var obj = { 0: "a", 1: "b", 2: "c" };
for (var i in obj) {
console.log(i, ":", obj[i]);
}使用对象字面量,在创建对象时直接向对象中添加属性
语法:
1
2
3
4
5
6
7
8
9
10var obj = {
属性名: 属性值,
属性名: 属性值,
属性名: 属性值,
属性名: 属性值,
};
//遍历对象
for (var v in obj) {
document.write("property:name =" + v + "value=" + obj[v] + "<br/>");
}
基本数据类型和引用数据类型
基本数据类型
- 基本数据类型的数据,变量是直接保存的它的值。
- 变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
- 比较两个变量时,对于基本数据类型,比较的就是值,
- String
- Number
- Boolean
- Null
- Undefined
引用数据类型
- 引用数据类型的数据,变量是保存的对象的引用(内存地址)。
- 如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
- 对于引用数据类型比较的是地址,地址相同才相同
- Object
函数(Function)
函数也是一个对象,也具有普通对象的功能(能有属性)
函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码
使用typeof检查一个函数时会返回function
函数的定义有三种方式:
- 采用function关键字来定义
- 采用匿名的方式来定义
- 采用new Function()的方式(了解,不推荐)
创建函数
函数声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function 函数名([形参1,形参2...形参N]){
语句...
}
function fun(){
alert("大家好") ;
}
// 调用 fun() ;
var a = function(){
alert("我是匿名函数") ;
}
// a() ;
var b = new Function("x","y","z","alert(x+y+z)") ;
小括号中最后一个参数是函数体,之前所有的参数都是形参.
// b(3,4,5) ;函数表达式
1
2
3var 函数名 = function([形参1,形参2...形参N]){
语句...
};
调用函数
没有重载的概念
函数调用的时候参数可以传递多个,可以和函数定义的形参个数不符合
如果函数重名了,那么调用的时候一定是调用最后一个,与参数无关。
语法:
1 | 函数对象([实参1,实参2...实参N]); |
函数的劫持
改变函数本身的作用.改变javascript的预定义的函数预定义好的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<script type="text/javascript">
//函数劫持:改变javascript的预定义的函数预定义好的功能
window.alert = function(x){
document.write(x) ;
}
alert("abc") ;
/*var a = function(){
alert("1") ;
}
a = function(){
alert("2") ;
}*/ //不是函数劫持
</script>
立即执行函数
- 函数定义完,立即被调用,这种函数叫做立即执行函数 ,立即执行函数往往只会执行一次
1 | (function (a, b) { |
形参和实参
形参:形式参数
定义函数时,可以在()中定义一个或多个形参,形参之间使用
,
隔开定义形参就相当于在函数内声明了对应的变量但是并不赋值,
形参会在调用时才赋值。
实参:实际参数
- 调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
- 调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
- 如果实参的数量大于形参,多余实参将不会赋值,
- 如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined
返回值
- 就是函数执行的结果。使用
return
来设置函数的返回值。- 语法:
return 值;
该值就会成为函数的返回值,可以通过一个变量来接收返回值
- 语法:
- return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
- return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。
- 如果return后不跟值,或者是不写return则函数默认返回undefined。
break、continue和return
- break:退出循环
- continue:跳过当次循环
- return:退出函数
作用域
作用域简单来说就是一个变量的作用范围。
在JS中作用域分成两种:
全局作用域
- 直接在script标签中编写的代码都运行在全局作用域中
- 全局作用域在打开页面时创建,在页面关闭时销毁。
- 全局作用域中有一个全局对象window,window对象由浏览器提供,
- 可以在页面中直接使用,它代表的是整个的浏览器的窗口。
- 在全局作用域中创建的变量都会作为window对象的属性保存
- 在全局作用域中创建的函数都会作为window对象的方法保存
- 在全局作用域中创建的变量和函数可以在页面的任意位置访问。
- 在函数作用域中也可以访问到全局作用域的变量。
- 尽量不要在全局中创建变量
函数作用域
- 函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。
- 函数作用域在函数执行时创建,在函数执行结束时销毁。
- 在函数作用域中创建的变量,不能在全局中访问。
- 当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,
- 如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,
- 如果找到了则使用,找不到则继续向上找,最后没有null
变量的声明提前
在全局作用域中,使用var关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。
所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。
在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明, 如果没有使用var关键字声明变量,则变量会变成全局变量
函数的声明提前
在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建, 也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性, 在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。
全局(内置)函数
方法名 | 描述 |
---|---|
isNaN | 用来判断变量是否是数字类型的字符串 NaN: not a Number ,不是一个数字 返回TRUE不是数字 |
parseInt,parseFloat | 将字符串转换为整形的数据(浮点数) |
eval | 将字符串转换为js代码 a. 主要执行字符串,将结果转换为数字 b. 将json格式的字符串转换为json |
escape() | 编码 |
unescape() | 解码 |
encodeURI() | 对网址(URL)进行编码 |
decodeURI() | (): 对网址(URL)进行解码 |
1 | if(isNaN(a)){ |
对象的属性和方法
call(),apply()
这两个方法都是函数对象的方法需要通过函数对象来调用
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
不同的是call是直接传递函数的实参,而apply需要将实参封装到一个数组中传递
- call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面
obj.myFun.call(db,'成都', ... ,'string' )
。 - apply 的所有参数都必须放在一个数组里面传进去
obj.myFun.apply(db,['成都', ..., 'string' ])
。 - bind 返回是函数,调用方法的时候后面多加个 () ,除了返回是函数以外,它 的参数和 call 一样。
1
2
3
4obj.myFun.call(db,'成都','上海'); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.apply(db,['成都','上海']); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,'成都','上海')(); // 德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,['成都','上海'])(); // 德玛 年龄 99 来自 成都, 上海去往 undefined- call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面
arguments
arguments和this类似,都是函数中的隐含的参数
arguments是一个类数组元素,它用来封装函数执行过程中的实参
所以即使不定义形参,也可以通过arguments来使用实参
arguments中有一个属性callee表示当前执行的函数对象
1
2
3
4
5
6
7
8
9
10
11//callee能够打印其本身
function calleeDemo() {
alert(arguments.callee);
}
//用匿名函数实现的计算10的阶乘
//匿名函数,没有名子,无名可调。可以用arguments.callee来代替匿名的函数
(function (n) {
if (n > 1) return n * arguments.callee(n - 1);
return n;
})(10);
this(调用函数的那个对象)
我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。
使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。
this是函数的上下文对象,根据函数的调用方式不同会执向不同的对象
- 以函数的形式调用时,this是window
- 以方法的形式调用时,this是调用方法的对象
- 以构造函数的形式调用时,this是新建的那个对象
- 使用call和apply调用时,this是指定的那个对象
- 在全局作用域中this代表window
对象构造函数,toString
构造函数是专门用来创建对象的函数,一个构造函数我们也可以称为一个类。
通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例
通过同一个构造函数创建的对象,我们称为一类对象
构造函数就是一个普通的函数,只是他的调用方式不同,
- 如果直接调用,它就是一个普通函数
- 如果使用new来调用,则它就是一个构造函数 。
例子:
1 | function Person(name, age, gender) { |
实例检查
- 创建一个新的对象
- 将新的对象作为函数的上下文对象(this)
- 执行函数中的代码
- 将新建的对象返回
- instanceof 用来检查一个对象是否是一个类的实例
- 语法:
1 | 对象 instanceof 构造函数 |
toString方法
当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值
如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法
1 | //修改Person原型的toString |
原型(prototype)
创建一个函数以后,解析器都会默认在函数中添加一个属性prototype
- prototype属性指向的是一个对象,这个对象我们称为原型对象。
- 当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。
- 这个隐含的属性可以通过
对象.__proto
__来访问。
- 这个隐含的属性可以通过
原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。
我们可以将对象中共有的属性和方法统一添加到原型对象中, 这样我们只需要添加一次,就可以使所有的对象都可以使用。
当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,
- 如果在自身中找到了,则直接使用。
- 如果没有找到,则去原型对象中寻找,如果找到了则使用,
- 如果没有找到,则去原型的原型中寻找,依此类推。
- 直到找到Object的原型为止,Object的原型的原型为null,如果依然没有找到则返回undefined
hasOwnProperty()
- 这个方法可以用来检查对象自身中是否含有某个属性
- 语法:
对象.hasOwnProperty("属性名")
1 | function employee(name, job, born) { |
垃圾回收(GC)
- 就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
- 这些垃圾积攒过多以后,会导致程序运行的速度过慢,
- 所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
- 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
- 此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢, 所以这种垃圾必须进行清理。
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
- 我们不需要也不能进行垃圾回收的操作
- 我们需要做的只是要将不再使用的对象设置null即可
数组(Array)
typeof(数组名)
:得到的是object,数组也是一个对象,是一个用来存储数据的对象和Object类似,但是它的存储效率比普通对象要高- 数组中保存的内容我们称为元素
- 数组使用索引(index)来操作元素
- 索引指由0开始的整数
- 数组的长度可以随时改变
- javascript中数组的下标可以是任意对象。
与java中数组的差别
- 类型区别
- Java中数组是有类型的,意味着一旦类型确定,则数组中所有的数据都是同一种类型。
- javascript中数组时没有类型的,意味着数组中的数据可以存放任意类型 (不推荐,取出转换麻烦)
- 长度区别
- java中数组的长度一旦确定就不能再更改了
- javascript中数组的长度是可以变化的(扩大缩小都可以)
- 变长的两种办法 :
- 指定length属性的值
- 指定某个数组中元素的值
- 下标类型区别
- java中的数组的数据引用必须用下标引用,小标必须是整数.
- javascript中数组的数据引用可以用任意对象
创建数组
采用new的方式
采用中括号[]来定义
1
2
3
4
5var arr = new Array(); //定义一个数组arr,初始长度为0
var arr1 = new Array(4); //定义一个数组arr1,初始长度是4
var arr2 = new Array(1, 2, 3, 4, 5); //定义一个数组arr2,初始化数据是1,2,3,4,5
var arr3 = []; //定义了一个数组,里面是空的
var arr3 = [3, 2, 4, 5]; //定义了一个数组,同时初始化数据
默认不初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var arr = new Array(); //定义一个数组arr,初始长度为0
var arr1 = new Array(4); //定义一个数组arr1,初始长度是4
arr1[0] = 1;
arr1[1] = 10;
alert(arr1[2]); //弹出来undefined,没有初始化
alert(arr1[100]); //相当于定义了一个变量arr1[100],没有赋值*/
//-----------------------
var arr3 = []; //定义了一个数组,里面是空的
var arr3 = [3, 2, 4, 5]; //定义了一个数组,同时初始化数据
//改变数组的的长度
alert(arr4.length);
//arr4.length = 100 ; //将数组的长度变为100
//alert(arr4.length) ;
//arr4[100] = 100 ; //将数组的长度变为101
//alert(arr4.length) ;
arr4.length = 2; //将数组的长度变为2,多于的数据将消失了
//alert(arr4[2]) ; //弹不出原来的数据了,弹出来undefined
//--数组下标的访问------------------
var arr5 = ["中国", "美国", "日本"];
arr5["中国"] = ["北京", "上海", "天津"];
alert(arr5["中国"][0]); //北京
获取和修改数组的长度
使用length属性来操作数组的长度
获取长度:
数组.length
- length获取到的是数组的最大索引+1
- 对于连续的数组,length获取到的就是数组中元素的个数
修改数组的长度:
数组.length = 新长度
- 如果修改后的length大于原长度,则多出的部分会空出来
- 如果修改后的length小于原长度,则原数组中多出的元素会被删除
向数组的最后添加元素 :
数组[数组.length] = 值;
数组的方法
添加,删除,
functionName | function |
---|---|
push() | 用来向数组的末尾添加一个或多个元素,并返回数组新的长度 |
pop() | 用来删除数组的最后一个元素,并返回被删除的元素 |
unshift() | 向数组的开头添加一个或多个元素,并返回数组的新的长度 |
shift() | 删除数组的开头的一个元素,并返回被删除的元素 |
reverse() | 可以用来反转一个数组,它会对原数组产生影响 |
concat() | 可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回 |
join() | 把数组的所有元素放入一个字符串. 默认用逗号连接 |
sort() | 排序 .默认同类型的数据相比较. |
截取 slice(sart,[end])
可以从一个数组中截取指定的元素
该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回
参数:
1.截取开始位置的索引(包括开始位置)
2.截取结束位置的索引(不包括结束位置)
第二个参数可以省略不写,如果不写则一直截取到最后
参数可以传递一个负值,如果是负值,则从后往前数
删除指定元素splice()
可以用来删除数组中指定元素,并使用新的元素替换
该方法会将删除的元素封装到新数组中返回
参数:
1.删除开始位置的索引
2.删除的个数
3.三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边
join([splitor]) 拼接为字符串
1 | 可以将一个数组转换为一个字符串 |
sort()
可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序
调用以后,会直接修改原数组。
V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。
可以自己指定排序的规则,需要一个回调函数作为参数:
我们可以在sort()添加一个回调函数,来指定排序规则,
回调函数中需要定义两个形参,
浏览器将会分别使用数组中的元素作为实参去调用回调函数
使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边
浏览器会根据回调函数的返回值来决定元素的顺序,
- 如果返回一个大于0的值,则元素会交换位置
- 如果返回一个小于0的值,则元素位置不变
- 如果返回一个0,则认为两个元素相等,也不交换位置
如果需要升序排列,则返回 a-b
如果需要降序排列,则返回b-a
指定排序的规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function(a,b){
//升序排列
//return a-b;
//降序排列
return b-a;
}
var students = [
{age: 18, name: "tom"},
{age: 20, name: "jack"},
{age: 19, name: "bob"}
]
students.sort(
(a, b) => {
return (a.name < b.name) ? -1 : (a.name > b.name) ? 1 : 0
}
)封装成方法
1
2
3
4
5
6
7
8
9// 统一封装
const sortBy = (key) => {
return (a, b) => {
var result = a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0;
return result;
};
};
students.sort(sortBy("name"));
数组遍历
遍历数组就是将数组中元素都获取到
一般情况我们都是使用for循环来遍历数组
1 | for (var i = 0; i < 数组.length; i++) { |
- 使用forEach()方法来遍历数组(不兼容IE8)
1 | 数组.forEach(function (value, index, obj) {}); |
forEach()方法需要一个回调函数作为参数,
数组中有几个元素,回调函数就会被调用几次,
每次调用时,都会将遍历到的信息以实参的形式传递进来,
我们可以定义形参来获取这些信息。
- value:正在遍历的元素
- index:正在遍历元素的索引
- obj:被遍历对象
包装类
JS中为我们提供了三个包装类:String() Boolean() Number()
通过这三个包装类可以创建基本数据类型的对象
例子:
1
2
3var num = new Number(2);
var str = new String("hello");
var bool = new Boolean(true);但是在实际应用中千万不要这么干。 当我们去操作一个基本数据类型的属性和方法时,解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,操作完成以后再将这个临时对象进行销毁。
Date对象
日期的对象,在JS中通过Date对象来表示一个时间
创建对象
1
2
3
4// 创建一个当前的时间对象
var d = new Date();
// 创建一个指定的时间对象
var d = new Date("月/日/年 时:分:秒");
方法
name | |
---|---|
getDate() | 当前日期对象是几日(1-31) |
getDay() | 返回当前日期对象时周几(0-6) 0 周日 1 周一 |
getMonth() | 返回当前日期对象的月份(0-11) 0 一月 1 二月 。。。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getTime() | 返回当前日期对象的时间戳 时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数 计算机底层保存时间都是以时间戳的形式保存的。 |
Date.now() | 可以获取当前代码执行时的时间戳 |
示例
1
2
3
4
5
6
7
8
9
10
11var d = new Date();
alert(d.toLocaleString()); //转换为11
alert(d.getYear()); //返回的是 "当前年份-1900" 的值(即年份基数是1900)
alert(d.getFullYear()); //获取正确的4位年份
alert(d.getMonth()); //月:0-11
alert(d.getDate()); //天
alert(d.getDay()); //0-6;星期天位0
alert(d.getHours());
0 - 23;
alert(d.getMinutes());
alert(d.getSeconds());
Math对象
- Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法
- 我们可以直接使用它来进行数学运算相关的操作
方法:
方法 | |
---|---|
Math.PI | 常量,圆周率 |
Math.abs() | 绝对值运算 |
Math.ceil() | 向上取整 |
Math.floor() | 向下取整 |
Math.round() | 四舍五入取整 |
Math.random() | 生成一个0-1之间的随机数(可以等于0,永远不能取得1) |
生成一个xy之间的随机数 | Math.round(Math.random()*(y-x)+x); |
Math.pow(x,y) | 求x的y次幂 |
Math.sqrt() | 对一个数进行开方 |
Math.max(x,y) | 求多个数中最大值 |
Math.min(x,y) | 求多个数中的最小值 |
1 | var a = 3.1; |
String对象
属性:length
查看字符串的长度
方法
方法名 | 描述 |
---|---|
charAt() | 根据索引获取指定的字符 |
charCodeAt() | 根据索引获取指定的字符编码 |
String.fromCharCode() | 根据字符编码获取字符 |
indexOf(str,start) | indexOf()是从前向后找,返回其第一次出现的索引 如果没有找到则返回-1。 第二个参数,来表示开始查找的位置 |
lastIndexOf() | lastIndexOf()是从后向前找 |
slice(start,[end]) | 可以从一个字符串中截取指定位置[star,end)的内容,并将截取到内容返回,不会影响原变量。 可以省略第二个参数,如果省略则一直截取到最后 可以传负数,如果是负数则从后往前数 |
substr(start,nums) | 和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量 |
substring() | 和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0,substring()中如果第二个参数小于第一个,自动调整位置 |
split() | 切割字符串 |
toLowerCase() | 将字符串转换为小写并返回 |
toUpperCase() | 将字符串转换为大写并返回 |
fontcolor() | 使用指定的颜色显示字符串 |
fontsize() | 设置字符串显示大小 |
link(): | 将字符串显示为超链接 |
big() | 字体变大 |
bold() | 字体变粗(一次) |
1 | var s = "abcdefg"; |
ES6中的字符串新方法
判断当前字符串中是否包含给定的字符串,返回布尔值。
String.prototype.includes(str)
1
2let str = "hello world";
console.log(str.include("hello")); // true判断浏览器类型。
1
2
3if (navigator.userAgent.includes("Chrome")) {
alert("这是Chrome浏览器!");
} else alert("这不是Chrome浏览器!");
判断当前字符串是否以给定字符串开头 / 结尾,返回布尔值。
String.prototype.startsWith(xxx) / String.prototype.endsWith()
1
2
3let str = "hello world";
console.log(str.startsWith("hello"));
console.log(str.endsWith("world"));检测地址、检测上传的文件是否以xxx结尾。
以指定的次数复制当前字符串,并返回一个新的字符串。
String.prototype.repeat(次数)
1
2let str = "mm and gg";
console.log(str.repeat(3)); // 'mm and ggmm and ggmm and gg'
填充字符串,可以输入两个参数,第一个参数是前后填充的字符总数,第二个参数是用来填充的字符串。
String.prototype.padStart(maxLength, fillString='')
String.prototype.padEnd(maxLength, fillString='')
;1
2
3
4let str = "hello";
console.log(str.padStrat(10, "world")); // 'worldhello'
let pad = "mmgg";
console.log(str.padEnd(str.length + pad.length, pad)); // 'mmgghello'
正则表达式
- 正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,
- 也可以将一个字符串中符合规则的内容提取出来。
创建正则表达式
- RegExp 对象正则表达式对象
- 注意:使用构造函数时,由于它的参数是一个字符串,而
\
是字符串中转义字符,如果要使用\
则需要使用\\
来代替
1 | var reg = new RegExp("正则","匹配模式"); |
匹配模式
- i:忽略大小写(ignore)
- g:全局匹配模式(默认为1次)
- 设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求
正则语法
| 或
[]
或[^ ]
除了[x-y]
x的ascii到y的ascii码之间的值[a-z]
小写字母 (也可以[e-i])[A-Z]
大写字母[A-z]
任意字母,但是还包括了其他ASCII在此之中的[0-9]
任意数字
元符号
检查一个字符串中是否含有 .
, .
表示任意字符 , 在正则表达式中使用\
作为转义字符
\.
:来表示.
\\
:表示\
\w
:任意字母、数字、_[A-z0-9_]
\W
:除了字母、数字、_[ ^A-z0-9_]
\d
:任意的数字[0-9]
\D
:除了数字[ ^0-9]
\s
:空格\S
:除了空格\b
:单词边界\B
:除了单词边界
量词
通过量词可以设置一个内容出现的次数 ,量词只对它前边的一个内容起作用
{n}
正好出现n次{m,n}
出现mn次{m,}
m次以上+
:至少一个,相当于{1,}
*
:0个或多个,相当于{0,}
?
:0个或1个,相当于{0,1}
边界表达式
(不要在java中用,javaScript中用)
^
:正则开始$
:正则结束 :注意结束前一个才是结束匹配
1 | reg = /^a/; //以a开头 |
方法
split()
- 可以根据指定内容将一个字符串拆分为一个数组
- 参数:
- 需要一个字符串作为参数,将会根据字符串去拆分数组
- 可以接收一个正则表达式,此时会根据正则表达式去拆分数组
match()
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
- 我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
可以为一个正则表达式设置多个匹配模式,且顺序无所谓
非全局查找时:返回一个集合:[匹配子项,index,input,groups]
1 | let str = "曹操草草的收拾了屋子,去操场约会去咯"; |
全局查找‘g’时:返回所有匹配的子项,会将匹配到的内容封装到一个数组Array 中返回
1
2
3
4
5let str = "曹操草草的收拾了屋子,去操场约会去咯";
let result = "结果他被放鸽子了";
let reg = /[草|操]/g;
str.match(reg); // ["操", "草", "草", "操"]
result.match(reg); // null
replace()
可以将字符串中指定内容替换为新的内容
默认只会替换第一个
参数:
- 被替换的内容,可以接受一个正则表达式作为参数
- 新的内容,空串则为删除””
1
2
3
4
5let str = "曹操草草的收拾了屋子,去操场约会去咯";
let result = "结果他被放鸽子了";
let reg = /[草|操]/g;
str.replace(reg, "*"); // "曹***的收拾了屋子,去*场约会去咯"
result.replace(reg, "*"); // "结果他被放鸽子了"
search()
- 可以搜索字符串中是否含有指定内容
- 如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回1
- 它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
- serach()只会查找第一个,即使设置全局匹配也没用
1 | let str = "曹操草草的收拾了屋子,去操场约会去咯"; |
test()
- 可以用来检查一个字符串是否符合正则表达式
- 如果符合返回true,否则返回false
- 例子:去掉两端的空格:
1 | let str = "曹操草草的收拾了屋子,去操场约会去咯"; |
exec方法
全局匹配时 reg.exec(str) 会依次匹配子项,直到匹配完成
1
2
3
4
5
6
7
8let str = "曹操草草的收拾了屋子,去操场约会去咯";
let result = "结果他被放鸽子了";
let reg = /[草|操]/g; // 全局匹配
console.log(reg.exec(str)); // ["操", index: 1, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)); // ["草", index: 2, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)); // ["草", index: 3, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)); // ["操", index: 12, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)); // null非全局匹配:
1
2
3
4
5
6
7
8
9let str = "曹操草草的收拾了屋子,去操场约会去咯"
let result = "结果他被放鸽子了"
let reg = /[草|操]/ // 非全局匹配
console.log(reg.exec(str)) // ["操", index: 1, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)) // ["操", index: 1, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)) // ["操", index: 1, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
console.log(reg.exec(str)) // ["操", index: 1, input: "曹操草草的收拾了屋子,去操场约会去咯", groups: undefined]
} // -作用域-
常用的正则验证
1 | // 是否带有小数 |
DOM
- 文档对象模型(Document Object Model),通过DOM可以来任意来修改网页中各个内容
说明 | |
---|---|
文档 | 文档指的是网页,一个网页就是一个文档 |
对象 | 对象指将网页中的每一个节点都转换为对象,转换完对象以后,就可以以一种纯面向对象的形式来操作网页了 |
模型 | 模型用来表示节点和节点之间的关系,方便操作页面 |
节点(Node) | 节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点,虽然都是节点,但是节点的类型却是不同的 |
常用的节点
- 文档节点 (Document),代表整个网页
- 元素节点(Element),代表网页中的标签
- 属性节点(Attribute),代表标签中的属性
- 文本节点(Text),代表网页中的文本内容
document查询
在网页中浏览器已经为我们提供了document对象,
它代表的是整个网页,它是window对象的属性,可以在页面中直接使用 。
根据元素的id属性查询一个元素节点对象:
document.getElementById("id属性值");
根据元素的name属性值查询一组元素节点对象:
document.getElementsByName("name属性值");
根据标签名来查询一组元素节点对象:
document.getElementsByTagName("标签名");
元素节点来查询
通过标签名查询当前元素的指定后代元素
元素.getElementsByTagName()
元素.childNodes
- 获取当前元素的所有子节点
- 子节点包括便签元素中的文本,子元素自包含标签元素
childNodes属性会获取包括文本节点在内的所有节点
- DOM标签标签间空白也会当成文本节点
- 注意:在IE8及以下的浏览器中,不会将空白文本当成子节点
元素.children
获取当前元素的所有子元素
元素.firstChild
获取当前元素的第一个子节点,会获取到空白的文本子节点
元素.lastChild
获取当前元素的最后一个子节点
元素.parentNode
获取当前元素的父元素
元素.previousSibling
获取当前元素的前一个兄弟节点
previousElementSibling
- 获取前一个兄弟元素,IE8及以下不支持
元素.nextSibling
获取当前元素的后一个兄弟节点
firstElementChild
- 获取当前元素的第一个子元素
firstElementChild不支持IE8及以下的浏览器,
innerHTML和innerText
- 这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性
- 两个属性作用类似,都可以获取到标签内部的内容,
- 不同是innerHTML会获取到html标签,而innerText会自动去除标签
innerHTML必须是有开始标签和结束标签的标签对象才能使用
- 如果使用这两个属性来设置标签内部的内容时,没有任何区别的
读取标签内部的文本内容
1
2</h1>h1中的文本内容</h1>
元素.firstChild.nodeValue
读取元素的属性
语法:
元素.属性名
例子:
1
2
3
4
5ele.name;
ele.id;
ele.value;
//注意:读取class属性时需要使用
元素.className;
修改元素的属性
语法:
元素.属性名 = 属性值
使用
innerHTML
可以获取或设置元素内部的HTML代码
DOM的加载顺序
浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。 如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,此时将会无法正常获取到DOM对象,导致DOM操作失败。
解决方式一: 可以将js代码编写到body的下边
1
2
3
4
5
6
7<body>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById("btn"); btn.onclick = function(){};
</script>
</body>解决方式二:将js代码编写到
window.onload = function(){}
中window.onload
对应的回调函数会在整个页面加载完毕以后才执行所以可以确保代码执行时,DOM对象已经加载完毕了
1
2
3
4
5
6
7<script>
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
};
};
</script>
document对象的属性和方法
document.all
获取页面中的所有元素,相当于document.getElementsByTagName(“*“);
document.documentElement
获取页面中html根元素
document.body
获取页面中的body元素
document.getElementsByClassName()
- 根据元素的class属性值查询一组元素节点对象
这个方法不支持IE8及以下的浏览器
document.querySelector()
- 根据CSS选择器去页面中查询一个元素
如果匹配到的元素有多个,则它会返回查询到的第一个元素
document.querySelectorAll()
- 根据CSS选择器去页面中查询一组元素
- 会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个
DOM修改
document.createElement("TagName")
- 可以用于创建一个元素节点对象,- 它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,
- 并将创建好的对象作为返回值返回
document.createTextNode("textContent")
- 可以根据文本内容创建一个文本节点对象
父节点.appendChild(子节点)
- 向父节点中添加指定的子节点
父节点.insertBefore(新节点,旧节点)
- 将一个新的节点插入到旧节点的前边
父节点.replaceChild(新节点,旧节点)
- 使用一个新的节点去替换旧节点
父节点.removeChild(子节点)
- 删除指定的子节点
- 推荐方式:
子节点.parentNode.removeChild(子节点)
以上方法,实际就是改变了相应元素(标签)的innerHTML的值。
1 | myClick("btn07", function () { |
DOM对CSS的操作
读取和修改内联样式
使用style属性来操作元素的内联样式
读取内联样式:
元素.style.样式名
元素.style.width
元素.style.height
注意:如果样式名中带有-,则需要将样式名修改为驼峰命名法将-去掉,然后后的字母改大写
background-color > backgroundColor
border-width > borderWidth
修改内联样式:
语法:
元素.style.样式名 = 样式值
通过style修改和读取的样式都是内联样式,由于内联样式的优先级比较高,
所以我们通过JS来修改的样式,往往会立即生效,
但是如果样式中设置了!important,则内联样式将不会生效。
读取元素的当前样式
正常浏览器 使用getComputedStyle()
- 这个方法是window对象的方法,可以返回一个对象
- 这个对象中保存着当前元素生效样式 通过该方法读取到样式都是只读的不能修改
参数:
要获取样式的元素
可以传递一个伪元素,一般传null
1
2//获取元素的宽度
getComputedStyle(box, null)["width"];
IE8 :使用
currentStyle
,通过这个属性读取到的样式是只读的不能修改语法:
元素.currentStyle.样式名
1
box.currentStyle["width"];
实现兼容性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/*
* 定义一个函数,用来获取指定元素的当前的样式
* 参数:
* obj 要获取样式的元素
* name 要获取的样式名
*/
function getStyle(obj, name) {
//对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错
if (window.getComputedStyle) {
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
//return window.getComputedStyle?getComputedStyle(obj , null)[name]:obj.currentStyle[name];
}
其他的样式相关的属性
- 注意:以下样式都是只读的,未指明偏移量都是相对于当前窗口左上角
属性 | 说明 |
---|---|
clientHeight | 元素的可见高度,包括元素的内容区和内边距的高度 |
clientWidth | 元素的可见宽度,包括元素的内容区和内边距的宽度 |
offsetHeight | 整个元素的高度,包括内容区、内边距、边框 |
offfsetWidth | 整个元素的宽度,包括内容区、内边距、边框 |
offsetParent | 当前元素的定位父元素,离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body, 当前元素和定位父元素之间的偏移量 |
offsetLeft | offsetLeft水平偏移量 |
offsetTop | offsetTop垂直偏移量 |
scrollHeight | 获取元素滚动区域的高度 |
scrollWidth | 获取元素滚动区域的宽度 |
scrollTop | 获取元素垂直滚动条滚动的距离 |
scrollLeft | 获取元素水平滚动条滚动的距离 |
判断滚动条是否滚动到底
- 垂直滚动条
scrollHeight -scrollTop = clientHeight
- 垂直滚动条
水平滚动
scrollWidth -scrollLeft = clientWidth
案例
标题栏的滚动
1 | <body onload="init()"> |
字体变变变
1 | function fun(){ |
字体颜色随机变换
1 | var arr = ["red","blue","green","yellow","#666666"] ; |
js修改CSS样式
对象.style,css样式有- 的,需要将-去掉,大写后面的第一个
1
2
3
4
5
6
7
8
9function fun() {
//拿到p标签对象
var p = document.getElementById("p");
//定义p的样式
//p.style.color = "red" ;
//p.style.border = "5px dashed green" ;
p.style.backgroundColor = "red";
}写一个css,类选择器(推荐)
1
2
3
4
5
6
7
8
9
10
11
12<style type="text/css">
.one{
color:red ;
border:6px solid green ;
cursor:hand;
}
</style>
//拿到p标签对象
var p = document.getElementById("p") ;
p.className = "one" ;//对象会应用选择器的样式
p.className = "" / "none"; //取消样式
定义方法修改元素的css
通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。 这样的执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便 我希望一行代码,可以同时修改多个样式
我们可以通过修改元素的class属性来间接的修改样式.这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好,并且这种方式,可以使表现和行为进一步的分离
1 | box.className += " b2"; //注意有空格,添加class属性 |
1 | //定义一个函数,用来向一个元素中添加指定的class属性值 |
省市联动
1 | <script> |
事件(Event)
- 事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。
- 我们可以为事件来绑定回调函数来响应事件。
绑定事件
可以在标签的事件属性中设置相应的JS代码
1
<button onclick="js代码。。。">按钮</button>
可以通过为对象的指定事件属性设置回调函数的形式来处理事件
1
2
3
4
5
6
7<button id="btn">按钮</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
};
</script>
事件对象
当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。
可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有做完实参传递,而是作为window对象的属性保存
例子:
1
2
3
4
5
6
7
8
9元素.事件 = function (event) {
// var e=event?event||window.event;
// 实现浏览器兼容
event = event || window.event;
};
元素.事件 = function (e) {
e = e || event;
};Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
鼠标移动事件
- onmousemove(event) : 鼠标移动事件 event是事件对象。名字固定
- onmouseover : 鼠标悬停事件
- onmouseout : 鼠标移出事件
鼠标点击事件
- onclick
img, 和widows加载与卸载事件
- onload ,onunload
聚焦与离焦事件
onfocus, onblur
focus():获得焦点
1
2
3
4
5
6
7
8
9
10
11
12
13function fun(obj) {
obj.style.border = "1px solid red ";
obj.style.backgroundColor = "#ff66ff";
obj.style.color = "green";
}
function fun1(obj) {
if (obj.value == "") {
alert("内容不得为空");
//obj.focus() ; //获得焦点
}
}
<input type="text" name="" onfocus = "fun(this)" onblur = "fun1(this)" />
键盘事件
onkeypress,onkeyup,onkeydown
1
2
3
4
5
6
7function fun(obj,e){
//拿到按键的asc码
obj.value = e.keyCode ;
}
<input type="text" name="" onkeypress = "fun(this,event)">
提交与重置事件
位置:form表单的
<form>
标签内,必须要return语句- onsubmit,onreset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function check(form){
//拿到文本框中的内容
var txt = form.username.value ;
//判断内容
if(txt == ""){
document.getElementById("sname").innerHTML = " <font color = red>* 姓名必须填写</font>" ;
form.username.focus() ;
return false;
}
return true ;
}
function fun(form){
alert("重置事件") ;
return true ;
}
<form method="post" action="01-鼠标的单击事件.html" onsubmit = "return check(this)" onreset = "return fun(this)">
姓名:<input type="text" name="username"><span id = "sname"></span><br>
<input type="submit" value = "提交">
<input type="reset" value = "重置">
</form>
选择与改变事件
onselect = "fun(this)"
onchange = "fun1(this.value)"
文本框: 内容发生改变,失去焦点
下拉框: 下标发生改变
onchange = "fun2(this.value,this.selectedIndex)"
- 多行文本框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function fun(obj){
alert(obj.value) ;
}
function fun1(v){
alert(v) ;
}
function fun2(v,index){
alert(v + ":" + index) ;
}
<input type="text" name="" onselect = "fun(this)" onchange = "fun1(this.value)" >
<select onchange = "fun2(this.value,this.selectedIndex)">
<option value = "china">中国</option>
<option value = "america"> 美国</option>
<option value = "japan">日本</option>
</select>
事件的冒泡(Bubble)
事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。
事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消
可以将事件对象的cancelBubble设置为true,即可取消冒泡
例子:
1
2
3
4元素.事件 = function (event) {
event = event || window.event;
event.cancelBubble = true;
};
事件的委派
指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的 我们可以尝试将其绑定给元素的共同的祖先元素
target : event中的target表示的触发事件的对象 ,使用它对触发事件的元素进行判断
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36<head>
<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 = "<a href='javascript:;' class='link'>新建的超链接</a>";
//将li添加到ul中
u1.appendChild(li);
};
//获取所有的a
var allA = document.getElementsByTagName("a");
//为ul绑定一个单击响应函数
u1.onclick = function (event) {
event = event || window.event;
//如果触发事件的对象是我们期望的元素,则执行否则不执行
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>
事件的绑定
addEventListener()
: 通过这个方法也可以为元素绑定响应函数参数:
- 事件的字符串,不要on
- 回调函数,当事件触发时该函数会被调用
- 是否在捕获阶段触发事件,需要一个布尔值,一般都传false
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,
这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
这个方法不支持IE8及以下的浏览器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15btn01.addEventListener(
"click",
function () {
alert(1);
},
false,
);
btn01.addEventListener(
"click",
function () {
alert(2);
},
false,
);attachEvent()
在IE8中可以使用attachEvent()来绑定事件 ,这个方法也可以同时为一个事件绑定多个处理函数, 不同的是它是后绑定先执行,执行顺序和addEventListener()相反参数:
- 事件的字符串,要on
- 回调函数
1
2
3
4
5
6
7btn01.attachEvent("onclick", function () {
alert(1);
});
btn01.attachEvent("onclick", function () {
alert(2);
});兼容性:定义一个函数,用来为指定元素绑定响应函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27/*
* addEventListener()中的this,是绑定事件的对象
* attachEvent()中的this,是window
* 需要统一两个方法this
*/
/*
* 参数:
* obj 要绑定事件的对象
* eventStr 事件的字符串(不要on)
* 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
- 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
IE8及以下的浏览器中没有捕获阶段
事件句柄 (Event Handlers)
属性 | 此事件发生在何时… |
---|---|
onabort | 图像的加载被中断。 |
onblur | 元素失去焦点。 |
onchange | 域的内容被改变。 |
onclick | 当用户点击某个对象时调用的事件句柄。 |
ondblclick | 当用户双击某个对象时调用的事件句柄。 |
onerror | 在加载文档或图像时发生错误。 |
onfocus | 元素获得焦点。 |
onkeydown | 某个键盘按键被按下。 |
onkeypress | 某个键盘按键被按下并松开。 |
onkeyup | 某个键盘按键被松开。 |
onload | 一张页面或一幅图像完成加载。 |
onmousedown | 鼠标按钮被按下。 |
onmousemove | 鼠标被移动。 |
onmouseout | 鼠标从某元素移开。 |
onmouseover | 鼠标移到某元素之上。 |
onmouseup | 鼠标按键被松开。 |
onreset | 重置按钮被点击。 |
onresize | 窗口或框架被重新调整大小。 |
onselect | 文本被选中。 |
onsubmit | 确认按钮被点击。 |
onunload | 用户退出页面。 |
鼠标 / 键盘属性
属性 | 描述 |
---|---|
altKey | 返回当事件被触发时,”ALT” 是否被按下。 |
button | 返回当事件被触发时,哪个鼠标按钮被点击。 |
clientX | 返回当事件被触发时,鼠标指针的水平坐标。 |
clientY | 返回当事件被触发时,鼠标指针的垂直坐标。 |
ctrlKey | 返回当事件被触发时,”CTRL” 键是否被按下。 |
metaKey | 返回当事件被触发时,”meta” 键是否被按下。 |
relatedTarget | 返回与事件的目标节点相关的节点。 |
screenX | 返回当个某事件被触发时,鼠标指针的水平坐标。 |
screenY | 返回当个某事件被触发时,鼠标指针的垂直坐标。 |
shiftKey | 返回当事件被触发时,”Shift” 键是否被按下。 |
拖拽事件
鼠标事件 :获取到鼠标的坐标
clientX
和clientY
- 用于获取鼠标在当前的可见窗口的坐标
- div的偏移量,是相对于整个页面的
pageX
和pageY
可以获取鼠标相对于当前页面的坐标- 但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用
var left = event.clientX;
var top = event.clientY;
页面定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<head>
<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>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
</body>监听拖拽
- 当鼠标在被拖拽元素上按下时,开始拖拽 onmousedown
- 当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
- 当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
1 | <head> |
滚轮事件
onwheel事件都支持
定义元素
1
2
3
4
5
6
7
8
9
10
11
12
13<head>
<style>
#box1 {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body style="height: 2000px;">
<div id="box1"></div>
</body>元素监听滚动事件
- onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
- 但是火狐不支持该属性
- 在火狐中需要使用addEventListener()函数来绑定 DOMMouseScroll 来绑定滚动事件
event.wheelDelta
可以获取鼠标滚轮滚动的方向- wheelDelta这个值我们不看大小,只看正负 ,向上滚 120 向下滚 -120
- wheelDelta这个属性火狐中不支持
- Firefox 使用detail,其余四类使用wheelDelta;
- detail,wheelDelta` 两者只在取值上不一致,代表含义一致,detail与wheelDelta只各取两个 值,detail只取±3,wheelDelta只取±120,其中正数表示为向上,负数表示向下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42<head>
<script type="text/javascript">
window.onload = function(){
//获取id为box1的div
var box1 = document.getElementById("box1");
box1.onmousewheel = function(event){
event = event || window.event;
/*
* 当鼠标滚轮向下滚动时,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);
};
</script>
</head>- onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
火狐绑定滚轮事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function 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);
});
}
}
键盘事件
- onkeydown :按键被按下
- 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
- 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。
- onkeyup 按键被松开 ,键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
- keyCode :可以通过keyCode来获取按键的编码 通过它可以判断哪个按键被按下 。
- 除了keyCode,事件对象中还提供了几个属性
- altKey
- ctrlKey
- shiftKey
- 这个三个用来判断alt ctrl 和 shift是否被按下
- 如果按下则返回true,否则返回false
1 | //console.log(event.keyCode); |
1 | input.onkeydown = function (event) { |
BOM
- 浏览器对象模型(browser object model)
- BOM可以使我们通过JS来操作浏览器
- 在BOM中为我们提供了一组对象,用来完成对浏览器的操作
BOM对象
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用
Window
- 代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navigator
- 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
Location
- 代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
History
- 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
- 由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
- 而且该操作只在当次访问时有效
Screen
- 代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
Navigator
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
一般我们只会使用userAgent来判断浏览器的信息,
userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容, 不同的浏览器会有不同的userAgent
火狐的userAgent
Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0
Chrome的userAgent
Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36
IE8
Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.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)
IE9
Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.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)
IE10
Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.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)
IE11
Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.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了
1 | alert(navigator.appName); --Netscape |
History
对象可以用来操作浏览器向前或向后翻页
length 属性,可以获取到当成访问的链接数量
back() 可以用来回退到上一个页面,作用和浏览器的回退按钮一样
forward() 可以跳转下一个页面,作用和浏览器的前进按钮一样
go() 可以用来跳转到指定的页面 ,它需要一个整数作为参数
- 1:表示向前跳转一个页面 相当于forward()
- 2:表示向前跳转两个页面
- -1:表示向后跳转一个页面
- -2:表示向后跳转两个页面
Location
该对象中封装了浏览器的地址栏的信息
如果直接打印location:
alert(location);
,则可以获取到地址栏的信息(当前页面的完整路径)如果直接将location属性修改为一个完整的路径,或相对路径 ,则我们页面会自动跳转到该路径,并且会生成相应的历史记录
location="http://www.baidu.com"
location = "01.BOM.html"
assign() 用来跳转到其他的页面,作用和直接修改location一样
reload() 用于重新加载当前页面,作用和刷新按钮一样
如果在方法中传递一个true:
location.reload(true)
,作为参数,则会强制清空缓存刷新页面replace() 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
- 不会生成历史记录,不能使用回退按钮回退
window
- 表示浏览器窗口
- 直接定义全局的函数都是window的函数
- window对象的函数或对象可以省略window关键字
- 属性
- document:获取文档对象
- innerheight:获取显示区高度
- innerwidth:获取显示区的宽度
方法
- open(url,窗口名字,弹出窗口的特征(位置,大小等)):打开窗口,返回一个window对象.
- close():关闭窗口
- alert():警告框
- confirm():确认框,返回boolean
- prompt: 输入框
- setTimeout(function,delaytime): 延时一段时间后,执行函数只执行一次,返回number类型
- clearTimeout(id);清楚timeout
- setInterval(function,delaytime):周期性执行,返回类型
- clearInterval(intervalId);清除interval
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32console.log(window.innerHeight);
console.log(window.innerWidth);
//打开新窗口
var newWindow = window.open(
"http://www.baidu.com",
"baidu",
"width=200px,height=200px,left=200px,top=200px",
);
//关闭窗口
newWindow.close();
var bool = confirm("确认删除吗?");
console.log(bool);
var name = prompt("请输入您的姓名", "张三");
console.log(name);
//只执行一次
var timeoutId = setTimeout(function () {
console.log("boom");
}, 2000);
//取消timeout
clearTimeout(timeoutId);
var i = 10;
var id = setInterval(function () {
i--;
console.log(i);
}, 1000);
clearInterval(id);
定时器
定时调用 :setInterval() ,可以将一个函数,每隔一段时间执行一次
参数:
- 回调函数,该函数会每隔一段时间被调用一次
- 每次调用间隔的时间,单位是毫秒
返回值:
- 返回一个Number类型的数据
- 这个数字用来作为定时器的唯一标识
clearInterval()可以用来关闭一个定时器
- 方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
clearInterval()可以接收任意参数,
- 如果参数是一个有效的定时器的标识,则停止对应的定时器
- 如果参数不是一个有效的标识,则什么也不做
1 | var num = 1; |
延时调用
setTimeout
延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择
1
2
3
4//应用:10秒倒计时广告
var timer = setTimeout(function () {
console.log("10秒倒计时广告结束");
}, 3000);使用clearTimeout()来关闭一个延时调用:
clearTimeout(timer);
JSON
JavaScript Object Notation JS对象表示法,JS中的对象只有JS自己认识,其他的语言都不认识。
键值对,用:冒号连接, 用逗号,分隔多个属性
属性值key可以不使用引号
1
2
3
4
5
6
7
8<script>
var jsonObj = {name:'zs' ,age:12};
var person=[{name:'zs' ,age:12}];
console.log(jsonObj);
console.log(jsonObj.name);
console.log(jsonObj.age);
console.log(person[0].age);
</script>
JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的和JS语法一致
JSON分类: 对象 {} ,数组 []
JSON中允许的值:
- 字符串 2. 数值 3. 布尔值 4. null 5. 对象 6. 数组
举例:
1
2
3
4
5
6var arr = '[1,2,3,"hello",true]'; //数组
var obj2 = '{"arr":[1,2,3]}'; //对象
var json =
'[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]'; //对象数组
区别
js是一个对象
json :字符串
js对象不要引号
json的key必须用引号
js对象不能传输
json用于传输
注意
JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错
eval():这个函数可以用来执行字符串形式的js代码,并将执行结果返回
- 如果使用eval执行的字符串中含有{},会将{}当成代码块。
- 如果不希望当成代码块解析,这需要在字符串前后加上
()
- 虽然功能强大,首先执行性能比较差,然后有安全隐患,开发中尽量避免使用
解决办法,引入一个js文件(功能就是创建JSON对象)
1
2
3
4
5
6
7var str1 = 'alert("hello")';
eval(str1); //会自动执行代码,弹出hello
var str2 = '{"name":"孙悟空","age":18,"gender":"男"}';
var obj = eval("(" + str2 + ")");
console.log(obj);
// {name: "孙悟空", age: 18, gender: "男"}
typeof obj; //"object"
json > js对象
JSON.parse()
- 可以将以JSON字符串转换为js对象
- 它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
1 | var o = JSON.parse(json); |
JS对象 > JSON
JSON.stringify()
可以将一个JS对象转换为JSON字符串- -ify/fy,表示”使……化。
需要一个js对象作为参数,会返回一个JSON字符串
1
2
3
4var obj3 = { name: "猪八戒", age: 28, gender: "男" };
var str = JSON.stringify(obj3);
console.log(str);
// "{"name":"猪八戒","age":28,"gender":"男"}"
js实现复制到剪切板
第一种,通过clipboard.js插件实现(推荐)clipboard传送门
第二种,纯js实现:
1
2
3
4
5
6
7
8document.getElementById("copy-text-btn").onclick = function () {
//获取文本并去掉空格
var ssrsss = document
.getElementById("text-content")
.innerText.replace(/\ +/g, "");
var flag = copy(ssrsss); //传递文本
alert(flag ? "复制成功" : "复制失败");
};- 使用input接收
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function copy(text) {
const input = document.createElement("input"); //创建input对象
document.body.appendChild(input); //添加元素
input.setAttribute("value", text);
input.select();
try {
var flag = document.execCommand("copy"); //执行复制
// console.log("复制成功");
} catch (eo) {
var flag = false;
}
document.body.removeChild(input); //删除元素
return flag;
}- 使用textarea文本框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function copyText(text) {
var textarea = document.createElement("textarea"); //创建input对象
var currentFocus = document.activeElement; //当前获得焦点的元素
var toolBoxwrap = document.getElementById("NewsToolBox"); //将文本框插入到NewsToolBox这个之后
toolBoxwrap.appendChild(textarea); //添加元素
textarea.value = text;
textarea.focus();
if (textarea.setSelectionRange) {
textarea.setSelectionRange(0, textarea.value.length); //获取光标起始位置到结束位置
} else {
textarea.select();
}
try {
var flag = document.execCommand("copy"); //执行复制
} catch (eo) {
var flag = false;
}
toolBoxwrap.removeChild(textarea); //删除元素
currentFocus.focus();
return flag;
}
localStorage
- HTML5中,新加入了一个localStorage特性,
- 主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k)
- localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。
优势与局限
优势
- localStorage拓展了cookie的4K限制
- localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
局限
- 浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
- 目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
- localStorage在浏览器的隐私模式下面是不可读取的
- localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
- localStorage不能被爬虫抓取到
localStorage与sessionStorage的区别
- localStorage属于永久性存储
- sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空
localStorage写入
如果是使用IE8以下浏览器的话,那么就要UserData来作为存储
首先在使用localStorage的时候,我们需要判断浏览器是否支持localStorage这个属性
1
2
3
4
5
6if (!window.localStorage) {
alert("浏览器不支持localstorage");
return false;
} else {
//主逻辑业务
}localStorage的写入有三种方法
- 控制台上面打印出来的结果是:string
- 存储进去的是int类型,但是打印出来却是string类型
- 这个与localStorage本身的特点有关,localStorage只支持string类型的存储。
1
2
3
4
5
6
7
8
9
10
11
12
13
14if (!window.localStorage) {
alert("浏览器不支持localstorage");
} else {
var storage = window.localStorage;
//写入a字段
storage["a"] = 1;
//写入b字段
storage.b = 1;
//写入c字段
storage.setItem("c", 3);
console.log(typeof storage["a"]);
console.log(typeof storage["b"]);
console.log(typeof storage["c"]);
}localStorage的使用也是遵循同源策略
localStorage读取
- 官方推荐的是getItem\setItem这两种方法对其进行存取
1 | if (!window.localStorage) { |
localStorage的删改
改和更改全局变量的值一样
1
2
3
4
5
6
7
8
9
10
11
12
13if (!window.localStorage) {
alert("浏览器不支持localstorage");
} else {
var storage = window.localStorage;
//写入a字段
storage["a"] = 1;
console.log(storage.a);
/*分割线*/
storage.a = 4;
console.log(storage.a); //a键已经被更改为4
}localStorage的删除
clear()
将localStorage的所有内容清除1
2
3
4
5
6var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
console.log(storage);
storage.clear();
console.log(storage);removeItem(key)
将localStorage中的某个键值对删除1
2
3
4
5
6var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
console.log(storage);
storage.removeItem("a");
console.log(storage.a);
localStorage的键获取
使用key()方法,向其中填入索引即可获取对应的键
1
2
3
4
5
6
7var storage = window.localStorage;
storage.a = 1;
storage.setItem("c", 3);
for (var i = 0; i < storage.length; i++) {
var key = storage.key(i);
console.log(key);
}
JS对象存入localStorage
我们可以使用JSON.stringify()这个方法,来将JS对象转换成为JSON字符串
1
2
3
4
5
6
7
8
9
10
11
12
13if (!window.localStorage) {
alert("浏览器不支持localstorage");
} else {
var storage = window.localStorage;
var data = {
name: "xiecanyong",
sex: "man",
hobby: "program",
};
var d = JSON.stringify(data);
storage.setItem("data", d);
console.log(storage.data);
}读取之后要将JSON字符串转换成为JSON对象,使用JSON.parse()方法
1
2
3
4//将JSON字符串转换成为JSON对象输出
var json = storage.getItem("data");
var jsonObj = JSON.parse(json);
console.log(typeof jsonObj); // Object对象