JavaScript-第一周

55 阅读17分钟

day01

一、JavaScript:

简称js,是一个运行在浏览器端的解释型、弱类型、面向对象的脚本语言。

浏览器端:环境,自带js解释器,打开浏览器可以自动运行,以后也会安装一个独立的js解释器。
解释型:在程序运行之前,不需要检查语法是否正确,直接运行,碰到错误就停止。
编译型:在程序运行之前,需要先检查语法是否正确,如果不正确,直接不运行。
弱类型:变量保存的数据可以是任意的,数据类型由数据来决定。
强类型:变量保存的数据,由数据类型来决定。
面向对象:对象名.属性名;对象名.方法名();

二、JavaScript的特点:

  • 可以使用一切编辑工具编辑代码;
  • 解释型
  • 弱类型
  • 面向对象
  • 可以做一切css完成不了的效果(轮播、选项卡、购物车、验证...)

三、引入:

  • 在html页面上书写一个script标签,在里面书写代码
<script>
   //js代码
</script>
  • 创建一个.js文件,再在html中进行引入
<script src="xx.js">
    //这里面不能写代码
</script>

四、输出方式/打桩输出:

  • 在控制台输出日志:console.log(想要输出的东西),不会影响到页面
  • 在页面输出日志:document.write(想要输出的东西),如果搭配上点击事件会把页面的所以东西替换掉
  • 在弹出框输出日志:alert(想要输出的东西),有时候会卡住整个页面,导致用户只能看见一个白板

五、变量:

创建后可以再次修改

语法:var 变量名 = 值
变量名不是随意的

  • 不能以数字开头
  • 建议驼峰命名法或下划线命名法
  • 命名要尽量见名知意
  • 如果变量名是name,不管你保存的数据类型是什么,都会悄悄给你转成字符串
  • 变量名不能是关键字
  • 声明变量不赋值结果为undefined
  • 同时创建多个变量:var 变量名 = 值,变量名 = 值;

六、常量:

创建后,不允许在修改了,其余特点和变量一样

语法:const 常量名 = 值

七、数据类型分类:

  • 原始/基本/值数据类型
    1. number:数字,NaN,颜色为蓝色
    2. string:字符串,必须加上""或者'',颜色为黑色
    3. Boolean:布尔,取值只有true和false,颜色为蓝色
    4. null:空,取值只有一个就是null,作用是释放变量释放内存,节约内存空间,提升网页的性能,颜色是灰色
    5. undefined:只有一个取值就是undefined,颜色为灰色
  • 引用/对象数据类型:11个对象
    查看数据类型:typeOf(变量)

八、运算符:

  • 算术运算符:+、-、*、/、%(取余)
    1. 算术运算符带有隐式转换,默认会把左右两边转为数字在计算
    2. true-->1
    3. false-->0
    4. undefined-->NaN
    5. null-->0
    6. "100"-->100
    7. "100px"-->NaN
    8. NaN:Not a Number,不是一个数字,但是它确实是数字类型,有两个缺点:
      a. 参与任何的算术运算结果均为NaN
      b. 参与任何的比较运算结果都为false
    9. +运算符号如果碰上了字符串,左右两边都会悄悄的转为字符串,然后拼接
  • 比较运算符:>、<、>=、<=、==、!=、===(值和数据类型都要相同)、!==
    1. 结果:一定是个布尔值
    2. 带有隐式转换:默认左右两边都会悄悄转为数字再比较大小
    3. 如果参与比较的左右两边都是一个字符串,则会按位PK每个字符的十六进制的unicode号(十进制ASCII码),数字0-9<大写A-Z<小写a-z<汉字。常识:汉字的第一个字:是 一 unicode号是 4e00 ascii是19968,汉字的最后一个字:是 龥 unicode号是 9fa5 ascii是40869
    4. NaN参与任何的比较运算结果都是false,isNaN()在接收到一个值之后,会尝试将这个值转换为数值,如果能成功转换则返回false,否则返回true;判断是否为NaN的方法:isNaN(x)
    console.log(isNaN("fe"));//true
    console.log(isNaN(1));//false
    console.log(isNaN(true));//false
    console.log(isNaN(false));//false
    console.log(isNaN(null));//false
    console.log(isNaN(undefined));//true
    console.log(isNaN(" "));//false
    
    1. undefined==null结果为true,但是undefined===null结果为false
    2. ===和!==都不带隐式类型转换,要求值和数据类型均相同
  • 赋值运算符:=、+=、-=、*=、/=、%=
    1. =:赋值:将=右边的东西,保存到=左边的变量名之中
    2. i=i+1 ==> i+=1
  • 逻辑运算符:&&(与)、||(或)、!(非)
    1. &&:与(并且),全部条件都满足,结果才为true,只要一个不满足,结果就为false
    2. ||:或,全部条件都不满足,结果才为false,只要一个满足,结果就为true
    3. !:颠倒布尔值
  • 自增自减运算符:++、--
    1. 自增:固定的每次只能+1
    2. 前++:先+1,再返回值
    3. 后++:先返回原值,再+1
    var a = 2;
    var result = a++ + a++ + ++a + a++ + ++a + ++a;
    // 	      2     3     5     5     7     8
    console.log(result);//30
    
  • 位运算:
    1. 左移:m<<n,读作m左移了n位,翻译:m*2的n次方
    2. 右移:m>>n,读作m右移了n位,翻译:m/2的n次方
    3. 底数只能是2

