JavaScript入门
Posted 黄强
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript入门相关的知识,希望对你有一定的参考价值。
JS介绍
// javascript的发明人 // 布兰登·艾奇(Brendan Eich),用了十天时间发明了JavaScript模型 // JavaScript简称JS // JavaScript是什么? // 1.脚本语言 // 编译语言:需要把代码编译成计算机所认知的二进制语言才能执行 // 脚本语言:不需要编译,直接执行 // 2.解释性语言 // 解释性语言:遇到一行代码就解释一行代码 // 其他语言:把所有代码编译完成后在执行代码 // 3.动态类型的语言 // 4.基于对象的语言 // 5.弱类型语言 // 弱类型语言:声明变量都用var,会自动辨别类型:var num = 10; var num2 = 10.23; // 强类型语言:声明变量的时候必须写上对应变量的类型:int num = 10; double num2 = 10.23; // JS分三个部分: // 1.ECMAScript js的基本语法 // 2.DOM Document Object Model 文档对象模型 // 3.BOM Browser Object Model 浏览器对象模型 // js代码注意问题 // 1.如果script的标签中有错误的js代码,那么这对script标签就不会执行 // 2.如果有一个script标签代码错误,但它不会影响其他的script标签 // 3.script标签在页面中可以多对出现 // 4.script标签一般放在body标签内容的最后,可以放在head中 // 5.如果script标签引用外部js文件,那么就不要在这对标签里面放任何js代码
数据输出输入
// 在浏览器弹出的提示框中显示 alert(); // 在浏览器的控制台中显示 console.log(); // 在浏览器页面中显示 document.write(); // 在浏览器中弹出输入框 prompt();
JS变量
/*什么是变量: 变量是计算机内存中存储数据的标识符,根据变量名可以获取到内存中存储的数据*/ /*为什么使用变量: 使用变量可以方便的获取或者修改内存的数据*/ // 变量的作用: // 操作数据:存储数据、读取数据 /*变量名的规范: 一般以字母,$符号,下划线开头 变量名一般都是小写,如果是多个单词,那么第一个单词的首字母小写,后面的单词首字母大写 变量名不能是关键字 区分大小写*/ // 变量声明 var name;// 有var 有变量名字但没有赋值 // 声明多个变量 var name,age,sex; // 变量的初始化:声明变量同时赋值 var xiu = undefined;// 声明变量没有赋值默认为undefined:未定义 var number = 20;// 存储一个数字(number) var name = "修抗";// 存储一个字符串(string) 字符串应该用单引号或者双引号包裹起来 var flag = true;// 存储一个真(true) 假(false) var nll = null;// 存储一个空(null) // 声明多个变量依次赋值 var num1,num2,num3; num1 = 10; num2 = 20; num3 = 30; // 声明多个变量并赋值 var num1 = 10,num2 = 20,num3 = 30; // 变量的交换(1) var num1 = 10,num2 = 20; var num3;//重新声明一个变量 num3 = num1;//num3 = num1 = 10 num1 = num2;//num1 = num2 = 20 num2 = num3;//num2 = num3 = 10 // 变量的交换(2)一般适用于数字的交换 var num4 = 10,num5 = 20; num4 = num4 + num5;//10+20=30 num5 = num4 - num5;//30-20=10 num4 = num4 - num5;//30-10=20 // 变量的交换(3) var num6 = 10,num7 = 20; num6 = num6 ^ num7; num7 = num6 ^ num7; num6 = num6 ^ num7;
JS数据类型
/* 原始数据类型:number,string,boolean,undefined,null,object 基本类型:number,string,boolean 复杂类型:object 空类型:undefined,null 基本类型的值在栈空间存储 复类类型的值在堆空间存储,然后在栈空间引用堆空间的地址 */ // 获取变量的数据类型 var xiu = "修抗"; console.log(typeof(xiu)); //string
进制介绍
// 八进制(数字前面加一个0代表八进制) var num = 012; // 十进制 var num2 = 10; // 十六进制(数字前面加一个0x代表十六进制) var num3 = 0xa; /*二进制-->十进制 1----1----0----0----1----0----1----0----1(二进制) 256--128--64---32---16---8----4----2----1 256--128--0----0----16---0----4----0----1(十进制) 二进制:110010101 = 256+128+0+0+16+0+4+0+1 = 405:十进制 */ /*二进制-->八进制 110----010----101(二进制) 6------2------5(八进制/每三位二进制为一组) 二进制:110010101 = 625:八进制 */ /*二进制-->十六进制 1----1001----0101(二进制) 1----9-------5(十六进制/每四位二进制为一组) 二进制:110010101 = 195:十六进制 */ /*十进制-->二进制 405-202-101-50--25--12--6---3---1 1---0---1---0---1---0---0---1---1(倒叙) 十进制:405 = 110010101:二进制 */
数字(Number)
// 小数类型和整数类型都是数字类型(Number) //数字的最大值和最小值 console.log(Number.MAX_VALUE);//最大值 console.log(Number.MIN_VALUE);//最小值 // Infinity 无穷大 // -Infinity 无穷小 // 小数的bug console.log(0.1+0.2);//结果不是0.3而是0.30000000000000004 // 不要用NaN验证NaN var xiu; console.log(xiu+10);//返回NaN console.log("你好" == "我好");//false:都是字符串,但是字符串内容不一样 console.log(xiu+10 == NaN);//false:都是NaN,但是里面的值不一样 // isNaN()判断是否不是数字,如果不是数字返回true
console.log(isNaN(NaN));
字符串(String)
// 字符串可以使用单引号,也可以使用双引号 var str = "xiu "; var str2 = ‘kang‘; // 查看字符串的长度 console.log(str.length); // 字符串拼接,用+链接 // 如果两边只要有一边为字符串,那么+就为拼接 // 如果两边都是数字。那么就是算术功能 var str3 = "1"; var str4 = ‘2‘; console.log(str3 + str4);//12
Boolean类型/Undefined类型/Null类型
// Boolean类型 // 布尔类型只有两个值 true(真) false(假) var flag = true; // Undefined // 表示声明一个变量没有赋值,变量只有声明的时候值默认为undefined var unde = undefined; // null类型 // 表示一个空,变量的值如果为空,必须手动设置 var str = null;
类型转换
// 其他类型转为数字类型:三种方式 // parseInt();转整数 console.log(parseInt("8sa"));//8 console.log(parseInt("as8"));//NaN console.log(parseInt("8.9"));//8 console.log(parseInt("8.2as"));//8 console.log(parseInt("sa6.8"));//NaN // parseFloat();转小数 console.log(parseFloat("8sa"));//8 console.log(parseFloat("as8"));//NaN console.log(parseFloat("8"));//8 console.log(parseFloat("8.9as"));//8.2 console.log(parseFloat("sa6.8"));//NaN // Number();转数字 console.log(Number("8sa"));//NaN console.log(Number("as8"));//NaN console.log(Number("8"));//8 console.log(Number("8.9as"));//NaN console.log(Number("sa6.8"));//NaN // 其他类型转为字符串类型:两种方式 // toString;不能转换没有意义的变量:null、undefined var xiu = 10; console.log(xiu.toString()); // String(); var kang = 20; console.log(String(kang)); // 其他类型转为布尔类型 // Boolean(); console.log(Boolean(0));//false console.log(Boolean(""));//false console.log(Boolean(null));//false console.log(Boolean(undefined));//false
运算符
// x+y // x和y是操作数 +是操作符 // 算术运算符(+、-、*、/、%) 10%4;//10除于4的余数 // 一元运算符(++、--) // 这个运算符只需要一个操作数就可以运算的表达式 // 前+ 后+ 前- 后- var x = 2; var y = 2; console.log(x++ +3);//5,后+,先参与运算,运算结束后在+1 console.log(x);//3 console.log(++y +3);//6,前+,先+1,然后在参与运算 console.log(y);//3 // 二元运算符() // 这个运算符需要两个个操作数就可以运算的表达式 // 三元运算符() // 这个运算符需要三个操作数就可以运算的表达式 // var 变量 = 表达式1 ? 表达式2 : 表达式3 // 如果表达式1结果为true,就执行表达式2,然后把表达式2的结果给变量 // 如果表达式1结果为false,就执行表达式3,然后把表达式3的结果给变量 var sear = true ? 1 : 2;//sear=1 // 复合运算符(+=、-=、*=、/=、%=) var num; num+=10;//num=num+10; // 关系运算符(<、>、<=、>=、!=、==、===、!=、!==) var xiu = "10"; var kang = 10; console.log(xiu==kang);//两个值都一样所以为true console.log(xiu===kang);//值一样,但是类型不一样所有为false // 逻辑运算符($$与-并且、 ||或-或者、 !非-取反、) console.log(true && true);//两个为true则为true console.log(true || false);//一个为true则为true console.log(!false);//false为true,true为false /* 运算符的优先级 1.() 优先级最高 2.一元运算符 ++ -- ! 3.算术运算符 先* / 后 + - 4.关系运算符 < <= > >= 5.相等运算符 == != === !== 6.逻辑运算符 先&& 在|| 7.赋值运算符 = */
流程控制
// 流程控制:代码的执行过程 // 流程控制的三种方式: // 1.顺序结构 // 从上到下,从左往右执行的顺序叫顺序结构(不严谨) // var xiu = 2;(不严谨的原因:先找到2,然后在将2赋值给xiu) // 2.分支结构 // if语句 /* if(表达式1) { 代码块1 }else if(表达式2) { 代码块2 }else { 代码块3 } 先运行表达式1,如果表达式1为true就执行的代码块1,如果为false就执行表达式2 如果表达式2,如果表达式2为true就执行的代码块2,如果为false就执行代码块3 else if()可以多次出现,也可以不写 else 只能出现一次,也可以不写 */ var x = prompt("请输入数字");//prompt()弹出一个输入框 if(x > 5){ console.log("大于5"); }else if(x < 5) { console.log("小于5"); }else if(x == 5) { console.log("等于5"); }else { console.log("请输入数字"); } // switch-case /* switch(表达式){ case 值1: 代码块;break; case 值2: 代码块;break; case 值3: 代码块;break; default:代码4; } 获取表达式的值,然后和值依次比较,如果和值相等执行相对应的代码块,遇到break跳出switch语句 如果和值都不相等,那么就执行default语句 表达式的值跟case的值比较是严格模式的比较(===) default可以省略 break可以省略:省略后不会跳出语句 会依次往下执行 */ var y = prompt("请输入1到3的整数"); switch(y){ case "1":console.log(y); break;//该语句为跳出语句 case "2":console.log(y); break; case "3":console.log(y); break; default:console.log("请输入1到3的整数"); } // 三元表达式 // 3.循环结构 // while /* var 变量 = 0; while(条件){ 循环体; 计数器; } 如果条件为false,就不执行while大括号里面的内容 如果条件为true,就执行循环体,然后执行计数器,循环结束后计数器+1,然后又去判断条件,直到条件为false停止循环 */ var xiu = 0;//计数器 while(xiu<10){ console.log(xiu);//循环体 xiu++;//计数器+1 } // do-while /* do { 循环体 }while(条件); 先执行循环体,然后在判断条件是否成立,如果为true继续执行循环体,然后在判断条件,直到条件为false跳出循环 */ var kang = 0; do { console.log(kang); kang++; }while(kang<0); // for /* for(表达式1;表达式2;表达式3;){ 循环体; } 先获取表达式1的值,然后判断表达式2,如果为false跳出循环,如果为true就执行循环体然后在执行表达式3,然后继续执行表达式2,直到条件为false */ for (var i = 1; i <= 10; i++) { console.log(i); }
break与continue关键字
// break关键字 // 作用:在循环中使用,遇到break则跳出当前循环 while(true){ console.log("修抗"); break;//本来是一个死循环,但是遇到break就跳出循环,所有就执行一次 } // continue关键字 // 作用:在循环中使用,遇到continue直接执行下次循环 // 输出10以内的奇数 var i = 0; while(i<10){ if(i%2==0){ i++; continue;//如果为偶数就继续下次循环 } document.write(i); i++; }
数组(Array)
// 数组:存储一组有序的数据 // 作用:可以一次性存储多个数据 // 数组的定义: /* 1.通过构造函数创建数组 var 数组名 = new Array(); var 数组名 = new Array(长度); 如果Array中只有一个值(整数),那么这个值就是该数组的长度(元素就个数) 如果有多个值,那么这些值就是该数组的数据(数组的长度就是有多少个值) */ var array = new Array();//创建一个空数组,没有数据 var array2 = new Array("25");//如果数组中没有数据,但有长度,那么数组的每个值就是undefined /* 2.通过字面量的方式创建数组 var array = []; */ var array3 = [];//创建空数组 var array4 = [3,34,46,7];//创建数组并添加数据 /* 数组元素:就是数组中存储的数据 数组个数:就是数组中元素的个数 数组下标:从0开始,到数组长度减1结束 通过下标设置数组元素值:数组名[下标] = 值 通过下标访问数组元素值:数组名[下标] */ // 获取数组的长度 array.length; // 注意: 数组中的数据类型可以不一样,但一般存储一样的数据,数组的长度可以任意改变 var array5 = [10,"哈哈",true,undefined,null,new Object()]; // 遍历数组 var array6 = [2,5,72,58,3,52]; for(var i=0;i<array6.length;i++){ console.log(array6[i]); } // 求数组的和 var array7 = [1,2,3,4,5]; var sum = 0; for(var i=0;i<array7.length;i++){ sum+=array7[i]; } console.log(sum); // 求数组的平均值 var array8 = [1,2,3,4,5]; var avg = 0; for(var i=0;i<array8.length;i++){ avg+=array8[i]; } console.log(avg/array8.length); // 求数组的最大值 var array9 = [1,2,3,4,5]; var max = array9[0]; for(var i=1;i<array9.length;i++){ if(max<array9[i]){ max=array9[i]; } } console.log(max); // 数组的倒叙 var array10 = [1,2,3,4,5]; for(var i=array10.length-1;i>=0;i--){ console.log(array10[i]); } // 去掉数组中的0 var array11 = [1,0,3,0,5]; var newArray11 = []; for(var i=0;i<array11.length;i++){ if(array11[i] != 0){ newArray11[newArray11.length] = array11[i]; } } console.log(newArray11); // 冒泡排序:把所有数据按照一定顺序进行排序(从大到小,从小到大) var arr = new Array(3,36,2,47,42,436,54); for (var i=0;i<arr.length-1;i++) { for(var j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){ var tame = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tame; } } } console.log(arr);
函数(function)
/* 函数:将重复的代码进行封装,在需要的时候进行调用 定义函数: function 函数名(){ 函数体; } 调用函数: 函数名(); 函数参数: 定义函数的时候,函数名后面的小括号里的变量就是参数 function 函数名(x,y){ 函数体; } 形参:定义函数时小括号里面的参数 function 函数名(x,y){ 函数体; } 实参:调用函数时小括号里面的参数 函数名(x,y); 函数的返回值: 在函数内部有return关键字并且关键字后面有内容,那么这个内容就是返回值 在调用的时候,如果需要返回值,就定义变量接收就行了 function 函数名(){ return 520; } var fun = 函数名();//此时fun变量的值就是函数返回的值 无参数无返回值的函数 function xiu(){ console.log("修抗"); } 无参数有返回值的函数 function xiu(){ return "修抗"; } 有参数无返回值的函数 function xiu(x,y){ console.log(x+y); } 有参数有返回值的函数 function xiu(x,y){ return x+y; } 命名函数:函数有名字 匿名函数:函数没有名字 定义匿名函数: function(){ 函数体; } 匿名函数不能直接调用,需要赋值给变量才能调用(这就是函数表达式) var fun = function(){ 函数体; } fun();//在变量后面添加小括号就可以调用匿名函数了 函数的自调用: (匿名函数)(); (function(){alert("修抗");})(); 函数做为参数使用: 如果一个函数作为参数使用,那么这个参数(函数)就是回调函数 function xiu(){ kang(); } function kang(){ 函数体; } 函数做为返回值使用: function xiu(){ return function(){ 函数体; }; } var kang = xiu();//将xiu的返回值赋值给变量,现在变量就是一个函数 kang();//直接加小括号掉用就行了 注意: 函数一旦重名,就会把前面的函数覆盖 匿名函数就不会出现重名的问题 形参和实参的个数可以不一致 函数没有明确返回值,但调用的时候接收了,那么接收的值为undefined 没有明确返回值:没有return或者return后面没有跟任何内容 return后面的代码不会执行 函数也有数据类型:function类型 */
函数中的几个参数
function f1(x,y){ //获取的函数的名字,只读 console.log(f1.name); // 获取实参的个数 console.log(f1.arguments.length); // 获取形参的个数 console.log(f1.length); // 调用者,如果该函数被其他函数调用,那么该属性就输出其他函数的源码 console.log(f1.caller); } f1(1,2);
sort()
// sort()对数组的元素进行排序,并返回数组 var arr = ["dfg","dgh","dsgar"]; arr.sort(function(x,y){ if(x>y){ return 1; }else if(x==y){ return 0; }else { return -1; } }); console.log(arr);
闭包
/* 闭包的概念: 在函数A中有一个函数或者对象,该函数或者对象可以访问函数A中定义的变量或者数据,此时形成了闭包 闭包的模式: 函数模式的闭包,对象模式的闭包 闭包的作用: 缓存数据,延长作用域链 闭包的优点缺点: 优点:可以缓存数据,缺点:缓存数据的同时不能释放空间 局部变量是在函数中,函数使用结束后,局部变量就会被自动释放 闭包后,里面的局部变量的使用作用域就会被延长,不会被释放 */ // 函数模式的闭包:在一个函数中有一个函数 function f1(){ var num = 10; function f2(){ console.log(num); } f2(); } f1(); // 对象模式的闭包:在一个函数中有一个对象 function f3(){ var num = 3; var obj = {age:num}; console.log(obj.age); } f3(); // 列子: function person(){ var num = 1; return function(){ num++; console.log(num); } } var per = person(); per();//2 per();//3 per();//4
沙箱
作用域
/* 局部变量:在函数内部定义的变量叫局部变量,只能在函数内部才能使用 全局变量:除了函数以外在其他任意位置定义的变量叫全局变量,可以在页面任意位置使用 隐式全局变量:声明变量的时候没有var就是隐式全局变量(可以在页面任意位置使用) 局部作用域:局部变量的使用范围 全局作用域:全局变量的使用范围 块级作用域:大括号里面定义的变量只能在当前大括号里面使用,而js不支持块级作用域(函数除外) 注意: 定义全局变量,只要页面不关闭就会一直占空间,消耗内存(就是卡),只有在页面隔壁的时候才会释放空间 定义局部变量,就只有在调用的时候占空间,调用完后就会释放空间(所以尽量使用局部变量) 全局变量不能被删除而隐式全局变量可以被删除,删除变量(delete 变量名;) 作用域链: var sum = 0; function f1(){ var sum = 1; f2(); function f2(){ var sum = 2; f3(); function f3(){ var sum = 3; alert(sum); } } } 如果当前没有变量就会去上一级找变量,没有继续去上一级,直到全局变量,这就是作用域链 */
预解析
// 预解析:提前解析代码 // 提前解析变量 console.log(sum);//输出undefined var sum = 0; /* 理解:浏览器帮我们做的事,浏览器将声明变量提前了,但没有把赋值提前 var sum; console.log(sum);//因为声明变量没有赋值,所以就是undefined sum = 0; */ // 提前解析函数 xiu(); function xiu(){ console.log("爱心"); } /* 理解:浏览器帮我们做的事,浏览器将声明的函数提前了 function xiu(){ console.log("爱心"); } xiu(); */ // 同时解析函数和变量 kang(); function kang(){ console.log(str); } var str = "埃辛"; /* 理解:浏览器帮我们做的事,浏览器先将声明的变量提前然后在将声明的函数提前 var str; function kang(){ console.log(str); } kang(); str = "埃辛"; */
函数声明出现的问题
/* 函数的声明 function f1(){} 函数表达式 var f1 = function(){}; */ if(true){ function f1(){ console.log("true"); } }else { function f1(){ console.log("false"); } } f1(); // 在IE10及之前输出的结果都是false,因为会把函数的声明提前 // 解决办法就是使用函数表达式,函数表达式不会被提前 var f2; if(true){ f2 = function(){ console.log("true"); } }else { f2 = function(){ console.log("false"); } } f2();
创建对象
/* 编程思想: 把一些生活中的经验融入到程序中 面向过程: 每件事的具体过程要知道,注重的是过程 面向对象: 所有的事都用对象来做,注重的是结果 面向对象的基本特性: 封装,继承,多态(抽象性) 对象的特征: 有属性或者方法
面向对象的编程思想:
根据需求,找出相关的对象,总结对象的特征和行为,把特征变成属性,行为变成方法,然后定义构造函数,实例化对象,通过对象调用属性或者方法,完成对应的需求,这就是编程思想 js不是面向对象的语言,但是可以模拟面向对象的思想 js是一门基于对象的语言 */ // 第一种方式创建对象:调用系统自带的构造函数 new Object() var obj = new Object(); obj.name = "修抗"; //添加属性1 obj.sex = "男"; //添加属性2 obj.xiu = function(){ //添加方法1 console.log("方法1"); } obj.kang = function(){ //添加方法2 console.log("方法2"); } // 调用属性的两种方式 console.log(obj.name); //对象.属性 console.log(obj["sex"]); //对象["属性"] // 调用方法的两种方式 obj.xiu(); //对象.方法名() obj["kang"](); //对象["方法名"]() // 第二种方式创建对象:自定义一个构造函数,然后在创建对象 // 创建自定义构造函数,构造函数与函数的区别在于首字母是否大写 function Person(name,age){ //添加属性 this.name = name; this.age = age; //添加方法 this.type = function(){ console.log("我叫"+this.name+",今年"+this.age+"岁"); }; } //调用自定义的构造函数创建对象,同时对属性进行初始化(实例化对象) var obj2 = new Person("修抗",24); // 调用属性和方法 console.log(obj2.name); obj2.type(); // 第三种方式创建对象:工厂模式创建对象 // 把创建对象的代码放在函数中,返回值就是这个对象, function createObject(name,age){ var obj3 = new Object(); obj3.name = name; obj3.age = age; obj3.xiu = function(){ console.log("我叫"+this.name+",今年"+this.age+"岁"); } return obj3; } var kang = createObject("修抗",20); kang.xiu(); // 第四种方式创建对象:字面量创建对象 // 方式1: var obj4 = {}; obj4.name = "修抗";// 添加属性 obj4.type = function(){// 添加方法 alert("方法"); } // 方式2: var obj5 = { name: "修抗", type:function(){ alert("方法2") } };
遍历对象的属性和值
var obj = { name : "修抗", age : 20 } for(key in obj){ console.log(key);//属性 console.log(obj[key]);//值 }
工厂模式和自定义构造函数的区别
// 自定义创建对象 function Penson(name){ this.name = name; } var obj = new Penson("修抗"); console.log(obj.name); //工厂模式创建对象 function createObj(){ var obj2 = new Object(); obj2.name = "爱心"; return obj2; } var obj3 = createObj(); console.log(obj3.name); /* 自定义创建对象与工厂模式创建对象的区别 自定义创建对象: 函数名是大写(首字母) 没有new 没有返回值 this是当前对象 通过new的方式创建对象 工厂模式创建对象: 函数名是小写 有new 有返回值 new之后的对象是当前对象 直接调用函数就可以创建对象 他们的共同点:都是函数,都可以创建对象,都可以传入参数 */
构造函数和实例对象之间的关系
// 自定义构造函数创建对象 function Person(name){ this.name = name; } //实例化对象 var obj = new Person("修抗"); // console.dir()可以把对象的构造显示出来 console.dir(Person);//输出构造函数 console.dir(obj);//输出实例化对象 console.log(Person.prototype.constructor == Person);//true console.log(obj.__proto__.constructor == Person);//true console.log(obj.constructor == Person);//true console.log(obj instanceof Person);//true /* 实列对象和构造函数的关系 实列对象是通过构造函数来创建的,创建的过程叫实例化 判断对象的数据类型(自定义对象) 1. 通过构造器的方式: 实列对象.构造器(constructor) == 构造函数的名字 obj.constructor == Person 2. 对象 instanceof 构造函数名字 obj instanceof Person */
构造函数创建对象带来的问题
function Person(name,age){ this.name = name; this.age = age; this.type = function(){ console.log("修抗"); } } var obj1 = new Person("修抗",20); var obj2 = new Person("修抗",20); // 他们指向的方法不是同一个方法,那么就开辟了不同的空间,浪费内存 console.log(obj1.type == obj2.type);//false // 解决办法 function f1(){ console.log("修抗"); } function Person2(name){ this.name = name; this.type = f1; } var obj3 = new Person2("修"); var obj4 = new Person2("修"); // 此时他们指的是同一个方法,节省空间,但函数可能重名,发生不必要的问题 console.log(obj3.type == obj4.type);//true // 可以使用原型解决该办法:原型的作用之一就是数据共享,节省内存空间
原型及原型链
//构造函数 function Person(name,age){ this.name = name; this.age = age; } // 实例化对象并初始化 var p1 = new Person("修抗",20); var p2 = new Person("爱惜",20); console.dir(Person);//查看构造函数的结构 console.dir(p1);//查看实列对象的结构 /* 实列对象中有两个属性(这两个属性是通过构造函数获取的) 构造函数中并没有name和age这两个属性 实列对象中有个属性,__proto__,也是对象,叫原型,不是标准属性,浏览器使用的 构造函数中有个属性,prototype,也是对象,叫原型,是标准属性,程序员使用的 constructor:构造函数 */ // 实列对象和构造函数的原型指向的是同一个构造函数 console.log(Person.prototype.constructor == p1.__proto__.constructor);//true // 通过原型添加方法 Person.prototype.type = function(){ console.log("修抗"); } // 因为他们指向的是同一个原型里面的构造函数里面的方法,是同一个方法 console.log(p1.type == p2.type);//true // 原型链:是一种关系,实列对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的
改变原型的指向和添加改变后的原型方法
function Person(){}; Person.prototype.sayHi = function(){ console.log("打招呼"); }; function Student(){}; Student.prototype.eat = function(){ console.log("牛皮"); }; Student.prototype = new Person(); var obj = new Student(); obj.sayHi(); // obj.eat();//报错 /* 实列对象的原型__proto__指向的是该对象所在的构造函数的原型对象 构造函数的原型对象(prototype)指向如果改变了,实列对象的原型(__proto__)指向也会发生改变 实列对象和原型对象之间的关系是通过__proto__原型来联系起来的,这个关系就是原型链 */
原型链最终的指向
function Person(){}; Person.prototype.sayHi = function(){ console.log("打招呼"); }; var obj = new Person(); console.dir(Person); // 实列对象中__proto__原型 // 构造函数中prototype原型 // 实列对象的原型和构造函数的原型指向是同一个地方 console.log(Person.prototype == obj.__proto__);//true // prototype是对象,那么对象就有原型 __proto__ // 实列对象中的__proto__原型指向的是构造函数的prototype // 构造函数的prototype的__proto__的指向是Object的prototype console.log(Person.prototype.__proto__ == Object.prototype);//true //Object的prototype的指向就是null console.log(Object.prototype.__proto__);//null
原型列子
<div id="dv"></div> <input type="button" id="btn" value="按钮"/> <script> function Person(btnObj,dvObj,json){ this.btnObj = btnObj; this.dvObj = dvObj; this.json = json; } Person.prototype.inio = function(){ var that = this; this.btnObj.onclick = function(){ // 当前this为按钮对象,所以需要在外面添加一个this变量 for(var key in that.json){ that.dvObj.style[key] = json[key]; } } } var dv = document.getElementById("dv"); var btn = document.getElementById("btn"); var json = {"width":"200px","height":"400px","backgroundColor":"red"}; //大概意思就是把添加样式的代码封装在构造函数中,方法在原型中添加 //点击按钮为id节点设置多个样式 var obj = new Person(btn,dv,json); obj.inio(); </script>
构造函数,实列对象,原型对象之间的区别
// 构造函数 function Person(name,age){ this.name = name; this.age = age; } // 通过构造函数创建实列对象,并初始化 var obj = new Person("修抗",20); // 构造函数里面的prototype属性指向的是构造函数里面的原型 // 通过构造函数为原型添加一个方法 Person.prototype.type = function(){ console.log("方法"); } // 原型对象里面的constructor指向的是自己所在的原型对象所在的构造函数中 console.log(Person.prototype.constructor);//输出的是Person构造函数 // 实列对象里面的__proto__属性指向构造函数里面的原型的方法 obj.__proto__.type();//调用原型里面的方法 // 构造函数的原型对象中的方法可以被实例化对象直接访问 obj.type();//调用原型里面的方法
构造函数的属性或者方法的搜索方式
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.name = "修抗"; var obj = new Person("小子",20); console.log(obj.name);//修抗 /* 实列对象使用属性或者方法, 先在实列中查找,有则直接使用, 无则去实列对象的__proto__指向的原型对象prototype中找,有则使用,没有则报错 */
为内置对象的原型对象添加方法
console.dir(Array); //内置对象的方法一般都在该构造函数指向的原型中 // 那么就可以通过构造函数的原型添加内置对象的方法 Array.prototype.mySort = function(){ for (var i = 0; i < this.length-1; i++) { for (var j = 0; j < this.length-1-i; j++) { if(this[j]>this[j+1]){ var time = this[j]; this[j] = this[j+1]; this[j+1] = time; } } } } var arr = [3,51,543,62,31,5]; // 使用自定义的内置方法 arr.mySort(); console.log(arr);
局部变量变成全局变量
//函数自调用 // (function(){ // var num = 10; // })(); // console.log(num);//报错,因为num是局部变量,无法在函数外使用 (function(){ var num = 10; // js是一门动态类型的语言,对象没有属性,点了就有了 // window是浏览器的顶级对象 window.num = num; })(); console.log(window.num);//10 console.log(num);//10
原型及原型链
function Person(){}; Person.prototype.sayHi = function(){ console.log("打招呼"); }; function Student(){}; Student.prototype.eat = function(){ console.log("牛皮"); }; Student.prototype = new Person(); var obj = new Student(); obj.sayHi(); // obj.eat();//报错 /* 实列对象的原型__proto__指向的是该对象所在的构造函数的原型对象 构造函数的原型对象(prototype)指向如果改变了,实列对象的原型(__proto__)指向也会发生改变 实列对象和原型对象之间的关系是通过__proto__原型来联系起来的,这个关系就是原型链 */
继承
/* 面向对象的基本特性 封装: 把一个值放在变量中叫封装 把重复的代码放在函数中叫封装 把重复的属性放在对象中叫封装 把功能类似的函数(方法)放在对象中叫封装 把类似的对象放在一个js文件中叫封装 继承: 面向对象的编程语言中有类(class)的概念,但是js不是面向对象的语言,所以js中没有类,但是js可以模拟面向对象的思想编程,js会通过构造函数来模拟类的概念 首先继承是一种关系,类与类之间的关系,js通过构造函数模拟类,然后通过原型来实现继承 继承是为了数据共享,js中的继承也是为了实现数据的共享 继承的关系:父类与子类的关系 多态: 一个对象有不同的行为,或者是同一个行为针对不同的的对象产生不同的结果,想要有多态,就要先有继承js中可以模拟多态,但不会使用,也不会模拟,因为数据不能共享,会占用大量内存空间 */ // 原型的作用之一:数据共享,节省内存空间 // 原型的作用之二:为了实现继承 /* 列子: Person的数据共享给Student就叫继承 */ function Person(name,age){ this.name = name; this.age = age; } Person.prototype.type = function(){ console.log("玩"); } function Student(score){ this.score = score; } // 通过改变原型的指向来模拟继承 Student.prototype = new Person("小明",20); Student.prototype.Study = function(){ console.log("学习"); } var stu = new Student("100"); // 人的方法和属性 console.log(stu.name);//小明 console.log(stu.age);//20 stu.type();//玩 // 学生的方法和属性 console.log(stu.score);//100 stu.Study();//学习
// 优点:继承了方法和属性
// 缺陷:改变原型指向的同时赋值了,那么子类调用的时候直接使用了父类初始化的属性
借用构造函数继承
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.type = function(){ console.log("玩"); } function Student(score,name,age){ Person.call(this,name,age); this.score = score; } Student.prototype.study = function(){ console.log("学习"); } var obj = new Student(20,"小明",30); console.log(obj.score);//20 console.log(obj.name);//小明 console.log(obj.age);//30 obj.study(); /* 借用构造函数: 把继承父类的构造函数拿过来使用 借用构造函数:构造函数的名字.call(当前对象,属性,属性...) 解决了属性继承,并且值不重复的问题 缺陷,无法继承父类的继承 */
组合继承
/* 原型实现继承 借用构造函数实现继承 组合继承:原型继承+借用构造函数继承 */ function Person(name,age){ this.name = name; this.age = age; } Person.prototype.sayHi = function(){ console.log("打招呼"); } function Student(score,naem,age){ // 借用构造函数实现继承 Person.call(this,name,age); this.score = score; } // 改变原型的指向 Student.prototype = new Person(); Student.prototype.eat = function(){ console.log("玩耍"); } var obj = new Student(10,20,100); console.log(obj.name); console.log(obj.age); console.log(obj.score); obj.sayHi(); obj.eat(); // 优点:父类的属性和方法都被继承了
apple()与call()
/* apply()和call()的作用: 改变this的指向 使用语法: 函数名字.apply(对象,[参数1,参数2...]); 方法名字.apply(对象,[参数1,参数2...]); 函数名字.call(对象,参数1,参数2...); 方法名字.call(对象,参数1,参数2...); */ // 修改函数的this指向 function f1(x,y){ console.log((x+y)+"..."+this); } // "use strict";//严格模式 // 在严格模式下,如果没有window,this指向为undefined // window.f1(1,2);//3...undefined f1(1,2);//3...window var obj = new Object(); // 通过apple或者call改变函数中的this指向 f1.apply(obj,[1,2]);//3...Object // 修改方法的this指向 function Person(age){ this.age = age; } Person.prototype.sayHi = function(x,y){ console.log((x+y)+"..."+this.age); } function Stuendt(age){ this.age = age; } var per = new Person(10); var stu = new Stuendt(20); // sayHi是per的实列对象 // 通过apple或者call改变了this的指向 per.sayHi.apply(stu,[1,2]);//3...20(此时的this.age是stu实列对象中的this) per.sayHi.call(stu,1,2);//3...20
bind()
/* bind的作用:复制一份然后在改变this的指向 使用语法: 函数名字.bind(对象,参数1,参数2...);返回值是复制后的这个函数 方法名字.bind(对象,参数1,参数2...);返回值是复制后的这个方法 */ // 修改函数的this指向 function f1(x,y){ console.log((x+y)+"..."+this); } f1(1,2);//3...window var obj = new Object(); // 复制一份的时候,把参数传入到f1函数中,x-->1,y-->2,obj就是this,默认为window // bind方法是复制的意思,参数可以在复制的时候传进去,也可以在复制之后传进去 var ff = f1.bind(obj); ff(1,2);//3...Object // 修改方法的this指向 function Person(age){ this.age = age; } Person.prototype.sayHi = function(x,y){ console.log((x+y)+"..."+this.age); } function Stuendt(age){ this.age = age; } var per = new Person(10); var stu = new Stuendt(20); // sayHi是per的实列对象 var pers = per.sayHi.bind(stu,1,2);//此时的this.age是stu实列对象中的this pers();//3...20
函数也是对象
function f1(){ console.log("哈哈"); } // f1是函数,也是对象 console.dir(f1); // 对象调用方法,说明该对象有这个方法 f1.call(); f1.apply(); // 所用的函数都是Function的实列对象 console.log(f1.__proto__ == Function.prototype);//true // 在构造函数Function的原型中就有call()和apply()方法 console.dir(Function);
拷贝继承
// 拷贝继承:把一个对象的属性或者方法复制到另外一个对象中 var obj = { name : "小明", type : function(){ console.log("修抗"); } }; // 方式1: // 改变的地址指向 var obj2 = obj; console.log(obj2.name); obj2.type(); // 方式2: // 通过for循环遍历对象依次赋值给新对象 var obj3 = {}; for(var key in obj){ obj3[key] = obj[key]; } console.log(obj3.name); obj3.type(); function Person(){}; Person.prototype.age = 10; Person.prototype.play = function(){ console.log("xiu"); } // 方式3: // 拷贝原型中的方法及属性 var obj4 = {}; for(var key in Person.prototype){ obj4[key] = Person.prototype[key]; } console.log(obj4.age); obj4.play();
内置对象
// 内置对象:自带的对象 // 在线文档(百度MDN):https://developer.mozilla.org/zh-CN/ // 常见的内置对象: /* 全局对象 Infinity--无穷大 escape()--加密字符串 unescape()--解码字符串 encodeURI()--加密字符串为URI decodeURI()--为加密的URI进行解码 encodeURIComponent()--将字符串加密为URI组件 decodeURIComponent()--为加密的URI组件解码 isFinite(number)--判断一个值是否是数字 isNaN(string)--判断一个值是否不是数字 Number(string)--将一个值转换为数字 parseFloat(string)--将一个值转换为小数 parseInt(string)--将一个值转换为整数 String(string)--将一个值转换为字符串 Boolean(string)--将一个值转换为布尔 */ /* Number对象 MAX_VALUE--最大数字 MIN_VALUE--最小数字 NaN--非数字 */ /* Boolean对象 toString()--将布尔值转换为字符串,并且返回结果 */ /* String对象 length--返回字符串的字符长度 fontcolor(color)--设置字符串的颜色(<FONT COLOR=>) Fontsize(size)--设置字符串的大小(<FONTSIZE=>) italics()--设置字符串的斜字体(<I>) Link(url)--设置字符串的a标签(<A HREF=>) strike()--设置字符串的删除线(<STRIKE>) sub()--设置字符串的下标(subscript)字体((SUB>) sup()--设置字符串的上标(superscript)字体(<SUP>) charAt(index)--返回指定索引处的字符 concat(string2)--连接两条或多条字符串 indexOf(searchString, startIndex)--返回字符串中第一个出现指定字符串的位置 lastlndexOf(searchString, startIndex)--返回字符串中最后一个出现指定字符串的位置 match(regex)-- 在字符串中查找指定值 replace(regex, newString)--将字符串中的某些字符替换成其它字符 slice(startIndex, endIndex)--将部分字符抽出并在新的字符串中返回剩余部分 split(delimiter)--将字符串分配为数组 substr(startIndex, length)-- 从startIndex取,取length个字符 substring(startIndex, endIndex)-- 从startIndex和endIndex之间的字符,不包括endIndex toLowerCase()-- 把字符串中的文本变成小写 toUpperCase()-- 把字符串中的文本变成大写 */ /* Array对象 length--获取数组元素的个数,即最大下标加1 concat(array1,arrayn)--合并数组,合并后返回结果 join(string)--将数组中元素合并为字符串,string为分隔符.如省略参数则直接合并,不再分隔 shift()--移除数组中的第一个元素并返回该元素 pop()--移除数组中的最后一个元素并返回该元素 unshift(value)为数组的开始部分加上一个或多个元素,并且返回该数组的新长度 push(value)--在数组的末尾加上一个或多个元素,并且返回新的数组长度值 reverse()--反转数组 sort()--按照元素的字母顺序排列,如果不是字符串类型则转换成字符串再排序,返回排序后的数组 toString()--将数组所有元素返回一个字符串,其间用逗号分隔 */ /* 9.Date对象 getDay()--返回一周中的第几天(0-6) getFullYear()--返回完整的4位年份数 getMonth()--返回月份数(0-11) getDate()--返回日(1-31) getHours()--返回小时数(0-23) getMinutes()--返回分钟(0-59) getSeconds()--返回秒数(0-59) getMilliseconds()--返回毫秒(0-999) toString()--将日期对象转换为字符串 */ /* Math对象 PI--∏的值(约等于3.14159) abs(x)--返回数字的绝对值 ceil(x)--返回 x 四舍五入后的最大整数 floor(x)--返回 x 四舍五入后的最小整数 max(x,y)--返回 x 和 y 之间较大的数 min(x,y)--返回 x 和 y 之间较小的数 pow(x,y)--返回 y^x 的值 random()--返回位于 0 到 1 之间的随机函数 round(x)--四舍五入后取整 */
基本包装类型
// 普通变量不能直接调用属性或者方法 // 对象可以直接调用属性或者方法 // 普通变量在执行代码的过程中调用的属性或者方法,那么此时的普通类型就变成了基本包装类型,此时的变量就是基本包装类型对象 // 基本包装类型有number,string,boolean var str = "修抗";//普通变量 str = str.replace("抗","康");//基本包装类型 var num = 10;//基本类型 var num2 = Number("10");//类型转换 var num3 = new Number("10");//基本包装类型 // 如果一个对象&&true,那么结果为true // 如果一个true&&对象,那么结果为对象 var fleg = new Boolean(false); console.log(fleg&&true);//true console.log(true&&fleg);//function
DOM介绍
// DOM:文档对象模型 // DOM就是把html看作一个文档,然后用DOM操作这些标签 // 文档(document):一个网页可以成为文档 // 元素(element):页面中所有的标签都是元素,元素可以看作一个对象 // 节点(node):页面中所有内容都是节点:标签,属性,文本 // 属性:标签的属性 // 根(root) // 文档及文档中的所有元素组成一个树形结构图:树状图(DOM树)
为元素注册事件
<!-- 要求:为按钮添加一个点击事件 事件源:button 事件名字:onclick 触发事件:点击时 响应:alert(‘...‘) -->
<!-- 第一个版本 --> <!-- html代码中嵌入js代码:不方便后期修改和维护 --> <button onclick="alert(‘第1个版本‘)">按钮1</button> <!-- 第二个版本 --> <!-- js代码很多,但是没有与js分离,只是把js写入函数中,调用就行了 --> <button onclick="xiu()">按钮2</button> <script> function xiu(){ alert("第2个版本"); } </script> <!-- 第三个版本 --> <!-- js与html分离 --> <button id="sear">按钮3</button> <script> // 获取id为sear的标签,标签就是元素,元素就是对象 var searObj = document.ElementById(sear);//返回一个元素对象 searObj.onclick = function(){ alert("第3个版本"); } </script>
DOM获取元素的方法
<!-- 根据id属性的值获取元素,返回来的是一个元素对象 document.getElementById("id的值"); --> <a href="#" id="av">百度</a> <input type="button" value="修改a标签的href属性值" id="but1"/> <script> // 要求:点击按钮修改a标签的href属性值 // 先通过id获取按钮并添加点击事件(onclick) document.getElementById("but1").onclick = function(){ // 然后在获取a标签并修改href属性的值 // 注:用DOM获取的标签就是元素,元素就是对象,可以通过对象修改属性的值 document.getElementById("av").href = "http://www.baidu.com"; } </script> <!-- 根据标签名字获取元素,返回来的是一个伪数组,里面保存了多个DOM对象 document.getElementsByTagName("标签的名字"); --> <p>段落</p> <p>段落</p> <p>段落</p> <input type="button" value="修改所有p标签的内容" id="but2"/> <script> // 要求:点击按钮修改所有p标签的内容 // 先通过id获取按钮并添加点击事件(onclick) document.getElementById("but2").onclick = function(){ // 然后获取所有的p标签并修改其内容 var pObj = document.getElementsByTagName("p");//是一个伪数组,数组里面的元素就是p标签 // 是一个伪数组,所以需要for循环遍历 for(var i=0;i<pObj.length;i++){ // 小提示:凡是成对的标签设置文本内容都使用innerText pObj[i].innerText = "修改"; } } </script> <!-- 根据name属性的值获取元素,返回来的是一个伪数组,里面保存了多个DOM对象 document.getElementsByName("name的值"); --> <input type="button" value="修改name=‘xiu‘的value值" id="but3"/> <input type="text" value="你好" name="xiu"/> <input type="text" value="你好" name="kang"/> <input type="text" value="你好" name="xiu"/> <script> // 要求:点击按钮修改name=‘xiu‘的value值 // 先通过id获取按钮并添加点击事件(onclick) document.getElementById("but3").onclick = function(){ var xiuObj = document.getElementsByName("xiu");//是一个伪数组 for(var i=0;i<xiuObj.length;i++){ // 小提示:在文本框中设置文本值就是设置value值 xiuObj[i].value = "修改"; } } </script> <!-- 根据类样式的名字来获取元素,返回来的是一个伪数组,里面保存了多个DOM对象 document.getElementsByClassName("class的值"); --> <input type="button" value="修改class=‘xiu‘的文本值" id="but4"/> <span class="xiu">修抗</span> <span>修抗</span> <span class="xiu">修抗</span> <script> // 要求:点击按钮修改class=‘xiu‘的文本值 // 先通过id获取按钮并添加点击事件(onclick) document.getElementById("but4").onclick = function(){ var classObj = document.getElementsByClassName("xiu");//是一个伪数组 for(var i=0;i<classObj.length;i++){ classObj[i].innerText = "修改"; } } </script> <!-- 根据选择器获取元素,返回来的是一个元素对象 document.querySelector("选择器的名字"); --> <input type="button" value="修改id=‘dv‘的样式" id="but5"/> <div id="dv"></div> <script> // 要求:点击按钮修改id=‘dv‘的样式 // 先通过id获取按钮并添加点击事件(onclick) document.getElementById("but5").onclick = function(){ document.querySelector("#dv").style.width = "300px"; document.querySelector("#dv").style.height = "300px"; // 在css中属性是多个单词的写法,那么在js操作DOM的时候,不要-,后面的单词首字母大写 // background-color: red;(css) // backgroundColor = "red";(js) document.querySelector("#dv").style.backgroundColor = "red"; } </script> <!-- 根据选择器获取元素,返回来的是一个伪数组,里面保存了多个DOM对象 document.querySelectorAll("选择器的名字"); --> <input type="button" value="修改所有p标签的内容" id="but6"/> <div class="kang">修抗</div> <div class="kang">修抗</div> <div class="kang">修抗</div> <script> // 要求:点击按钮修改class=‘kang‘的文本值 // 先通过id获取按钮并添加点击事件(onclick) document.querySelector("#but6").onclick = function(){ var kangObj = document.querySelectorAll(".kang");//是一个伪数组 for (var i = 0; i < kangObj.length; i++) { kangObj[i].innerText = "aixin"; } } </script>
操作DOM的案例(0)
<!-- 点击按钮显示和隐藏文字 --> <input type="button" value="隐藏" id="but"/> <p id="xiu">修抗</p> <script> //小提示:如果操作DOM的id属性有点多,那么可以将这个DOM操作封装起来,直接调用 function my$(id){ return document.getElementById(id); } my$("but").onclick = function(){ if(this.value == "隐藏"){ my$("xiu").style.display = "none";//隐藏 this.value = "显示"; }else if(this.value == "显示"){ my$("xiu").style.display = "block";//显示 this.value = "隐藏"; } } </script>
操作DOM的案例(1)
<!-- 点击按钮选中单选框/复选框(表单操作) --> <input type="button" value="修改性别" id="but"/> <input type="radio" value="男" name="sex" />男 <input type="radio" value="女" name="sex"/>女 <!-- checked="checked":选中 在表单标签中,如果属性和值只有一个时,并且这个值就是这个属性本身 那么在html中,值可以默认不写:checked 在js的DOM操作的时候,值为布尔类型:checked = true --> <script> document.getElementById("but").onclick = function(){ var radioObj = document.getElementsByTagName("input"); if(radioObj[1].checked == false){ radioObj[1].checked = true; }else if(radioObj[1].checked == true){ radioObj[2].checked = true; } } </script>
操作DOM的案例(2)
<!-- 点击按钮为div添加class属性(css样式操作) --> <style> .cls { width: 100px; height: 100px; border: 1px solid red; } </style> <input type="button" value="按钮" id="but"/> <div id="xiu"></div> <script> // <div id="xiu" class="cls"></div> // 在js代码中操作DOM的时候,设置元素的类样式时,不能使用class关键字,应该使用calssName document.getElementById("but").onclick = function(){ document.getElementById("xiu").className = "cls"; } </script>
操作DOM的案例(3)
<!-- 点击按钮隔行换色 --> <input type="button" value="按钮" id="but"/> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <script> document.querySelector("#but").onclick = function(){ var list = document.querySelectorAll("li"); for(var i=0;i<list.length;i++){ list[i].style.backgroundColor = i%2==0 ? "yellow" : "red"; } } </script>
操作DOM的案例(4)
<!-- 高亮效果(css的hover效果) --> <ul id="uu"> <li>1</li> <li>2</li> </ul> <script> // onmouseover:鼠标进入事件 // onmouseout:鼠标移出事件 // 先获取id=‘uu‘里面的li标签,是一个伪数组 var listObj = document.getElementById("uu").getElementsByTagName("li"); for (var i = 0; i < listObj.length; i++) { listObj[i].onmouseover = function(){ this.style.backgroundColor = "red"; } listObj[i].onmouseout = function(){ this.style.backgroundColor = ""; } } </script>
操作DOM的案例(5)
<!-- 模拟搜索框的效果 --> <input type="text" value="请输入搜索内容" id="txt" style="color:gray" /> <script> // onfocus获取焦点 // onblur失去焦点 var txt = document.getElementById("txt"); txt.onfocus = function(){ if(this.value == "请输入搜索内容"){ this.value = ""; this.style.color = "#000"; } } txt.onblur = function(){ if(this.value.length == 0){ this.style.color = "gray"; this.value = "请输入搜索内容"; } } </script>
操作DOM的案例(6)
<!-- 点击验证文本框的长度是否合法 --> <input type="text" id="txt" /> <input type="button" id="but" value="按钮"/> <script> document.getElementById("but").onclick = function(){ var txtObj = document.getElementById("txt"); if(txtObj.value.length>3 && txtObj.value.length<6){ alert("YES"); }else { alert("NO:账号长度应该大于3并且小于6,当前长度为"+txtObj.value.length ); } } </script>
修改标签中的文本内容
<!-- textContent 作用:为标签设置或者调用文本内容 谷歌火狐支持,IE8不支持 --> <!-- 要求:修改p标签里面的内容 --> <input type="button" value="按钮" id="btn1"> <p>爱心</p> <script> document.querySelector("#btn1").onclick = function(){ document.querySelectorAll("p")[0].textContent = "修抗"; } </script> <!-- innerText 作用:为标签设置或调用文本内容 低版本的谷歌火狐不支持,IE8支持 --> <!-- 要求:修改p标签里面的内容 --> <input type="button" value="按钮" id="btn2"> <p>爱心</p> <script> document.querySelector("#btn2").onclick = function(){ document.querySelectorAll("p")[1].innerText = "修抗"; } </script> <!-- 因为不同浏览器支持的属性不一样 所以需要设置兼容代码 原理:如果浏览器不支持该属性,那么该属性的类型为 undefined --> <script> function setInnerText(elen,txt){ if(typeof elen.innerText != "undefined"){ elen.innerText = txt; }else { elen.textContent = txt; } } document.querySelector("#btn1").onclick = function(){ setInnerText(document.querySelectorAll("p")[0],"修改"); } </script>
innerText与innerHTML的区别:
<!-- innerText 主要用于设置文本,如果设置标签内容是没有标签效果的 可以获取标签里面的所有文本内容,但是不能获取标签 innerHTML 可以设置文本内容,也可以设置HTML标签的内容 可以获取标签里面的所有文本内容,也可以获取里面标签 --> <input type="button" value="按钮" id="but"/> <input type="button" value="按钮" id="but2"/> <div id="dv"> 修抗 <p>爱惜</p> </div> <script> function my$(id){ return document.getElementById(id); }; my$("but2").onclick = function(){ // my$("dv").innerText = "<p>修抗<p>";//页面不会解析html标签,会把标签显示出来 my$("dv").innerHTML = "<p>修抗<p>";//页面会解析html标签,不会把标签显示出来 } my$("but").onclick = function(){ // console.log(my$("dv").innerText);//修抗 爱惜 console.log(my$("dv").innerHTML);//修抗 <p>爱惜</p> } </script>
自定义属性操作
<!-- 自定义属性:本身HTML标签没有这个属性,而是自己添加的 作用:为了存储一些数据
自定义属性无法直接通过DOM对象获取(设置)值的,需要借助方法 setAttribute(属性的名字,属性的值):设置自定义属性和值 getAttribute(属性的名字):获取自定义属性的值 --> <ul id="uu"> <!-- score就是自己添加的属性 --> <li>路飞的成绩</li> <li>娜美的成绩</li> <li>索隆的成绩</li> <li>乔巴的成绩</li> <li>山治的成绩</li> </ul> <script> // 要求:点击名字弹出本人的成绩 // 首先获取ul里面的li标签并添加点击事件 var list = document.getElementById("uu").getElementsByTagName("li"); for (var i = 0; i < list.length; i++) { //为标签添加自定义属性和值 list[i].setAttribute("score",(i+1)*10); list[i].onclick = function(){ // alert(this.score);//弹出的都是undefined // 在html中添加的自定义属性,需要使用 getAttribute("自定义属性的名字") 才能获取自定义属性的值 alert(this.getAttribute("score")); } } </script>
移除属性
<!-- removeAttribute:移除元素的属性--> <p id="xiu">按钮</p> <script> //要求:删除p标签的id属性 document.getElementsByTagName("p")[0].removeAttribute("id"); </script>
节点操作
<!-- 节点关系: <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p>内容</p> <div>标签</div> </body> </html> html 的子节点是 head body head body 的父节点是 html meta title 是兄弟节点 --> <div id="dv"> <p id="p1">p标签</p> <span id="sp">span标签</span> <s>s标签</s> </div> <script> var p1 = document.querySelector("#p1"); var dv = document.querySelector("#dv"); var sp = document.querySelector("#sp"); // 获取p标签的父节点(父节点) console.log(p1.parentNode); // 获取p标签的父元素(父元素) console.log(p1.parentElement); // 获取div的子节点(子节点) console.log(dv.childNodes);//5个字节点(换行也是节点) // 获取div的子元素(子元素) console.log(dv.children);//3个字元素 // 获取div的第一个子节点(第一个子节点) console.log(dv.firstChild);//是换行 #text // 获取div的第一个子元素(第一个子元素) console.log(dv.firstElementChild);//获取的是p标签 // 获取div的最后一个子节点(最后一个子节点) console.log(dv.lastChild);//是换行 #text // 获取div的最后一个子元素(最后一个子元素) console.log(dv.lastElementChild);//获取的是s标签 // 获取span的前一个兄弟节点(前一个兄弟节点) console.log(sp.previousSibling);//是换行 #text // 获取span的前一个兄弟元素(前一个兄弟元素) console.log(sp.previousElementSibling);//获取的是p标签 // 获取span的后一个兄弟节点(后一个兄弟节点) console.log(sp.nextSibling);//是换行 #text // 获取span的后一个兄弟元素(后一个兄弟元素) console.log(sp.nextElementSibling);//获取的是s标签 // 获取div的id属性节点() console.log(dv.getAttributeNode("id"));//id=‘p1‘ // 节点的属性: // nodeType 节点的类型(返回数字 1标签 2属性 3文本) // nodeName 节点的名字(标签节点-大写的标签名字 属性节点-小写的属性名字 文本节点-#text) // nodeValue 节点的值(标签节点-null 属性节点-属性值 文本节点-文本内容) //标签 var p2 = document.querySelector("#p1"); console.log(p2.nodeType);//1 console.log(p2.nodeName);//P console.log(p2.nodeValue);//null // 属性 var typeP = p2.getAttributeNode("id"); console.log(typeP.nodeType);//2 console.log(typeP.nodeName);//id console.log(typeP.nodeValue);//p1 </script>
创建元素的几种方式
<script> // 将DOM操作id的DOM封装起来 function my$(id){ return document.getElementById(id); } </script> <!-- oppendChild(obj); 把新元素追加到子元素后面 --> <input type="button" value="按钮1" id="but1" /> <div id="dv1"></div> <script> // 先创建一个元素 var i = 0; my$("but1").onclick = function(){ i++; var butObj = document.createElement("input"); butObj.type = "button"; butObj.value = "按钮"+i; my$("dv1").appendChild(butObj); } </script> <!-- insertBefore(newObj,obj); 把新元素追加到指定子元素前面 --> <input type="button" value="按钮2" id="but2" /> <div id="dv2"></div> <script> // 先创建一个元素 my$("but2").onclick = function(){ i++; var butObj = document.createElement("input"); butObj.type = "button"; butObj.value = "按钮"+i; my$("dv2").insertBefore(butObj,my$("dv2").firstElementChild); } </script> <!-- replaceChild(); 替换子元素 --> <input type="button" value="按钮3" id="but3" /> <div id="dv3"> <p>修抗</p> </div> <script> document.getElementById("but3").onclick = function(){ var sObj = document.createElement("s"); sObj.innerHTML = "xiukang"; var dv3Obj = document.querySelector("#dv3"); dv3Obj.replaceChild(sObj,dv3Obj.firstElementChild); } </script> <!-- removeChild(obj); 删除子元素 --> <input type="button" value="按钮4" id="but4" /> <div id="dv4"> <p>修抗1</p> <p>修抗2</p> <p>修抗3</p> </div> <script> my$("but4").onclick = function(){ while(my$("dv4").firstElementChild){ my$("dv4").removeChild(my$("dv4").firstElementChild); } } </script>
只创建一个元素
<input type="button" value="按钮" id="btn"/> <div id="dv"></div> <script> // 只创建一个元素 // 思路:判断有没有该元素,有则删除,无则创建 var i=0; document.getElementById("btn").onclick = function(){ i++; var pObj = document.createElement("p"); pObj.id = "xiu"; pObj.innerHTML = "修抗"+i; if(document.getElementById("xiu")){ document.getElementById("dv").removeChild(document.getElementById("xiu")); } document.getElementById("dv").appendChild(pObj); } </script>
克隆节点
<div> <a href="#"><img src="images/timg.jpg" alt=""></a> </div> <script> /* 克隆节点 cloneNode(true) 参数为布尔类型:true表示连子节点一起克隆 */ var aObj = document.getElementsByTagName("a")[0].cloneNode(false); document.getElementsByTagName("div")[0].appendChild(aObj); </script>
为元素添加多个重复的事件
<!-- addEventListener() 参数1:事件的类型,没有on 参数2:事件的处理函数 参数3:布尔类型,目前就写false this指向当前绑定的对象 谷歌,火狐支持,IE8不支持 --> <!-- 要求:给按钮添加多个点击事件 --> <input type="button" value="按钮" id="btn1"/> <script> document.getElementById("btn1").addEventListener("click",function(){ console.log("修抗1"); },false); document.getElementById("btn1").addEventListener("click",function(){ console.log("修抗2"); },false); </script> <!-- attachEvent() 参数1:事件的类型 参数2:事件的处理函数 this指向window对象 谷歌,火狐不支持,IE8支持 --> <!-- 要求:给按钮添加多个点击事件 --> <input type="button" value="按钮" id="btn2"/> <script> document.getElementById("btn2").attachEvent("onclick",function(){ console.log("修抗3"); }); document.getElementById("btn2").attachEvent("onclick",function(){ console.log("修抗4"); }); </script> <!-- 因为不同浏览器使用的方法不一样 所以需要设置兼容代码 原理:判断 对象.方法 如果为fasle就不支持该方法 不要小括号(如果有小括号就是该方法的返回值) --> <script> function addEventListener(elem,type,fun){ if(elem.addEventListener){ elem.addEventListener(type,fun,false); }else if(elem.attachEvent){ elem.attachEvent("on"+type,fun); }else { elem["on"+type] = fun; } } addEventListener(document.querySelector("#btn1"),"click",function(){ alert(2); }); </script>
解绑事件
<!-- 方式1: 将事件处理函数设置为null就可以解绑事件了 --> <input type="button" value="绑定事件1" id="btn1"/> <input type="button" value="解除事件1" id="btn2"/> <script> document.getElementById("btn1").onclick = function(){ console.log("绑定事件1"); } document.getElementById("btn2").onclick = function(){ document.getElementById("btn1").onclick = null; } </script> <!-- 方式2: 使用removeEventListener()解除事件 参数1:事件的名字 参数2:处理函数的名字(须是命名函数) 参数3:false IE8不支持 --> <input type="button" value="绑定事件2" id="btn3"/> <input type="button" value="解除事件2" id="btn4"/> <script> function f1(){ console.log("绑定事件2"); } document.querySelector("#btn3").addEventListener("click",f1,false);//设置命名函数 document.querySelector("#btn4").onclick = function(){ document.querySelector("#btn3").removeEventListener("click",f1,false); } </script> <!-- 方式3: 使用detachEvent()解除事件 参数1:事件的名字 参数2:处理函数的名字(须是命名函数) 只有IE8支持 --> <input type="button" value="绑定事件3" id="btn5"/> <input type="button" value="解除事件3" id="btn6"/> <script> function f2(){ console.log("绑定事件3"); } document.querySelector("#btn5").attachEvent("onclick",f2);//设置命名函数 document.querySelector("#btn6").onclick = function(){ document.querySelector("#btn5").detachEvent("onclick",f2); } </script> <!-- 设置解绑函数的兼容代码 --> <script> function removeEventListener(elen,type,funName){ if(elen.removeEventListener){ elen.removeEventListener(type,funName,false); }else if(elen.retachEvent){ elen.retachEvent("on"+type,funName); }else{ elen["on"+type] = null; } } </script>
事件冒泡
<!-- 事件冒泡 有多个元素嵌套,并且这些元素都绑定了相同的事件,如果里面的事件触发了.那么外面元素的事件会主动触发 --> <div id="dv1" style="width:300px;height:300px;background-color: red"> <div id="dv2" style="width:200px;height:200px;background-color: blue"> <div id="dv3" style="width:100px;height:100px;background-color: yellow"></div> </div> </div> <script> document.getElementById("dv1").onclick = function(){ console.log(this.id); } document.getElementById("dv2").onclick = function(){ console.log(this.id); //IE谷歌支持,火狐不支持 window.event.cancelBubble = true; } // 事件处理函数参数对象 document.getElementById("dv3").onclick = function(e){ console.log(this.id); //谷歌火狐支持,IE8不支持 e.stopPropagation(); } </script>
输入框的提示信息
<div id="dv"> <input type="text" id="txt" /> </div> <script> function my$(id){ return document.getElementById(id); } var keyWord = ["小明你好","小杨你不好","小明你不好啊","苹果吃了","苹果不能吃"]; //设置输入框的键盘松开事件(onkeyup) my$("txt").onkeyup = function(){ // 创建一个新数组 var newKeyWord = []; // 获取输入框的值 var text = this.value; for(var i=0;i<keyWord.length;i++){ // 判断是否有该字符并且索引为0 if(keyWord[i].indexOf(text)==0){ // 将元素追加到新数组中 newKeyWord.push(keyWord[i]); } } if(my$("dv1")){ my$("dv").removeChild(my$("dv1")); } // 判断新数组的元素是否为0或者文本框的长度为0 if(newKeyWord.length==0 || this.value.length==0){ if(my$("dv1")){ my$("dv").removeChild(my$("dv1")); } return; } var divObj = document.createElement("div"); divObj.style.width = "158px"; divObj.style.border = "1px solid red"; divObj.id = "dv1"; my$("dv").appendChild(divObj); for (var i = 0; i < newKeyWord.length; i++) { var pObj = document.createElement("p"); pObj.innerHTML = newKeyWord[i]; divObj.appendChild(pObj); } } </script>
BOM介绍
/* 浏览器中的顶级对象:window 页面中的顶级对象:document 页面中所有内容都是属于浏览器的,页面中的内容也是window的 */ var num = 10; console.log(window.num); function f1(){ console.log("修抗"); } window.f1();//方法的本质的函数,函数也是方法 window.document.write("haha"); // 因为页面中的所有内容都是window的,所以window可以省略 alert(window.name);//该属性有点特殊,输出是空白,一般没有的属性输出都是undefined // 下面两个是一样的,如果window被占用了就可以使用top console.log(top); console.log(window);
对话框
// 下面三个方式,尽量在测试的时候用,因为每个浏览器的样式都不同,而且无法改变样式 // 一般用css做出来 window.alert("弹出提示框"); window.prompt("请输入账号"); window.confirm("你确定退出吗");
页面加载事件
window.onload = function(){ alert("页面加载完毕后才触发的事件,页面中的节点包括外部引入的js文件"); } // 扩展事件:谷歌不支持,IE8支持 window.onunload = function(){ alert("页面关闭后才触发的事件"); } window.onbeforeunload = function(){ alert("页面关闭前触发的事件"); }
location对象(浏览器地址栏)
// 获取的是#及后面的内容 console.log(window.location.hash); // 获取的是主机名及端口号 console.log(window.location.host); // 获取的是主机名 console.log(window.location.hostname); // 获取的是文件的相对路径 console.log(window.location.pathname); // 获取的是端口号 console.log(window.port); // 获取的是协议 console.log(window.location.protocol); // 获取的是?及后面的内容 console.log(window.location.search); // 设置浏览器地址并跳转 window.location.href = "https://www.baidu.com";//属性 window.location.assign("https://www.baidu.com");//方法 window.location.replace("https://www.baidu.com");//没有历史记录(不能后退) // 重新加载页面 window.location.reload();
history对象(浏览器前进后退功能)
window.history.forward();//前进 window.history.back();//后退
navigator对象(获取浏览器和操作系统的类型)
//获取当前浏览器的类型 console.log(navigator.userAgent); //获取当前操作系统的类型 console.log(navigator.platform);
定时器
/* 定时器:setInterval() 参数1:函数 参数2:时间(毫米) 返回值:定时器的id 执行过程:每隔一段时间就执行一次函数 */ var timeId = setInterval(function(){ console.log("哈哈"); },1000); /* 停止定时器:clearInterval() 参数:定时器的id */ clearInterval(timeId); /* 一次性定时器:setTimeout 参数1:函数 参数2:时间(毫米) 返回值:定时器的id 执行过程:隔一段时间只执行一次函数 */ var timeId2 = setTimeout(function(){ console.log("只执行一次"); }); /* 停止一次性定时器:clearTimeout() 参数:定时器的id 虽然说一次性定时器执行一次就不执行了,但内存中还是有该定时器存在占空间的 */ claerTimeout(timeId2);
定时器案例1(随机图片位置,动画效果)
<input type="button" id="but1" value="执行"/> <input type="button" id="but2" value="暂停"/><br/> <img src="images/timg.jpg" alt="" width="200"> <script> var timeId; document.getElementById("but1").onclick = function(){ timeId = setInterval(function(){ var x = Math.random()*100+1; var y = Math.random()*100+1; document.querySelectorAll("img")[0].style.marginTop = x+"px"; document.querySelectorAll("img")[0].style.marginLeft = y+"px"; },100); } document.getElementById("but2").onclick = function(){ clearInterval(timeId); } </script>
定时器案例2(等待多少秒点击按钮)
<input type="button" value="重新获取验证码5秒" id="but" disabled/> <script> var time = 5; var timeId = setInterval(function(){ time--; if(time>0){ document.getElementById("but").value ="重新获取验证码"+time+"秒"; }else { document.getElementById("but").value ="重新获取验证码"; document.getElementById("but").disabled = false; clearInterval(timeId); } },1000); </script>
定时器案例3(设置图片渐变透明化,动画效果)
<img src="images/timg.jpg" alt="" width="300" id="im"/> <input type="button" value="渐变" id="but"> <script> document.getElementById("but").onclick = function(){ var opacity = 10; var timeId = setInterval(function(){ opacity--; if(opacity==0){ clearInterval(timeId); } document.getElementById("im").style.opacity = opacity/10; },200); } </script>
定时器案例4(设置div宽度,动画效果)
<input type="button" value="按钮" id="but"> <div id="dv" style="width:100px;height:100px;background-color:red"></div> <script> document.getElementById("but").onclick = function(){ /* 为了防止定时器还没有执行完成就又重新打开定时器 所以需要提前清除定时器 需要在定时器返回值前面添加一个对象 */ clearInterval(document.getElementById("but").timeId); var width = 100; document.getElementById("but").timeId = setInterval(function(){ width+=10; if(width == 400){ clearInterval(document.getElementById("but").timeId); } document.getElementById("dv").style.width = width+"px"; },100); } </script>
定时器案例4(设置div位置,动画效果)
<input type="button" value="移动到200px" id="but"> <input type="button" value="移动到400px" id="but2"> <div id="dv" style="width:100px;height:100px;background-color:red;position:relative"></div> <script> function animate(elem,target){ //获取目标当前位置 var left = elem.offsetLeft; var timeId = setInterval(function(){ // 设置每次移动的步数 var stop = 20; var stop = target>left?stop:-stop; // 设置每次移动后的位置 left+=stop; if(Math.abs(target-left)>Math.abs(stop)){ elem.style.left = left+"px"; }else{ clearInterval(timeId); elem.style.left = target+"px"; } },100); } document.getElementById("but").onclick = function(){ animate(document.getElementById("dv"),200); } document.getElementById("but2").onclick = function(){ animate(document.getElementById("dv"),400); } </script>
offset系列
<style> #dv1{ width: 200px; height: 200px; background-color: red; } #dv2{ width: 100px; height: 100px; background-color: blue; } </style> <div id="dv1" style="width:100px"> <div id="dv2"></div> </div> <input type="button" value="效果" id="btn"> <script> var dv1 = document.getElementById("dv1"); var dv2 = document.getElementById("dv2"); document.getElementById("btn").onclick = function(){ /* 在style标签中设置的样式是获取不到的 只能获取style属性中设置的样式 所以这种方式废了 console.log(dv1.style.width); console.log(dv1.style.height); */ /* 以后获取元素的宽和高,应该使用offset系列来获取 offsetWidth:获取元素的宽 offsetHeight:获取元素的高 offsetTop:获取元素距离上边位置的值 offsetLeft:获取元素距离左边位置的值 注意事项: 如果没有脱离文档流,那么: offsetLeft = 父级元素margin + 父级元素padding + 父级元素的border + 自己的margin 如果脱离文档流,那么: offsetLeft = 自己的Left + 自己的margin offsetTop与offsetLeft是相同的一个道理 */ console.log(dv2.offsetWidth);//100 console.log(dv2.offsetHeight);//100 } </script>
通过document获取元素
//获取的是body标签,如果在外部引用的js中获取的是null console.log(document.body); // 获取的是title标签中的文本 console.log(document.title); // 获取html标签 console.log(document.documentElement);
轮播图
<style> *{ margin: 0; padding: 0; } #lbt { width: 500px; height: 280px; position: relative; margin: 0 auto; overflow: hidden; } #photo { width: 500px; height: 280px; } #photo ul { position: absolute; width: 2000px; } #photo li { list-style: none; float: left; } #focus { width: 500px; position: absolute; top: 140px; color: #fff; text-align: center; line-height: 25px; display: none; } #focus span { display: block; width: 40px; height: 25px; background-color: rgb(0,0,0,0.2); } #focus span:nth-child(1){ float: left; } #focus span:nth-child(2){ float: right; } #serial { position: absolute; right: 10px; bottom: 10px; } s { display: block; width: 15px; height: 15px; background-color: red; float: left; margin: 0 10px; border-radius: 50%; } .s{ background-color: blue; } </style> <div id="lbt"> <!-- 轮播图的图片 --> <div id="photo"> <ul> <li><img src="images/1.jpg" alt="" width="500"></li> <li><img src="images/2.jpg" alt="" width="500"></li> <li><img src="images/3.jpg" alt="" width="500"></li> <li><img src="images/4.jpg" alt="" width="500"></li> </ul> </div> <!-- 轮播图的序列号 --> <div id="serial"> </div> <!-- 轮播图的左右焦点 --> <div id="focus"> <span><</span><span>></span> </div> </div> <script> //将指定目标移动多少距离 function animate(elem,target){ //获取目标当前位置 var left = elem.offsetLeft; var timeId = setInterval(function(){ // 设置每次移动的步数 var stop = 20; var stop = target>left?stop:-stop; // 设置每次移动后的位置 left+=stop; if(Math.abs(target-left)>Math.abs(stop)){ elem.style.left = left+"px"; }else{ clearInterval(timeId); elem.style.left = target+"px"; } },10); } var lbt = document.getElementById("lbt"); // 获取整个轮播图的div var photo = lbt.children[0]; // 获取相框 var ulObj = photo.children[0]; // 获取序列号 var serial = lbt.children[1]; var focus = lbt.children[2]; // 获取左焦点 var leftSpan = focus.children[0]; // 获取右焦点 var rightSpan = focus.children[1]; // 定义一个全局变量 var xiu = 0; // 设置序列号 for (var i = 0; i < ulObj.children.length; i++) { // 创建s标签 var sObj = document.createElement("s"); // 添加自定义属性 sObj.setAttribute("index",i); // 为序列号添加鼠标进入时间 sObj.onmouseover = function(){ // 先删除所有s标签的样式 for (var i = 0; i < serial.children.length; i++) { serial.children[i].removeAttribute("class") } // 然后在当前s标签中添加样式 this.className = "s"; xiu = this.getAttribute("index"); // 将相框移动位置 animate(ulObj,-xiu*500); } // 将创建好的s标签添加到序列号中 serial.appendChild(sObj); } //设置默认第一个序列号的样式 serial.children[0].className = "s"; // 因为做无缝效果,克隆第一张图片并添加到图片最后 ulObj.appendChild(ulObj.children[0].cloneNode(true)) ; // 设置相框的宽度为所有图片宽度总和 ulObj.style.width = ulObj.children.length*500+"px"; //设置显示或者隐藏左右焦点 photo.onmouseover = function(){ focus.style.display = "block"; } photo.onmouseout = function(){ focus.style.display = "none"; } focus.onmouseover = function(){ focus.style.display = "block"; } focus.onmouseout = function(){ focus.style.display = "none"; } // 为右焦点添加点击事件 rightSpan.onclick = rightOver; // 右焦点的点击事件 function rightOver(){ // 判断是不是最后一张图片 if(xiu==ulObj.children.length-1){ xiu = 0; // 因为第一张图片和最后一张图片是一样的 // 所有如果是最后一张图就把图片设置为第一张图片 // 用户可以最后一张图是第一张图片的错觉 ulObj.style.left = 0; serial.children[0].className = "s"; } xiu++; animate(ulObj,-xiu*500); //删除所有序列号样式 for (var i = 0; i < serial.children.length; i++) { serial.children[i].removeAttribute("class") } // 如果是最后一张图片,那么就把第一个序列号设置样式,其他的默认 if(xiu==ulObj.children.length-1){ serial.children[0].className = "s"; }else { serial.children[xiu].className = "s"; } } // 为左焦点添加点击事件 leftSpan.onclick = function(){ if(xiu==0){ xiu = ulObj.children.length-1; ulObj.style.left =-xiu*500+"px"; } xiu--; for (var i = 0; i < serial.children.length; i++) { serial.children[i].removeAttribute("class") } serial.children[xiu].className = "s"; animate(ulObj,-(xiu)*500); } // 设置自动轮播图 // 原理就是重复点右焦点现实轮播图 setInterval(rightOver,1000); </script>
正则表达式
// 中括号 // [0-9]匹配任何从0到9的十进制数 // [a-z]匹配任何小写从a到z的字符 // [A-Z]匹配任何大小从A到Z的字符 // [A-Za-z]匹配任何大写A到小写z的字符 // 量词 // p+。匹配任何至少包含一个字符p的字符串 // p*。匹配任何包含零个或多个字符p的字符串 // p?。匹配任何包含零个或一个字符p的字符串 // p{2}。匹配任何包含两个连续p的字符串 // p{2,3}。匹配任何包含两个或三个连续p的字符串 // p{2,}。匹配任何包含两个或以上p的字符串 // p$。匹配任何以p结尾的字符串 // ^p。匹配任何以p开头的字符串 // [^0-9]。匹配任何不包含0到9的十进制数 // p.p。匹配任何包含p和p之间的字符串 // ^.{2}$。匹配任何只包含两个字符的字符串 // <b>(.*)</b>。匹配任何被<b></b>包围的字符串 // p(hp)*。匹配任何包含一个p,p后面是hp的字符串 // 预定义字符范围(字符类) // [:digit:]数字[0~9] // [:lower:]小写字母[a~z] // [:upper:]大写字母[A~Z] // [:alpha:]大小写字母[A~Za~z] // [:alnum:]大小写字母以及数字[A~Za~z0~9] // [:xdigit:]十六进制字符[A~Fa~f0~9] // [:graph:]33~126范围的可打印ASCII字符 // [:cntrl:]控制字符,如制表符、退格符或反斜杠 // [:space:]空白字符:空格、水平制表符、垂直制表符、换行、换页或换行 // [:punct:]标点符号 // 修饰符 // i不区分大小写 // g查找所有出现 // m将字符串视为多行 // s将字符串视为一行 // x忽略正则表达式中的空格和注释 // 元字符 // A 只匹配字符串开头 // 匹配单词边界 // B 匹配除单词边界之外的任何字符 // d 匹配数字字符 // D 匹配非数字字符 // s 匹配空白字符 // S 匹配非空白字符 // [] 包围一个字符类 // () 包围一个字符分组或定义一个反引用 // $ 匹配行尾 // ^ 匹配行首 // . 匹配除换行之外的任何字符 // 引出下一个元字符 // w 匹配任何只包含数字字母和下划线的字符串 // W 忽略下划线、数字和字母 // 创建正则表达式对象 var reg = new RegExp(/^[a-z]/); // 调用方法验证字符串是否匹配,返回布尔值 var flag = reg.test("sfsdew"); console.log(flag); /* var reg = /^[a-z]/; var flag = reg.test("sfsdew"); console.log(flag); var flag = /^[a-z]/.test("sfsdew"); console.log(flag); */ // 正则表达式的其他方法: var str1 = "费12劲34即56放78解90分"; // 要求:将字符串中的数字提取出来放在数组中 var arr1 = str1.match(/[0-9]+/g); console.log(arr1);//[12,34,56,78,90] var str2 = "2018-08-09"; // 要求:将字符串中的年月日分别提取出来 var arr2 = str2.match(/(d+)[-](d+)[-](d+)/); console.log(RegExp.$1);//2018 console.log(RegExp.$2);//08 console.log(RegExp.$3);//09 var str3 = "修抗你好哟,真的好哟"; // 要求:将字符串中的"好"替换成"不好" var arr3 = str3.replace(/好/g,"不好"); console.log(arr3);//修抗你不好哟,真的不好哟 var str4 = " 修 抗 "; // 要求:删除字符串中的所有空格 var arr4 = str4.replace(/s+/g,""); console.log(arr4); var str5 = "HHhhsabcdhhH"; // 要求:将字符串中的大小写"h"替换成"A" var arr5 = str5.replace(/[h]/gi,"A"); console.log(arr5);//AAAAsabcdAAA
1
以上是关于JavaScript入门的主要内容,如果未能解决你的问题,请参考以下文章