js:1.

JS第一周

一、JS:轻量级的客户端脚本编程语言
1、编程语言 
HTML+CSS是标记语言 
编程语言是具备一定逻辑的,拥有自己的编程思想(面向对象编程[OOP]、面向过程编程)
面向对象的语言 
C++
JAVA
PHP
C#(.net)
JS
…
面向过程 
C语言
2、目前的JS已经不仅仅是客户端语言了,基于NODE可以做服务器端程序,所以JS是全栈编程语言
3、学习JS,我们学习它的几部分组成
ECMAScript(ES):规定了JS的语法和模型
DOM:document object model 文档对象模型,提供各种API(属性和方法)让JS可以获取或者操作页面中的HTML元素(DOM元素)
BOM:browser object model 浏览器对象模型,提供各种API让JS可以操作浏览器
二、ECMAScript
它是JS的语法规范,JS中的变量、数据类型、语法规范、操作语句、设计模式等等都是ES规定的
JS大部分的语法都是ES3.0的
三、变量(variable)
它不是具体值,只是一个用来存储具体值的容器或者代名词,因为它存储的值可以改变,所以称为变量
基于ES语法规范,在JS中创建变量有以下方式
var (ES3)
function(ES3) 创建函数(函数也是变量,只不过存储的值时函数类型的而已)
let(ES6)
const(ES6) 创建的是变量
import(ES6) 基于ES6的模块规范导出需要的信息
class(ES6) 基于ES6创建类
1./*
2. *语法:
3. *var [变量名]=值;
4. *let [变量名]=值;
5. *const [变量名]=值;
6. *function 函数名(){}
7. */
8.
9.
10.var n=13;
11.n=15;
12.alert(n+10);=>弹出来25 此时的N代表15
13.
14.const m=100;
15.m=200;=>Uncaught TypeError: Assignment to constant variable.
16.不能给一个常量重新的赋值(常量存储的值不能被修改,能够修改就是变量了)
创建变量,命名的时候要遵循一些规范
严格区分大小写
遵循驼峰命名法:按照数字、字母、下划线或者$来命名(数字不能作为名字的开头),命名的时候基于英文单词拼成一个完整的名字(第一个单词字母小写,其余每一个有意义单词的首字母都大写)
不能使用关键字和保留字:在JS中有特殊含义的叫关键字,未来可能会成为关键字的叫做保留字
1.var n=12;
2.var N=13;=>两个n不是同一个变量
3.
4.
5.var studentInfo/student_info/_studentInfo(下划线在前的,都是公共变量)/$studentInfo(一般存储的是JQ元素)...
6.
7.语义化强一些
8.add/create/insert
9.del(delete)/update/remove(rm)
10.info/detail
11.log(日志)
12.
13.
四、JS中的数据类型
数据值是一门编程语言进行生产的材料,JS中包含的值有以下类型(JS中数据类型分类)
基本数据类型(值类型) 
数字number
字符串string
布尔boolean
null
undefined
引用数据类型 
对象object 
普通对象
数组对象
正则对象
日期对象
…
函数function
ES6中新增加的一个特殊类型:Symbol(唯一的值)
1.[基本数据类型]
2.//=>number类型
3.var n = 13;//=>0 -13 13.2 数字类型中有一个特殊的值NaN(not a number代表不是一个有效的数字,但是属于number类型的)
4.
5.//=>string类型
6.var s ='';//=>"" '13' "{}" JS中所有用单引号或者双引号包裹起来的都是字符串,里面的内容是当前字符串中的字符(一个字符有零到多个字符组成)
7.
8.
9.//=>布尔类型
10.var b = true;//=>布尔类型只有两个值 truefalse假
11.
12.
13.[引用数据类型]
14.//普通对象
15.var o ={name:'珠峰培训',age:9};//=>普通的对象:由大括号包裹起来,里面包含多组属性名和属性值(包含多组键值对,各组键值对由逗号分隔) {}空对象
16.
17.//数组对象
18.var ary = [12,23,34,56];//=>中括号包裹起来,包含零到多项内容,这种是数组对象  []空数组
19.
20.//正则对象
21.var reg = /-?(\d|([1-9])\d+)(\.\d+)?/g;//=>由元字符组成一个完整的正则 //不是空正则是单行注释,正则不可以为空
22.
23.//function函数
24.function fn(){
25.
26.}
27.
28.[Symbol]
29.创建出来的是一个唯一的值
30.var a = Symbol('珠峰');
31.var b = Symbol('珠峰');
32.
33.a==b //=>false
34.const和Symbol的结合,定义唯一的不变的数值
35.