九、用户输入框:

var 变量=prompt("提示文字");

day02

一、流程控制结构:

  • 顺序结构:默认:从上向下依次执行每一句话
  • 分支结构:通过条件判断,选择部分代码执行
  • 循环结构:通过条件判断,选择要不要重复执行某块代码

二、分支结构

  • if...else... :
  1. 一个条件,一件事,满足就做,不满足就不做
    if(条件){
            操作;
    }
    
  2. 一个条件,两件事,满足就做第一件,不满足就做第二件
    if(条件){
            操作;
    }else{
            默认操作;
    }
    
  3. 多个条件,多件事,满足谁,就做谁
    if(条件1){
            操作1;
    }else if(条件2){
            操作2;
    }else{
            默认操作;
    }
    
  • switch...case:
switch(变量/表达式){
        case1:
            操作1;
            break;
        case2:
            操作2;
            break;
        default:
            默认操作;
}
1. case在做比较的时候是不带有隐式转换的
2. default可以省略不写的,但是不推荐,如果不写,条件都不满足的情况,则什么事儿都不会发生

if 和 switch的区别:

  • switch...case:

    1. 优点:执行效率较高,速度快(他比较时,case做的不是范围查找,而是等值比较)
    2. 缺点:必须要知道最后的结果是什么才可以使用
  • if...else...:

    1. 优点:可以做范围判断
    2. 缺点:执行效率较慢,速度慢(他做的是范围查找)
      建议:代码开发完过后,要做代码优化,要尽量的少用if...else...,多用switch...case和三目运算
  • 三目运算:简化分支的

语法

  1. 条件?操作1:默认操作; === if...else...
  2. 条件1?操作1:条件2?操作2:默认操作 === if...else if..else

注意

  1. 默认操作不能省略,省略了会报错
  2. 如果操作复杂,不能使用三目运算:操作只能有一句话,如果操作有多句话还是推荐使用switch或if
    页面上一切数据js获取到后都是字符串类型

三、强制(显示)数据类型转换:

  • 转字符串:2种方法
  1. var str=x.toString();//x不能undefined和null,会报错,undefined和null不能使用.做任何操作,因为他们不是对象
  2. var str=String(x);//万能的,任何人都可以转为字符串,但是绝对不要手动使用,完全等效于隐式转换,还不如+""
// .toString()方法 undefined和null不能转 会报错 因为它们不是对象
var num = 11
console.log(num);
console.log(num.toString());
console.log(true);
console.log(true.toString());
console.log(undefined);
// console.log(undefined.toString());//会报错
// console.log(null.toString());//会报错

// String()方法 任何人都可以 还不如+""
console.log(String(2));
console.log(String(true));
console.log(String(null));
console.log(String(undefined));
  • 转数字:3种方法
  1. parseInt(str/num); - parse解析 Int整型 - 专门用于将【字符串转为整数】,执行原理:从左向右依次读取转换每个字符,碰到非数字字符就停止转换,如果一来就不认识则为NaN,不认识小数点。
  2. parseFloat(str); - parse解析 Float浮点型 - 专门用于将【字符串转为小数】,执行原理:几乎和parseInt一致,认识第一个小数点
  3. Number(x);万能的,任何人都可以转为数字,但是绝对不要手动使用,完全等效于隐式转换,还不如 -0 *1 /1
