(一)JS初次使用;
1.搭建JS开发环境;
(1)在控制后台输出;
(2)在HTML页面输出;
1).html页面元素事件中输出,如onclick="";
2) .通过<script>在这里输出JS代码</script>,并且script可存在html 任意标签位置。
3).写到外部js文件,通过<script src="url.js"></script>引入;
script的属性;src,type,defer(设置延迟),async(异步加载页面内容)。 |
2.代码块;指<script></script>里面包含的js代码为一块代码块,js是按代码块顺序执行。
3.浏览器内核;内容排版引擎(html和css)和脚本解释引擎(js)。
4.Error;指程序的代码错误,导致程序中断。
(1)错误处理;指的是程序代码错误,仍然不会导致程序中断的机制。
如;try{//可能出错的正常代码} catch(err){//出错后的处理代码包括用户提 示,保存进度,日志记录}finaly{//一段无论如何都会执行的代码};
(2)错误类型;SyntaxError,RangeError,ReferenceError,TypeError,URLError, EvalError。
(二)JS基本语法;
1.基本语法;
(1)JS是由Unicode字符集编写的,且严格区分大小写,但html不区分大小写。
(2)注释;//和/**/,转义字符 \仅仅对特殊字符有转义功能,对正常字符没有效果 ,如\t(制表符),\",\',\\(一个\)。
2.变量;
(1)var声明多个变量,号隔开,不用var声明视为全局变量,调用为声明的变量为语 法错误,调用声明未赋值的变量为undefined,var的声明不能使用delete 删除该变量,if(var i)和while(var i)是语法错误的,for(var i(in))是可以的,js会声明提前。
3.数据的基本类型;
(1)包括:undefined,null,number,string,boolean六种基本类型,typeof只能区分基本数据类型和函数,但是不能准确区分对象和数组。其 中typeof a,如果a未声明,仍然返回undefined,不报语法错误。
问题:怎么区分对象和数组,或者区分对象和数组的几种方法? 1.构造函数。2.父原型对象。3..class属性。4.Array.isArray(obj)。5.obj.constrctor。注意:.constructor可以检测大部分数据类型,但是对象null和undefined会抛出异常错误,这时可以把值先转为布尔值,true表示存在然后在调用.constructor。typeof的结果为字符串"类型"。.constructor的结果为如String。 (15)可将数值转换为对象。 |
(2)Number数值类型:不在区分整数和浮动型,所有数值都是浮动型。整数32位, 浮动64位一般。
1).toString(2~36进制参数),可以吧数值转换为对应进制的字符串。注意:
a/(25).toString(),25数字必须加括号,否则语法错误。
2).浮动数溢出,即二进制的浮点数不能正确处理十进制小数,如0.1+0.2不等于0.3,但是可以转换为(1+3)/10;
3).特殊数值NaN,NaN==="number"且NaN !==NaN,isNaN(num)用于判断
数字与NaN;isNaN("A")==true,isNaN("15")==false;即纯数字形式的字符串是数值。
4).isFinite(num),判断num是否是NaN,无穷大的数值。
(3)字符串String类型:有.length,有下标,可遍历,应在一行内显示不允许换行,换行用换行符\n,+在字符串中有拼接的作用。
(4)布尔值boolean类型:在js中undefined,null,"",0,NaN和false这6个 值转换为逻辑值时时false,被称为假值,其他任何类型的数据转换为逻辑值都是 true。如Boolean(NaN)==false; 其中!a 等价于 a==null; b=b?b:"OK",表 示如果b为null,则b="ok",否则b=b;
(5)Underfined类型:其唯一值underfined,null==undefined,都是假值所有成立。但类型不同所有null===undefined是不成立的。a==undefined,在已声明 a下时判断a是否赋值,未声明a下是语法错误。函数在没返回值下,调用输出 undefined。
4.严格模式;"use strict";
(1)在全局script下顶端或在函数下顶端(前可有注释)声明,否则无效。
(2)严格模式的执行:1.不允许全局变量,否则语法错误。
2.静默失败升级为错误。
3.this不在默认指向全局。如果function f() {return !this;} //返回false,因为在非严格模式下 this指向全局,!this表示不是指向全局,所有是错误的。 但是unction f(){"use strict"; return !this;} // 返回true,因为在严格模式下,this指向undefined,所有!this表示不指向全局指向undefined。
4.禁止调用argunments,callee,caller,禁止递归函数,否 则语法错误。
5.函数参数重名则报错,对象重名也报错,对对象的四大只读 属性赋值修改也会报错。
6.禁止在非函数的代码块内声明函数,如在条件和循环语句中 声明函数是语法错误。
(三)运算符;
1.算术运算符:+,-,*,/,%,-(取反),++,--;
(1)以上算术运算符的特殊规则:
1).任意数(包括0与无穷)与NaN运算结果都是NaN。
2).正负无穷之和为NaN,两负无穷之差为NaN。
3).正负无穷与任意非0非NaN之乘积为无穷, 否则为NaN。
4).正负无穷与无穷相除为NaN,任意数与0, -0相除都正负无穷大。
5).无穷模任意数(包括0和无穷)结果都是NaN, 任意非无穷数模无穷数,结果为模前面那个非无穷数,0模任意数结果为0.
6).++,--只能作用于变量,数组元素,对象属性, 不能作用于具体的数值,如4++为错误。
2.逻辑运算符;&&,||,!。
(1)六个假值:null,undefined,NaN,"",0,false。其余类型都是true。
(2)逻辑与(&&):式1 && 式2;其中式1,式2结果为false/ture,但是这个逻辑与&&,结果不一定是false/true。如果式1或式2中包含 null/NaN/undefined,则返回相应的null,NaN,undefined。无穷大Infinity为true。&&优先级高于||。
(3)逻辑或(||):式1 || 式2;与逻辑与(&&)用法一样。
(4)逻辑非(!):! 式1;结果一定是false/true。 !a <=> a==null是true。
注意:if(式1 &&(||) 式2){}时;先要判断是否会短路逻辑造成式2不能被执行,然后在判断判断整个式1 && 式2的false/true而确定是否执行if语句。
3.关系运算符;<,>,<=,>=,==,===,!=,!==。
(1)规则:1.如果运算数都是数字,或一个数字一个纯数字形式的字符串,则转换为数字进行比较运算大小。
2.如果都是字符串,或一个布尔一个字符串,则转换为字符串比较 unicode码大小。
3.如果一个是数字,另一个是字符串,则用parseInt()转换为数字 比较(开头不是数字的字符串会被转换为NaN)。
4.引用对象的值来说,==与===操作的结果都是一样的,即使值一样,但是地址不一样,也都是false。如var a={},b={};c=a;则a与 b值相等地址不相等,结果即不全等又不相等,而c与a地址和值都相等,所有即全等又相等。
注意:(a in obj)中in运算符可检测属性a是否是对象obj或由其继承来的成员。
4.赋值运算符;=,+=,-+,*=,/=,%=,&=,^=,|=。
(1)连续赋值:var a=b=c=d=f=10;此类1=100赋值为false。
(2)优先级:(a=6&&(b=function(){return a;})()); 返回undefined,因为=号比&&和()运算低,所有先执行b,结果b中a没有赋值。
5.对象操作运算符;new,delete,[]和.,()。
(1)new:创建一个新对象。
(2)delete:删除指定的对象的属性,数组的元素,或变量(var声明的变量不 能删除)。结果返回true/false。如果删除不存在的时返回true,且其只删除值类型的数据。不是清空值(null),而是把其值变为了undefined。
(3)[]和'.':用于访问对象或数组。[]可以将里面的纯数字字符串转换为数字,且 可以通过变量或者字符串表达式来间接传递特定值。如var b="x",var a={x:1};a[b]返回1,而a.b返回undefined。
6.其他运算符;三目运算符(?:) ,逗号(,) ,void运算符。
(1)注意:逗号运算符优先级最低,且a=(b=1,c=2);结果a=2。
(2)void:出现在任意类型运算符之前,总是使得结果返回undefined。如void1或函数void(a,a++),结果都是undefined。
(四)程序逻辑结构;
1.空语句:没有任何代码只有一个';'号的语句不会执行和报错,如; 或 for();
2.逻辑结构:
(1)顺序执行;
(2)选择执行;
1).if(){};
2).if(){}else{};
3).if()else if(){}...else if()else{};
4).switch(){...case 值...(default...};
5).选择的嵌套;
注意:选择逻辑中的条件语句即()里的语句,不能var 声明变量,且特别注意如果是短路逻辑判断表达式2是否已声明,因为短路逻辑可能让表达式2不能执行,且注意运算符的优先顺序。
(3)循环执行;
1).while(){}; 循环条件为true不变时为死循环。
2).do{}while();
3).for(;;){};仅遍历原生属性。
4).for(... in ...){};结果是依次获得下标而非值,可以遍历原生(自有)属性和继承属性,以及额外属 性(即添加进去的属性);
注意:循环结构是最浪费资源的;
3.结构跳转: 1).break; 中断当前层的循环。
2).continue; 跳过当前层的当次循环,进入下一次循环。
(五)数组;
1.创建数组: 1).var arr=[];
2).var arr=new Array();
2.数组的length:
1).JS中可以不按照下标顺序添加新元素,且直接未赋值的下标的值预定义为undefined。如果获取下标对应的值不存在也是返回 undefined。且下标值必须>=0 && <2^32-1。如果下标值太大,或为负数,浮点数,布尔值,对象和其他值,JS会自动转换为字符串作为关联数组的下标。
2).对arr.length=5;如果arr原来的长度大于5,则截断arr使得其长度为5,超出部分会丢失。如果小于5,则会尾部添加预定义undefined值,使得其长度为5.
3).in运算符,如("a" in arr),用于判断"a"是否是arr里面的值,返回布尔值。
3.二维数组:JS不支持二维数组,但是可以通过其他样式构造操作,如循环的嵌套。
4.操作数组的API:
1).遍历数组;for(){}或for(..in..){};
2).增删数组元素;
(1) delete arr[i]; 删除元素的值,而不是元素,不改变其数组的长 度。
(2) arr.push(e1,e2...)/unshift(e1,e2...);在数组的尾部/头部添加元素e1,e2...,返回新数组的长度。
(3) arr.pop()/shift();删除数组的尾部/头部的最后一个/第一个元素,返回删除后的元素。
(4) arr.concat(arr1,arr2...);向数组arr尾部添加新数组arr1,arr2...的元素,返回新数组。
3).增删改数组的元素;
(1) arr.slice(start,end);截取并返回arr的子数组。
(2) arr.splice(start,count,e1,e2,...);增删改数组返回新数组, count表示删除的个数,如果为0或为负表示都不删除。
4).数组排序;
(1) arr.sort();如果sort()没有参数,表示按照unicode码升序排序,且自动把数组元素转换为字符串。Undefined默认排到尾部。 如果数组元素全为数值且参数是匿名函数function (a,b){//return a-b/b-a};表示如果返回a-b为升序,b-a为降序。
5).数组与字符串的转换;
(1) arr.toString();表示把数组按,号隔开元素转换为字符串。可以把 二维数组的每个元素都隔开转为字符串。
(2) arr.join("分隔符");表示把数组的元素按"分隔符"转换为字符串。
6).定位与倒序;
(1) var i=arr.indexOf("字符",fromi);
(2) var i=arr.lastIndex("字符",fromi);
(3) arr.reverse();将原数组倒序排列,返回原数组。
7).迭代;
(1) var bool=arr.every/some(function(elem,i,arr){return});表示判断数组中是否所有元素都符和条件/是否包含符合条件的元素。
(2) arr.foreach/map(function(elem,i,arr){return});对数组中每个元素执行相同的操作并返回原数组/新数组。
(3) arr.filter(function(elem,i,arr){return});从原数组中选取符号条件的元素组成新数组。
(4) arr.reduce(function(prev,elem,i,arr){});数组中每个元素的累加和。
(六)函数;
1.定义:保存一段封装的代码的对象。
2.创建方法:
1).function 函数名(){};
2).var 函数名=function(){};
3).var 函数名=new function("参数","函数体");
3.重载:在js中,相同函数名,传入不同参数,执行不同的操作。默认js不支持重载,但是可以用函数自带的接收参数的类数组argunments。
1.String有关的API;
(1)String VS数组: 相同点;1.下标。2.length。3.for遍历。4.slice()截取。
不同点;类型不同,所有API不通用。
(2)大小写的相互转换:str.toUpperCase();返回新字符串。
str.toLowerCase();返回新字符串。
(3)字符串与unicode的转换:var unicode=str.charCodeAt(字符串下标=0);
var str=String.fromCharCode(unicode);
(4)截取子字符串:var str1=str.slice(start,end);返回新字符串。
var str1=str.substring(start,end);返回新字符串。
var str1=str.substr(start,n);返回新字符串。
(5)获取指定位置i的字符:var str1=str[i];
var str1=charAt(i);
(6)获取关键字符的位置:var i=str.indexOf("关键字符",fromi=0);
var i=str.lastIndex("关键字符");
(7)通过正则获取敏感词位置:var i=str.search(/正则/);
(8) 通过正则获取敏感词:var str1=str.match(/正则/ig);ig表示不区分大小写,全部敏感词获取。
(9)替换(删除)字符串的敏感词:var str1=str.replace(/正则/ig,"新内容");
var str1=str.replace(/正则/ig,function(kw){return kw=?});
(10)切割字符串成数组:var arr=str.split("自定义切割符");
var arr=str.split(/正则表达式/);
(11)去掉字符串的首尾空格:var str1=str.trim();
2.正则表达式;规定字符串中字符出现规律的表达式。一般API对其执行一次就返回。
(1)作用: 1.验证字符串格式,如邮箱,密码等。
2.查询字符串的敏感词。
(2)预定义字符集:\d => [0-9];
\w => [a-Za-z0-9_];
\s => 一切空字符,如空格,Tab键,换行....;
点‘.’ => 通配符;
(3)量词:定义字符集出现次数。{n.m},{n,},{n}, * , + , ? 。
(4)其他: 1. 分组()与选择 |;
2. 空字符首(^\s+),空字符尾(\s+$)及(\b单词\b);
3.RegExp;保存一条正则表达式,并提供操作验证和查找正则表达式的API对象。
(1)创建方法:1. var reg=/正则/ig;
2. var reg=new RegExp("正则","ig");
(2)应用:1. 验证格式;var bool=reg.text(str); 必须^和$。
2. 查找敏感词及位置;var arr=reg.exec(str); arr=[0:敏感词,index:位置],但是只能找到一个就返回,找不到返回null。
4.Math;保存一个数学计量的常量,并提供操作计算的API的对象。不需要创建。
(1)API: Math.ceil(num)——取上整值;
Math.floor(num)——取下整值;VS parseInt(num);
Math.round(num)——四舍五入;VS num.tofixed(d);
Math.pow(底数,冥)——乘方;
Math.sqrt(num)——开方;
Math.max/min((...arr)/参数1,参数2,...)——最大、最小值;
Math.random()——0-1之间的随机数;
Math.abs(num)——绝对值;
Math.PI/E——0-1之间的随机数;
5.Date; 保存一个日期值,并提供操作日期值的API的对象。并修改原日期值。
(1)创建方法:
1. var date=new Date();获取当前计算机的时间。
2. var date=new Date("yyyy/mm/dd hh:mm:ss");
3. var date=new Date(ms); 毫秒转日期。
var ms=date.getTime(); date转毫秒数。
4. var date1=new Date(date2); 复制日期副本。
(2)API:1. 八个单位;FullYear Month Date Day Hours Minutes Seconds/Milliseconds 。
2. 一对get/set函数;每个单位一对函数,除了Day没有set函数外。
(3)日期的计算: 1. 两个日期直接相减,结果为毫秒数。
2. get获取当前日期值,在用set修改原日期值,返回原date。
(4)日期格式化(简化): to(GMT/Locale(Date/Time))String;
6.Error;保存错误的对象。
(1)错误处理:即即使程序出错,也不会中断退出的机制。
(2)操作:try{//可能出错的正常代码}catch(err){//出错后执行的代码,提示用户,保存进度,记录日志/或throw new Error("错误信息提示")}。
(3)六种常见错误类型:
1. SyntaxError——语法错误;
2. ReferenceError——引用错误,即需要的变量没有找到;
3. TypeError——类型错误,即错误调用函数或对象的API;
4. RangeError——范围错误,即参数的范围错误;
5. URLError——URL格式错误;
6. EvalError——eval()错误,一般很少见;
7.Function;保存一段封装的代码的对象。
(1)声明创建的三种方式:
1. function 函数名(参数列表){//return 结果};
2. var 函数名=function(){}; 避免1那样的声明提前。
3. var 函数名=new Function("参数n","函数体");
(2)匿名函数:即不指定函数名,用后立即释放的函数。包括;
1. 回调;一个函数被另一个函数调用。如sort(),replace();
2. 自调;函数被自己调用。(function(){})();
(3)垃圾回收: 主动和自动;
(4)作用域与作用域链:变量的可用范围是作用域(分为全局,局部变量),由多级作用域逐级形成的链式结构为作用域链(控制着全局和布局变量)。以下是作用域与作用域链的形成。
(5)闭包:集合全局变量和局部变量的优点,既代码重用,又不会被篡改的机制。其是由于外层函数的活动对象AO无法释放形成。闭包可能占据更多的内存,但可以用完后立即赋值null释放内存。
1).步骤;1. 用外层函数包裹受保护的变量和函数,确定变量的最终值。
2. 将内层函数返回到外部,如return,或将内层函数赋值给全局变量,或将内层函数包裹在对象或数组中并返回这个对象或数组。
3. 调用外层函数,得到内层函数。
以下是闭包的形成:
(6) this;始终执行调用对象,或谁让调用(动了)函数,就指向谁(如window/button/子对象...),即谁调用,执行谁,如果没有就指向window,静态绑定this的方法;
1).将this作为参数传递进去,如;<ANY onclick=f(this)> ,function f(_this){};
2).在函数内将this存储给变量,如;function f(){var _this=this...return _this};
3).bind(thisobj,...);永久静态绑定一个指定的obj对象。使用new创建一个this指向实例对象。
(7)函数的调用方法;
1).方法/元素调用,函数作为一个对象的方法,用.调用如.onclick。
2).函数调用,用函数名()直接调用此时this相当于window的调用。
3).构造函数调用,用new构造函数的子对象,然后子对象调用构造函数方法。
4).apply/call(),强行调用函数。
(8) 优先级;
1).函数名和形参同名下,形参变量名优先级高于函数。
2).函数名/参数与作为传参的类数组arguments同名下,参数要优先级高于类数组高于函数。
3).局部变量(已赋值下)与形式参数同名下,赋值的局部变量优先级高,如果是局部变量没有赋值,形参的优先级高于局部变量。通常下应用把形参直接赋值给其函数内的局部变量。
(七)对象;
1.定义:描述一个现实中具体事物的属性和功能的程序。
2.面向对象:就是程序用对象结构来描述一个具体事物的属性和功能,便于大量数据的管理和维护。
3.三大特点:
1).封装:
⑴ 直接量:var obj={属性:值,...,方法(){},...};this.属性名表示对象自己访问自己的属性及方法都必须这样。
⑵ new创建空对象:var obj=new Object();创建空对象,obj.属性名/["属性名"]=值,依次向对象中添加属性及值。
⑶ 构造函数:构造函数,function类型名(){this.属性名=属性参数,...,this.方法名=function(){}};调用自 己的属性,用.属性名/方法名即可。
2).继承:父对象的成员,子对象无需创建API就可以直接调用。
1).原型对象;保存同一类型的所有子对象共有方法的父对象。添加:构造函数.prototype.共有方法=值/function(){};
2).自有属性及共有属性;仅当前对象所有的属性为自有属性,保存在原型对象中为所有子对象共有的属性为共有属性。二者都可 以通过子对象.属性名获得其属性值,但是自有属性的修改为子对象.属性名=值,共有属性的的修改为构造函数
的.prototype.共有属性=值;var bool=obj .hasOwnProperty("属性名"),用于判断是否包含指定的自有属性,true为自有属性。
3).内置对象;内置对象是ES标准中,浏览器厂商已经实现的对象,包Number,String,Boolean(这三个为包装类型),Array, Math,Date,RegExp,Error,Function,Object,Global(Window)共11中内置对象,包装类型指专门封装一个原始类型的值并提供操作原始类型指的API的对 象,内置对象由构造函数和原型对象组成。
4).原型链;由多级父元素逐级继承形成的链式结构。控制着属性和方法的使用顺序,VS作用域链,保存和控制所有的变量的使用顺序。如下图:
5).实例方法与静态方法;
⑴ 修改一个对象的父对象:Object.setPrototypeOf(child,father);
⑵ 修改一类对象的父对象:构造函数.prototype=father;
⑶ 自定义继承:包括定义抽象父类型(父类型构造函数及父类型原型对象)和让子类型继承抽象父类型(子类型原型对象继承父类型原型对象,子类型构造函数借用父类型构造函数)。如下图;
3).多态:重载(如js默认不支持一个函数名执行不同结果,但是函数自带argunment可接收传入参数的类数组)和重写(如原型链上同一个函数,在不同位置具有不同函数)。
4.ES5:
1).严格模式:包括js文件或script标签下,及单个函数内顶部,"use strict";
(1)具体:禁止给未声明的变量赋值,禁止将默认失败升级为错误,禁止递归,匿名函数的this不在指向全局。
2).保护对象:
⑴ 保护属性:命名属性(数据属性和访问器属性)和自有属性;数据属性的四大特(value,writable,enumerable,configurable),访问器属性的四大特性(set(){},set(){},enumerable,configurable);
⑵ 保护结构:阻止扩展(Object.preventExtensions(obj)),密封(Object.seal(obj)),冻结(Object.freeze(obj))。
3).Object.create();基于现在父对象,创建一个子对象并扩展其自有属性,var child=Object.create(father/*,{设置4大属性})。
4).call(),apply(),bind();call()和apply()在调用函数时替换不正确的this指定的对象,前者需要独立传参,后者需要把参数放进数组中传入。bind()是基于现有函数,创建一个新函数,并永久绑定this指定对象。
5.ES6:
1).let:替代var,避免声明提前,相同作用域内不允许重复let第二个变量,仅在当前作用域内有效,避免全局污染,增加选择语句的的块级作用域{}。
2).参数增强:
(1)默认值default; 参数=default值 => 参数=参数 || 默认值;
(2)剩余参数;(参数1,...,...arr),代替arguments传参。类数组对象转为数组: var arr=Array.prototype.slice.call(arguments) //arguments.slice()//完整复制arguments。
(3)打散数组;(...arr),代替apply();
3).箭头函数:对匿名函数的简化。
4).模板字符串: `...${}...`;
5).解构:数组解构,对象解构,函数参数定义和调用时解构;
6).for...of:for(var elem of arr){},简化for()循环索引数组。
7).简化构造函数和原型对象:
(1)class定义; class 类型名(参数列表){
this.属性名=参数;
}
方法名(){}
...
}
⑴ 用class封装构造函数和原型对象方法定义 。
⑵ 构造函数名提升为class名,构造函数更名为固定的关键词Constructor。
⑶ 直接写在class中的方法,默认都保存在原型对象中。
(2)继承:
⑴ extends fhther => Object.setPrototypeof(child,father);
⑵ super(...) => 抽象父对象构造函数名.call(this,...);
(3)访问器属性:其前2大特性改为get 访问器属性 (){},set 访问器属性(val){};
8).Promise(.all):对回调函数的规范写法,避免回调深渊。
(1) 定义接收回调函数的主函数:function fun(){
return new Promies(function(){
....callback();......
})
}
(2) 调用主函数执行,并传入下一个要执行的回调函数:
fun().then(callback);
(八)DOM;
1.定义;Document Object Model,统一操作页面内容的API,几乎100%兼容所有浏览器。
1).原生js:包括ECMAScript,DOM,BOM。
2.DOM Tree;
1).定义:所有网页内容在内存中都是以树型结构存储,更好的体现了层次关系。
2).内容:根节点对象—document,节点对象(所有元素,文本,注释...)——node。
3).三大属性:
(1)nodeType; document——9。
element——1。
attribute——2。
text——3。
(2)nodeName; document——#document。
element——全大写的标记名。
attribute——属性名。
text——#text。
(3)nodeValue; document——null。
element——null。
attribute——属性值。
text——文本内容。
3.查找;
1).四种方法;
(1) 不需要查找就可直接获得元素。
document.documentElement ->html;
document.head -> head;
document.body -> body;
document.forms[i/id/name] -> 某个form;
(2)按节点查找;节点树:包含一切网页内容的DOM Tree。
elem.parentNode; elem的父节点。
elem.childNodes; elem下所有子节点的动态集合。
elem.firstChild/lastChild; elem下首/尾节点。
elem.previousSibling; elem前一个节点。
elem.nextSibling; elem后一个节点。
元素树:仅包含元素的DOM tree。
elem.parentElement; elem 的父节点。
elem.children; elem的所有子节点,动态集合。
elem.firstElementChild/lastElementChild;
elem.preciousElementSibling;
elem.nexElementSibling;
查找一个元素的所有子元素方法? 1.递归(深度优先遍历); 2循环(节点迭代器); |
(3)按照HTML查找;
⑴ 按照id查找:var elem=document.getElementById("id");返回一个元素或null。
⑵ 按照标签名查找:var elems=parent.getElementsByTagName("标签名");返回多个元素组成的动态集合或空集合。
⑶ 按name查找:var elems=document.getElementsByName("name");返回多个元素组成的动态集合或空集合。
⑷ 按class查找:var elems=parent.getElementsByClassName("className");返回多个元素组成的动态集合或空集合。
(4)按照选择器查找;
⑴ 查找一个元素:var elem=parent.querySelector("选择器");
⑵ 查找所有元素:var elem=parent.querySelectorAll("选择器");返回非动态集合或空集合。
4.修改;
1).内容:(1)elem.innerHTML——获取/修改双标记元素内容;
(2)elem.textContent——获取/修改文本内容;去内嵌标记转义文本;
(3)elem.value——获取/修改单标记内容;
2).属性:(1)核心DOM——支撑一切结构化文档(html,xml)的DOM API;
⑴ var value=elem.getAttribute("属性名")——获取属性值;
⑵ elem.setAttribute("属性名","值")—修改属性值;
⑶ elem.hasAttribute("属性名")—判断属性是否存在;
⑷ elem.removeAttribute("属性名")——移除属性;
(2)HTML DOM——对部分核心DOM API的简化;
⑴ var value=elem.属性名——获取属性值;
⑵ elem.属性名=值——修改属性值;
⑶ elem.属性名 !="";判断属性是否存在。
⑷ elem.属性名="";移除属性。 例外:class=>className;
(3)状态属性——selected,disabled,checked。三大状态属性值类型是bool,只能用HTML DOM操作,因为核心DOM只能操作值类型是字符串的。且三大状态属性都有对应的选择器::selected, :disable, :checked。
(4)自定义拓展属性——用于选中触发事件元素,保存业务数据。
⑴ 定义和选择器:<ANY data-属性名="值"...>;选择器[data-属性名=值]。
⑵ 访问方法:无法用HTML DOM访问,只能用核心DOM访问或用 HTML5访问。在HTML5中用elem.dataset.属性
名访问修改。
3).样式:
(1) 内联样式;
⑴ 修改:elem.style.属性名="值"; 属性名一律去_变驼峰。
⑵ 获得完整计算后的样式:var style=getComputedStyle(elem); var value=style.属性名。计算后的样式只读不能修改,且可能影 响其他元素的样式。
(2) 样式表(内部/外部);
⑴ 获得样式表对象:var sheet=document.styleSheets[i];
⑵ 获得要修改属性所在的cssRule:var rule=sheet.css Rules[i]; 一个cssRule为一个{},如果是keyframes,还需要再次获得rule下的cssRule。
⑶ 修改rule.style的css属性:rule.style.属性名="值";可 以用class批量应用修改样式。
5.添加与删除;
1).添加:(1)创建空元素,var elem=document.createElement("标签名");
(2)设置关键属性,elem.属性名=值;
(3)将新元素添加在指定父元素下,
末尾添加——parent.appendChild(elem);
中间插入child——parent.insertBefore(elem,child);
替换child——parent.replaceChild(elem,child);
2).优化以上添加删除操作,减少对DOM树的操作次数。
(1) 同时添加父和子元素,先将子元素添加到父元素,再将父元素一次性添加到页面。
(2) 同时添加多个平级的子元素,可借助临时保存在文档片段,最后在一次性添加到页面,然后文档片段立即释放,不占据内存。
步骤如下:⑴ 创建临时文档片段;
var frag=document.createDocumentFragment();
⑵ 将多个平级子元素添加到临时文档片段中;
frag.appendChild(child);
⑶ 将临时文档片段添加到页面;
parent.appendChild(frag);
6.HTML DOM 常用对象;即简化部分HTML元素操作的API。
1).Image:代表页面上一个<img>元素; 创建,var img=new Image();
2).Select:代表页面上一个<select>元素;
⑴ 属性:select.selectedIndex,获得当前select中选择项的下标位置。
select.value/innerHTML,获取当前select的value值/内容。
select.options,获取当前select的所有option集合。
select.options.length,获取当前select的option总个数。
select.options.length=0,清空所有option。
select.length => select.options.length。
⑵ 方法:select.add(option) => select.appendChild(option),但是add不支持frag,append支持frag。
select.remove[i],移除i位置的option。
3).Option:代表页面上一个<option>元素;
⑴ var option=new Option(text,value);表示创建option并添加其属性及值option.innerHTML=text,option.value=value。
4).Table:处理行分组thead,tbody,tfoot。
⑴ 创建行分组:var thead/tbody/tfoot=table.createTHead/TBody/ Tfoot();
⑵ 删除行分组:table.deleteTHead/TFoot(); 不能删除tbody,因为一个 表可能有多个tbody。
⑶ 获得行分组:table.tHead/tFoot/tBodies[i];
5).行分组thead/tbody/tfoot,处理着具体的每行;
⑴ 添加行:var tr=行分组.insertRow(i); i为具体的行,i=0为行分组下的首行,不写i为行分组下的尾行。
⑵ 删除行:行分组.delectRow(i);i是行相对行分组下的位置。无法直接获取。tr.rowIndex表示tr在整个表中的相对位置。删除行:table.deleteRow(tr.rowIndex)。
⑶ 获取行:行分组.rows[i];
6).行处理着每个单元格;
⑴ 添加格:var td=tr.insertCell(i);不写i为行下的尾列,不能添加th。
⑵ 删除格:tr.deleteCell(i);
⑶ 获取格:tr.cells[i];
7).Form;代表页面的一个<form>元素。
⑴ 获取:var form=document.forms[i/id];
⑵ 属性:form.elements;获取表单里的所有表单元素的集合。
form.elements.length => form.length; 所表单元素的个数。
⑶ 方法:form.submit();手动提交表单。
8).Element,代表表单中某个表单元素;
⑴ 获取:var elem=form.elements[i/id/name]; 或var elem=form.name;
⑵ 方法:elem.focus()/blur();获得/失去焦点。
(九)BOM:
1.BOM:Browser Object Model;专门操作浏览器的API,没有统一标准。
1).window:(1)代替ES标准中的global充当全局变量。
(2)封装所有的BOM的API。
2).打开和关闭窗口:window.open("url","target")/close();
四种方式:(1)在当前窗口打开,可后退;
html: <a href="url" target="_self"></a> ;
js: <a href="javascript:function(){open("url",
"_self")}"></a>
(2)在当前窗口打开,不可后退,如付款成功页面;
js: location.replace("url");
(3)在新窗口打开,可打开多个;
html: <a href="url" target="_blank"></a>;
js: open("url","_blank");
(4)在新窗口打开,只能打开一个,如准备付款页面;
html: <a href target="自定义name"></a>;
js: open("url","自定义name");
3).history:保存当前窗口打开后成功访问过的url历史记录的栈;
(1)API: history.go(1/-1/0/-2....);前进/后退/刷新;
4).location:封装正在打开页面的url的对象;
(1)API:location.href/protocol/host/hostname/port /pathname/search/hash;
(2)在当前窗口打开链接:
⑴ 可后退;location.assign("url") => location.href="url" => location="url";
⑵ 不可后退;location.replace("url");
(3)刷新:
⑴ 普通刷新,即先从历史记录中加载,若没有再从服务器加载。F5,history.go(0),location.reload();
⑵ 强制属性,即强制从服务器中加载,如股票页面刷新。location.reload(true);
5).navigator:专门保存浏览器配置信息的对象。其可以用.访问如下属性;
(1) cookieEnabled;判断浏览器是否启用cookie,cookie是客户端保存用户私密信息的小文件。因为客户端程序都是临时保存数据,所有需要通过cookie在本地硬盘永久创建一个保存私密信息 的小文件,cookie可以记住任何东西,如网页登录中记住密码的保存。var bool=navigator.cookie;判断浏览器是否开启cookie;
(2)plugins;保存浏览器插信息的集合。插件就是为浏览器添加新功 能的小程序,如银行首次支付页面需要先下载一个插件。navigator.plugins["插件名"] !==undefined来判断浏览器是否有这个插件,var str=navigator.userAgent;表示获得浏览器名称和版本的字符串。
6).定时器:
(1)周期性定时器;即每隔一段时间反复执行。
⑴ 创建并启动/调用任务函数task();
⑵ 启动定时器:var timer=setInterval(task,ms);
⑶ 停止定时器:clearInterval(timer);timer表示定时器的 唯一序号。再主动释放timer=null,包括手动停止和自动停止(达到临界值)。
(2)一次性定时器;隔上一段时间执行一次后就立即停止。
⑴ 创建并启动/调用任务函数task();
⑵ 启动定时器:var timer=setTimeout(task,ms);
⑶ 停止定时器:clearTimeout(timer);
注意:上2个定时器只是将task()包括在定时器中,当定时器执行函数时,先将task()的调用加入等待列表中,等待列表中的函数必须在主程序执行完后才能执行。
7).event事件:浏览器自动或手动触发时的页面状态的改变。事件处理函数指事 件发生时,自动调用的函数。
(1)为事件提交绑定处理函数:
⑴ 在HTML中绑定:<ANY on事件名="js语句/函数">
⑵ 在js中绑定单个事件:elem.on事件名=function(){};
⑶ 在js中绑定多个事件:elem.addEventListener("事件名");elem.removeElementListener("事件名");
注意:移除处理函数必须找到原函数对象,其this指正则触发的事件的.前的元素对象。
8).DOM事件模型:事件触发后,发生的一些列行为。
(1) 三个阶段:
⑴ 由内向外捕获记录;
⑵ 目标触发;
⑶ 由内向外冒泡;
(2) 事件对象e:事件发生时自动创建的,封装事件信息的,并提供修改默认事件行为的API对象。
⑴ 阻止冒泡:e.stopPropagation();
⑵ 利用冒泡:减少事件监听个数;获取目标元素:this =>父元素; e.target 为最初触发事件的目标元素,不随着冒泡而改变。鉴别目标元素类型:e.target.nodeName="标签名";
⑶ 取消事件:事件处理函数执行过程中,可取消事件的触发。 浏览器默认事件是不想要的,如<a>提交时在url添加#锚点名称不是想要的,执行过程中出错了不想继续,e.preventDefault();
(3)鼠标坐标:
⑴ 相对于屏幕左上角;e.screenX,e.screenY。
⑵ 相当于文本显示区左上角;e.clientX,e.clientY。
⑶ 相当于当前元素左上角;e.offsetX,e.offsetY。应用:比如鼠标拖动图片移动。
(4)页面滚动:
⑴ 事件:window.onscroll=function(){ 属性:滚动距离, scrollTop=document.documentElement.scrollTop || document.body.scrollTop }
⑵ 方法:window.scrollTo(0,scrollTop); window.scrollBy(0,增量);应用:比如跳转楼层。
问题集合:
1.函数的调用方法:
(1)用.方法调用。
(2)用函数名()调用。
(3)构造函数调用。
(4)apply/call()强制调用。
2.应用:
(1)下拉列表/菜单:列表的嵌套+鼠标移入移出事件+相对绝对定位实现;
(2)模拟短信聊天及文字大小和页面样式的用户自定义:
(3)注意:图片的相对路径(可以通过isOK=ture/false开关来实现src的切换),innerHTML值,颜色值不能用来做条件判断,会产生兼容性问题,以及input.type获取type值不兼容于IE6.7.8;但是可以通过隐藏和新建input实现切换。Elem.style.styleFloat/cssFloat:分别在IE和非IE下兼容,也可将其添加到class属性中解决所有兼容问题,如.left{float:left}。
(4)JS中可以把所有的.换成[],不会有兼容性问题。如elem.style['width']可以修改width属性名;透明度的兼容性filter:alpha(opacity:80);opacity:0.8;
(5)关于图片轮播的问题;可以提前加载图片和图标上的文字内容缓存在数组中;
(6)关于循环中i的值问题,for里面如果存在内函数则其i不能用用于内函数,以及循环中,提前缓存数据(arr.length和代码片段加载)加快运行速度;
(7)自定义属性:JS可以给任意HTML元素添加任意自定义属性(空除外),可应用于单击切换图片的开关,而不影响其他相同元素,或改变本元素的值或属于,不影响其他相同元素。
3.用typeof 查询数据类型;
(1)直接输入fun,与调用fun()的区别,前者直接输入完整的函数代码,后者输出函数的结果。
(2)数据之间的转换:
Number()将纯数字的字符串/单个纯数字类型元素数组转换为数值类型,空字符串转换为0;将布尔值转为为1/0,其他的转换为NaN,将对象、underdifinite转换为NaN;
parseInt(num,10)将字符串从左到右数字整数部分转换可识别+,-,忽视空格;第二个参数为进制数(6,8,10进制),不写默认是10进制;
parseFloat(num,10)将字符串从左到右数字数字(包括小数)部分转换可识别+,-,忽视空格;
(3)函数传参,形参和实参:参数的类型可以是数值,布尔,字符串,对象,函数等各种数据类型;如通过判断传入参数的类型typeof 从而执行不同的结果;通过a===a可以判断a是否是NaN;重用代码,代码相识,不同部分为参数传入;
4.js全局/局部作用域的2步:
(1)预解析:对var和function,参数,的声明提前解析,并即将最终值存入,然后在执行;
alert(a); //预解析相同变量名会覆盖,输出a=function a(){}这个结果。
var a=1;
alert(a); //输出a=1
function a(){};
alert(a); //仍然输出a=1
a(); //因为a执行到这步是a=1不在是函数,所以输出underdifine;
(2)逐行自上而下执行表达式/函数调用:参数本质也算函数的局部变量。
5.ico图标:<link href=".ico" ref="Shortcut icon"/>;
6.渐变的兼容性;火狐-moz-,苹果/谷歌-webkit-,IE-ms-(IE9,8下是滤镜),以及其他无前缀;IE7以下不支持渐变+background:颜色值即可;IE6,7,8不支持边框border-radius圆角;
7.项目步骤:
(1)分析:
1).结构布局、相同结构重用、命名;
2).重置样式;如list-style;margin;padding;font-size,font-family;
3).共用样式类;
8.自定义index的应用:
(1)隔行变色,鼠标移动上去变灰色,移出还原;单击反选checkbox;评分;
9.函数体内return:其函数体内return之后的代码不在执行;
10.函数参数无法确定时用arguments伪数组。
11.getComputedStyle("elem.属性名");获取计算机计算后最后的elem的属性值;但是不支持IE8及以下浏览器,IE8及以下有elem.currentStyle.属性名可以获取属性值;
//0.封装原生jQuery的$函数
function $(v) {
if(typeof v==='function'){
window.onload=v;
}else if(typeof v==='string'){
return document.getElementById(v);
}else if(typeof v==='object'){
return v;
}
}
//1.封装一个函数用于兼容IE6.7.8浏览器的获取元素属性值的函数
function getStyle(obj,attr) {
return obj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj)[attr];
// if(obj.currentStyle){
// return (obj.currentStyle[attr]);//兼容IE6~8
// }else{
// return (getComputedStyle(obj)[attr]);//兼容其他浏览器
// }
//注意:getStyle()函数获取background值为复合样式;有兼容性问题;需要改成backgroundColor获取单一的值;
//且字符串的属性名不能有空格,不然无法读取,且不能获取未给elem元素设置(内联或内外样式表设置)的样式,未定义;
}
//2.封装函数获取任意元素curEle的到body的top和Left函数;
function offSet(curEle) {
var totalLeft = null;
var totalTop = null;
var par = curEle.offsetParent;
//首先把自己本身的相加
totalLeft += curEle.offsetLeft;
totalTop += curEle.offsetTop;
//现在开始一级一级往上查找,只要没有遇到body,我们就把父级参照物的边框和偏移相加
while (par){
if (navigator.userAgent.indexOf("MSIE 8.0") === -1){
//不是IE8我们才进行累加父级参照物的边框
totalTop += par.clientTop;
totalLeft += par.clientLeft;
}
//把父级参照物的偏移相加
totalTop += par.offsetTop;
totalLeft += par.offsetLeft;
par = par.offsetParent;
}
return {left: totalLeft,top: totalTop};//返回一个数组,方便我们使用哦。
}
12.document.title=值;
13.函数的三种调用方式,函数调用fun(),元素单击事件调用elem.onclick=fun;定时器调用setInterval(fun,1000);
14.定时器原则,如果由用户控制定时器开关(移入移出/单击等),一定要先关再开,即先清除之前的定时器(无论是否为空)再开启新的定时器,否则会定时器效果叠加;
window.onload=function(){
setTimeut(function(){//可以设置在页面加载完全之后一次广告弹出
elem.display="inline-block";
setTimeout(function(){//在其里面可在嵌套设置setTimeout定时 器表示广告显示的显示的时间
elem.display="none";
},2000)
},3000),
15.num%=arr.length可以让num始终在0~arr.length-1之间;
16.图片轮播:先声明一个timer=null用于存放定时器,将轮播的定时器设置为一个函数,可以页面加载成功2秒后调用函数即可开启轮播,在鼠标移入是清除定时器clearTimeout(timer);在鼠标移出时再重新调用定时器函数;也可应用于鼠标移开几秒后在执行某个如收缩等事件;也可以给元素单独自定义元素定时器名clearInterval(elem.timer),要让元素准确运动到800px位置,可以先设置if(speed>800){speed=800}然后在执行运动,最后当if(speed>=800){clearInterval(elem.timer)};
17.str.charcodeAt(i)+for循环可以判断str是否全为数字。str.charCodeAt(i)与String.fromCharCode(120201)可以将文字或数字通过转换后的编码再按照某种方式如加减乘除某个数值的计算方式或多次计算后在转换为字符串形成对原字符串的加密。
18.通过字符串的split()函数可以实现查找高亮显示/修改文本中搜索的文字内容。
19.json:就是跨平台的数据存储个格式(对象格式);如varjson={'name':'top'}、{name:'top'}其中'name'比name更具有安全性,可用./[]访问对象的值。
20.DOM/BOM/ECMAscript是JS的原生.
21.new创建的都是对象,如var str='hellow',为基本类型字符串,var str=new String('hellow')为基本类型的字符串对象。
22.基本类型的包装对象,String,Number,Boolean;如String.prototype.方法=function(){//方法体};str.方法该调用是正确的;如果直接通过'str.方法=值'创建的方法在构造函数中,不在原型对象里,所有不能alert(str.方法);
23.原型链:实例对象与原型直接的链接,叫做原型链!
24.当一个实例对象的构造函数的属性与原型方法重名相同时,前者优先级高;如var arr=[];arr.num=10;Array.prototype.num=20;alert(arr.num)结果为10;
25.hasOwnProperty()用于判断某实例对象自身是否具有某属性方法,而不是其原型对象是否具有某方法,如var arr=[];arr.num=10,Array.prototype.num2=20;
arr.hasOwnProperty('num/num2');结果为true/false;
26.arr.constructor==Array判断查看arr的构造函数结果为Array;Array.prototype查看的是原型对象。
27.四种情况下不能直接用this:
(1)行间样式里;
(2)定时器内;
(3)嵌套函数内;
(4)绑定事件,attachEvent有问题;
28.类数组不是数组,不能完全用数组的API,比如getElementsByTagName()获取的结果是类数组。
BOM:
1.window.open(url不写表示打开空白页面,’_self’/’_blank’);window可以省略不写,表示window。
2.Window.close();不同浏览器下存在兼容问题。
3.获取当前浏览器的信息:window.navigator.userAgent.indexOf(“MISE”),indexOf(“MISE”)判断是否是IE浏览器。
4.浏览器可视宽高度:Document.documentElement/body.lientWidth/clientHeight;document/body的兼容性问题;
5.滚动距离:var scrollTop=document.documentElement.scrollTop || document.body.scrollTop;解决了兼容性的问题;
6.内容高:div1.scrollHeight;<div id=”div1” style=”overflex:hidden;height:100px”><div height=’100px’></div></div>。
7.onscroll/onresize/onfocus/onblur;页面滚动事件/窗口大小变化事件/获得焦点事件/失去焦点事件;
8.事件冒泡:当一个元素接收到事件时,会把他接收到的所有传播给他的父级元素,直到传递到最顶级父级;var ev=ev || event;解决兼容性问题;
9.阻止冒泡:当前元素要阻止冒泡事件中函数的调用;只需要obj.cancelBubble=true/false;
(1)应用:如单击某个按钮div显示,点击除按钮外其他页面div隐藏;
(2)应用:侧边栏的分享到,利用冒泡,绑定在父元素鼠标移入移除事件,不绑定在子元素上,<div><div>分享到</div></div>;
10.一个对象上同一个事件绑定多个函数,有兼容性问题;
IE:obj.attachEvent(带on的事件名称,事件函数),this指向window;
标准:obj.addEventListener(不带on的事件名称,事件函数,是否捕获true/false),事件函数中this指向出发该事件的对象;
11.fun.call(参数1就是函数fun的this指向对象,参数s就是传入函数fun中的一个或多个函数参数);
Function bind(obj,没有on的事件名称,函数名){ //自定义事件绑定, if(obj.addEventListener){ //解决了兼容性问题;
obj.addEventListener(不带on的事件对象,函数名,false);
}else{
obj.attachEvent(带on的事件名,function(){
函数名.call(obj); //解决了this指向window对象;
})
};
12.事件捕获:IE下不存在事件捕获;
False=冒泡:事件由触发元素向外依次触发——出;
True=事件捕获:事件由外向触发元素依次触发——进;
13.事件取消:(1)on事件名=null;
(2)obj.dettachEvent(事件名,取消的事件名)——IE下;
(3)obj.removeEventListener(事件名,事件函数;是否捕获这里与绑定事件时的true/false必须一致才能取消);
14.键盘事件:onkeydown/onkeyup/e.keyCode:键盘按下事件如果按下不松手会连续触发,但是会停顿一会,可以用定时器解决/键盘松开事件/键盘的按键编号;ctrlkey/shiftkey/altkey为布尔值,表示当一个事件发生的瞬间其是否被按下,按下为true否则为false;如按下shift/ctrl全选的应用;
15.事件默认行为:return false可阻止事件默认行为(指IE8以上,可以阻止默认行为,IE8一下不能使用此阻止默认行为);
16.右键菜单事件:oncontextmenu,即鼠标右键单击显示右键菜单触发的事件;
(1)应用:自定义右键菜单,根据鼠标的位置(e.clientX/Y)显示自定义div的位置和右键菜单事件制作自定义右键菜单;
17.拖拽事件:
(1)onmousedown:选择元素,当鼠标按下选择,如果有文字/图片被选择会触发浏览器默认行为,需要在该onmousedown事件接收后阻止默认行为return false/非标准下用全局捕获;
(2)onmousemove:避免鼠标移动太快鼠标移出元素,可以将onmousemove的obj定义在document,该事件发生在onmousedown内,并设置其obj为documnent;
(3)onmouseup:清空documnent.onmousemove/onmouseup=null;避免移动到其他元素上无法实现释放,可改成obj为document;
18.设置全局捕获:obj.setCapture();当我们给一个元素设置全局捕获后,那么这个元素就会监听之后所有的事件,并当有事件发生时,就会强制将该事件抢到该obj的该事件下,有兼容性问题,释放全局捕获obj.releaseCapturn();
(1)应用:在onmousedown时判断如果有全局捕获就设置全局捕获;
在onmouseup时判断如果有释放全局捕获就释放全局捕获;
(2)应用:有范围的拖拽,如在可视区内拖拽;
(3)磁性吸附:在onmousemove事件中当其距离小于某个值时,将其赋值给一个边界值,即可实现磁性吸附;
19.碰撞检测:九宫格规则;
20.放缩边框:上下左右拉缩;
21.自定模拟滚动条:<div id=”滚动条”><div id=”滑滚动”></div></div>;
22.鼠标滚轮事件:IE/谷歌下:onmousewheel=function(){};
火狐下:DOMMouseScroll必须用先判断是否有addEventListener,然后在addEventListener绑定;
判断上或下滚动IE/谷歌下:e.wheelDelta向上滚动:值为-120;
向下滚动:值为+120;
火狐下:e.detail向上滚动:值为-3;
向下滚动:值为+3;
注意:鼠标滚轮事件可能会触发body滚动条的默认行为;