扩展:JS代码如何被运行,以及运行后如何输出结果 
[如何被运行]
把代码运行在浏览器中(浏览器内核来渲染解析)
基于NODE来运行(NODE也是一个基于V8引擎渲染和解析JS的工具,不是一门语言)
[如何输出结果]
alert():在浏览器中通过弹框的方式输出(浏览器提示框)
1.var num =12;
2.alert(num);//=>window.alert全称,window可省略
3.
4.var str='珠峰';
5.alert(str);
6.
7.基于alert输出的结果都会转换为字符串:把值(如果是表达式先计算出结果)通过toString这个方法转换为字符串,然后再输出
8.alert(1+1);=>'2'
9.alert(true);=>'true'
10.alert({name:'xxx'});=>'[object Object]'
11.
12.//=>为什么对象toString后的结果就是object Object?
13.
confirm():和alert的用法一致,输出的结果也是转换为字符串,只不过提示框中有确定和取消两个按钮,所以它是确认提示框
1.var flag =confirm('确认要退出吗?');
2.if (flag){
3.    //=>flag:true 用户点击的是确定按钮
4.}else{
5.    //=>flag:false 用户点击的是取消按钮
6.}
prompt():在confirm的基础上增加输入框,点击取消返回的是null,点击确定若有内容返回内容,若无内容返回”(空字符串)
console.log():在浏览器控制台输出日志(按F12 (FN+F12)打开浏览器的控制台)
Elements:当前页面中的元素和样式在这里都可以看到,还可以调整样式结构等
Console:控制台,可以在JS代码中通过.log输出到这里,也可以在这里直接的编写JS代码
Sources:当前网站的源文件都在这里
……
console.dir():比log输出的更加详细一些(尤其是输出对象数据值得时候)
console.table:把一个JSON数据按照表格的方式输出
…(自己回去扩展更多console输出方法)
五、数据类型的详细剖析
基本数据类型
1.number数字类型
NaN:not a number 但是它是数字类型的 
isNaN():检测当前值是否是非有效数字,返回true代表非有效数字,返回false代表是有效数字
(1)把其他数据类型转换为number数字类型的方法
a.Number()
[字符串转换为数字]
Number(‘13’) ->13
Number(‘13px’)->NaN 如果当前字符串中出现任意一个非有效数字字符,结果则为NaN
Number(‘13.5’)->13.5 可以识别小数
[布尔转换为数字]
Number(true)->1
Number(false)->0
[其它]
Number(null)->0
Number(undefined)->NaN
把引用数据类型值转换为数字:先把引用值调取toString转换为字符串,然后再把字符串调取Number转换为数字
[对象] 
({}).toString() ->’[object Object]’ ->NaN
[数组] 
[12,23].toString()->’12,23’->NaN 
[12].toString()->’12’->12 
[正则] 
/^/.toString() -> '/^/’ ->NaN 
[函数] 
function(){}.toString ->’ function(){}’->NaN 
2、当前检测的值已经是数字类型,是有效数字返回false,不是返回true(数字类型中只有NaN不是有效数字,其余都是有效数字)
b、parseInt/parseFloat
等同于Number,也是为了把其它类型的数值转换为数字类型
和Number的区别在于字符串转换分析上
Number:出现任意非有效数字字符,结果就是NaN
parseInt:把一个字符串中的整数部分解析出来 
parseFloat:把一个字符串中小数(浮点数)部分解析出来
1.parseInt('13.5px') =>13
2.parseFloat('13.5px') =>13.5
3.
4.parseInt('width:13.5px') =>NaN 从字符串最左边字符开始查找有效数字字符,并且转换为数字,直到遇到一个非有效数字字符,查找结束
(2)isNaN检测的机制
首先验证当前要检测的值是否为数字类型的,如果不是,浏览器会默认把值转换为数字类型
其他基本类型转换为数字:直接使用Number()这个方法来转换的
1.//=>语法:isNaN([vaule])
2.var num=12;
3.isNaN(num);//->检测num变量存储的值是否为非有效数字 false
4.
5.isNaN('13')=>false
6.isNaN('珠峰')=>true
7.isNaN(true)=>false
8.isNaN(false)=>false
9.isNaN(null)=>false
10.isNaN(undefined)=>true
11.isNaN({age:9})=>TRUE
12.isNaN([12,23])=>true
13.isNaN([12])=>false
14.isNaN(/^$/)=>true
15.isNaN(function(){})=>true
(3)NaN(除了数字可能是任何其他东西)的比较
1.NaN==NaN false NaN和谁都不相等,包括自己
思考题:有一个变量num,存储的值不知道,我想检测它是否为一个有效数i字,下面方案是否可以
1.if(Number(num)==NaN){
2.    alert('num不是有效数字');
3.}
4.NaN和谁都不相等,条件永远不成立(即使num确实不是有效数字,转换的结果确实是NaN,但是NaN!=NaN)
5.
6.if(isNaN(num)){
7.    //=>检测数字是否为有效数字的唯一方法
8.    alert('num为非有效数字!')
9.}
10.
2.布尔类型
只有两个值:true/false
把其他数据类型转换为布尔类型的方法
Boolean()
!
!!
1.Boolean(1)->true
2.Boolean(0)->false
3.Boolean(NaN)->false
4.
5.!'珠峰培训'->先把其它数据类型转换为布尔类型,然后再取反
6.
7.!!NaN->取两次反,等价于没取反,也就剩下转换为布尔类型,与Boolean的效果一样
8.
9.真实项目中想将数据转换为布尔类型,一般直接用!!
10.
规律:在JS中只有0、NaN、空字符串、null、undefined这五个值转换为布尔类型为false,其余都为true
3、null && undefined
都代表空或者没有
null:空对象指针
undefined:未定义
null:一般都是意料之中的没有(通俗理解:一般都是人为手动赋值为null,后续程序中我们会再次给他赋值)
1.var num = null;//=>null是手动赋值的,预示着我会把num变量的值进行修改
2....
3.null=12;
undefined:代表的没有一般都不是人为手动控制的,大部分都是浏览器自主为空(后面可以赋值也可以不赋值)
1.var num;//=>此时变量的值,浏览器给分配的就是undefined(声明)
2....
3.后面可以赋值也可以不赋值
引用数据类型
object对象类型
普通对象
由大括号包裹起来的
有零到多组属性名和属性值(键值对)组成
属性是用来描述当前对象特征的,属性名是当前具备这个特征,属性值是对这个特征的描述(专业语法,属性名称为键[key],属性值称为值[value],一组属性名和属性值称为一组键值对)
1.var obj = {name:'珠峰培训',age:8};
2.
3.//=>对象的操作:对键值对的增删改查
4.[获取]
5.语法:对象.属性/对象[属性]
6.obj.name
7.obj['name'] 一般来说对象的属性名都是字符串格式,属性值可以是各种类型的
8.
9.[增/改]
10.JS对象中,属性名是不允许重复的,是唯一的
11.obj.name='周啸天';//=>原有对象中存在NAME属性,此处属于修改属性值
12.obj.sex='';//=>原有对象不存在sex,此处相当于给当前对象新增一个属性sex
13.obj['age']=9;
14.
15.[删除]
16.- 彻底删除:对象中不存在这个属性了
17.delete obj['age']
18.
19.- 假删除:并没有移除这个属性,只是让当前属性的值为空
20.obj.sex=null;
21.obj.sex='';//=>不算假删除,代表的就是字符串,只不过为空而已
22.
23.在获取属性值得时候,如果当前对象有这个属性名,则可以正常获取到值(哪怕是null),但是如果没有这个属性名,则获取的结果是undefined
24.
25.
26.----
27.var obj = {name:'珠峰培训',age:8};
28.var name = 'zhufeng'
29.
30.obj.name//=>'珠峰培训' 获取的是NAME属性的值
31.
32.obj['name']//=>'珠峰培训' 取的是NAME属性的值
33.
34.obj[name]//=>此处的NAME是一个变量,我们要获取的属性名不叫NAME,是NAME存储的值'zhufeng'=>obj['zhufeng']=>没有这个属性,属性值是undefined
35.
36.----
37.'name'和 name的区别?
38.=> 'name'是一个字符串值,它代表的是本身
39.=> name是一个变量,它代表的是本身存储的这个值

 
一个对象的属性名不仅仅是字符串格式的,还有可能是数字格式的
1.var obj = {name:'珠峰培训',age:8,0:12};
2.obj[0]//=>12
3.obj['0']//=>12
4.obj.0//=>Uncaught SyntaxError(语法错误): Unexpected number