// parseInt(str/num)  转整数
console.log(parseInt(20.2));//20
console.log(parseInt("20.2"));//20
console.log(parseInt("20p"));//20
console.log(parseInt("p9"));//NaN
console.log(parseInt(".5"));//NaN
// parseFloat(str) 转小数
console.log(parseFloat(20));//20
console.log(parseFloat(20.65555));//20.65555
console.log(parseFloat("2.3"));//2.3
console.log(parseFloat("2.3p"));//2.3
console.log(parseFloat("o7"));//NaN
console.log(parseFloat(".9"));//0.9
// Number(x) 万能的 不如-0 *1 /1
console.log(Number("8.2"));//8.2
console.log(Number("8.2p"));//NaN
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0
  • 转布尔
  1. Boolean(x);万能的,任何人都可以转为布尔,但是绝对不要手动使用,完全等效于隐式转换,还不如 !!x
  2. 只有6个为false:0,"",undefined,NaN,null,false,其余全部都是true。
  3. 在分支或循环的条件之中,不管以后写什么,他都会悄悄的转为一个布尔值,自带此方法
console.log(Boolean(1));
// 只有以下六种情况为false  其余都为true
console.log(Boolean(0));
console.log(Boolean(""));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(false));
console.log(Boolean(NaN));

四、案例

 // 判断不同分数
var score = prompt("请输入分数:")
if (!isNaN(score)) {
    if (score <= 100 && score >= 0) {
        if (score >= 90) {
            alert("大于等于90")
        } else if (score >= 80) {
            alert("大于等于80")
        } else if (score >= 70) {
            alert("大于等于70")
        } else if (score >= 60) {
            alert("大于等于60")
        } else {
            alert("不及格")
        }
    } else {
        alert("请输入0-100的数字!")
    }
} else {
    alert("请输入数字!")
}
// 计算BMI标准体重
var weight = prompt("请输入体重:(kg)")
var height = prompt("请输入身高:(m)")
var BMI = weight/(height*height)
if (!isNaN(weight) && !isNaN(height)) {
    if (BMI > 30) {
        alert("肥胖")
    } else if (BMI > 25) {
        alert("超重")
    } else if (BMI < 20) {
        alert("偏廋")
    } else {
        alert("正常")
    }
} else {
    alert("恶意输入!")
}
console.log(weight);
// 计算应缴纳的税  方法一
var salary = prompt("请输入工资:")
if (!isNaN(salary)) {
    var s = 0
    if (salary >= 10000) {
        s += (salary - 10000)*0.1
        salary = 10000
    }
    if (salary >= 5000) {
        s += (salary - 5000)*0.05
        salary = 5000
    }
    if (salary >= 3500) {
        s += (salary - 3500)*0.025
        salary = 3500
    }
    alert("应缴纳的税为:" + s)
} else {
    alert("恶意输入!")
}

// 方法二
/* if (salary >= 10000) {
    s = (salary - 10000)*0.1 + (10000 - 5000)*0.05 + (5000 - 3500)*0.025
    alert("应缴纳的税为:" + s)
} else if (salary >= 5000) {
    s = (salary - 5000)*0.05 + (5000 - 3500)*0.025
    alert("应缴纳的税为:" + s)
} else if (salary >= 3500) {
    s = (salary - 3500)*0.025
    alert("应缴纳的税为:" + s)
} */
// 用户输入年月,判断每月有多少天  方法一
var year = parseInt(prompt("请输入年份:"))
var month = parseInt(prompt("请输入月份:"))
/* if (!isNaN(year) && !isNaN(monyh)) {
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
        alert("31天")
    } else if (month == 4 || month == 6 || month == 9 || month == 11) {
        alert("30天")
    } else if (month == 2) {
        if ((year%4==0 && year%100!=0) || (year%400==0)) {
            alert("29天")
        } else {
            alert ("28天")
        }
    }
} else {
    alert("恶意输入!")
} */

// 方法二
switch(month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        alert("31天")
        break
    case 4:
    case 6:
    case 9:
    case 11:
        alert("30天")
        break
    case 2:
        switch((year%4==0&&year%100!=0) || (year%400==0)) {
            case true:
                alert("29天")
                break
            case false:
                alert("28天")
        }
}

day03

一、循环结构

反复执行相同或者相似的操作
1、循环三要素:
  • 循环条件:开始-结束,循环的次数
  • 循环体:做的是什么操作
  • 循环变量:记录当前在哪里,并且会不断的变化

二、3种循环

1、while循环

语法

var 循环变量=几;
while(循环条件){
        循环体;
        循环变量变化;
}

执行原理:首先创建出循环变量,判断循环条件,如果条件满足,则做一次循环体操作,并不会退出循环,而会回头再次判断条件满不满足,如果满足,则做一次循环体操作,直到条件不满足,才会退出循环。

  • 宏观上好像感觉循环是一瞬间就结束了,但是微观上循环其实是一次一次执行的
  • 在不确定循环次数的时候,需要使用死循环,while(true){死循环}
  • break:退出整个循环,多半都是用来搭配死循环的
  • continue:退出本次循环,下一次依然会执行
