数据类型
- String 字符串
- Number 数值
- Boolean 布尔值
- Null 空值
- Undefined 未定义
- Object 对象
- 其中String Number Boolean Null Undefined属于基本数据类型
- 而Object属于引用数据类型
String字符串
- 在JS中字符串需要使用引号引起来
- 使用双引号或单引号都可以,但是不要混着用
- 引号不能嵌套,双引号不能放双引号,单引号不能放单引号
var str = 'hello'; str = '我说:"今天天气真不错!"';
number 数字类型
- 整数和浮点数(小数)
- JS中可以表示的数字的最大值
- 1.7976931348623157e+308
- Number.MAX_VALUE
- Number.MIN_VALUE 大于0的最小值
- 5e-324
- 如果使用Number表示的数字超过了最大值,则会返回一个
- Infinity 表示正无穷
- -Infinity 表示负无穷
- 使用typeof检查Infinity也会返回number
- NaN 是一个特殊的数字,表示Not A Number
- 使用typeof检查一个NaN也会返回number
- 可以使用一个运算符 typeof 来检查一个变量的类型
- 语法:typeof 变量
- 检查字符串时,会返回string
- 检查数值时,会返回number
var b = "123"; con(typeof b);
Boolean
- 布尔值只有两个,主要用来做逻辑判断
- true 表示真
- false 表示假使用typeof检查一个布尔值时,会返回boolean
var bool = false; con(typeof bool); con(bool);
null
- Null(空值)类型的值只有一个,就是null
- null这个值专门用来表示一个为空的对象
- 使用typeof检查一个null值时,会返回object
undefined
- Undefined(未定义)类型的值只有一个,就undefind
- 当声明一个变量,但是并不给变量赋值时,它的值就是undefined
- 使用typeof检查一个undefined时也会返回undefined
转义字符
- 在字符串中我们可以使用\作为转义字符,当表示一些特殊符号时可以使用\进行转义
- \ " 表示 "
- \' 表示 '
- \n 表示换行
- \t 制表符
- \ 表示\
强制类型转换
- 指将一个数据类型强制转换为其他的数据类型
- 类型转换主要指,将其他的数据类型,转换为
- String Number Boolean
将其他的数据类型转换为String
- 方式一:
- 调用被转换数据类型的toString()方法
- 该方法不会影响到原变量,它会将转换的结果返回
- 但是注意:null和undefined这两个值没有toString()方法,
- 如果调用他们的方法,会报错
- 方式二:
- 调用String()函数,并将被转换的数据作为参数传递给函数
- 使用String()函数做强制类型转换时,
- 对于Number和Boolean实际上就是调用的toString()方法
- 但是对于null和undefined,就不会调用toString()方法
- 它会将 null 直接转换为 "null"
- 将 undefined 直接转换为 "undefined"
var a = 123; //调用a的toString()方法 //调用xxx的yyy()方法,就是xxx.yyy() a = a.toString(); a = true; a = a.toString(); a = null; //a = a.toString(); //报错 a = undefined; //a = a.toString(); //报错 a = 123; //调用String()函数,来将a转换为字符串 a = String(a); a = null; a = String(a); a = undefined; a = String(a); con(typeof a); con(a);
强制转换number
- 转换方式一:
- 1.如果是纯数字的字符串,则直接将其转换为数字
- 2.如果字符串中有非数字的内容,则转换为NaN
- 3.如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
- 布尔 --> 数字
- true 转成 1
- false 转成 0
- null --> 数字 0
- undefined --> 数字 NaN
- 使用Number()函数
- 字符串 --> 数字
- 转换方式二:
- 这种方式专门用来对付字符串
- parseInt() 把一个字符串转换为一个整数
- parseFloat() 把一个字符串转换为一个浮点数
var a = "123"; //调用Number()函数来将a转换为Number类型 a = Number(a); a = false; a = Number(a); 0 a = null; a = Number(a); 0 a = undefined; a = Number(a); nan a = "123567a567px"; //调用parseInt()函数将a转换为Number /* * parseInt()可以将一个字符串中的有效的整数内容去出来, * 然后转换为Number */ a = parseInt(a); /* * parseFloat()作用和parseInt()类似,不同的是它可以获得有效的小数 */ a = "123.456.789px"; a = parseFloat(a); /* * 如果对非String使用parseInt()或parseFloat() * 它会先将其转换为String然后在操作 */ a = true; a = parseInt(a); a = 198.23; a = parseInt(a); con(typeof a); con(a);
强制转换布尔
- 使用Boolean()函数
- 除了空串,其余的都是true
- null和undefined都会转换为false
- 对象也会转换为true
- 数字 ---> 布尔
- 除了0和NaN,其余的都是true
- 字符串 ---> 布尔
var a = 123; //true a = -123; //true a = 0; //false a = Infinity; //true a = NaN; //false //调用Boolean()函数来将a转换为布尔值 a = Boolean(a); a = " "; a = Boolean(a); a = null; //false a = Boolean(a); a = undefined; //false a = Boolean(a);
其他进制数字
- 如果需要表示16进制的数字,则需要以0x开头
- 如果需要表示8进制的数字,则需要以0开头
- 如果要要表示2进制的数字,则需要以0b开头
- 但是不是所有的浏览器都支持
//十六进制 a = 0x10; a = 0xff; a = 0xCafe; //八进制数字 a = 070; //二进制数字 //a = 0b10; //向"070"这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析 a = "070"; //可以在parseInt()中传递一个第二个参数,来指定数字的进制 a = parseInt(a,10);
Object 对象
- 对象的分类:
- 由开发人员自己创建的对象
- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
- 比如 BOM DOM
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object....
- 1.内建对象
- 2.宿主对象
- 3.自定义对象
创建对象
- 1.使用new关键字调用的函数,是构造函数constructor
- 构造函数是专门用来创建对象的函数
- 使用typeof检查一个对象时,会返回object
var obj = new Object();
- 2.使用对象字面量来创建一个对象
var obj = {};
- 使用对象字面量,可以在创建对象时,直接指定对象中的属性
- 语法:{属性名:属性值,属性名:属性值....}
var obj2 = { name:"猪八戒", age:13, gender:"男", test:{name:"沙僧"} };
- 3.使用工厂方法创建对象
- 通过该方法可以大批量的创建对象
function createPerson(name , age ,gender){ //创建一个新的对象 var obj = new Object(); //向对象中添加属性 obj.name = name; obj.age = age; obj.gender = gender; obj.sayName = function(){ aler); }; //将新的对象返回 return obj; } var obj2 = createPerson("猪八戒",28,"男"); var obj3 = createPerson("白骨精",16,"女"); var obj4 = createPerson("蜘蛛精",18,"女");
在对象中保存的值称为属性
- 向对象添加属性
- 语法:对象.属性名 = 属性值;
- 向obj中添加一个name属性obj.name = "孙悟空";
- 向obj中添加一个age属性obj.age = 18;
- 语法:对象["属性名"] = 属性值
- obj["123"] = 789; obj["nihao"] = "你好";
读取对象中的属性
- 语法:对象.属性名
- 如果读取对象中没有的属性,不会报错而是会返回undefined
con);
- 语法:对象["属性名"]
obj["gender"]
修改对象的属性值
- 语法:对象.属性名 = 新值
obj.name = "tom";
删除对象的属性
- 语法:delete 对象.属性名
delete obj.name;
in 运算符
- 通过该运算符可以检查一个对象中是否含有指定的属性
- 如果有则返回true,没有则返回false
- 语法:"属性名" in 对象
con("name" in obj);
函数 function
- 函数也是一个对象
- 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
- 函数中可以保存一些代码在需要的时候调用
- 使用typeof检查一个函数对象时,会返function
1.使用 函数声明 来创建一个函数
- 语法:function 函数名([形参1,形参2...形参N]){ 语句...}
function fun2(){ con("这是我的第二个函数~~~"); alert("哈哈哈哈哈"); document.write("~~~~(>_<)~~~~"); } //调用fun2 fun2();
使用 函数表达式 来创建一个函数
var 函数名 = function([形参1,形参2...形参N]){ 语句.... }
var fun3 = function(){ con("我是匿名函数中封装的代码"); }; fun3();
返回值
- return 来设置函数的返回值语法:
- return 值
- 函数中return后的语句都不会执行
function sum(a , b , c){ var d = a + b + c; return d; }
//调用函数 //变量result的值就是函数的执行结果 //函数返回什么result的值就是什么 var result = sum(4,7,8);
立即执行函数
- 函数定义完,立即被调用,这种函数叫做立即执行函数
- 立即执行函数往往只会执行一次
(function(){ alert("我是一个匿名函数~~~"); })()
(function(a,b){ con("a = "+a); con("b = "+b); })(123,456)
函数也可以称为对象的属性,
- 如果一个函数作为一个对象的属性保存,
- 那么我们称这个函数时这个对象的方法
- 调用这个函数就说调用对象的方法(method)
var obj2 = { name:"猪八戒", age:18, sayName:function(){ con); } }; obj2.sayName();
枚举对象中的属性
- 使用for ... in 语句
- 语法:for(var 变量 in 对象){ }
- for...in语句 对象中有几个属性,循环体就会执行几次
- 每次执行时,会将对象中的一个属性的名字赋值给变量
var obj = { name:"孙悟空", age:18, gender:"男", address:"花果山" }; for(var n in obj){ con("属性名:"+n); con("属性值:"+obj[n]); }
作用域
- 作用域指一个变量的作用的范围
1.全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
- 在全局作用域中:
- 创建的变量都会作为window对象的属性保存
- 创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问的到
var a = 10; var b = 20; //var c = "hello"; //con); function fun(){ con("我是fun函数"); } (); ("hello");
2.函数作用域
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
- 在函数作用域中可以访问到全局作用域的变量
- 在全局作用域中无法访问到函数作用域的变量
- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
- 如果没有则向上一级作用域中寻找,直到找到全局作用域
- 如果全局作用域中依然没有找到,则会报错ReferenceError
- 在函数中要访问全局变量可以使用window对象
//创建一个变量 var a = 10; function fun(){ var a = "我是fun函数中的变量a"; var b = 20; //con("a = "+a); function fun2(){ con("a = "+window.a); } fun2(); }
变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值),
- 但是如果声明变量时不适用var关键字,则变量不会被声明提前
- con("a = "+a);var a = 123;
函数的声明提前
- 使用函数声明形式创建的函数 function 函数(){}
- 它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
- 使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
//fun(); //函数声明,会被提前创建 function fun(){ con("我是一个fun函数"); } //函数表达式,不会被提前创建 var fun2 = function(){ con("我是fun2函数"); }; fun2();
- 在函数中,不适用var声明的变量都会成为全局变量
function fun5(){ //con("c = "+c); //c = 10; //d没有使用var关键字,则会设置为全局变量 d = 100; }
this(函数的上下文对象)
- 解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
- 这个隐含的参数就是this,this指向的是一个对象,
- 这个对象我们称为函数执行的 上下文对象,
- 根据函数的调用方式的不同,this会指向不同的对象
- 1.以函数的形式调用时,this永远都是window
- 2.以方法的形式调用时,this就是调用方法的那个对象
- 3.当以构造函数的形式调用时,this就是新创建的那个对象
- 4.使用call和apply调用时,this是指定的那个对象
function fun(){ //con("a = "+a+", b = "+b); con); } //fun(); //创建一个对象 var obj = { name:"孙悟空", sayName:fun }; var obj2 = { name:"沙和尚", sayName:fun }; //con == fun); var name = "全局的name属性"; (); //以函数形式调用,this是window //fun(); //以方法的形式调用,this是调用方法的对象 (); obj2.sayName();
arguments(封装实参的对象)
- arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
- 在调用函数时,我们所传递的实参都会在arguments中保存
- argumen可以用来获取实参的长度
- arguments[0] 表示第一个实参
- 它里边有一个属性叫做callee,这个属性对应一个函数对象,就是当前正在指向的函数的对象
function fun(a,b){ //con(arguments instanceof Array); //con(arguments)); //con(arguments[1]); //con(argumen); con == fun); } fun("hello",true);
构造函数
- 构造函数和普通函数的区别就是调用方式的不同普通函数是直接调用,而构造函数需要使用new关键字来调用
- 构造函数的执行流程:1.立刻创建一个新的对象2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象3.逐行执行函数中的代码4.将新建的对象作为返回值返回
function Person(name , age , gender){ = name; = age; = gender; = function(){ aler); }; } function Dog(){ } var per = new Person("孙悟空",18,"男"); var per2 = new Person("玉兔精",16,"女"); var per3 = new Person("奔波霸",38,"男"); var dog = new Dog();
- 使用instanceof可以检查一个对象是否是一个类的实例语法: 对象 instanceof 构造函数如果是,则返回true,否则返回false
con(per instanceof Person);
原型 prototype
- 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
- 这个属性对应着一个对象,这个对象就是我们所谓的原型对象
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,
- 指向该构造函数的原型对象,我们可以通过
- __proto__来访问该属性
function MyClass(){ } //向MyClass的原型中添加属性a MyCla = 123; //向MyClass的原型中添加一个方法 MyCla = function(){ alert("hello"); }; var mc = new MyClass(); var mc2 = new MyClass(); //向mc中添加a属性 mc.a = "我是mc中的a"; //con); mc.sayHello();
- 原型对象也是对象,所以它也有原型,
- 当我们使用一个对象的属性或方法时,会现在自身中寻找,
- 自身中如果有,则直接使用
- 如果没有则去原型对象中寻找,如果原型对象中有,则使用,
- 如果没有则去原型的原型中寻找,直到找到Object对象的原型,
- Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined
con("hasOwnProperty")); con("hasOwnProperty")); con); con); con)
- 当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值
- 如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法
function Person(name , age , gender){ = name; = age; = gender; } //修改Person原型的toString Per = function(){ return "Person[name="++",age="++",gender="++"]"; }; //创建一个Person实例 var per = new Person("孙悟空",18,"男"); var per2 = new Person("猪八戒",28,"男"); //Person[name=孙悟空,age=18,gender=男] /* = function(){ return "Person[name="++",age="++",gender="++"]"; };*/ var result = (); //con("result = " + result); //con("toString")); con(per2); con(per);
垃圾回收
- 就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
- 这些垃圾积攒过多以后,会导致程序运行的速度过慢,
- 所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
- 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
- 此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理。
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作
- 我们需要做的只是要将不再使用的对象设置null即可
var obj = new Object(); //对对象进行各种操作。。。。 obj = null;
call()和apply()
- 这两个方法都是函数对象的方法,需要通过函数对象来调用
- 当对函数调用call()和apply()都会调用函数执行
- 在调用call()和apply()可以将一个对象指定为第一个参数此时这个对象将会成为函数执行时的this
- call()方法可以将实参在对象之后依次传递
- apply()方法需要将实参封装到一个数组中统一传递
function fun(a,b) { con("a = "+a); con("b = "+b); //alert(this); } var obj = { name: "obj", sayName:function(){ aler); } }; (obj,2,3); (obj,[2,3]); var obj2 = { name: "obj2" }; /*(); (); fun();*/ (obj); //(obj); //fun(); .apply(obj2);
添加类
addClass(box,"b2");
移除类
removeClass(box,"b2");
检查obj中是否含有cn
hasClass(obj , cn)
toggleClass可以用来切换一个类
function toggleClass(obj , cn){ //判断obj中是否含有cn if(hasClass(obj , cn)){ //有,则删除 removeClass(obj , cn); }else{ //没有,则添加 addClass(obj , cn); } }
删除一个元素中的指定的class属性
function removeClass(obj , cn){ //创建一个正则表达式 var reg = new RegExp("\\b"+cn+"\\b"); //删除class obj.className = obj.cla(reg , ""); }
添加指定的class属性值
function addClass(obj , cn){ //检查obj中是否含有cn if(!hasClass(obj , cn)){ obj.className += " "+cn; } }
判断一个元素中是否含有指定的class属性值
function hasClass(obj , cn){ //判断obj中有没有cn class //创建一个正则表达式 //var reg = /\bb2\b/; var reg = new RegExp("\\b"+cn+"\\b"); return reg.te); }
流程控制语句
- JS中的程序是从上到下一行一行执行的
- 通过流程控制语句可以控制程序执行流程,
- 使程序可以根据一定的条件来选择执行
- 语句的分类:
- 1.条件判断语句
- 2.条件分支语句
- 3.循环语句
1.条件判断语句 (if)
- 使用条件判断语句可以在执行某个语句之前进行判断,
- 如果条件成立才会执行语句,条件不成立则语句不执行。
语法一:
if(条件表达式){ 语句...}
if(a > 10 && a <= 20){ alert("a大于10,并且 a小于等于20"); }
- if语句在执行时,会先对条件表达式进行求值判断,
- 如果条件表达式的值为true,则执行if后的语句,
- 如果条件表达式的值为false,则不会执行if后的语句。
- if语句只能控制紧随其后的那个语句,
- 如果希望if语句可以控制多条语句,可以将这些语句统一放到代码块中
语法二:
if(条件表达式){ 语句...}else{ 语句...}
- if...else...语句
- 当该语句执行时,会先对if后的条件表达式进行求值判断,
- 如果该值为true,则执行if后的语句
- 如果该值为false,则执行else后的语句
if(age >= 60){ alert("你已经退休了~~"); }else{ alert("你还没退休~~~"); }
语法三:
- if(条件表达式){
- 语句...
- }else if(条件表达式){
- 语句...
- }else if(条件表达式){
- 语句...
- }else{
- 语句...
- }
- if...else if...else
- 当该语句执行时,会从上到下依次对条件表达式进行求值判断
- 如果值为true,则执行当前语句。
- 如果值为false,则继续向下判断。
- 如果所有的条件都不满足,则执行最后一个else后的语句
- 该语句中,只会有一个代码块被执行,一旦代码块执行了,则直接结束语句
if(age > 17 && age <= 30){ alert("你已经成年了"); }else if(age > 30 && age <= 60){ alert("你已经中年了"); }else if(age > 60 && age <= 80){ alert("你已经退休了"); }else{ alert("你岁数挺大的了~~"); }
switch
- 语法:switch(条件表达式){case 表达式: 语句... break;case 表达式: 语句... break;default: 语句... break;}
- 执行流程:
- 在执行时会依次将case后的表达式的值和switch后的条件表达式的值进行全等比较,
- 如果比较结果为true,则从当前case处开始执行代码。
- 当前case后的所有的代码都会执行,我们可以在case的后边跟着一个break关键字,
- 这样可以确保只会执行当前case后的语句,而不会执行其他的case
- 如果比较结果为false,则继续向下比较
- 如果所有的比较结果都为false,则只执行default后的语句
- switch...case..语句
var num = 3; switch(num){ case 1: con("壹"); //使用break可以来退出switch语句 break; case 2: con("贰"); break; case 3: con("叁"); break; default: con("非法数字~~"); break; }
2. 循环语句
while循环
- 语法:while(条件表达式){ 语句...}
- while语句在执行时,
- 先对条件表达式进行求值判断,
- 如果值为true,则执行循环体,
- 循环体执行完毕以后,继续对表达式进行判断
- 如果为true,则继续执行循环体,以此类推
- 如果值为false,则终止循环
do...while循环
- 语法:
- do{
- 语句...
- }while(条件表达式)
- 执行流程:
- do...while语句在执行时,会先执行循环体,
- 循环体执行完毕以后,在对while后的条件表达式进行判断,
- 如果结果为true,则继续执行循环体,执行完毕继续判断以此类推
- 如果结果为false,则终止循环
var i = 11; while(i <= 10){ //3.定义一个更新表达式,每次更新初始化变量 document.write(i++ +"<br />") do{ document.write(i++ +"<br />"); }while(i <= 10)
for循环
- for循环的语法:for(①初始化表达式;②条件表达式;④更新表达式){ ③语句...}
- for循环的执行流程:
- ①执行初始化表达式,初始化变量(初始化表达式只会执行一次)
- ②执行条件表达式,判断是否执行循环。
- 如果为true,则执行循环③
- 如果为false,终止循环
- ④执行更新表达式,更新表达式执行完毕继续重复②
for(var i = 0 ; i < 10 ; i++ ){ alert(i); }
- for循环中的三个部分都可以省略,也可以写在外部如果在for循环中不写任何的表达式,只写两个;此时循环是一个死循环会一直执行下去,慎用 for(;;){ alert("hello"); }
break
- break关键字可以用来退出switch或循环语句
- 不能在if语句中使用break和continue
- break关键字,会立即终止离他最近的那个循环语句
for(var i=0 ; i<5 ; i++){ con("@外层循环"+i) for(var j=0 ; j<5; j++){ break; con("内层循环:"+j); }
- 可以为循环语句创建一个label,来标识当前的循环
- label:循环语句
- 使用break语句时,可以在break后跟着一个label,
- 这样break将会结束指定的循环,而不是最近的
outer: for(var i=0 ; i<5 ; i++){ con("@外层循环"+i) for(var j=0 ; j<5; j++){ break outer; con("内层循环:"+j); } }
continue
- continue关键字可以用来跳过当次循环
- 同样continue也是默认只会对离他最近的循环循环起作用
for(var i=0 ; i<5 ; i++){ if(i==2){ continue; } con(i); }
事件
- onmousemove
- 该事件将会在鼠标在元素中移动时被触发
解决事件对象的兼容性问题
event = event || window.event;
坐标
- clientX可以获取鼠标指针的水平坐标
- cilentY可以获取鼠标指针的垂直坐标
- var x = event.clientX; var y = event.clientY;
- pageX和pageY可以获取鼠标相对于当前页面的坐标
事件的冒泡(Bubble)
- 冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
- 将事件对象的cancelBubble设置为true,即可取消冒泡
- event.cancelBubble = true;
事件的委派
- 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素从而通过祖先元素的响应函数来处理事件。
- 事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
- target
- event中的target表示的触发事件的对象
window.onload = function(){ var u1 = document.getElementById("u1"); //点击按钮以后添加超链接 var btn01 = document.getElementById("btn01"); b = 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; i == "link"){ alert("我是ul的单击响应函数"); } }; };
事件绑定
- b = function(){ alert(2); };
- 对象.事件 = 函数 的形式绑定响应函数
- b("click",function(){ alert(1); },false);
- 参数:1.事件的字符串,不要on2.回调函数,当事件触发时该函数会被调用3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
- addEventListener() 这个方法也可以为元素绑定响应函数
- addEventListener()中的this,是绑定事件的对象
- 兼容多个浏览器
- function bind(obj , eventStr , callback){
i){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数
callback.call(obj);
});
}
}
事件的传播
- 1.捕获阶段
- 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
- 2.目标阶段
- 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
- 3.冒泡阶段
- 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
- 希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
function bind(obj , eventStr , callback){ i){ //大部分浏览器兼容的方式 obj.addEventListener(eventStr , callback , true); }else{ /* * this是谁由调用方式决定 * callback.call(obj) */ //IE8及以下 obj.attachEvent("on"+eventStr , function(){ //在匿名函数中调用回调函数 callback.call(obj); }); } }
滚动的事件
- onmousewheel鼠标滚轮滚动的事件
- 火狐需要使用 DOMMouseScroll 来绑定滚动事件
- event.wheelDelta 可以获取鼠标滚轮滚动的方向
- 火狐中使用event.detail来获取滚动的方向
//判断鼠标滚轮滚动的方向 i > 0 || event.detail < 0){ //向上滚,box1变短 box1. = box1.clientHeight - 10 + "px"; }else{ //向下滚,box1变长 box1. = box1.clientHeight + 10 + "px"; }
键盘事件
- onkeydown 按键被按下
- onkeyup 按键被松开
- keyCode 来获取按键的编码
- altKey ctrlKey shiftKey
- 这个三个用来判断alt ctrl 和 shift是否被按下
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #box1{ width: 100px; height: 100px; background-color: red; position: absolute; } </style> <script type="text/javascript"> //使div可以根据不同的方向键向不同的方向移动 /* * 按左键,div向左移 * 按右键,div向右移 * 。。。 */ window.onload = function(){ //为document绑定一个按键按下的事件 document.onkeydown = function(event){ event = event || window.event; //定义一个变量,来表示移动的速度 var speed = 10; //当用户按了ctrl以后,速度加快 i){ speed = 500; } /* * 37 左 * 38 上 * 39 右 * 40 下 */ switc){ case 37: //alert("向左"); left值减小 box1. = box1.offsetLeft - speed + "px"; break; case 39: //alert("向右"); box1. = box1.offsetLeft + speed + "px"; break; case 38: //alert("向上"); box1. = box1.offsetTop - speed + "px"; break; case 40: //alert("向下"); box1. = box1.offsetTop + speed + "px"; break; } }; }; </script> </head> <body> <div id="box1"></div> </body> </html>
字符串
- 创建一个字符串
- var str = "Hello Atguigu";
length属性
- 可以用来获取字符串的长度
con);
charAt()
- 可以返回字符串中指定位置的字符
- 根据索引获取指定的字符
str = "中Hello Atguigu";
var result = (6);
charCodeAt()
- 获取指定位置字符的字符编码(Unicode编码)
result = (0);
S()
- 可以根据字符编码去获取字符
result = S(0x2692);
indexof()
- 该方法可以检索一个字符串中是否含有指定内容
- 如果字符串中含有该内容,则会返回其第一次出现的索引
- 如果没有找到指定的内容,则返回-1
- 可以指定一个第二个参数,指定开始查找的位置
lastIndexOf();
- 该方法的用法和indexOf()一样,
- 不同的是indexOf是从前往后找,
- 而lastIndexOf是从后往前找
- 也可以指定开始查找的位置
str = "hello hatguigu"; result = ("h",1); result = ("h",5);
slice()
- 可以从字符串中截取指定的内容
- 不会影响原字符串,而是将截取到内容返回参数:
- 第一个,开始位置的索引(包括开始位置)
- 第二个,结束位置的索引(不包括结束位置)
- 如果省略第二个参数,则会截取到后边所有的也可以传递一个负数作为参数,负数的话将会从后边计算
str = "abcdefghijk"; result = (1,4); result = (1,-1);
substring()
- 可以用来截取一个字符串,可以slice()类似参数:
- 第一个:开始截取位置的索引(包括开始位置)
- 第二个:结束位置的索引(不包括结束位置)
- 不同的是这个方法不能接受负值作为参数,如果传递了一个负值,则默认使用0而且他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换
result = (0,1);
substr()
- 用来截取字符串参数:
- 1.截取开始位置的索引
- 2.截取的长度
str = "abcdefg";
result = (3,2);
split()
可以将一个字符串拆分为一个数组 参数: 需要一个字符串作为参数,将会根据该字符串去拆分数组
str = "abcbcdefghij";
result = ("d");
- 如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素
result = ("");
toUpperCase()
- 将一个字符串转换为大写并返回
toLowerCase()
- 将一个字符串转换为小写并返回
数组(Array)
创建数组对象
1.构造函数创建数组
var arr = new Array();
var arr2 = new Array(10,20,30);
- 使用typeof检查一个数组时,会返回objectcon(typeof arr);
2.使用字面量来创建数组
var arr = [];
- 字面量创建数组时,可以在创建时就指定数组中的元素
var arr = [1,2,3,4,5,10];
向数组中添加元素
- 语法:数组[索引] = 值
arr[0] = 10; arr[1] = 33; arr[2] = 22; arr[3] = 44;
读取数组中的元素
- 语法:数组[索引]
con(arr[3]);
获取数组的长度
- 语法:数组.length
- 连续的数组,使用length可以获取到数组的长度(元素的个数)
- 非连续的数组,使用length会获取到数组的最大的索引+1
con);
修改length
- 如果修改的length大于原长度,则多出部分会空出来
- 如果修改的length小于原长度,则多出的元素会被删除
arr.length = 10;
向数组的最后一个位置添加元素
arr[arr.length] = 70;
//创建一个数组数组中只有一个元素10 arr = [10]; //创建一个长度为10的数组 arr2 = new Array(10); //con); //数组中的元素可以是任意的数据类型 arr = ["hello",1,true,null,undefined]; //也可以是对象 var obj = {name:"孙悟空"}; arr[arr.length] = obj; arr = [{name:"孙悟空"},{name:"沙和尚"},{name:"猪八戒"}]; //也可以是一个函数 arr = [function(){alert(1)},function(){alert(2)}]; //con(arr); //arr[0](); //数组中也可以放数组,如下这种数组我们称为二维数组 arr = [[1,2,3],[3,4,5],[5,6,7]]; con(arr[1]);
var arr = ["孙悟空","猪八戒","沙和尚"]
push()
- 该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精");
pop()
- 该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
result = arr.pop();
unshift()
- 向数组开头添加一个或多个元素,并返回新的数组长度
arr.unshift("牛魔王","二郎神");
shift()
- 可以删除数组的第一个元素,并将被删除的元素作为返回值返回
result = arr.shift();
遍历
for(var i=0 ; i<arr.length ; i++){ con(arr[i]); }
forEach()
- 需要一个函数作为参数
- 第一个参数,就是当前正在遍历的元素
- 第二个参数,就是当前正在遍历的元素的索引
- 第三个参数,就是正在遍历的数组
arr.forEach(function(value , index , obj){ con(value); });
slice()
- 从数组提取指定元素
- 不会改变元素数组,而是将截取到的元素封装到一个新数组中返回
- -1 倒数第一个
- -2 倒数第二个
- 索引可以传递一个负值,如果传递一个负值,则从后往前计算
- 1.截取开始的位置的索引,包含开始索引
- 2.截取结束的位置的索引,不包含结束索引
- 参数:
var result = arr.slice(1,4);
splice()
- 删除数组中的指定元素
- splice()会影响到原数组,会将指定元素从原数组中删除
- 将被删除的元素作为返回值返回
- 第一个,表示开始位置的索引
- 第二个,表示删除的数量
- 第三个及以后。。可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边
- 参数:
var result = arr.splice(3,0,"牛魔王","铁扇公主","红孩儿");
var arr = ["孙悟空","猪八戒","沙和尚"]; var arr2 = ["白骨精","玉兔精","蜘蛛精"]; var arr3 = ["二郎神","太上老君","玉皇大帝"];
concat()
- 连接两个或多个数组,并将新的数组返回
- 不会对原数组产生影响
var result = arr.concat(arr2,arr3,"牛魔王","铁扇公主");
join()
- 将数组转换为一个字符串
- 不会对原数组产生影响,而是将转换后的字符串作为结果返回
arr = ["孙悟空","猪八戒","沙和尚","唐僧"];
result = arr.join("@-@");
reverse()
- 反转数组(前边的去后边,后边的去前边)
- 直接修改原数组
arr.reverse();
sort()
- 对数组中的元素进行排序
- 也会影响原数组,默认会按照Unicode编码进行排序
arr.sort();
我们可以在sort()添加一个回调函数,来指定排序规则, 回调函数中需要定义两个形参, 浏览器将会分别使用数组中的元素作为实参去调用回调函数 使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边 浏览器会根据回调函数的返回值来决定元素的顺序, 如果返回一个大于0的值,则元素会交换位置 如果返回一个小于0的值,则元素位置不变 如果返回一个0,则认为两个元素相等,也不交换位置 如果需要升序排列,则返回 a-b 如果需要降序排列,则返回b-a
arr = [5,4,2,1,3,6,8,7]; arr.sort(function(a,b){ //前边的大 /*if(a > b){ return -1; }else if(a < b){ return 1; }else{ return 0; }*/ //升序排列 //return a - b; //降序排列 return b - a; });
算术运算符
- 当对非Number类型的值进行运算时,会将这些值转换为Number然后在运算
- 任何值和NaN做运算都得NaN
+
- +可以对两个值进行加法运算,并将结果返回
- 如果对两个字符串进行加法运算,则会做拼串 会将两个字符串拼接为一个字符串,并返回
- 任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串的操作
-
- 可以对两个值进行减法运算,并将结果返回
*
- 可以对两个值进行乘法运算
/
- / 可以对两个值进行除法运算
%
- % 取模运算(取余数)
result = a + 1; result = 456 + 789; result = true + 1; result = true + false; result = 2 + null; result = 2 + NaN;
一元运算符
- 正号
- 正号不会对数字产生任何影响
正则表达式
创建正则表达式的对象
- var 变量 = new RegExp("正则表达式","匹配模式");
- i 忽略大小写
- g 全局匹配模式
- 在构造函数中可以传递一个匹配模式作为第二个参数
test()
使用这个方法可以用来检查一个字符串是否符合正则表达式的规则, 如果符合则返回true,否则返回false
var str = "a";
var result = reg.test(str);
字面量来创建正则表达式
- var 变量 = /正则表达式/匹配模式
var reg = /a/i;
创建一个正则表达式,检查一个字符串中是否有a或b
- 使用 | 表示或者的意思
reg = /a|b|c/;
[]里的内容也是或的关系
[ab] == a|b [a-z] 任意小写字母 [A-Z] 任意大写字母 [A-z] 任意字母 [0-9] 任意数字 [^ ] 除了
量词
* - 通过量词可以设置一个内容出现的次数 * - 量词只对它前边的一个内容起作用 * - {n} 正好出现n次 * - {m,n} 出现m-n次 * - {m,} m次以上 * - + 至少一个,相当于{1,} * - * 0个或多个,相当于{0,} * - ? 0个或1个,相当于{0,1}
var reg = /a{3}/; //ababab reg = /(ab){3}/; reg = /b{3}/; reg = /ab{1,3}c/; reg = /ab{3,}c/; reg = /ab+c/; reg = /ab*c/; reg = /ab?c/;
^ 表示开头
$ 表示结尾
reg = /^a/; //匹配开头的a reg = /a$/; //匹配结尾的a
. 表示任意字符
- 在正则表达式中使用\作为转义字符 . 来表示. \ 表示\
\w 任意字母、数字、_ [A-z0-9]\W除了字母、数字、 A-z0-9_ \d 任意的数字 [0-9]\D除了数字 0-9 \s空格\S除了空格 \b 单词边界\B除了单词边界
电子邮件
var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;