当我们存储的属性名不是字符串也不是数字的时候,浏览器会调用toString的方法把这个值转换为字符串,然后再进行存储
obj[{}]=300; =>先把({}).toString()后的结果作为对象的属性名存储进来 obj[‘[object Object]’]=300
obj[{}]=>获取的时候也是先把对象转换为字符串’[object Object]’,然后获取之前存储的300?


数组对象(对象都由键值对组成的)
数组对象获取、增加、修改属性的方法是和普通对象一样的,其实普通对象对属性操作的方法对于其他对象类型及函数类型时一样的

数组对象的属性名是数字(我们把数字属性名称为当前对象的索引)
数组对象真删除 
被删除的键值对对应的索引即属性名会变没,属性值会变为empty,但是数组长度不会变
数组对象假删除 
与普通对象的效果一样,属性值变为null

中括号的语法问题 
直接定义数组的时候中括号不支持除数字以外的字符,会报错,想要在数组中有除数字以外的字符,只能通过属性的增加

索引的概念:即是数字又能递增
六、JS的运行机制
1、当浏览器(它的内核/引擎)渲染和解析JS的时候,会提供一个供JS代码运行的环境,我们把这个环境称之为”全局作用域(global scope)”->栈内存 
2、代码自上而下执行(之前还有一个变量提升阶段)
栈内存:本身就是一个供JS代码执行的环境,所有的基本类型值都会直接的在栈内存中开辟一个位置进行存储 
堆内存:用来存储引用数据类型中的信息值的,对象存储时键值对,函数存储的是代码字符串
基本数据类型运行方法
基本数据类型的值会存储在当前作用域下
1.var a = 12;
2.var b=a;
3.b=13;
4.console.log(a);//=>12
5.
1)在当前作用域下开辟一个空间存储12
2)在当前作用域中声明一个变量a(var a)
3)让声明的变量和存储的12进行关联(把存储的12赋值给a,赋值操作叫做定义)
基本数据类型(也叫作值类型),是按照值(让两个空间没有关联)来操作的:把原有的值复制一份放到新的空间或者位置上,和原来的值没有关系
引用数据类型运行方法
引用数据类型的值不能直接存储到当前的作用域下(因为可能存储的内容过于复杂,我们需要先开辟一个新的空间(理解为仓库),把内容存储到这个空间中)
1.var obj1={n:100};
2.var obj2=obj1;
3.obj2['n'] = 200;
4.console.log(obj1.n);=>200
1)因为对象的内容比较复杂,所以会另开辟一个新的内存空间(该空间不属于当前的作用域)->堆内存,把对象中的键值对一次存储起来(为了保证后面可以找到这个空间,此空间有一个16进制的地址)
2)声明一个变量
3)让变量和空间地址关联在一起(把空间地址赋值给变量)
引用类型不是按值操作,它操作的是空间引用地址:把原有空间的地址赋值给新的变量,但是原来的空间没有被克隆,还是一个空间,这样就会出现多个变量关联的是相同的空间,相互之间就会存在影响了