2、for循环

语法

for(var 循环变量=几;循环条件;循环变量变化){
    循环体;
}
  • 死循环:for(;;){}
  • while和for的区别: 他们原理上几乎没有区别,一般来说我们不确定循环次数的时候,会使用while循环-死循环,如果确定循环次数的时候,会使用for循环-大部分情况都是它
3、do...while循环

语法:

var 循环变量=几;
do{
    循环体;
    循环变量的变化
}while(循环条件)

while和do...while的区别: 区别只看第一次,如果第一次条件都满足,那么两者没有任何区别。但是如果第一次条件不满足,那么while一次都不会执行,而do...while至少会执行一次。

三、获取随机整数公式

var r = parseInt(Math.random()*(max - min + 1) + min)

四、function的基础

1、概念
function也叫函数也叫方法,先预定好,以后可以反复使用的代码段
2、如何使用函数:2步
  • 定义/创建/声明
function 函数名(形参,...){
    函数体/代码段;
}
  • 调用函数:
    1. 在js内部写:函数名(); - 程序员写几次就会调用几次
    2. 在HTML上面绑定事件:
    <elem onclick="函数名()"></elem>
    //什么元素都可以绑定事件
    

(1) 不带参数的函数,用于执行一些固定的操作
(2) 带参数的函数,可以根据我们传入的实参不同,做的略微不同

3、何时使用函数:
  • 不希望打开页面立即执行
  • 希望用户来触发,提升用户的体验感
    函数是js的第一等公民
4、循环和函数的区别
  • 循环:几乎是一瞬间就完成了
  • 函数:需要调用后才会执行

五、案例

// 输出1000句hello  方法一:while
/* var i = 1;
while(i<=1000) {
    console.log(i + "hello");
    i++;
} */
// 方法二  for
for(var i = 1; i <= 1000; i++) {
    console.log(i + "hello");
}
// 求1-1000所有数字和 方法一:while
/* var i = 1,
    sum = 0;
while (i <= 1000) {
    sum += i;
    i++
}
console.log(sum); */
// 方法二:for
for(var i = 1,sum = 0; i <= 1000; i++) {
    sum += i;
}
console.log(sum);
// 求1-1000所有偶数的和 方法一:while
/* var i = 1,
    sum = 0;
while(i <= 1000) {
    if(i % 2 == 0) {
        sum += i;
    }
    i++;
}
console.log(sum); */

// 方法二:for
for(var i = 1,sum = 0; i <= 1000; i++) {
    if (i % 2 == 0) {
        sum += i;
    }
}
console.log(sum);
// 猜数字小游戏1-100 方法一:while
var r = parseInt(Math.random()*(100 - 1 + 1) + 1);
var hp;
var dif = prompt("请选择难度:\n1.简单;\n2.一般;\n3.困难");
hp = dif == 1? 15 : dif == 2 ? 10 : dif == 3 ? 5 : 1
while(1) {
    if (hp > 0) {
        var user = parseInt(prompt("请输入您要猜的数字:目前生命值为" + hp));
        if (!isNaN(user)) {
            if(user > r) {
                alert("大了");
                hp--;
            } else if (user < r) {
                alert("小了");
                hp--;
            } else {
                alert("对了");
                break;
            }
        } else {
            alert("恶意输入!")
        }
    } else {
        alert("没有生命了");
        break;
    }
}
// 方法二:把while(1)改为for(;;)
// 求1/1+1/3+...+1/999的和
for(var i = 1,sum = 0; i <= 999; i+=2) {
    sum += 1/i;
}
console.log(sum);
//九九乘法表
for(var j = 1; j <= 9; j++) {
    for(var i = 1,str = ""; i <=j; i++) {
        str += i + "*" + j + "=" + i*j + " "
    }
    console.log(str);
}
// 让用户输入一个年份,我们来输出这个年份之后的5个闰年
var year = prompt("请输入一个年份:");
count = 0;
while(1) {
    if(count == 5){break}
    year++;
    if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
        console.log(year);
        count++;
    }
}

day04

一、自定义函数

函数就是需要先定义好,以后可以反复使用的一个代码段

1.1 何时使用

不希望打开页面立即执行,以后可以反复使用,希望用户来触发

1.2 如何使用

  • 创建:2种方式
  1. 声明方式:
function 函数名(形参列表) {
    操作
    return 返回值/结果
}
  1. 直接量方式:
var 函数名 = function(形参列表) {
    操作
    return 返回值/结果
}
  • 调用
