赞
踩
* JavaScript诞生于1995年,主要用于前端验证,比如用户名的长度 密码的长度 邮箱的格式等
* ECMAScript是一个标准,这个标准需要各厂商去实现; 一般认为和JS一个意思;
包括 ECMAScript DOM(文档对象模型 通过Js操作网页) BOM(浏览器对象模型 通过JS操作浏览器)
不同浏览器实现方式 浏览器 js实现方式 Firefox Spidemonkey
Internet Explorer JScript/Chakra Safari JavascriptCore Chrome V8 Carakan Carakan
目录
5. foreach--遍历数组(只支持IE8以上的浏览器)
JS-DOM (Document Object Model)
-第一条第一条代码(3个输出语句):记住 alert document.write console.log
* console 用户看不到
#代码①
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
-
- <!-- JS代码需要写到script标签中 -->
- <script type="text/javascript">
-
- alert("Hello World!我是弹出框");
- document.write("把我写在body里啦~~");
- console.log("我在控制台呢,body里看不到哦");
-
- </script>
-
- </head>
- <body>
-
- </body>
- </html>
* 写在body标签中(不方便维护,不推荐)
* 写在内部script标签中
* 写在外部JS文件中,然后在html中引用(推荐!)
注:JS代码是按照从上到下一步步执行的
* 注释 (多行注释&单行注释)
* 区分大小写
#代码②
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
-
- /*
- 多行注释 JS注释
- 注释内容不会被执行,可以在源代码中查看*/
-
- // 单行注释
-
- /*
- 1. JS中严格区分大小写
- 2. JS中每条语句以分号结尾;如果不写浏览器会添加上,消耗系统资源
- 3. JS中自动忽略多个空格和代码
- */
- alert("我区分大小写 Wo Qu");
-
- // 字面量和变量演示:
- var age=27;
- console.log(age);
- </script>
- </head>
- <body>
-
- </body>
- </html>
-- 字面量就是1234....写什么输出什么;
-- 变量用来保存字面量,比如 a=1234;
-- 声明变量使用var关键字声明一个变量,比如 var a;
为变量赋值a=1234;
-- 声明和赋值同时进行: var a=1234; var age=27;
console.log(age); 27就会在控制台显示了(如上#代码②)
Ⅰ. String 字符串
* 字符串需要用单引或双引引起来,引号不能同类嵌套
var str= '我说:“今天天气真不错!”’; console.log(str);
* 在字符串中可以使用\作为转义字符,表示特殊符号时可以用\转义
\" 表示 "
\' 表示 ‘
\n 表示换行
\t 制表符 相当于按了table
\\ 表示 \
var str= '我说:“今天天气真不错!”’; console.log(str);
str="我说:\“今天\t天气真不错!\”"; (注意上一行已经给str声明了,这一行不用再写var了)
输出字符串: alert("str"); 输出变量str: alert(str);
Ⅱ. Number 数值
在JS中所有的数值都是number类型,包括整数和小数
var a=123.456; (数字) var b="123.456";(字符串)
可以用typeof来检查变量的类型,比如 console.log(typeof a);
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- // JS中可以表示数字的最大值 Number.MAX_VALUE
- console.log(Number.MAX_VALUE);
- // JS中可以表示数字的最小正值 Number.MIN_VALUE
- console.log(Number.MIN_VALUE);
-
- // 如果使用Number表示的数字超过了最大值,会返回一个
- // (-)Infinity,表示(负)正无穷。
- var a=-Number.MAX_VALUE * Number.MAX_VALUE;
- console.log(a);
-
- // NON not a number
-
- // 在JS中整数的运算基本可以保证精确,但浮点数(小数)可能不精确
- var b=1+2;
- console.log(b);
- var c=0.1+0.2;
- console.log(c);
- </script>
- </head>
- <body>
-
- </body>
- </html>
Ⅲ. Boolean 布尔值
只有2个,true false
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Boolean布尔值</title>
- <script type="text/javascript">
- /* Boolean布尔值只有两个: true(真) false(假)*/
- var bool=true;
- console.log(bool);
- console.log(typeof bool);
-
- var a=true;
- console.log(a);
- console.log(typeof a);
- </script>
- </head>
- <body>
-
- </body>
- </html>
Ⅳ. Null 空值
只有1个值 null 空对象 检查为object
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- /* Null类型的值只有一个,就是null,专门表示空对象*/
- var a=null;
- console.log(a);
- // 使用typeof检查时会返回object
- console.log(typeof a);
-
- // Undefined类型的值只有一个,就是undefined,当声明一个对象,但不给对象赋值时,它的值就是undefined
- var b;
- console.log(b);
- // 使用typeof检查时也会返回undefined
- console.log(typeof b);
- </script>
- </head>
- <body>
-
- </body>
- </html>
Ⅴ. Undefined 未定义 (见上html)
不给对象赋值时,值为undefined
Ⅵ. Object 对象(Object为引用数据类型,其他均为基本数据类型)
附加1:强制类型转换
1. 强制将其他数据类型转换为String
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- /*强制类型转换:
- --将一个数据强制转换为其他类型数据
- --主要指将其他数据类型转换为 String Number Boolean*/
-
- /*其他数据转为String,
- 方式一:调用被转换数据类型的toString()方法;
- 该方法不会影响原变量;但有局限性,对null和undefined会报错
- */
- var a=123;
- a=a.toString();
- console.log(a);
- console.log(typeof a);
-
- var b=true;
- b=b.toString();
- console.log(b);
- console.log(typeof b);
- // 调用xxx的yyy()方法,就是xxx.yyy();
-
- // var c=null;
- // c=c.toString();
- // console.log(c);
- // console.log(typeof c);
-
- // var d;
- // d=d.toString();
- // console.log(d);
- // console.log(typeof d);
-
- /*其他数据转为String,
- 方式二:调用String()函数
- */
-
- var e=null;
- e=String(e);
- console.log(e);
- console.log(typeof e);
- </script>
- </head>
- <body>
-
- </body>
- </html>
2. 强制将其他数据类型转换为Number
var a="abc"; 转换 a=Number(a);
①String转Number:转换方式1:
*纯数字的字符串直接转化为数字;
* 字符串中有非数字内容,转换为NAN;
* 字符串是空的,或是全为空格的字符串
转换方式2:(也可以转换Boolean等)
整数 a="123px"; 转化ParseInt(a); 小数 a="123.456px"; ParseFloat(a);
可以将一个字符串的有效数字内容取出来转换为Number,后面的字母不变
② Boolean转Numbe rtrue→1 false→0
③ Null转Number 数字 0
④ Undefined转Number 数字 NAN
3. 强制将其他数据类型转换为Boolean
数字转Boolean,除了0和NAN是false,其余都是true;
字符串转Boolean,除了空串是false,其余都是true;
null和undefined都会转成false;
对象也会转换为true
附加2:其它进制的数字
在JS中,表示16进制数字,需要0x开头; a=0x10 16 a=0xff a=0xCafe
8进制的数字,以0开头; a=070
2进制的数字,以0b开头;a=0b10
注:a="070";转化为Number,用a=parseint(a);转化时,有的浏览器当成8进制解析为56,有的当成10进制解析为70,因此用 a=ParseInt(a,10);
-- 在JS中所有的可以自主命名的都可以称为标识符,例:变量名、函数名、属性名;
-- 命名规则:
* 标识符中只可以含有 字母、数字、_、$
* 标识符不能以数字开头
* 标识符不能是ES中的关键字或保留字(下图)
* 一般采用驼峰命名法:首字母小写,其他每个单词首字母大写,其余小写 helloWorld
举例:var d3=打比方;
console.log(d3);
-- JS底层标识符实际采用的是Unicode编码,理论上讲utf-8的所有内容都可以作为标识符,
文字也可以,但一般不采用。
运算符也叫操作符,通过运算符对一个或多个值进行运算,并获取运算结果,比如typeof就是运算符,可以来获得一个值的类型,它会将该值类型以字符串的形式返回。
对非Number类型的值进行运算时,会将这些值转换为Number,然后再进行运算;任何值和NAN运算都得NAN; + - * / %
1. + 两个值加法运算,并返回结果;如果两个字符进行加法运算,则会拼串,并返回,
任何值和字符串做加法,都会先转化为字符串然后做拼串,举例:
可以利用这一特点,将任意数据类型转换为String,只需为任意类型数据 + 一个 “”即可,这是一种隐士的类型转换,浏览器会自动完成,实际上也是调用 String()函数,举例:
c=123; c=c+""; console.log("c= " + c); → c=123 console.log(typeof c)是String
2. 任何值做 - * / 运算时都会自动转化为NUmber,利用这一特点也可做隐式转化,通过一个值 -0 *1 /1 将其转化为Number,原理和Number()函数一样,使用起来更简单。
3. % 取模取余数 举例:
result = 9 % 3; console.log("result= " + result) → 0
result = 9 % 4; console.log("result= " + result) → 1
1. 只需操作一个数
+ 正号不会对数字产生任何影响;- 负号可以对数字进行取反;
对于非Number类型的值,它会先将其转化为Number再运算,可以使用+号转换,原理和Number()一样,举例: var a=123; a=-a; a=true; a="18"; a=+a; console.log("a= " + a)
2. 自增和自减
* 自增:通过自增使变量在自身基础上增加1,即自增之后原变量的值会立即增加1;
自增分两种:a++ 和 ++a;无论哪一种都会使原变量的值自增1
不同的是 a++ 和 ++a的值不同:a++的值等于自增前的值, ++a的值等于自增后的值。
* 自减:通过自减使变量在自身基础上减1;
自减分两种:a-- 和 --a;无论哪一种都会使原变量的值自减1
不同的是 a-- 和 --a的值不同:a--的值等于自减前的值, --a的值等于自减后的值。
练习:条件 var n1=10, n2=20;
1. 非运算 ! 对布尔值进行取反操作 true变false false变true
--如果对一个值进行两次取反则该值不会变化 a=!!a;
--如果对非布尔值非运算,会将其先转换为布尔值再取反;可以了利用这一特点将其他数据类型转换为布尔值,为任意数据类型取两次反即可,原理和Boolean()函数一样 var b=10; b=!!b;
2. 与运算 && 找false
--两个值中只要有一个值为false就会返回false,只有两个值都为true时才会返回true;
--JS中的“与”属于短路的与,如果第一个值为false就不会看第二个了
3. 或运算 || 找true
--两个值中只要有一个值为true就会返回true,只有两个值都为false时才会返回false;
--JS中的“或”属于短路的或,如果第一个值为true就不会看第二个了
4. 非布尔值的与或运算 (返回原值)
--与运算 先将其转化为布尔值再运算并返回原值;
如果第一个值为true,则必然返回第二个值;
如果第一个值为false,必然返回第一个值;
如果两个值都为true,则返回后边的 var result = 5 && 6;→ 6
--或运算
如果第一个值为true,则直接返回第一个值; result = 2 || 1;→ 2
如果第一个值为false,必然返回第二个值; result = NAN || 1; →1
可以将符号右侧的值赋值给符号左侧的变量
+= a += 5 等价于 a = a + 5
-= a -= 5 等价于 a = a - 5
*= a += 5 等价于 a = a * 5
/= a /= 5 等价于 a = a / 5
%= a %= 5 等价于 a = a % 5
通过关系符比较两个值的大小 关系成立返回true,不成立返回false;
> 大于号 >= 大于等于 < 小于 <=小于等于
var result = 5 > 10; → false var result = 5 > 4; → true
console.log(1 > true); → false console.log(1 >= true); → true
console.log(1 > "0"); → true console.log(10 > null); → true
console.log(10 <= "hello"); → false
任何值和NAN做任何比较都是false
非数值情况: 会将其转换为数字然后比较;如果两侧都是字符串,不会转换为数字,而是会比较字符串中Unicode编码,一个一个比
a. 相等 --使用==做相等运算,相等返回true,否则返回false;
--如果值的类型不同会自动转为相同类型再比较;console.log("1" == 1);→true
--NaN不和任何值相等,包括它本身 console.log(NaN==NaN);→false
--可以通过isNaN() 函数来判断一个值是否为NaN,是返回true,否则返回false
var b = NaN; console.log(isNaN(b));
b. 不相等 --使用 != 做不相等运算 不相等返回false,相等返回true 也会做类型的自动转换
c. 全等 --使用 ===表示全等,和相等类似,但它不做自动转化,必须两个值完全一样
console.log("123" === 123);→false console.log("123" ==== 123);→true
d. 不全等 --使用 !== 表示 和不等类似 如果两个值的类型不同,直接返回true
-- 语法: 条件表达式?语句1:语句2;
-- 执行流程: 首先对条件表达式求值,true执行语句1并返回结果,false语句2返回结果
举例:a>b ? alert("a大") : alert("b大");
--如果条件表达式的求值结果是一个非布尔值,则会将其转化为布尔值再运算
-- , 运算符 使用 , 可以分割多个语句,一般可以在声明多个变量时使用 var a=1, b=2, c=3;
-- 运算符优先级: a. 先乘除 后加减
b. 有一个运算符优先级的表,位置越靠上优先级越高
c. 如果遇到优先级不确定,可以用()来改变优先级
举例:var result = 1+2*3; var result = 1 || (2 && 3); console.log("result= " +result);
--流程控制语句从上到下逐行执行,并控制程序流程,根据一定条件选择执行
--代码块:
在JS中可以使用{}来为语句进行分组,一个大括号代表一个代码块,
代码块里的语句要么都执行,要么都不执行;
JS中的代码块只有分组的作用,不会把内部和外部的内容隔离。
-- 可以在执行某个语句之前判断,条件成立执行,不成立不执行;
--语法1: if (条件表达式)
语句
-- if 语句执行时先对条件表达式求值判断,值为true则执行if后的语句,false不会执行
-- if 语句只能控制紧随其后的那个语句,如果希望控制多条,则统一放到代码块中
举例:var a=15; if(a>10 && a<=20){alert("a大于10,并且a小于等于20");}
--语法2: if(条件表达式){语句}
else{语句}
--执行时先对条件表达式求值判断,值为true则执行if后的语句,false执行else语句
--语法3: if (条件表达式){语句}
else if(条件表达式) {语句}
else if(条件表达式) {语句}
else{语句}
--语句执行时,会从上至下依次对条件表达式进行求值判断,true执行当前语句,false继续向向下判断, 如果都不满足,则执行else; 该语句中只有一个代码会被执行,一旦代码执行,就不会往下执行了
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- /*从键盘输入小明的期末成绩
- 当成绩为100时,"奖励一辆BMW"
- 当成绩为80-90时,"奖励一台iphone15s"
- 当成绩为60-80时,"奖励一本参考书"
- 其他时,什么奖励也没有*/
-
- /*prompt()可以弹出一个提示框,该提示框带有一个文本框
- 在文本框输入一段内容,该函数需要一个字符串作为参考,该字符串将会作为提示框的提示文字。
- 用户输入的内容将会作为函数的返回值返回,可以定义一个变量来接收该内容*/
-
-
- var score = prompt("请输入小明的期末成绩(0-100):");
- // 判断值是否合法
- if(score>100 || score<0 || isNaN(score)){alert("别瞎写~~");
- }else{
- // 根据score来判断给小明什么奖励
-
- if(score == 100){
- alert("奖励一辆BMW");
- }else if (score>=80) {alert("奖励一台iphone15s")
-
- }else if (score>=60) {alert("奖励一本参考书")
-
- }else{alert("挨打")}
- }
-
- </script>
- </head>
- <body>
-
- </body>
- </html>
--语法: switch(条件表达式){ case表达式:语句 break;
case表达式:语句 break;
default: 语句 break;}
-- 执行流程: 执行时会依次将case后表达式的值和switch后条件表达式的值进行全等比较
结果为true,则从当前case处开始执行代码(默认执行其后的所有代码,可用break终止)
结果为false,则继续向下执行,如果所有结果都为false,就只执行default后的语句
-- switch和if语句功能上是重复的,双方功能可以实现,使用时根据自己习惯
-- 通过循环语句可以反复执行一段代码多次
-- 语法1: while(条件表达式){ 语句 }
-- 执行时先对条件表达式进行求值判断,如果值为true,则执行循环体,循环体执行完毕,继续对表达式判断,为true在接着执行循环体,以此类推;如果为false,则终止循环。
--创建一个循环:1. 创建一个初始化变量 var i = 1;
2. 在循环中设置一个条件表达式 while(i<11){}
3. 定义一个更新表达式,每次更新初始化变量 document.write(i++ +"br/>")
-- 语法2: do....while语句在执行时,会先执行循环体再判断,如果为true再继续执行,如果为false,则终止循环
注:实际上两个功能相似,只是一先一后,do...while 可以保证至少执行一次,while不能
提供了专门的位置来放三个表达式:初始化表达式 条件表达式 更新表达式
-- 语法:for(初始化表达式;条件表达式; 更新表达式;){语句}
-- 执行流程: ①初始化表达式,初始化变量;
②执行条件表达式,判断是否执行循环 true执行,false终止
③执行更新表达式,执行完毕后重复②
for循环中的三个部分都可以省略,也可以写在外部 ,如果不写任何表达式就是死循环
——————记得补上代码和练习
通过for循环输出图形,外部循环可以控制高度,内部循环控制宽度
for(var i=0; i<5; i++){
for(var j=0; j<5; j++){ document.write(" * "); }
document.write(" <br/> ");
}
break:用来退出switch或循环语句,不能在if语句中使用break和continue
可以为循环创建一个lable,来识别当前的循环,lable:循环语句 使用break时,在break后面后跟一个lable,这样break就会结束指定的循环,而不是最近的
continue:跳过当此循环,只对最近的循环起作用
测试程序性能,执行前开启计时器console.time("计时器的名字");需要一个计时器的名字作为参数 console.time("test"); 执行后用Console.timeEnd("test"); 来停止一个计时器
加上break可以提升性能 Math.sart() 开方
内建对象 宿主对象 自定义对象
对象也是数据类型的一种,上一篇有写到6中数据类型,对象object是一种引用数据类型,其他string、number、Boolean、null、undefined是基本数据类型;
-- 基本数据类型都是单一的值,值和值之间没有联系,不能成为一个整体;
-- 对象属于复合的数据类型,可以保存多个不同数据类型的属性;
内建对象:由ES标准中定义的对象,在任何ES的实现中都可以使用
自定义对象:创建对象,使用new关键字调用的函数,是构造函数constructor,构造函数是专门用来创建对象的函数。
① 创建对象 var obj = new object();
② 向对象中添加属性 属性名:不强制要求遵守标识符规范,尽量遵守 对象.属性名=属性值
obj.name="孙悟空";
obj.gender="男";
obj.age="18";
③ 读取对象中的属性(如果读取对象中没有的属性,不会报错而会返回undefined)
console.log(obj); console.log(obj.gender); console.log(obj.hello)没有则会返回defined
④ 修改对象的属性名: 对象.属性名=新属性值 obj.name="tom"; console.log(obj.name);
⑤ 删除对象的属性: delete 对象.属性名 delete obj.name;
1. 属性名: 如果要使用特殊的属性名,不能用 . 的方式,语法: 对象["属性名"]=属性值;
obj["123']=789; obj["你好"]="你好"; console.log(obj["123"]);
2. 属性值:JS对象的属性值可以是任意的数据类型,甚至可以是一个对象
obj.test = true; obj.test = null; obj.test = undefined;
var obj2 = new object(); obj2.name = "猪八戒";
obj.test = obj2; console.log(obj.test.name);
通过该运算符可以检查一个对象中是否含有指定的属性 有则返回true,无则返回false
语法: "属性名" in 对象
举例: console.log("test2" in obj); console.log("name" in obj);
基本数据类型保存的是值,引用数据类型保存的是地址
1. 基本数据的变量都是保存到栈内存的,基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量的值不会影响其他变量;
2. 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个对象保存的是同一对象引用的地址,当通过一个变量修改属性时,另一个也受影响。
3. 当比较两个基本数据类型的值时,就是比较值;而比较两个引用数据类型时,比较的时内存地址,如果两个对象(属性值)是一模一样的,但地址(属性名)不同,也会返回false
例: console.log(obj3 == obj4); 就会返回false
Var obj={} ; obj.name="孙悟空”;
Var obj2={name:"zbj",age:28,gender:"nan" test:{name:"shs"}};
Console.log(obj2);
函数也是一个对象,函数中可以封装一些功能(代码),在需要时可以调用或执行这些功能(代码),使用typeof检查一个函数对象时,会返回function
①使用函数声明来创建一个函数
语法:function 函数名([形参1,形参2....形参N]){语句...}
②使用函数表达式创建一个函数
语法:var 函数名=function([形参1,形参2....形参N]){语句....}
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- /*使用函数声明创建一个函数
- function fun2(){
- console.log("这是我的第二个函数~~");
- alert("哈哈哈哈");
- document.write("笑笑不说话");
- }
- console.log(fun2);
- // 调用函数fun2
- fun2();
- */
-
- //使用函数表达式创建一个函数
- var fun3 = function(){
- console.log("我是匿名函数中封装的代码");
- }
- // 调用函数fun3
- fun3();
- </script>
- </head>
- <body>
-
- </body>
- </html>
函数的参数可以是任意的数据类型
定义一个用来求和的函数:可以在函数的()中指定一个或多个形参(形式参数),多个形参之间用,隔开,声明形参就相当于在函数的内部声明了对应的变量,但是并不赋值。
调用函数时,可以在()中指定实参,会赋值给对应的形参,下图
调用函数解析时不会检查实参的类型,注意检查
--多余实参不会被赋值
--实参如果比形参少,则多的形参是undefined
-- return后的值将作为函数的执行结果返回,可以定义一个变量来接受结果
-- 变量result的值就是函数的执行结果,函数返回什么,result的值就是什么
-- 在函数中,return后的语句不会执行
-- 实参可以是任意的数据类型,包括对象
-- 当参数过多时,可以将参数封装到一个对象中,通过对象传递
返回值可以是任意的数据类型,包括对象和函数,可以在函数里再声明一个函数
语法:函数对象() 函数定义完立即被调用,则叫立即执行函数,立即执行函数往往只执行一次
例: ( function(){ alert("我是一个立即执行函数"); } )();
(function (a,b){ console.log("a="+a); console.log("b="+b);})(123,456);
对象的属性值可以是任意数据类型 包括函数;
如果一个函数作为对象的属性保存,我们称这个函数是这个对象的方法
调用这个函数就是调用对象的方法(method) 除了名称没其他区别
赋值:
①全局作用域 :
-- 直接写在script标签中的JS代码都在全局作用域,页面打开时创建关闭时销毁
-- 全局作用域中有个全局对象Window,代表浏览器窗口,由浏览器创建可以直接使用
-- 在全局作用域中创建的变量都会作为window对象的属性保存,函数都会作为window对象的放法保存;全局作用域中的变量都是全局变量,在页面的任意部分可以访问到
声明提前:
a. 变量的声明提前:使用var关键字声明的变量,会在代码执行前被声明,但不会赋值
例: console.log("a="+a); var a=123; (此时a被提前声明但没有赋值a=undefined)
b. 函数的提前声明:使用函数声明形式创建的 function 函数(){} 会在代码执行前被创建,所以我们可以在函数声明前来调用函数;
注意:使用函数表达式创建的函数,不会被提前声明,不能声明前调用 否则报错
②函数作用域:
a. 调用函数作用域,函数执行完毕,函数作用域销毁;
b. 每调用一次函数会创建一个新的函数作用域,他们之间相互独立;
c. 函数作用域中可以访问到全局作用域,反之不可以;
d. 在函数作用域中操作一个变量时,会在自身作用域中寻找,有就用,没有则会向上一级寻找,直到全局作用域,如果依然没有找到,直接报错referenceerror。
e. 要在函数中直接访问全局变量可以使用window对象
声明提前:
函数声明也会在函数中所有的代码执行前执行
③debug 在浏览器--检查--source---进行调试
解析器调用函数每次都会向函数内部传递一个隐含的参数this,指向的是一个对象,这个对象称为函数执行的上下文对象;根据函数的调用方式不同,this指向不同的对象
-- 以函数形式调用 this永远是window
-- 以方法形式调用 this是调用方法的那个对象
? 通过该方法可以大批量创建对象
构造函数就是一个普通的函数,创建方式和普通函数无区别,不同的是构造函数习惯上首字母大写;
构造函数和普通函数的区别是调用方式不同,普通函数直接调用,构造函数需要使用new关键字调用;
构造函数的执行流程:
① 立刻创建一个新的对象
② 将新建的对象设置为函数中this,在构造函数中使用this来引用新建的对象
③ 逐行执行函数中的代码
④ 将新建的对象作为返回值返回
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类,将通过一个构造函数创建的对象称为该类的实例。
附:使用instanceof可以检查一个对象是否是一个类的实例
方法在构建函数内创建的,那么构造函数每执行一次就会创建一个新的sayName方法,也就是所有实例的sayName都是唯一的,这样导致执行一万次就要一万个新的放大且一模一样,没必要,可以进行修改,使所有对象共享一个方法。
但该方法有局限性和问题,函数定义在全局,污染了全局作用域的命名空间,也很不安全
解决方法:原型对象
①我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象--原型对象;
②普通函数调用prototype没有任何作用,当以构造函数形式调用时,可以通过__proto__来访问该属性;
③原型对象相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,可以将对象中共有的内容统一设置到原型对象中,这样不用分别为每个对象添加,也不影响全局;
④当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,有直接使用,没有就会去原型对象中找,找到直接使用,如果还没有再去原型对象的原型中去找,直到找到object对象的原型,依然没有找到则返回undefined。
注:使用in检查对象中是否含有某个属性
程序运行久了会产生垃圾,积攒过多导致运行速度慢,利用垃圾回收机制处理垃圾;
当一个对象没有任何变量或属性对它引用时无法操作该对象,这种对象就是垃圾,JS有自动的垃圾回收机制会自动清除销毁,我们需要做的只是将不再使用的对象设置为null即可
数组和普通对象功能类似,也是来储存值的,不同的是普通对象使用字符串作为属性名,数组使用数字作为索引操作元素。
索引:从0开始的整数就是索引,数组的存储性能比普通对象摇号,开发中常用来存储数据
数组中的元素可以是任意数据类型,包括对象和函数
①push(数组末尾添加一个或多个元素)
-- 该方法将添加的元素作为方法的参数传递,这些元素会自动添加至数组的末尾
-- 会将数组的长度作为返回值返回
②pop(删除数组的最后一个元素)
-- 该方法将被删除的元素作为返回值返回
③unshift(数组开头添加元素)
-- 会将新的数组长度作为返回值返回
④shift(删除数组第一个元素)
-- 该方法将被删除的元素作为返回值返回
l
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- // 练习
- function Person(name, age){
- this.name=name;
- this.age=age;
- }
- // 修改Person原型中的tostring
- Person.prototype.toString=function(){
- return "Person[name="+this.name+",age="+this.age+"]"
- }
- var per=new Person("孙悟空",18);
- var per2=new Person("猪八戒",28);
- var per3=new Person("红孩儿",8);
- var per4=new Person("蜘蛛精",16);
- var per5=new Person("二郎神",38);
- var perArr=[per,per2,per3,per4,per5];
- // 创建一个函数,将perArr中满18岁的Person提取出来,然后封装到一个新的数组中并返回 arr 形参,要提取的数组
- function getAdult(arr){
- var newArr=[];
- for(var i=0; i<arr.length; i++){
- var p=arr[i];
- if(p.age>=18){
- newArr.push(p);
- }
- }
- return newArr;
- }
- var result=getAdult(perArr);
- console.log(result);
- </script>
- </head>
- <body>
-
- </body>
- </html>
--这种函数由我们创建的,但不由我们调用,称为回调函数
--数组中有几个元素函数会执行几次,每次执行浏览器会将遍历到的元素以实参的形式传递出来,我们可以来定义形参读取这些内容
① slice 从数组中提取指定元素
-- 参数:
截取开始位置的索引,包括开始索引
截取结束为止的索引,不包含结束索引
索引可以传递负值,表示倒数第几个
② splice 删除数组中的指定元素,会影响原数组,指定元素从原数组删除,并将被删除的元素作为返回值返回
-- 第一个表示开始位置的索引,
第二个表示删除的数量,
第三个及以后可以传递新元素,自动插入开始位置索引的前面
③练习:去除数组中重复的数字(使用嵌套for循环)
var arr = [1,2,3,2,1,3,4,2,5]; (JS-7)
① concat() 可以连接两个或多个数组,并将新的数组返回;不会对原数组产生影响;既可以传输组,也可以传元素;
② join() 可以将数组转换为一个字符串,不对原数组产生影响;将转换后的字符串返回;可以指定一个字符串作为参数,这个字符串会成为连接符,如果不指定连接符,则默认使用,作为连接符
③ reverse() 直接修改原数组,反转前后颠倒
④ sort() 对数组中元素排序,也影响原数组,默认按Unicode编码排序 对纯数字也一样
⑤ 可以利用回调函数和sort指定排序规则
回调函数中需要定义两个形参,浏览器将分别使用数组中的元素作为实参去调用回调函数,使用的元素不确定,但肯定在数组中,a一定在b前面,浏览器会根据与回调函数的返回值决定元素的排序
返回大于0的值,元素交换位置;
返回小于0 等于0的值,位置不变
call和apply 函数对象的方法,通过函数对象来调用
调用函数时,浏览器每次都会传递两个隐含的参数:
① 函数的上下文对象this,② 封装实参的对象arguments
arguments是一个类数组对象,可以通过索引来操作数据,也可以获取长度;在调用函数时,所传递的实参都会在arguments中保存;arguments.length 获取实参的长度;
即使不定义形参,也可以通过arguments来使用实参,arguments[0] 表示第一个实参 arguments[1]表示第二个实参
date表示时间
创建当前时间:如果直接使用构造函数创建date对象,则会封装为当前代码执行的时间
var d=newDate();
Console.log(d);
创建指定的时间对象,构造函数时传递一个表示时间的字符串作为参数
-- 日期的格式: 月份/日/年 时:分:秒
-- getDate() 获取当前对象是几日 getDay() 当前是周几 getMonth() 当前月份
-- getTime() 获取当前日期对象的时间戳(指格林威治标准时间1970年1月1日,0时0分0秒到当前时间所花费的毫秒数(1秒=1000毫秒)) 计算机底层保存时间时用的都是时间戳
Math 不是构造函数,属于工具类,不用创建对象,里面封装了数学运算相关的方法
Math.PI 圆周率
Abs() 计算绝对值
Math.cile() 向上取整 小数进一
Math.floor() 向下取整小数舍去
Math.round() 四舍五入取整
Math.random()生成0-1之间的随机数,不包括0和1
max() min()获取最大值和最小值
Math.pow(x,y) 返回x的y次幂
Math sqrt 开方
三个包装类将基本数据类型转换为对象,但实际应用中不会使用基本数据类型的对象,容易出不可预料的问题,主要用于浏览器将基本数据类型转化为对象。
String() 基本数据类型转换为String对象 Number() Boolean() 同
字符串string的方法
--Length 可以用来获取字符串的长度
-- charAt() 返回字符串中指定位置的字符,根据索引获取
-- charCodeAt() 获取字符串中指定位置字符的编码,返回Unicode编码
-- formCharCode() 可以根据字符编码去获取字符
-- concat() 链接两个或多个字符串,和+一样作用
-- indexof() 检索字符串中是否含有指定内容。如果含有该内容,则会返回第一次出现的索引,如果没有找到指定内容,则返回-1;可以在第二个参数指定开始查找的位置
-- slice() 从字符串中截取指定内容,不影响原字符串,将截取内容返回
参数:第一个开始的索引位置包括开始、
第二个结束的位置不包括结束位置
省略第二个参数就会截取后面所有,可以负数-1倒数第一个、、、
-- substring() 也是截取字符串 和slice相似,不同的是这个方法不能接收负值,负值默认为0,自动调整参数位置,如果小于第一个参数,俩参数交换位置,比如(1,0)会自动调整为(0,1)
-- substr() 用来截取字符串,第一个参数截取开始位置的索引,第二个截取的长度
-- split() 将一个字符串拆分为一个数组
参数:需要一个字符串作为参数,将会根据该字符串拆分数组
如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素
-- toUpperCase() 将一个字符串转化为大写并返回
-- toLowerCase() 将一个字符串转化为小写并返回
注:后面记得跟练习和代码
用于定义一些字符串的规则,计算机可以根据正则表达式检查一个字符串是否符合规则,将字符串中符合规则的内容提取出来,正则表达式也是对象object,使用typeof检查正则对象,返回object
-- 创建正则表达式 语法: var 变量 = newRegExp("正则表达式","匹配模式");
-- 正则表达式的方法: test() 检查一个字符串是否符合正则表达式的规则,符合true,反之false
-- Var reg = new RegExp("a"); 检查字符串中是否含有a,大A也不行;在构造函数中可以传递一个匹配模式作为第二个参数: i 忽略大小写 g 全局匹配模式
使用字面量创建正则表达式,语法: var 变量=/正则表达式/匹配模式
构造函数方式 Var reg=new RegExp("a", "i"); 灵活
字面量方式 Reg=/ a / i; 简单
-- split() 根据任意字母拆分字符串,即使不指定全局匹配,也会全部拆分
-- Search() 搜索字符串中是否含有指定内容;搜到返回第一次出现的索引,没搜到返回-1,只能查找到第一个,不能全局查找
-- Match() 根据正则表达式,从一个字符串中将符合条件的内容提取出来,默认match找到第一个符合要求的内容就停止;
可以设置正则表达式为全局匹配模式g,这样可以匹配到所有内容;
会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
-- replace() 可将字符串中指定内容替换成新的内容
参数: 被替换的内容,新的内容
默认只替换第一个被替换的内容可以接收一个正则表达式作为参数
① 量词: --通过量词可以设置一个内容连续出现的次数
-- 量词支队它前边的一个内容起作用
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
HTML DOM 模型被结构化为对象树:
JS中通过DOM对HTML操作
Document文档:整个HTML网页文档
Object 对象:将网页中的每个部分转换为一个对象
Model模型:表示对象之间的关系,方便我们获取对象
浏览器加载页面时自上而下读取,一行行运行,如果将script写在页面上面,执行代码时页面还没有加载,需如图将script写在body内容的下面
我们可以为window绑定一个onload事件,这个onload事件会在整个页面加载完成后才触发,其对应的响应函数会在页面加载完成后执行,可以确保代码执行时所有的DOM对象已经加载完毕了。如下:
HTML标签,浏览器会将页面中所有的标签都转换为一个元素节点, 我们可以通过document的方法来获取元素节点。
①获取元素节点
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window .onload=function(){
-
- //通过id获取元素节点
- var btn01=document.getElementById("btn01");
- console.log(btn01.innerHTML);
- // 通过标签名获取一组元素节点
- var btn=document.getElementsByTagName("button");
- console.log(btn.length);
- // 通过类名class获取元素节点
- var btn03=document.getElementsByClassName("btn03");
- console.log(btn03);
- // 通过CSS选择器获取 该方法总会返回唯一的元素,即使满足条件的有多个也只会返回一个
- var btn04 = document.querySelector(".btn04");
- console.log(btn04);
- // 创建一个无序列表,通过CSS选择器选择该列表的所有li
- var list=document.querySelectorAll(".list li");
- console.log(list);
- };
- </script>
- </head>
- <body>
- <button id="btn01">通过id获取元素节点</button>
- <button>通过标签名获取一组元素节点</button>
- <button class="btn03">通过类名class获取元素节点</button>
- <button class="btn04">通过CSS选择器获取元素节点</button>
-
- <ul class="list">
- <li>列表项1</li>
- <li>列表项2</li>
- <li>列表项3</li>
- <li>列表项4</li>
- </ul>
-
- </body>
- </html>
②获取元素子节点
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window .onload=function(){
- // 通过具体的元素节点调用 语法: 当前元素节点.后代节点标签名
- var btnlist=document.getElementById("btnlist");
- // 获取btnlist下的所有button节点
- var btn=btnlist.getElementsByTagName("button");
- console.log(btn.length);
- for (var i=0; i<btn.length; i++){
- console.log(btn[i].innerHTML);
- }
-
- // childNodes属性 获取包括文本节点、、空白等在内的所有节点
- var btn=btnlist.childNodes;
- console.log(btn.length);
- // children属性获取当前元素的所有子元素,不包括文本节点
- var btn2=btnlist.children;
- console.log(btn2.length);
-
- // firstChild 获取当前元素的第一个节点,也叫文本节点
- var fir=btnlist.firstChild;
- console.log(fir);
- // firstElementChild 获取当前元素的第一个子元素
- var fir2=btnlist.firstElementChild;
- console.log(fir2);
- };
- </script>
- </head>
- <body>
- <div id="btnlist">
- <button id="btn01">我是按钮01</button>
- <button id="btn02">我是按钮02</button>
- <button id="btn03">我是按钮03</button>
- <button id="btn04">我是按钮04</button>
- <button id="btn05">我是按钮05</button>
- </div>
-
- </body>
- </html>
③获取元素的父节点和兄弟节点
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window .onload=function(){
- // parentNode 获取id为bj的元素父节点
- var bj=document.getElementById("bj");
- var pn=bj.parentNode;
- // 和innerHTML相似,但它会获取元素内部的内容
- console.log(pn.innerText);
- // previousSibling 获取bj的前一个兄弟节点,包括文本节点
- var pre=bj.previousSibling;
- console.log(pre);
- // previousElementSibling 获取bj的前一个兄弟元素
- var pre1=bj.previousElementSibling;
- console.log(pre1.innerText);
- };
- </script>
- </head>
- <body>
- <ul class="city">
- <li id="js">江苏</li>
- <li id="bj">北京</li>
- <li>上海</li>
- <li>广州</li>
- <li>深圳</li>
- </ul>
- </body>
- </html>
元素的属性,属性节点并非是元素节点的子节点,而是元素节点的一部分。可以通过元素节点来获取指定的属性节点。
例如:元素节点.getAttributeNode("属性名")
,根据元素节点的属性名获取一个属性节点对象
HTML标签中的文本内容
文本节点一般是作为元素节点的子节点存在的。获取文本节点时,一般先要获取元素节点,在通过元素节点获取文本节点。
例如:元素节点.firstChild;
,获取元素节点的第一个子节点,一般为文本节点。
方法 | 描述 |
---|---|
元素节点.innerText | 获取 HTML 元素的 inner Text 内部内容 |
元素节点.innerHTML | 获取 HTML 元素的 inner HTML |
元素节点.属性 | 获取HTML的属性值 |
元素节点.getAttribute(attribute) | 获取 HTML 元素的属性值 |
元素节点.style.样式 | 获取 HTML 元素的行内样式值 |
方法 | 描述 |
---|---|
document.createElement(element) | 创建元素节点,需要一个标签名作为参数,根据该标签名创建元素节点对象 |
.removeChild(element) | 删除子节点 语法: 父节点.removeChild(子节点); |
.appendChild(element) | 添加子节点,语法: 父节点.appendChild(子节点); |
.replaceChild(element) | 替换子节点 语法: 父节点.replaceChild(新节点,旧节点); |
document.write(text) | 写入 HTML 输出流 |
document.createAttribute(attribute) | 创建属性节点 |
document.createTextNode(text) | 创建文本节点 |
元素节点.insertBefore(element) | 在指定的子节点前面插入新的子节点 |
语法: 元素.style.样式名=样式值
注意:如果CSS样式名中含有-,在JS中是不合法的,要修改为驼峰命名法,去掉-,-后的首字母大写,比如background-color 应写作 backgroundColor
通过style属性设置的样式都是内链样式,优先级高,可以立即显示,如果CSS样式中设置 !important,此时样式是最高优先级,JS也不能覆盖,导致JS样式失效,所以尽量不要添加。
用getComputedStyle() 来获取元素样式,是window的方法,可以直接使用,需要两个参数
第一个: 要获取样式的元素
第二个:可以传一个元素,一般都传null ?
该方法会返回一个对象,对象中封装了当前元素对应的样式,如果获取的样式没有设置,则会获取真实的值而不是默认值,比如:没有设置width,他不会获取到auto,而是一个长度。
Var obj=getComputedStyle(box1,null);
Alert(obj.width);
或者Alert(getComputedStyle(box1,null).width);
定义一个函数来获取指定元素当前的样式
参数:Obj 要获取的元素 Name 要获取的样式名
Function getStyle(obj,name){Return getComputedStyle(obj,null)[name];}
其他样式属性:
属性 | 描述 |
---|---|
clientWidth clientHeight | 获取元素的可见宽度和高度,包括内容区和内边距,属性不带px |
offsetWidth offsetHeight | 获取元素整个的宽度和高度,包括内容区、内边距和边框 |
offsetParent | 获取离当前元素最近的开启了定位的父元素,如果所有祖先元素都没有开启已定位,则返回body |
offsetLeft offsetTop | 当前元素对于其定位父元素的水平和垂直偏移量 |
scrollWidth scrollHeight scrollLeft scrollTop | 获取整个滚动区域的宽度和高度 获取水平和垂直滚动条滚动的距离 |
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递,在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标,键盘的按下
鼠标在div移动时 显示鼠标的坐标 onmousemove 该事件会在鼠标在元素中移动时被触发
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style>
- #areaDiv{
- width: 100px;
- height: 100px;
- background-color: red;
- }
- #showMsg{
- width: 100px;
- height: 20px;
- border: 1px solid;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var areaDiv=document.getElementById("areaDiv");
- var showMsg=document.getElementById("showMsg");
- areaDiv.onmousemove=function(event){
- // 在IE8中,响应函数被触发时,浏览器不会传递事件对象,而是将事件对象作为window对象的属性保存
- if(!event){
- event=window.event;
- }
- var x=event.clientX;
- var y=event.clientY;
- showMsg.innerHTML= "x=" +x+ ",y="+y;
- }
-
- }
-
- </script>
- </head>
- <body>
- <div id="areaDiv"></div>
- <br/>
- <div id="showMsg"></div>
- </body>
- </html>
2.2 鼠标拖拽事件
拖拽流程:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style type="text/css">
- #box1{
- width: 100px;
- height: 100px;
- background-color: red;
- position: absolute;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var box1=document.getElementById("box1");
- // 为box1绑定一个鼠标按下事件
- box1.onmousedown=function(event){
- event=event||window.event;
- // 解决鼠标总是跳回box1左上角的问题
- var ol=event.clientX-box1.offsetLeft;
- var ot=event.clientY-box1.offsetTop;
- // 当鼠标按下并且为document绑定鼠标移动的事件
- document.onmousemove=function(event){
- // 当鼠标你按下且在页面中移动时 box1坐标随鼠标的坐标而定,但此时松开鼠标移动鼠标依然会动
- var left=event.clientX-ol;
- var top=event.clientY-ot;
- box1.style.left=left+"px";
- box1.style.top=top+"px";
- }
-
- // 在鼠标按下事件执行后,为document绑定鼠标松开事件,鼠标在页面中松开时,鼠标移动事件取消,box1停止移动
- document.onmouseup=function(){
- document.onmousemove=null;
- // 要进行下次鼠标按下移动事件,则还要再取消鼠标松开事件
- document.onmouseup=null;
- }
- }
- }
- </script>
- </head>
- <body>
- 我是一段文字
- <div id="box1"></div>
- <div id="box2"></div>
- </body>
- </html>
设置两个div 都可以被拖拽:重点 drag setCapture releaseCapture
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</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;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var box1=document.getElementById("box1");
- var box2=document.getElementById("box2");
- // 给box1和box2开启拖拽
- drag(box1);
- drag(box2);
-
- // 提取一个专门用来设置拖拽的函数,参数:开启拖拽的元素
- function drag(obj){
- //当鼠标被在拖拽元素上按下时,开始拖拽
- obj.onmousedown=function(event){
- // 解决事件兼容性问题
- event=event||window.event;
-
- // 设置obj捕获所有鼠标按下的事件
- // setCapture() 只有IE支持,在火狐中调用不会报错,但谷歌会报错
- obj.setCapture && obj.setCapture();
-
- // obj的偏移量 鼠标.clentX - 元素.offsetLeft
- // obj的偏移量 鼠标.clentY - 元素.offsetTop
- var ol=event.clientX-obj.offsetLeft;
- var ot=event.clientY-obj.offsetTop;
-
- // 当鼠标按下并且为document绑定鼠标移动的事件
- document.onmousemove=function(event){
- // 解决事件兼容性问题
- event=event||window.event;
-
- // 被拖拽元素跟随鼠标的移动而移动
- var left=event.clientX-ol;
- var top=event.clientY-ot;
-
- // 修改obj的位置
- obj.style.left=left+"px";
- obj.style.top=top+"px";
- }
-
- // 在鼠标按下事件执行后,为document绑定鼠标松开事件,鼠标在页面中松开时,鼠标移动事件取消,停止移动
- document.onmouseup=function(){
- document.onmousemove=null;
- // 要进行下次鼠标按下移动事件,则还要再取消鼠标松开事件
- document.onmouseup=null;
- // 鼠标松开时取消对事件的捕获
- obj.releaseCapture && obj.releaseCapture();
- }
-
- /*
- 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
- 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
- 如果不希望发生这个行为,则可以通过return false来取消默认行为,
- 但是这招对IE8不起作用
- */
- return false;
- }
- }
- }
- </script>
- </head>
- <body>
- <div id="box1"></div>
- <div id="box2"></div>
- </body>
- </html>
事件的冒泡(Bubble):指事件的向上传导,当后代元素上的事件被触发时,其父元素和祖先元素的相同事件也相继被触发;开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡,可以通过事件对象来取消
3.1 演示和取消事件冒泡
取消冒泡:将事件对象的cancelBubble设置为true即可
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style type="text/css">
- #box1{
- width: 200px;
- height: 200px;
- background-color: yellowgreen;
- }
- #s1{
- background-color: yellow;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var s1=document.getElementById("s1");
- s1.onclick=function(event){
- event=event||window.event;
- alert("我是span的单击响应函数");
-
- // 取消冒泡:将事件对象的cancelBubble设置为true即可
- event.cancelBubble=true;
- };
- var box1=document.getElementById("box1");
- box1.onclick=function(){
- alert("我是box1的单击响应函数");
- }
- document.body.onclick=function(){
- alert("我是body的单击响应函数");
- }
- }
- </script>
- </head>
- <body>
- <div id="box1">
- 我是box1
- <span id="s1">我是span</span>
- </div>
- </body>
- </html>
3.2 事件的委派
指将一件事统一绑定给元素的共同祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件;
事件委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能。
target event中的target表示触发事件的对象
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- // var allA=document.getElementsByTagName("a");
- // for(var i=0; i<allA.length; i++){
- // allA[i].onclick=function(){
- // alert("我是a的单击响应函数");
- // }
- // }
-
- // 需求:只绑定一次事件即可应用到多个元素上,即使元素是后添加的,尝试将其绑定给元素的共同祖先元素,即 事件委派
- var ul=document.getElementById("ul");
- ul.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="ul" style="background-color: #bfa;">
- <li>
- <p>我是p元素</p>
- </li>
- <li><a href="javascript:;" class="link" >超链接1</a></li>
- <li><a href="javascript:;" class="link" >超链接2</a></li>
- <li><a href="javascript:;" class="link" >超链接3</a></li>
- </ul>
- </body>
- </html>
① 对象.事件=函数
此形式绑定响应函数,只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,后面的会覆盖前面的,如下:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- // 点击按钮以后弹出一个内容
- var btn01=document.getElementById("btn01");
-
- // 为btn01绑定第一个响应函数
- btn01.onclick=function(){
- alert(1);
- }
- // 为btn01绑定第二个响应函数
- btn01.onclick=function(){
- alert(2);
- }
-
- }
- </script>
- </head>
- <body>
- <button id="btn01">我是个按钮</button>
- </body>
- </html>
② addEventListener() 中的this是指绑定事件的对象,可以同时为一个元素的相同事件绑定多个响应函数,这样事件被触发时,响应函数将会按照函数绑定顺序执行。
语法:addEventListener(参数1,参数2,参数3);
参数1:事件的字符串,不要on,比如click,而不是onclick;
参数2:回调函数,当事件被触发时,该函数会被调用;
参数3:一个布尔值,一般传false,是否在捕获阶段触发事件
但此方法不支持IE8,在IE8要用attachEvent() 中的this是指window,但火狐和chrome不支持
语法: attachEvent(参数1,参数2);
参数1:事件的字符串,要on,比如onclick
参数2:回调函数
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- // 点击按钮以后弹出一个内容
- var btn01=document.getElementById("btn01");
-
- // addEventListener 同时为一个元素的相同事件绑定多个响应函数,这样事件被触发时,响应函数将会按照函数绑定顺序执行
- btn01.addEventListener("click",function(){
- alert(1);
- },false);
- btn01.addEventListener("click",function(){
- alert(2);
- },false);
-
- // IE8版本绑定
- btn01.attachEvent("onclick",function(){
- alert(3);
- })
- btn01.attachEvent("onclick",function(){
- alert(4);
- })
- }
- </script>
- </head>
- <body>
- <button id="btn01">我是个按钮</button>
- </body>
- </html>
③ bind绑定函数完成两个方法this的统一
语法:bind(boj,eventStr,callback)
参数1:obj 要绑定的事件的对象
参数2:eventStr 事件的字符串(不要on)
参数3:callback 回调函数
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- // 点击按钮以后弹出一个内容
- var btn01=document.getElementById("btn01");
- bind(btn01,"click",function(){
- alert(1)
- });
-
- function bind(obj,eventStr,callback){
- if(obj.addEventListener){
- obj.addEventListener(eventStr,callback,false);
- }else{
- obj.attachEvent("on"+ eventStr,callback);
- }
- }
- }
- </script>
- </head>
- <body>
- <button id="btn01">我是个按钮</button>
- </body>
- </html>
事件的传播:关于事件的传播网景公司和微软公司有不同的理解
-- 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
-- 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素。
W3C综合了两个公司的方案,将事件传播分成了三个阶段:
-- 捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
-- 目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件
-- 冒泡阶段:事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件
注:如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true,一般情况下我们不希望在捕获阶段触发事件,所以这个参数一般都是false
IE8以下的浏览器中没有捕获阶段
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style type="text/css">
- #box1{
- width: 100px;
- height: 100px;
- background-color: red;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- // 鼠标向上滚动时,box1变长,向下时,box1变短
- var box1=document.getElementById("box1");
- // box1.onmousewheel=function(){
- // alert("滚~~");
- // };
- // 火狐不支持onmousewheel属性,需要使用DOMMouseScroll来绑定滚动事件,该事件需要通过addEventListener()函数来绑定
-
-
- box1.onmousewheel=function(event){
- event=event||window.event;
- // alert(event.detail);
- // wheelDelta 判断鼠标滚动的方向 ,这个值不看大小,只看正负,上正下负
- // 火狐中用 detail获取滚动的方向,上负下正
- if(event.wheelDelta>0 || event.detail<0){
- box1.style.height=box1.clientHeight-10+"px";
- }else{
- box1.style.height=box1.clientHeight+10+"px";
- }
-
- // 滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,这是浏览器的默认行为,可以取消,如下
- event.preventDefault && event.preventDefault();
- return false;
- }
-
- // 使用addEventListener()来绑定响应函数,取消默认行为时不能使用return false; 需要用event来取消默认行为event.Default(); 但是IE8不支持,直接调用会报错
- bind(box1,"DOMMouseScroll",box1.onmousewheel);
- function bind(obj,eventStr,callback){
- if(obj.addEventListener){
- obj.addEventListener(eventStr,callback,false);
- }else{
- obj.attachEvent("on"+ eventStr,callback);
- }
- }
- }
- </script>
- </head>
- <body>
- <div id="box1"></div>
- </body>
- </html>
-- 键盘事件onkeydown 按键被按下,对于onkeydown来说,如果一直按着某个按键不松手,则事件会一直触发;如果连续触发,第一次和第二次之间会间隔稍长一些,其他的会非常快,这种设计是为了防止误操的发生。
-- onkeyup按键被松开
键盘事件一般都会绑定给一些可以获取到焦点的对象或是document
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- // document.onkeydown=function(){
- // console.log("按键按下");
- // };
-
- document.onkeydown=function(event){
- event=event||window.event;
- // console.log(event.keyCode);
- if(event.keyCode===89 && event.ctrlKey){
- console.log("y和Ctrl键都被按下了");
- }
- }
-
- // document.onkeyup=function(){
- // console.log("按键松开啦");
- // }
-
- var input =document.getElementsByTagName("input")[0];
- input.onkeydown=function(event){
- event=event||window.event;
- console.log("xingbuxinga");
- //使文本框中不可以输入数字 数字 48-57
- if(event.keyCode >=48 && event.keyCode<=57){
- return false;
- }
- }
- }
- </script>
- </head>
- <body>
- <input type="text">
- </body>
- </html>
除了keyCode,还有其他按键判断, altKey ctrlKey shiftKey 判断alt ctrl shift 键是否被按下,按下返回true,否则返回false
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- var box1=document.getElementById("box1");
- document.onkeydown=function(event){
- event=event||window.event;
- var speed=10;
- // 按了Ctrl以后速度变为50
- if (event.ctrlKey) {
- speed=50;
- }
-
- // 条件分支语句,把表达式的值与每个 case 的值进行对比,如果存在匹配,则执行关联代码
- // 37-40 左上右下
- switch(event.keyCode){
- case 37:
- box1.style.left=box1.offsetLeft-speed+"px";
- break;
- case 39:
- box1.style.left=box1.offsetLeft+speed+"px";
- break;
- case 38:
- box1.style.top=box1.offsetTop-speed+"px";
- break;
- case 40:
- box1.style.top=box1.offsetTop+speed+"px";
- break;
- };
- }
- }
- </script>
- </head>
- <body>
- <div id="box1" style="width: 100px; height: 100px; background-color: red; position: absolute;"></div>
- </body>
- </html>
通过JS操作浏览器,BOM为我们提供了一组对象,来完成对浏览器的操作。
● Navigator 当前浏览器的信息,通过该对象识别不同的浏览器
● Location 当前浏览器的地址栏信息,操作浏览器跳转页面
● History 浏览器的历史记录,操作浏览器的历史记录,隐私原因,该对象不能获取具体的历史记录,只能操作浏览器向前或向后翻页,该操作只在当次访问有效
● Screen 用户的屏幕信息,获取用户显示器相关的信息
这些BOM对象都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用,比如: console.log(location); console.log(history);
Navigator 代表当前浏览器的信息,通过该对象可以识别不同的浏览器;由于历史原因,Navigator对象中的大部分属性已经不能帮我们识别浏览器了,一般我们会用userAgent懒判断浏览器的信息,userAgent是一个字符串,包含用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent
如果通过UserAgent不能判断,还可以通过一些浏览器特有的对象来判断浏览器的信息,比如: ActiveXObject
History 对象可以操作浏览器向前或向后翻页
length 属性: 获取当前访问的链接数量 alert(history.length);
back() 可以退回上一个页面,作用和浏览器的回退按钮一样
forward() 可以跳到下一个页面,作用和浏览器的前进按钮一样
go() 跳到指定的页面,需要一个整数作为参数;1 表示向前跳一个页面,相当于forward(); 2表示向前跳两个; -1表示向后跳一个; -2表示向后跳两个
直接打印location,可以获取地址栏的信息(当前页面的完整路径) alert(location);
如果将location属性修改为一个完整的路径或相对路径,则我们的页面会自动跳转到该路径,并且会生成相应的历史记录。location="http://www.baidu.com"; location="48-BOM History.html";
assign() 用来跳转到其他的页面,作用和直接修改location一样 location.assign("http://www.baidu.com");
reload() 重新加载当前页面,和刷新按钮一样,如果在方法中传递一个true作为参数,会强制清空缓存,刷新页面 location.reload(true);
replace() 可以使用一个新的页面来替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用退回按钮退回 location.replace("48-BOM History.html");
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- var btn=document.getElementById("btn");
- btn.onclick=function(){
- alert(location);
- location="http://www.baidu.com";
- location.assign("http://www.baidu.com");
- location.reload(true);
- // 下面这个是我自己建的一个HTML文件,测试能否跳转
- location.replace("48-BOM History.html");
- }
- }
-
- </script>
- </head>
- <body>
- <button id="btn">Location</button>
- </body>
- </html>
4.1 定时调用setInterval() 使程序可以每间隔一段时间执行一次
setInterval() 参数:1. 回调函数,该函数每隔一段时间被回调一次; 2. 每次调用间隔的时间,单位是毫秒
返回值: 返回一个Number类型的数据, 这个数字用来作为定时器的唯一标识
clearInterval() 关闭定时器, 方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- window.onload=function(){
- var count=document.getElementById("count");
- var num=1;
- var timer=setInterval(function(){
- count.innerHTML=num++;
- if(num==8){
- clearInterval(timer);
- }
- }, 1000);
-
- var timer=setTimeout(function(){
- console.log(num++);
- },3000);
- clearTimeout(timer);
- }
- </script>
- </head>
- <body>
- <h1 id="count"></h1>
- </body>
- </html>
4.2 延时调用 setTimeout() 函数不马上执行,隔一段时间执行,只执行一次;
与定时调用的区别:定时调用会执行多次,延时调用只会执行一次,两者可以互相代替的,开发中根据需要选择,用定时的比较多。 clearTimeout() 关闭延时调用
4.3 练习定时器
getStyle(obj,name) obj要获取样式的元素 name样式名
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style type="text/css">
- *{
- margin: 0;
- padding: 0;
- }
- #box1{
- width: 100px;
- height: 100px;
- background-color: red;
- position: absolute;
- left: 0;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var box1=document.getElementById("box1");
- var btn01=document.getElementById("btn01");
- var timer;
- btn01.onclick=function(){
- clearInterval(timer);
- timer=setInterval(function(){
- var oldValue=parseInt(getStyle(box1,"left"));
- var newValue=oldValue+20;
- if(newValue>800){
- newValue=800;
- }
- box1.style.left=newValue+"px";
- if(newValue==800){
- clearInterval(timer);
- }
- },100);
- }
-
- // 定义一个函数,来获取指定元素的当前样式
- // getStyle(obj,name) obj要获取样式的元素 name样式名
- function getStyle(obj,name){
- if(window.getComputedStyle){
- return getComputedStyle(obj,null)[name];
- }else{
- return obj.currentStyle[name];
- }
- }
-
- }
-
- </script>
-
- </head>
- <body>
- <button id="btn01">点击按钮以后box1向右移动</button>
- <br/> <br/>
- <div id="box1"></div>
- </body>
- </html>
通过style 每修改一个样式浏览器就需要重新渲染一次页面,执行性能比较差,而且当我们要修改多个样式时也不太方便
5.1 addClass(obj,cn) 向元素中添加指定的class属性值
obj:要添加class属性的元素,cn:要添加的class属性值5.2 removeClass() 删除一个元素中指定的class属性
5.3 toggleClass() 切换一个class属性 如果元素中有这个类删除,没有则添加
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style type="text/css">
- .b1{
- width: 100px;
- height: 100px;
- background-color: red;
- }
- .b2{
- width: 200px;
- height: 200px;
- background-color: yellow;
- }
- </style>
- <script type="text/javascript">
- window.onload=function(){
- var box1=document.getElementById("box1");
- var btn01=document.getElementById("btn01");
- var b1=document.getElementsByClassName("b1");
- btn01.onclick=function(){
- // 方法1:style 每修改一个样式浏览器就需要重新渲染一次页面,执行性能比较差,而且当我们要修改多个样式时也不太方便
- // box1.style.width="150px";
- // 通过一行代码,同时修改多个样式 修改box的class属性
- // box1.className +=" b2";
-
- // addClass(box1, " b2");
- // removeClass(box1,"b2");
- toggleClass(box1,"b2");
- }
-
- // addClass(obj,cn) 向元素中添加指定的class属性值
- // obj:要添加class属性的元素,cn:要添加的class属性值
- function addClass(obj, cn){
- if(!hasClass(obj,cn)){
- obj.className += "" +cn;
- }
- }
-
- // 判断obj中有没有cn class 有true,无false
- function hasClass(obj,cn){
- // 创建一个正则表达式
- var reg=new RegExp("\\b"+cn+"\\b");
- return reg.test(obj.className);
- }
-
- // removeClass() 删除一个元素中指定的class属性
- function removeClass(obj,cn){
- var reg=new RegExp("\\b"+cn+"\\b");
- obj.className = obj.className.replace(reg, "");
- }
-
-
- // toggleClass() 切换一个class属性 如果元素中有这个类删除,没有则添加
- function toggleClass(obj,cn){
- if(hasClass(obj,cn)){
- removeClass(obj,cn);
- }else{
- addClass(obj,cn);
- }
- }
- }
-
- </script>
- </head>
- <body>
- <button id="btn01">点击按钮以后修改box1的样式</button>
- <div id="box1" class="b1 b2"></div>
- </body>
- </html>
JSON:JavaScript Object Notation(JS对象标记法),是一种存储和交换数据的语法。
数据在浏览器和服务器进行交换是,这些数据只能是文本,JSON就是文本,且可以把任何JS对象转换为JSON,将JSON发送到服务器,同样我们可以性服务器接收任何JSON转换为JS。
JSON和JS对象格式一样,不过JSON字符串中的属性名必须加双引号
JSON.parse() JSON转换为JS
JSON.stringify() JS转换为JSON字符串
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <script type="text/javascript">
- // 创建一个对象(加引号的)
- var obj='{"name":"孙悟空", "age":18, "gender":"男"}';
- // 创建一个数组(加引号的)
- var arr='[1,2,3,"hello",true]';
- console.log(obj);
- var obj2={name:"猪八戒", age:28, gender:"男"};
-
- // JSON.parse() JSON转换为JS
- var o=JSON.parse(obj);
- var o2=JSON.parse(arr);
- console.log(o.gender);
-
- // JSON.stringify() JS转换为JSON字符串
- var str=JSON.stringify(obj2);
- console.log(str);
- </script>
- </head>
- <body>
-
- </body>
- </html>
JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。
JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。
由于这种相似性,无需解析器,JavaScript 程序能够使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。
eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行。如果参数是一个表达式,eval() 函数将执行表达式。如果参数是Javascript语句,eval()将执行Javascript 语句。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。