案例一
1.var obj = {
2.    n: 10,
3.    m: obj.n * 10 //=>Uncaught TypeError: Cannot read property 'n' of undefined(类型错误,找不到undefined下的属性n,undefined是基本数据类型没有属性)
4.};
5.console.log(obj.m);
6.
7.
8. 1)形成一个全局作用域(栈内存)
9. 2)代码自上而下执行
10.     a.首先开辟一个新的堆内存(AAAFFF111),把键值对存储到堆内存中
11.     n:10
12.     m:obj.n*10 =>obj.n此时堆内存信息还没有存储完成,空间的地址还没有给obj,并没有关联起来,堆内存会知道全局作用域内声明了一个变量obj,此时的obj是undefined(相当于var obj;),obj.n<=>undefined.n
13.     //=>undefined为基本数据类型,没有属性
案例二
1.var obj={
2.    n:10,
3.    m:n*10//=>Uncaught ReferenceError: n is not defined
4.};
5.
6.//开辟了新的堆内存(AAAFFF222),把键值对存储在堆内存中
7.因为并没有声明过n,所以不会知道n是什么,所以会出现n is not definde
案例三
1.var ary1 = [3, 4];
2.var ary2 = ary1;
3.ary2[0] = 1;
4.ary2 = [4, 5];
5.ary2[1] = 2;
6.ary1[1] = 0;
7.console.log(ary1, ary2);