函数名()
1. var 接住返回的结果 = 函数名(实参列表)
2. 其实return的本意是退出函数,但是如果return后面跟着一个数据,顺便将数据返回到函数作用域的外部,但是return只负责返回,不负责保存,所以调用函数时要自己拿个变量来接住他
3. 就算省略return,默认也有,会return一个undefined
4. 具体需不需要得到函数的结果,看你自己:如果有一天你在全局希望拿着函数的结果去做别的操作,那么记得加return
5. 前辈们提供给你的方法,大部分基本上都加了return

1.3 作用域:

  • 全局作用域:
    • 全局变量 和 全局函数,在页面的任何一个位置都可以使用。
  • 函数作用域:
    • 局部变量 和 局部函数,在【当前函数调用时,内部可用】
  • 使用规则
    • 优先使用局部的,局部没有找全局要,全局也没有那就会报错
  • 局部可以使用全局的,但是全局不能使用局部的 - 解决:return

1.4 全局污染:

函数中对着未声明的变量直接赋值会造成全局污染:全局本身没有这个东西,但是被函数作用域给添加上了

1.5 声明提前:

在程序正式执行之前,将var声明的变量(轻)和function声明的函数(重),都会悄悄的集中定义在当前作用域的顶部,但是赋值留在原地
  1. 提升var在function之前
  2. 声明方式创建的函数会完整的提前
  3. 直接量方式创建的函数不会完整提前,只有变量名部分会提前

1.6 重载:

相同的函数名,根据传入的实参的不同,自动选择对应的函数去执行,但是JS不支持,函数名如果重复了,后面的肯定会覆盖掉前面的
  • 目的: 减轻我们程序员的压力,记住一个方法就可以执行很多的操作
  • 解决:在【函数内部】自带一个arguments的对象(类似数组对象):不需要我们去创建 - 哪怕没有写任何形参,他也可以接受住所有实参,所以默认你看他length长度为0
  1. 通过下标去获取传入的某一个实参:arguments[i] - i从0开始
  2. 通过length去获取到底传入了几个实参:arguments.length
  3. 通过判断传入的实参的不同,在内部去写判断,从而变相的实现重载

二、数组的基础

数组:创建一个变量可以保存【多个数据】
数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素
除了最后一个元素,每个元素都有唯一的后继元素
每个元素都有一个自己的位置,称之为叫做下标,下标都是从0开始的,到最大长度-1结束

2.1 创建数组:

  • 直接量方式:
var arr=[];//空数组
var arr=[数据1,...];
  • 构造函数方式:
var arr=new Array();//空数组
var arr=new Array(数据1,...);

2.2 获取数组之中的元素:

数组名[i]

2.3 后续添加/替换元素:

数组名[i]=新数据;
如果下标处没人则为添加,如果下标处有人则为替换

2.4 数组具有三大不限制

  • 不限制元素的类型
  • 不限制元素的长度
  • 不限制下标越界
    1. 如果获取元素时,下标越界,返回的是一个undefined
    2. 如果添加元素时,下标越界,会得到一个稀疏数组,如果我们搭配上我们学过循环去遍历获取每个元素,那么你会得到很多很多undefined

2.5 数组中有一个唯一的属性:length

  • 语法:数组名.length
  • 作用:获取到数组的长度,长度是从1开始的
  • 向末尾添加元素:arr[arr.length]=新数据;
  • 获取数组的倒数第n个元素:arr[arr.length-n];
  • 缩容:删除倒数n个元素:arr.length-=n;

2.6 遍历数组:

往往很多情况,我们不会拿出某个元素来使用,而是拿出每个元素来进行 相同 或 相似的操作 - 搭配上循环
  • 固定公式
for(var i=0;i<arr.length;i++){
    arr[i];//当前次元素
}

三、案例

// 创建一个方法 传入一个实参的时候求平方 传入两个实参的时候求和
function fn() {
    /* if(arguments.length == 1) {
        return arguments[0]*arguments[0]
    } else if(arguments.length == 2) {
        return arguments[0] + arguments[1]
    } */
    switch(arguments.length) {
        case 1:
            return arguments[0]*arguments[0]
            break
        case 2:
            return arguments[0] + arguments[1]
            break
    }
}
console.log(fn(2));
console.log(fn(3,3));
// 准备一个数组 获取最大值 
var arr = [1,52,566,56,2,33,526,65,,2,5,88,888]
var max = arr[0]//声明一个最大值变量 假设数组第一个数字为最大值
// 遍历数组
for(var i = 0; i < arr.length; i++) {
    // 把数组中的每一位和max比较   如果数组中的数字大于max  就把这个数字赋值给max
    if(arr[i] > max) {
        max = arr[i]
    }
}
console.log(max);
// 准备一个数组 让用户输入一个字 看看数组里面有没有这个字 有就返回下标 没有返回-1
var arr = ['今','天','星','期','四']
var user = prompt("请输入一个字:目前有"+arr)
var index = -1
for(var i = 0; i < arr.length; i++) {
    if(user == arr[i]) {
        index = i
    }
}
if(index == -1) {
    alert("没找到!")
} else {
    alert("找到了,下标为:"+index)
}
//去重1:用户输入到重复的了,就去掉 
/* var arr = ["今","天","星","期","四"]
var user = prompt("请输入数字,目前有:"+arr)
index = -1
for(var i = 0; i < arr.length; i++) {
    if(user == arr[i]) {
        index = i
    }
}
if(index == -1) {
    alert("没找到")
}else{
    for(var i = index; i < arr.length; i++) {
        arr[i] = arr[i+1]
    }
    arr.length--
    console.log(arr);
} */

//去重2:数组里面已经有很多很多重复的了
var arr = [1,2,1,55,6,2,1,2,3,6,55,9,9,8,7,55]
for(var i = 0; i < arr.length; i++) {
    for(var j = i + 1; j < arr.length; j++) {
        if(arr[j] == arr[i]) {
            for(var k = j; k < arr.length; k++) {
                arr[k] = arr[k+1]
            }
            arr.length--
            j--
        }
    }
}
console.log(arr);
// 准备一个数组,录入员工名称,不断地录入,直到用户输入了exit才停止,在控制台输出看看录入哪些人
var arr = []
while(1) {
    var user = prompt("请输入员工姓名:")
    if(user == "exit") {break}
    arr[arr.length] = user
}
console.log(arr);

day05

一、DOM

概念:(document object model)文档对象模型,专门用于操作HTML文档的,提供了一些方法给你。

二、DOM树

  • 概念:DOM将我们的HTML看作了是一个倒挂的树状结构,但是树根不是html标签,而是document的对象。
  • document对象:不需要我们程序员创建,由浏览器的js解释器自动创建,一个页面只有一个document树根。
  • 作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法)
  • DOM会将页面上的每个元素、属性、文本、注释等等都会被视为一个DOM元素/节点/对象。

三、查找元素

3.1 直接通过HTML的特点去查找元素

  • 通过id查找元素:
var elem = document.getElementById("id值")
  1. 返回值:找到了返回当前找到的DOM元素,没有找到返回一个null
  2. 如果出现多个相同的id,只会找到第一个
  3. 不使用此方法,id留给后端用
  4. 其实根本不用查找,id直接可用
<div id="box"></div>
<script>
    // 通过id去找
    var div = document.getElementById('box')
    var div1 = document.getElementById('box1')
    console.log(div);//<div id="box"></div>
    console.log(div1);//null
</script>
  • 通过标签名查找元素:
var elems = document/已经找到的父元素.getElementsByTagName("标签名")
  1. 返回值:找到了返回一个类数组DOM集合,没找到得到空集合
  2. js只能直接操作DOM元素,不能操作DOM集合,解决方式是要么拿到下标要么遍历
  3. 不一定非要从document开始查找,如果从document去找,会找到所有元素,可以换成已经找到的某个父元素
<ul>
    <li>第一个li1</li>
    <li>第一个li2</li>
    <li>第一个li3</li>
    <li>第一个li4</li>
</ul>
<ul>
    <li>第二个li1</li>
    <li>第二个li2</li>
    <li>第二个li3</li>
    <li>第二个li4</li>
</ul>
<script>
    //通过标签名查找
    var ul1 = document.getElementsByTagName('ul')[0]
    var lis1 = ul1.getElementsByTagName('li')
    var lis = document.getElementsByTagName('li')
    var as = document.getElementsByTagName('a')
    console.log(lis);//HTMLCollection(8) [li, li, li, li, li, li, li, li]
    console.log(as);//HTMLCollection []
    console.log(lis[0]);//拿到第一个li
    console.log(lis1);//HTMLCollection(4) [li, li, li, li]
    console.log(lis1[0]);//拿到第一个ul里面的第一个li
</script>
  • 通过class查找元素:
var elems = document/已经找到的父元素.getElementByClassName("class名")
  1. 返回值,找到了返回一个类数组DOM集合,没找到得到空集合
  2. js只能直接操作DOM元素,不能操作DOM集合,解决方式是要么拿到下标要么遍历
  3. 不一定非要从document开始查找,如果从document去找,会找到所有元素,可以换成已经找到的某个父元素