七、JS中的判断操作语句
1、if/else if/else
1.var num =12;
2.if(num>10){
3.    num++;//=>num=num+1 num+=1
4.}else if(num>=0 && num<=10){
5.    num--;
6.}else{
7.    num+=2;
8.}
9.console.log(num);
只要有一个条件成立,后面不管是否还有成立的条件,都不在判断执行了
1.var num = 10;
2.if(num>5){
3.    num+=2;
4.}else if(num>8){
5.    num+=3;
6.}else{
7.    num+=4;
8.}
9.console.log(num);//=>12
关于条件可以怎么写?
1.//  >= /<= /== 常规比较
2.if(0){
3.    //=>不管你在条件判断中写什么,最后总要把其计算出TRUE/FALSE来判断条件是否成立(把其他它类型的值转换为布尔类型,只有0/NaN/''/null/undefined)是false,其余都是true
4.}
5.if('3px'+3){
6.    //=>在JS中,+ - * / % 都是数学运算,除 + 以外,其余运算符在运算的时候,如果遇到了非数字类型的值,首先会转换为数字类型(Number),然后再进行运算
7.
8.    //=>在JS中除了数学相加,还有字符串拼接的作用,如果运算中遇到了字符串,则为字符串拼接,而不是数学相加
9.
10.    '3px'+3=>'3px3'
11.}
12.
13.if('3px'-3){
14.    '3px'-3=>NaN
15.}
BAT面试题
1.var num = parseFloat('wideth:12.5px');//=>NaN
2.if(num==12.5){
3.    alert(12.5);
4.}else if(num==NaN){//=>NaN!=NaN
5.    alert(NaN);
6.}else if(typeof num='number'){//=>typeof NaN->"number"
7.    alert(0);
8.}else{
9.    alert('啥也不是!')
10.}
2、三元运算符
语法:条件?条件成立做的事情:不成立做的事情;
1.var num = 12;
2.if (num>10){
3.    num++;
4.}else{
5.    num--;
6.}
7.
8.//=>改成三元运算符:num>10?num++:num--;
特殊情况
1.//=>如果三元运算符中的某一部分不需要任何的处理,我们用null/undefined/void 0...占位即可
2.var num = 12;
3.if (num>10){
4.    num++;
5.}
6.num>10?num++:null;
7.
8.//=>如果需要执行多项操作,我们把其用小括号包裹起来,每条操作语句用逗号分隔
9.num=10;
10.if(num>=10){
11.    num+=10;
12.    num*=10;
13.}
14.num>10?(num++,num*10):null;
思考题
1.var num = 12;
2.if(num>0){
3.    if(num<10){
4.        num++;
5.    }else{
6.        num--;
7.    }
8.}esle{
9.    if(num==0){
10.        num++;
11.        num=num/10;
12.    }
13.}
14.
15.//=>改写成三元符
16.num>0?(num>10?num++:num--):(num==0?(num++,num=num/10):null);
17.
18.if(0<n<10){
19.    num++;
20.}else if(n>=10){
21.    num--;
22.}else if(n==0){
23.    num++;
24.    num=num/10;
25.}
26.
27.0<n<10?num++:(n>=10?num--:(n==0?(num++,num=num/10):null));
3、switch case
JS中的一种判断方式 
switch case 应用于变量(或者表达式等)在不同值情况下的不同操作,每一种case结束后都要加break(结束整个判断)
1.var num = 10;
2.if(num==10){
3.    num++;
4.}else if(num==5){
5.    num--;
6.}else{
7.    num==0
8.}
9.
10.//=>改写为switch case语句
11.var num = 10;
12.switch(num){
13.    case 10:
14.        num++;
15.        break;
16.    case 5:
17.        num--;
18.        break;
19.    default:
20.        num==0;
21.}
swith case中每一种case情况与变量之间的比较都是基于’===’绝对相等来完成的
1.'10'==10
2.=>true 相等比较,如果等号左右两边的类型不一样,首先会转换为一样的数据类型,然后再进行比较
3.=>当前案例中,就是把字符串'10'转换为数字了,然后再比较的
4.
5.'10'===10 绝对比较,如果两边的数据类型不一样,则直接不相等,它要求类型和值都完全一样才会相等(真实项目中为了保证代码的严谨性,我们应该更多使用绝对比较)
不加break的小应用
1.//=>不叫break,后面的条件不管是否成立,都会被执行;利用此机制,我们可以完成一些特殊的处理,例如:如果num等于10和等于5都要做同一件事情,那么我们写在一起,不用加break即可
2.
3.var num = 9;
4.switch (num) {
5.    case 10:
6.    case 5:
7.        num--;
8.        break;
9.    default:
10.        num = 0;
11.}
12.console.log(num);
13.
1.var a = [4], b = '3';
2.
3.function foo(a, b) {
4.    return Math.abs(a - b) < 2;
5.}
6.
7.switch (true) {
8.    case !(a && b):  
9.        console.log('a:'+a,' b:'+b);
10.        break;
11.    case foo(a,b):  
12.        console.log('a - b < '+Math.abs(a-b));
13.    case a == b:
14.        console.log(a+'=='+b);
15.        break;
16.    case a < b:
17.        console.log(a+'<'+b);
18.        break;
19.    case a > b:
20.        console.log(a+'>'+b);
21.        break;
22.    default:
23.        break;
24.}
25.
26.输出
27.a-b<1
28.4==3
n++和n=n+1是否一样?
1.var n = '10';
2.n=n+1
3.//=>属于字符串拼接,结果是'101'
4.n+=1
5.//=>属于字符串拼接,结果是'101'
6.n++;
7.//=>此时这种写法还是数学运算,不是字符串拼接,结果是11
for 循环
作用:按照一定的规律,重复去做某件事情,此时我们就需要使用循环来处理了
for 循环的语法组成
1.定义初始值 var i = 0
2.设立循环成立的条件(条件成立循环继续,不成立循环结束) i<ary.length
3.条件成立会执行循环体中的内容(大括号包裹的就是循环体)
4.执行步长累加的操作
1.
2.var ary = [12,23,45];
3.
4./*==itar [TAB] 自动补全循环的代码==*/
5.
6.for (var i = 0; i < ary.length; i++) {
7.//    第一次循环 i=0 i<3 ... i=1
8.//    第二次循环 i=1 i<3 ... i=2
9.//    第三次循环 i=2 i<3 ... i=3
10.//    第四次循环 i=3 i<3  循环结束(本次没有循环)
11.    console.log(ary[i]);
12.}
1.//取数组中的奇数项
2.var ary = [12,23,45,67,86,97];
3.
4.for (var i = 0; i < ary.length; i++) {
5.    //12%5: %称为模,用12除以5取余
6.    if (i%2===0){
7.        console.log(ary[i]);
8.    }
9.}
10.
11.for (var i = 0; i < ary.length; i+=2) {
12.    console.log(ary[i]);
13.}
测验
1.for (var i = 1; i <=10; i+=2) {
2.    if(i<=5){
3.        i++;
4.        continue;
5.    }else{
6.        i-=2;
7.        break;
8.    }
9.    i--;
10.    console.log(i);
11.}
12.console.log(i);//=>5
13.
八、JS中检测数据类型的方法
typeof 
constructor
instanceof
Object.prototype.toString.call()
1、typeof(逻辑运算符)
语法:typeof[value] =>检测value数据类型
返回值:使用typeof检测出来的结果是一个字符串,字符串中包含对应的数据类型,例如:’number’/’string’/’boolean’/’undefined’/’object’/’function’
typeof null =>’object’ 因为null代表空对象指针(没有指向任何的内存空间)
typeof检测数组/正则/对象,最后返回的都是’object’,也就是基于这种方式无法细分对象
九、获取页面中的DOM操作
1、document.getElementById
在整个文档中通过元素的ID属性值来获取这个元素对象 
getElementById获取元素的方法 
document限定了获取元素的范围,我们把这个范围称之为:”上下文[context]”
1.var oBox = document.getElementById('box');
2.
3.1.通过getElemntById获取的元素是一个对象数据类型的值(里面包含很多内置的属性)
4.
5.typeof oBox =>'object'
6.
7.2.分析包含的属性
8.className:存储的是一个字符串,代表当前元素的样式类名
9.
10.id:存储的是当前元素的ID值(字符串)
11.
12.innerHTML:存储当前元素中所有的内容(包含HTML标签)
13.
14.innerTEXT:存储当前元素中所有的文本内容(没有元素标签)
15.
16.onclick:元素的一个事件属性,基于这个属性,可以给当前元素绑定点击事件
17.
18.onmouseover:鼠标滑过事件
19.
20.onmouseout:鼠标离开事件
21.
22.style:存储当前元素所有的"行内样式值",获取和操作的都只能是写在标签上的行内样式,写在样式表中的样式,无法基于这个属性获取到
思考题:获取扩展,如何获取当前元素的所有样式(不管是写在哪的?) style只能获取写在行内上的
1.getComputedStyle(ele,null/伪类)一个可以获取当前元素所有最终使用的CSS属性值。返回的是一个CSS样式对象([object CSSStyleDeclaration]) 
非ie浏览器中使用,第一个参数是要获取样式对应的元素,第二个null就是考察本身
2.currentStyle是IE浏览器的一个属性,返回的是CSS样式对象
ie浏览器使用
element指JS获取的DOM对象 
element.style //只能获取行内式样式 
element.currentStyle //IE浏览器获取非行内式样式 
window.getComputedStyle(element,伪类) //非IE浏览器获取非行内式样式 
document.defaultView.getComputedStyle(element,伪类)//非IE浏览器获取非行内嵌样式
[context].gexElementsByTagName
在指定的上下文中,通过元素的标签名获取一组元素集合
上下文是我们自己来指定的
1.var oBox = document.getElementById('box');
2.
3.var boxList = oBox.getElementsByTagName('li');
4.console.dir(boxList);
5.
6.1.获取的结果是一个元素集合(HTMLCollection),首先它也是对象数据类型的,结构和数组非常相似(数字作为索引,length代表长度),但是不是数组,我们把它叫做“类数组”
7.
8.boxList[0] 获取当前集合中的第一个LI(通过索引获取到具体的某一个LI即可)
9.
10.boxList.length 获取集合中LI的数量
11.
12.2.集合中的每一项存储的值又是一个元素对象(对象数据类型,包含很多的内置属性,例如:id/className...)
13.
14.boxList[1].style.color='red';  修改集合中第二个LI的文字颜色
15.
 