<p class="p">1</p>
<p class="p">2</p>
<p class="p">3</p>
<p class="p">4</p>
<p class="p">5</p>
<script>
    // 通过class查找
    var ps = document.getElementsByClassName('p')
    var spans = document.getElementsByClassName('span')
    console.log(ps);//HTMLCollection(5) [p.p, p.p, p.p, p.p, p.p]
    console.log(ps[0]);//<p class="p">1</p>
    console.log(spans);//HTMLCollection []
</scripe>

3.2 通过关系去获取元素:

前提条件是必须先找到一个元素才可以使用关系
  • 父元素:elem.parentNode - 单个元素
  • 子元素:elem.children - 集合
  • 第一个子元素:elem.firstElementChild - 单个元素
  • 最后一个子元素:elem.lastElementChild - 单个元素
  • 前一个兄弟:elem.previousElementSibling - 单个元素
  • 后一个兄弟:elem.nextElementSibling - 单个元素
<div class="box1">
    <span>1</span>
    <span class="s">
        <b>1</b>
        <b>2</b>
    </span>
    <span>3</span>
</div>
<script>
    // 通过关系去查找元素
    var s = document.getElementsByClassName('s')[0]
    console.log(s);//<span class="s"></span>
    console.log(s.parentNode);//找父元素      拿到的是box1 -单个元素
    console.log(s.children);//找子元素       拿到的是HTMLCollection(2) [b, b]
    console.log(s.firstElementChild);//找第一个子元素   拿到的是<b>1</b>
    console.log(s.lastElementChild);//找到最后一个子元素   拿到的是<b>2</b>
    console.log(s.previousElementSibling);//找到前一个兄弟  拿到的是<span>1</span>
    console.log(s.nextElementSibling);//找到后一个兄弟   拿到的是<span>3</span>
</script

四、操作元素

前提是先找到元素,才能操作元素
```
<ul>
    <li>第1li</li>
    <li>第2li</li>
    <li>第3li</li>
    <li>第4li</li>
    <li>第5li</li>
</ul>
<script>
    var lis = document.getElementsByTagName('li')
    // lis.style.color = "#fc1"//报错  Cannot set properties of undefined (setting 'color')
    lis[0].style.color = "#fc1"
</script>
```

4.1 内容

  • elem.innerHTML:获取和设置开始标签到结束标签之间的内容,支持识别标签的 - 双标签
    1. 获取:elem.innerHTML
    2. 设置:elem.innerHTML="新内容"
  • elem.innerText:获取和设置开始标签到结束标签之间的纯文本,不识别标签的 - 双标签
    1. 获取:elem.innerText
    2. 设置:elem.innerText="新内容"
  • input.value:专门获取/设置input里的内容
    1. 获取:input.value
    2. 设置:input.value="新内容
<body>
    <button>点击</button>
    <a href="https://www.baidu.com/">百度</a>
    <script>
        // 点击切换百度和京东
        var btn = document.getElementsByTagName('button')[0]
        var a = document.getElementsByTagName('a')[0]
        btn.onclick = function() {
            if(a.innerHTML == "百度") {
                a.innerHTML = "京东"
                a.href = "https://www.jd.com/"
            } else {
                a.innerHTML = "百度"
                a.href = "https://www.baidu.com/"
            }
        }
    </script>
</body>

4.2 属性

  • 获取属性值
    1. elem.getAttribute("属性名")
    2. elem.属性名 - 简化版
  • 设置属性值:
    1. elem.setAttribute("属性名,"属性值")
    2. elem.属性名="属性值" - 简化版
  • 简化版的缺点:
    1. class必须写为className - ES6(2015年)class变成了一个关键字
    2. 不能操作自定义属性

4.3 样式

我们使用内联样式来操作js因为:不会影响到其他样式并且优先级最高
  • 获取样式:elem.style.css属性名
  • 设置样式:elem.style.css属性名="css属性值"
  • 特殊点
    1. css属性名,有横线的地方,去掉横线,变成小驼峰命名法
    2. border-radius --> borderRadius
    3. 获取时,我们只能取到内部样式

4.4 绑定事件

elem.on事件名=function(){
    操作
    关键字this:
        如果单个元素绑定事件,this指的就是这个元素
        如果多个元素绑定事件,this指的就是当前触发事件的元素
}

一切的获取,往往都是为了判断
一切的设置,可以说是添加也可以说是修改

五、案例

<!-- 开关门效果 -->
<button id="btn" style="background-color: #df6215;">···</button>
<div id="box"></div>
<script>
    btn.onclick = function() {
        if(btn.style.backgroundColor == "rgb(223, 98, 21)") {
            box.style.display = "block"
            btn.style.backgroundColor = "#f3af84"
        } else {
            box.style.display = "none"
            btn.style.backgroundColor = "#df6215"
        }
    }
</script>
<table border="1">
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
</table>
<script>
    // 表格隔行变色 奇数次点击奇数行变色 偶数次点击偶数行变色

    var trs = document.getElementsByTagName('tr')
    var j = 0//点击次数
    for(var i = 0; i < trs.length; i++) {
        trs[i].onclick = function() {
            j++
            if(j%2==0) {
                for(var i = 0; i < trs.length; i++) {
                        trs[i].style.backgroundColor = "#fff"
                    if(i%2==0) {
                        trs[i].style.backgroundColor = "pink"
                    }
                }
            } else {
                for(var i = 0; i < trs.length; i++) {
                        trs[i].style.backgroundColor = "#fff"
                    if(i%2!=0) {
                        trs[i].style.backgroundColor = "#fc1"
                    }
                }
            }
        }
    }
</script>
<!-- 选项卡 -->
<ul>
    <li class="active" dy="0">家电</li>
    <li dy="1">数码</li>
    <li dy="2">超市</li>
    <li dy="3">建材</li>
    <li dy="4">维修</li>
</ul>
<div class="active">家电</div>
<div>数码</div>
<div>超市</div>
<div>建材</div>
<div>维修</div>
<script>
    /* var lis = document.getElementsByTagName('li')
    var divs = document.getElementsByTagName('div')
    for(var i = 0; i < lis.length; i++) {
        lis[i].onclick = function() {
            for(var i = 0; i < lis.length; i++) {
                lis[i].style.backgroundColor="#067cea"
                divs[i].style.display="none"
            }
            this.style.backgroundColor="#9cb6f3"
            var j =this.getAttribute("dy")
           divs[j].style.display="block"
        }
    } */
    var lis = document.getElementsByTagName('li')
    var divs = document.getElementsByTagName('div')
    for(var i = 0; i < lis.length; i++) {
        lis[i].index = i//把下标保存起来
        lis[i].onclick = function() {
            for(var i = 0; i < lis.length; i++) {
                lis[i].className=''
                divs[i].className = ''
            }
            this.className='active'
            divs[this.index].className='active'
        }
    }
</script>
<!-- 购物车 -->
<table>
    <thead>
        <tr>
            <th>商品名称</th>
            <th>单价</th>
            <th>数量</th>
            <th>小计</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>iPhone6</td>
            <td>4488</td>
            <td>
                <button>-</button>
                <span>1</span>
                <button>+</button>
            </td>
            <td>4488</td>
        </tr>
        <tr>
            <td>iPhone6 plus</td>
            <td>5288</td>
            <td>
                <button>-</button>
                <span>1</span>
                <button>+</button>
            </td>
            <td>5288</td>
        </tr>
        <tr>
            <td>iPad Air 2</td>
            <td>4288</td>
            <td>
                <button>-</button>
                <span>1</span>
                <button>+</button>
            </td>
            <td>4288</td>
        </tr>
        <tr>
            <td>iPad Air 3</td>
            <td>5288</td>
            <td>
                <button>-</button>
                <span>1</span>
                <button>+</button>
            </td>
            <td>5288</td>
        </tr>
        <tr>
            <td>iPad Air 4</td>
            <td>6288</td>
            <td>
                <button>-</button>
                <span>1</span>
                <button>+</button>
            </td>
            <td>6288</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td colspan="3">总计:</td>
            <td id="total"></td>
        </tr>
    </tfoot>
</table>
<script>
    var btns = document.getElementsByTagName('button')
    for(var i = 0; i < btns.length; i++) {
        btns[i].onclick = function() {
            if(this.innerHTML == '+') {
                subtotal(1,this)
            } else {
                subtotal(-1,this)
            }
            getTotal()
        }
    }
    getTotal()
    function subtotal(num,btns) {
            if(num==1) {
                var span = btns.previousElementSibling
            } else {
                var span = btns.nextElementSibling
            }
            var spanT = parseInt(span.innerHTML) + num
            if(spanT > 0 ) {
                span.innerHTML = spanT
            }
            var price = btns.parentNode.previousElementSibling
            var subtotal = btns.parentNode.nextElementSibling
            subtotal.innerHTML = price.innerHTML * span.innerHTML
    }
    function getTotal() {
        var tbody = document.getElementsByTagName('tbody')[0]
        var trs = tbody.getElementsByTagName('tr')
        for(var i = 0,sum = 0; i < trs.length; i++) {
            var subtotal = trs[i].lastElementChild
            sum += parseInt(subtotal.innerHTML)
        }
        total.innerHTML = sum
    }
</script>