案例:隔行变色
1.===利用css样式来实现隔行变色,利用伪类选择器==
2.//nth-child(n):当前容器所有子元素中的第N个
3.//nth-of-type(n):先给当前容器按照某一个标签名进行分组,获取分组中的第N个
4.
5.==奇偶行变色==
6.//nth-of-type(even)  even代表偶数,odd代表奇数
7.
8.==隔三行变色==
9.//nth-of-type(3n+1)
10.//nth-of-type(3n+2)
11.//nth-of-type(3n)
1.<ul class="box" id="box">
2.    <li>岁末,珠峰就业还在一直创造奇迹</li>
3.    <li>珠峰成长的秘密-兴盛衰败一挥间,长留慈悲在心念</li>
4.    <li>珠峰培训帮我实现外企梦—上海姑娘徐米米的故事</li>
5.    <li>应届毕业生也能拿20多万年薪,我是面霸,我一口气拿下六个大公司offer</li>
6.    <li>学完之真的能推荐进百度吗,我来揭发珠峰培训的老底</li>
7.    <li>担心逻辑差,学不会,23岁切图小妹工资翻倍</li>
8.</ul>
9.
10.
11.//1.获取BOX中所有的LI
12.//想要修改BOX的样式有2种方法
13.
14.//a.通过style样式修改行内样式
15.//oBox.style.backgroundColor = 'pink' =>相当于给oBox增加了行内的样式
16.
17.//b.先利用class实现在css中设置好样式,然后给元素添加这个class名即可
18.//oBox.className='box bgColor';
19.//oBox['className']+=' bgColor';
20.=>不要忘记加上空格,否则会变成class='boxbgColor',此时不仅新加的样式没有,原有的样式也不会有
21.
22.
23.-----
24.var oBox = document.getElementById('box');
25.var boxList = oBox.getElementsByTagName('li')
26.
27.
28.for (var i = 0; i < boxList.length; i++) {
29.//    索引是奇数代表偶数行
30.    if(i%2!=0){
31.        // boxList[i].style.backgroundColor='red';
32.        boxList[i].className +='bgColor';
33.    }
34.}
35.
36.
37.
38.for (var i = 1; i < boxList.length; i+=2){
39. boxList[i].style.backgroundColor='pink';
40.}
案例隔行变色–总结 
1.利用数组的方式
1.var colorArray=['bgColor1','bgColor2','bgColor3'];
2.for (var i = 0; i < oList.length; i++) {
3.    oList[i].className=colorArray[i%3];
4.}
2.采用类名对应的方式来实现
1.
2.        .bg0{
3.            background: green;
4.        }
5.        .bg1{
6.            background: red;
7.        }
8.        .bg2{
9.            background: blue;
10.        }
11.
12.for (var i = 0; i < oList.length; i++) {
13.    oList[i].className='bg'+i%3;
14.}
3.不是遍历每个li,而是遍历每一组,每组三个li
1.for (var i = 0; i < oList.length; i+=3) {
2.    oList[i].className='bg0';
3.    i+1<=oList.length-1?oList[i+1].className='bg1':null;
4.    i+2<=oList.length-1?oList[i+2].className='bg2':null;
5.}
巧用布尔类型的转化与==比较的方法
1.for (var i = 0; i < oList.length; i++) {
2.    if(i%3){//1、2
3.        if(i%3==true){//1
4.            oList[i].className='bg1';
5.        }else{
6.            oList[i].className='bg2';
7.        }
8.    }else{
9.        oList[i].className='bg0';
10.    }
11.}
案例隔行变色,高亮显示–总结 
鼠标滑过的时候加上样式类,鼠标离开的时候去除样式类
1.var box=document.getElementById('box'),
2.    oList=box.getElementsByTagName('li');
3.
4.for (var i = 0; i < oList.length; i++) {
5.    oList[i].className='bg'+i%3;
6.    oList[i].onmouseover=function () {
7.        this.className+=" over";
8.    }
9.    oList[i].onmouseout=function () {
10.        this.className=this.className.replace(' over','');
11.    }
12.}
将原有class类名用自定义属性存储起来,经过的时候类名变为over,离开的时候变为原来的类名
1.for (var i = 0; i < oList.length; i++) {
2.    oList[i].className='bg'+i%3;
3.    oList[i].myClass=oList[i].className;
4.    oList[i].onmouseover=function () {
5.        this.className='over';
6.    }
7.    oList[i].onmouseout=function () {
8.        this.className=this.myClass;
9.    }
10.}
函数
在JS中,函数就是一个方法(一个功能体),基于函数一般都是为了实现某个功能
1.var total=10;
2.total+=10;
3.total=total/2;
4.total=toatl.toFixed(2)//=>保留小数点后面两位
5.(数字由一个方法toFixed用来保留小数点后面的位数)
6.
7....
8.在后续的代码中,我们依然想实现相同的操作(加10除以2)我们需要重新编写代码
9.
10....
11.这样的方式会导致页面中存在大量冗余的代码,也降低了开发的效率,如果我们能把实现这个功能的代码进行“封装”,后期需要这个功能执行即可,这样就好了。
12.
13.
14.**函数诞生的目的就是为了实现封装**:把实现一个功能的代码封装到一个函数中,后期想要实现这个功能,只需要把函数执行即可,不必要再次编写重复的代码,起到了**低耦合高内聚(减少页面中的冗余代码,提高代码的重复使用率)**的作用
15.
1.===ES3标准中===
2.//=>创建函数
3.function fn(){
4.    var total = 10;
5.    total+=10;
6.    total/=2;
7.    total=total.toFixed(2);
8.    console.log(total);
9.}
10.fn(); =>执行函数的意思
11.
12.ES3标准中:function 函数名([参数]){
13.    函数体:实现功能的JS代码
14.}
15.//=>执行函数
16.函数名();
17.
18.
19.===ES6标准创建箭头函数===
20.
21.let 函数名(变量名)=([参数])=>{
22.    函数体;
23.}
24.函数名();
25.
26.let fn=()=>{
27.    let total=10;
28.    ...
29.}
函数的运行机制
函数作为引用数据类型中的一种,它也是按照引用地址来操作的
1.function fn(){
2.    var total = 10;
3.    total+=10;
4.    total/=2;
5.    total=total.toFixed(2);
6.    console.log(total);
7.}
8.fn();
9.
10.[创建函数]
11.1.函数也是引用类型,首先会开辟一个新的堆内存,把函数体中的代码当做**字符串**存储到内存中(对象向内存中存储的是键值对)
12.2.把开辟的堆内存地址赋值给函数名(变量名)
13.
14.输出fn =>代表当前函数本身
15.输出fn() =>代表执行函数
16.
17.所以是否加小括号是两种不同本质的操作
18.
19.[函数执行]
20.目的:把之前存储到堆内存中的代码字符串变为真正的JS代码,自上而下执行,从而实现应有的功能
21.
22.
23.1.函数执行,首先会形成一个私有的作用域(一个供代码执行的环境,也是一个栈内存)
24.2.把之前在堆内存中存储的字符串复制一份过来,变为真正的JS代码,在新开辟的作用域中自上而下执行
25.3.函数每次执行的时候都会开辟一个新的私有作用域将代码复制过来从上而下执行,每次执行函数都是独立的,两次执行没有关系

函数中的参数
参数是函数的入口:当我们在函数中封装一个功能,发现一些原材料不确定,需要执行函数的时候,用户传递进来才可以,此时我们就基于参数的机制,提供出入口
1.//=>创建函数的时候的参数是形参,形参相当于入口,是变量(n/m就是变量)
2.function sum(n,m){
3.    //=>n和m分别对应要求和的两个数字
4.    var total = 0;
5.    total = n+m;
6.    console.log(total);
7.}
8.
9.//=>函数执行时的参数是实参,实参是具体的数据值
10.sum(10,20);   //=>n=10 m=20
11.sum(10);  //=>n=10 m=undefined
12.sum();    //=>n和m都是undefined
13.sum(10,20,30);  //=>n=10 m=20   30没有形参变量
选项卡
1.//思路:
2.//1.先让所有的LI&&DIV的class都为空(xxx.className=''),再让当前点击的这个LI和对应的DIV有ACTIVE这个样式类即可
3.//2.给所有的LI绑定点击事件,当点击任何一个LI的时候,都做第1步操作
4.
5.//获取所有li和div元素
6.var tabBox = document.getElementById('tabBox');
7.var tabList = tabBox.getElementsByTagName('li');
8.var divList = tabBox.getElementsByTagName('div');
9.
10.//封装一个方法完成页卡,即思路中的第一步
11.function changeTab(n) {
12.    //=>N:形参变量,当执行这个方法的时候,会把当前点击的这个LI的索引传递过来
13.
14.    //=>1.所有都没有选中样式
15.    for (var i = 0; i < tabList.length; i++) {
16.        tabList[i].className = '';
17.        divList[i].className = '';
18.    }
19.    //=>2.当前点击的有选中样式
20.    tabList[n].className = 'active';
21.    divList[n].className = 'active';
22.}
23.
24.//给每一个LI绑定点击事件
25.
26.===按原有思路===
27.for (var i = 0; i < tabList.length; i++) {
28.    //tabList[i] <=>每一轮循环当前要操作的那个LI对象
29.    tabList[i].onclick = function () {
30.        changeTab(i);//=>需要把当前点击的这个LI的索引传递进来
31.    }
32.}
33.
34. //=>事件绑定:给当前元素的某一个事件绑定一个方法,绑定的时候方法没有执行(属于创建一个方法),当在页面中手动触发点击事件的时候绑定的方法才会执行
35. //=>所以:
36. i=0 第一次循环
37. tabList[0].onclick=function () {
38. "changeTab(i);"
39. };
40. i++
41. i=1 第二次循环
42. tabList[1].onclick=function () {
43. "changeTab(i);"  changeTab(i)
44. };
45. i++
46. i=2
47. tabList[2].onclick=function () {
48. "changeTab(i);"
49. };
50. i++
51. i=3
52. //循环结束,此时因为只是函数创建的阶段,所以函数体只是存放在堆内存中的代码字符串,也就是说此时的changeTab(i)中的i只是字符串i,并不是索引,循环三次结束后i等于3
53.
54.//循环结束后点击li执行的时候
55.tabList[传进来的索引].onclick=function () {
56. "changeTab(3);"
57.
58.
59.===正确的写法===
60.//给每一个li增加一个自定义属性,每个li是个单独的对象,可以用对象的属性增加方法来增加自定义属性来存储自己对应的索引
61.for (var i = 0; i < tabList.length; i++) {
62.    //=>每一轮循环的时候,给每一个LI设置一个自定义属性“ZF-INDEX”,存储的值是各自的索引
63.    tabList[i]['zfIndex'] = i;
64.    tabList[i].onclick = function () {
65.        //this:代表的是当前点击的这个LI
66.        changeTab(this.zfIndex);//=>需要索引
67.    }
68.}
69.
选项卡的其他思路
让上一次有样式的li的样式清空,当前点击的li加上类样式
1.var lastIndex=0;//=>因为当前第一个li有样式,所以索引从0开始
2.for(var i=0;i<oList.length;i++){
3.    oList[i].myIndex=i;
4.    oList[i].onclick=function (){
5.    if(lastIndex===this.myIndex) return;
6.        oList[lastIndex].className='';
7.        oDiv[lastIndec].className='';
8.
9.        this.className=oDiv[this.myIndex].className='active';
10.    lastIndex=this.myIndex;
11.    }
12.}
13.
14.}
1.function change(curele){
2.    for(var i=0;i<oList.length;i++){
3.        if(oList[i]===curele){
4.            oList[i].className='active';
5.            oDiv[i].className='active';
6.            continues;
7.        }
8.        oList[i].className='';
9.        oDiv[i].className='';
10.    }
11.}
12.
13.for(var i=0;i<oList.length;i++){
14.    oList[i].onclick=function (){
15.        change(this);
16.    }
17.}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值