JS学习之路

JS学习之路

目录

JS基础语法

几个输出语句

JS的编写位置

标识符

字符串

强制类型转换

运算

对象

函数

this相关

构造函数

数组

Date

包装类

正则表达式

DOM

事件

DOM 查询

图片切换

全选练习

DOM增删改

DOM与CSS样式

事件对象

BOM

定时器简介

综合练习

轮播图制作

二级菜单制作

JSON

JS基础语法

  1. 解释型语言(不需要编译)
  2. 类似于C和JAVA的语法结构
  3. 动态语言
  4. 基于原型的面向对象

几个输出语句

  1. alert(""); 用于控制浏览器弹出一个警告框
  2. document.write(""); 用于在页面中写一个内容
  3. console.log(""); 用于向控制台输出语句

输出方式:

​ 1. var name = prompt("输入的你的名字");弹出一个输入框

JS的编写位置

  1. 可以编写到button中、a中(但是,结构与行为耦合,不方便维护,不推荐使用)

    1
    2
    3
    <button onclick="alert('讨厌,你点我干嘛~~')">点我一下</button>

    <a href="javascript:alert('让你点你就点啊????')">也点我一下</a>
  2. 可以编写到script

  3. 可以编写到外部文件(最佳方式)(一旦用于外部文件,里面就能填写代码,会自动忽略)

    1
    <script src="first.js"></script>

标识符

在JS中所有有我们自主命名的都可以称为标识符:变量名、函数名、属性名

明明标识符需要遵守如下规则:

  1. 标识符中含有字母、数字、_、$
  2. 标识符不能以数字开头
  3. 标识符不能是ES中的关键字或保留字
  4. 一般采用驼峰命名法

注意:与C不同的地方在于可以使用$

注意:JS底层保存标识符时实际上采用的Unicode编码,所以理论上讲,所有utf-8中含有的内容都可以作为标识符

1
2
var 锄禾日当午 = 123;
console.log(锄禾日当午);

字面量

JS共有六种数据类型:

String 字符串

Number 数值

Boolean 布尔值

Null 空值

Undefined 未定义

Object 对象

前五个为基本数据类型,后者为引用数据类型

可以使用typeof来检查类型

使用Number.MAX_VALUE表示数字最大值,其中infinity表示正无穷

使用Number.MIN_VALUE表示数字最小值

使用NaN表示一个特殊的数字类型

访问null时,返回null类型

访问var c;时,返回undefined类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var a = 123;
var b = "123";
console.log(typeof a);
console.log(typeof b);

console.log(Number.MAX_VALUE);
console.log(Number.MAX_VALUE * Number.MAX_VALUE);

console.log(Number.MIN_VALUE);

console.log("abc" * "cde");

var d = null;
console.log(d);

var c;
console.log(c);
2

强制类型转换

转换为字符串:

  1. a.toString()方法
  2. a = String(a)函数
  3. a = a + ""利用字符串的加法性质

转换为数字:

  1. a.parseInt()a.parseFloat方法

    1
    2
    3
    可以将字符串中的有效的整数内容取出来
    如 123abc567
    取出来的是 123
  2. a = Number(a)函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //字符串————>数字
    1. 如果是纯数字的字符串,直接转换为数字
    2. 如果字符串中有非数字的内容,则转换为NaN
    3. 如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
    //布尔————>数字
    1. true 转换为 1
    2. false 转换为 0
    //null————>数字 0
    //undefined ————> 数字NaN
  3. a = a - 0a = a*1a = a /1利用运算的性质

  4. a = + a直接加一个正号

进制的转换

1
2
3
4
5
var a = oxff;    //十六进制
var b = 070; //八进制,有些浏览器会把它当作八进制,有些浏览器会把它当作十进制
var c = 0b10; //二进制

b = parseInt(b,10)//可通过这种方式来统一规范

转换为布尔值

1
2
3
4
5
6
7
//字符串————>布尔值
除了空串,其余都为true
//数字————>布尔值
除了0和NaN,其余的都是true
//null————>false
//undefined————>false
//对象————> true

运算

做加法运算时,自动转换为字符串

1
2
3
4
5
var result;
result = 1 + 2 + "3";
console.log(result); //输出“33”
result = "1" + 2 + 3;
console.log(result); //输出“123”

做减法、乘法、除法运算时,自动转换为Number

1
2
3
4
result = 100 - "1";    // 99
result = 2 * "8"; // 16
result = 2 * undefined; // NaN
result = 2 * null; // 0

关系运算符,比较的时候

1
2
3
4
console.log("1" < 5);       //true 字符串转换为数字
console.log("11" < "5"); //true 比较unicode编码
console.log("abc" < "cde"); //true 比较unicode编码
console.log("戒" > "我"); //true 比较unicode编码

对象

生成一个对象:

1
2
3
4
var person = new Object();
person.name = "王子豪";
person.age = 19;
person.gender = "男";

对象属性的删除与修改:

1
2
3
4
//修改
person.age = 20;
//删除
delete person.age;

特殊属性名

1
2
//语法:对象["属性名"] = 属性值
person["1234"] = 56;

in 运算符:用于检查一个对象中是否含有指定的属性

1
2
document.write("name" in person);//注意,就算是.运算符也要用双引号
document.write("1234" in person);

对象字面量的使用:

1
2
3
4
5
6
7
8
9
10
var classmate  = {
name:"王著",
age:18,
gender:"男"
school:{
name:"中山大学"
dormitory:"520"
}
}
document.write(classmate.name, classmate.age, classmate.gender);

基本数据类型和引用数据类型之间的区别:

类似于每一个对象是一个指针

枚举对象中的属性

1
2
3
4
for( var i in classmate){
console.log(i);
console.log(i + ":" + clssmate[i]); //输出如 name:王著
}

函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//创建一个函数对象
var fun = new Function();
//可以将要封装的代码以字符串的形式传递给构造函数
var fun1 = new Function("document.write('hellofunction');");
fun1();
//一般不会用上述方法

//函数声明:
//语法:
function 函数名([形参1,形参2,...形参N]){
语句...
}
//函数表达式:
//语法:
var fun3 = function(){
语句...
}

函数的实参可以是任意数据类型,同时调用函数时,不会检查实参的数量

如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined

1
2
3
4
5
6
7
function sum(a,b){
document.write(a+b);
}
sum(123,456); //输出579
sum(123,"hello"); //输出"123hello"
sum(true,false); //输出"1"
sum(123,456,true,null,false); //输出579

立即执行函数(只会执行一次)

1
2
3
(function(){
alert("这是一个匿名函数");
})();

this相关

解析器在调用函数每次都会向函数内部传递进一个隐含的参数——this,this指向的是一个对象。这个对象我们称为函数执行的上下文对象。

根据函数的调用方法的不同,this会指向不同的对象

1
2
3
4
5
6
7
8
9
10
11
function fun(){
console.log(this);
}
var obj = {
name:"孙悟空",
sayName:fun
};

console.log(obj.sayName == fun); //这里的方法与函数是同一个对象
obj.sayName(); //输出 Object,对象的this
fun(); //输出 Window,全局的this

用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function fun(){
console.log(this.name); //可以在函数里使用this
}
var obj1 = {
name:"孙悟空",
sayName:fun
};
var obj2 = {
name:"猪八戒",
sayName:fun
};
var obj3 = {
name:"沙和尚",
sayName:function(){
console.log(this.name);
}
}
obj1.sayName();
obj2.sayName();
obj3.sayName();

构造函数

工厂中的创建对象方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
function creatPerson(name, age, gender){
//创建一个新对象
var obj = new Object();
//向对象添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
}
//将新对象返回
return obj;
}

构造函数:

1
2
3
4
5
6
7
8
9
10
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function(){
alert(this.name);
};

var per = new Person("孙悟空", 18, "男");
}

使用instanceof可以检查一个对象是否是一个类的实例

1
2
console.log(per instanceof Person);        //返回true
console.log(per instanceof Object); //返回true,所有对象都是Object的子类(祖宗)

原型对象:

4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//使所有的对象共享同一个方法,避免同一个方法创建很多次
function Person(name, age, gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = fun;
}
//假如采用下列方式:
//在全局作用域中定义
function fun(){
alert(this.name);
}
//***********污染全局作用域的命名空间,同时很不安全************//

//向原型对象中添加sayName方法
Person.prototype.sayName = function(){
alert(this.name);
};
5

但是,使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true。可以使用对象的hasOwnPropery

image-20210209204919405

数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//创建数组对象
var arr = new Array();
arr[0] = 10;
arr[1] = 31;
arr[2] = 33;
console.log(arr); //输出 10,31,33
console.log(arr[3]); //输出 undefined
console.log(arr.length); //输出3,!!!!!!!注意length是属性
//length可被直接修改

//使用字面量创建数组
var arr1 = [];
var arr2 = [1,2,3,4,5];
//使用构造函数创建数组
var arr3 = new Array(10,20,30);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!注意!!!!!!!!!!!!
var arr4[10]; //表示大小为1,元素为10的数组
var arr5 = new Array(10); //表示创建大小为10的数组

可查看JS参考手册https://www.w3school.com.cn/jsref/jsref_obj_array.asp

数组中可以存放任何数据类型

1
2
var obj = {name:"孙悟空"};
arr = ["hello",1,true,null,undefined,obj];//都可以存放,甚至包括 函数和数组

数组的方法

继续学习参考手册https://www.w3school.com.cn/jsref/jsref_obj_array.asp

常用的有如下:join()pop()shift()unshift()push()splice()slice()


遍历数组

foreach()方法,只支持IE8以上的浏览器

1
2
3
4
//forEach()方法需要一个函数作为参数
arr.forEach(function(){
console.log("hello");
});

数组排序

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [5,4,2,3,1,7,8,9,6];
arr.sort(); //排序
arr.forEach(function(item){
console.log(item);
}); //forEach中添加的函数,可以含有三个参数currentValue, index, arr

arr.sort(function(a,b){
return b - a;
}); //添加一个比较函数,进行逆序排序

arr.forEach(function(item){
console.log(item);
});

Date

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//创建一个Date对象
//封装为当前代码的执行时间
var date = new Date();

//创建一个指定的时间对象
var date2 = new Date("2/10/2021 20:52:30");
//
var date = date2.getDate();
var day = date2.getDay();
var month = date2.getMonth();
var year = date2.getYear();
var hour = date2.getHours();
var minute = date2.getMinutes();
var second = date2.getSeconds();
//时间戳,从格林威治标准时间的1970年1月1日,0时0分0秒,到当前时间的毫秒数
//计算机底层保存时间时,使用的都是时间戳
var time = date2.getTime();

//输出格林威治时间的时间戳的得到的是负值????
var date2 = new Date("1/1/1970 0:0:0");
console.log(date2.getTime()); //这是因为显示的是东八区时间

使用时间戳检测代码性能

1
2
3
4
5
6
var start = Date.now();
for(var i = 0 ; i< 100 ; i++){
console.log(i);
}
var end = Date.now();
console.log("执行了" + (end - start) + "毫秒");

包装类

JS提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象。

1
2
3
4
5
6
7
8
var num = new Number(3);
var str = new String("hello");
var bool = new Boolean(true);
num.name = "sansan";
//方法和属性只能添加给对象,不能添加给基本数据类型
var s = 123;
s.hello = "hello"; //先将s变为一个对象,再将对象销毁

正则表达式

1
2
3
4
5
6
7
350396117@qq.com
邮件的规则:
前边XXXXX + @ + XXXXX + .com

正则表达式用于定义一些字符串的规则:
计算机可以根据正则表达式,来检查一个字符串是否符合规则
获取将字符串中符合规则的内容提取出来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//创建一个正则表达式的对象(Regular Expression)
/*
语法:
var 变量 = new RegExp("正则表达式","匹配模式");
*/
var reg = new RegExp("a"); //这个正则表达式用于检查字符串中是否含有a
var str = "a";
/*正则表达式的方法
test()
- 使用这个方法可以检查一个字符串是否符合正则表达式的规则,
如果符合返回true,否则返回false
*/
console.log(reg.test(str)); //true
console.log(reg.test("sdjkasdk"));//true
console.log(reg.test("sdd"));//false

/*使用字面量来创建正则表达式
- 语法:var 变量 = /正则表达式/匹配模式
*/
var reg2 = /a/i; //字面量的形式定死了,不能传变量

匹配模式:

1
2
3
4
//传递一个匹配模式作为第二个参数:
i 忽略大小写(ignored)
g 全局匹配模式(global)
m 执行多行匹配

练习:

1
2
//创建一个正则表达式,检查一个字符串是否含有a或b
var reg = /a|b/;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//创建一个正则表达式,检查一个字符串中是否有字母
/*
"[]"里也是或的关系
[ab] == a|b
[a-z] == 任意小写字母
[A-Z] == 任意大写字母
[A-z] == 任意字母
[0-9] == 任意数字
*/
var reg = /[A-z]/; //任意字母

//检查一个字符串中是否含有abc或adc或aec
reg = /a[bde]c/;

/*
[^ ] 除了里面的东西,都行
*/
//除了a、b、ab,任意字符串都行
reg = /[^ab]/;

字符串与正则表达式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
split()方法
- 可以将一个字符串拆分为一个数组
- 方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式拆分字符串

*/
var str = "1a2b3d4h56j7";
//根据任意字母拆分字符串
var result = str.split(/[A-z]/);
document.write(result); //输出 1,2,3,4,56,7

/*
search()方法
- 可以搜索字符串中是否含有指定内容
- 如果搜索到指定内容,则会返回第一次出现的索引,否则返回-1
- 它可以接受一个正则表达式作为参数,根据正则表达式去检索字符串
*/
str = "hello abc hello aec afc";
result = str.search(/a[bef]c/);//搜索abc或aec或afc

/*
match()
- 可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
- 默认情况下,match只会找到第一个符合要求的内容
我们可以设置正则表达式为全局匹配模式
*/
str = "1a2b3d4h56j7";
result = str.match(/[A-z]/);
console.log(result); //输出 a // 即使只有一个元素,也返回到数组中
result = str.match(/[A-z]/g);
console.log(result); //输出 a,b,d,h,j

/*
replace()方法
- 可以将字符串中指定内容替换为新的内容
- 参数
1. 被替换的内容,可以接受一个正则表达式作为参数
2. 新的内容,
- 默认只会替换第一个,可以使用全局匹配模式

*/
result = str.replace(/a-z/gi, "@_@");
console.log(result);

量词:

1
2
3
4
5
6
7
/*
- 通过量词可以设置一个内容的出现次数
- {X} 出现X次
*/
var reg = /a{3}/; // aaa
reg = /(ab){3}/; //ababab

image-20210211132940291

去除前后的空格:

1
2
3
str1 = str.replace(/^\s*/,"");//去除前面的空格
str2 = str.replace(/^\s*|\s*$/g,"");//去除前后的空格
console.log(str);

手机号:

1
2
3
4
5
6
7
8
9
10
11
/*手机号规则:
13767890123
1. 以1开头
2. 第二位3-9任意数字
3. 三位以后任意数字9个

/^1[3-9][0-9]{9}$/
*/
var phoneStr = "13767890123";
var phoneReg = /^1[3-9][0-9]{9}$/;
console.log(phoneReg.test(phoneStr));

电子邮件:

1
2
3
4
5
6
7
/*任意字母数字下划线.任意字母数字下划线@任意字母数字.任意字母(2-5位)任意字母(2-5位)
\w{3,} (\.\w+)* @ [A-z0-9]+ (\.[A-z]{2,5}){1,2}

*/
var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
var email = "abc@abc.com";
console.log(emailReg.test(email));

DOM

DOM(Document Object Model) 文档对象模型

  • 文档:就是整个HTML网页文档
  • 对象:将网页的每一个部分都转换为了一个对象(万物皆是对象,包括文档本身)
  • 模型:使用模型来表示对象之间的关系,这样方便我们获取对象
image-20210211163807649
image-20210211164137276
image-20210211164314588
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<button id = "btn">
我是一个按钮
</button>
<script>
/*浏览器已经为我们提供了 文档节点 对象,这个对象是window属性
可以在页面中直接使用,文档节点代表的是整个网页*/
console.log(document); //输出HTMLDocument

//获取button对象
var btn = document.getElementById("btn");
console.log(btn); //输出button对象

//修改按钮文字
btn.innerHTML = "I'm a button";
</script>
</body>

事件

事件,就是文档或浏览器窗口中发生的一些特定的交换瞬间。JavaScript和HTML之间的交互是通过事件实现的。(点击某个元素,将鼠标移动至某个元素上方,按下键盘上的某个键,等等)

可以在事件对应的属性中设置一些js代码,当事件被触发时,这些代码将会执行。

<button id = "btn" onclick = "alert('讨厌,你点我干什么');">我是一个按钮</button>

但是,结构与行为耦合,不方便维护,不推荐使用

可采取下列的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<button id = "btn">
我是一个按钮
</button>
<script>
//获取button对象
var btn = document.getElementById("btn");
console.log(btn); //输出button对象

//绑定一个双击事件
btn.ondblclick = function(){
alert("你还点~~~");
};
</script>
</body>

DOM 查询

通过document对象调用:

  1. getElementById(): 通过id属性获取一个元素节点对象
  2. getElementsByTagName(): 通过标签名获取一组元素节点对象
  3. getElementsByName(): 通过name属性获取一组元素节点对象

通过具体的元素节点调用:

  1. getElementsByTagName(): 方法,返回当前节点的指定标签名后代节点
  2. childNodes: 属性,表示当前节点的所有子节点
  3. firstChild: 属性,表示当前节点的第一个子节点
  4. lastChild: 属性,表示当前节点的最后一个子节点
  5. parentNode属性,表示当前节点的父节点
  6. previousSibling : 属性,表示当前节点的前一个兄弟节点
  7. nextSibling : 属性,表示当前节点的后一个兄弟节点

制作一个查询的封装函数:

1
2
3
4
function myClick(idStr, fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}

图片切换

基本步骤思路:

  1. 获取标签变量。较简单的是通过标签获取;也可以通过TagName(不过要注意是否是数组)
  2. 两个按钮都绑定一个单击事件

耶~~,可以完全靠自己写出来啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* *{
padding: 0px;
margin: 0px;
} */
#outer{
margin : 100px auto;
padding:10px;
width: 350px;
background-color: rgb(190, 183, 113);
text-align:center;
}
</style>
<script>
window.onload = function(){
var prev = document.getElementById("prev");
var next = document.getElementById("next");
var img = document.getElementById("diary");
var info = document.getElementById("info");
//数组
var imgArr = ["1.jpg", "2.jpg", "3.jpg"];
var index = 0;
var len = imgArr.length;
info.innerHTML = "一共有" + len + "张图片,这是第"+ (index + 1) + "张";
prev.onclick = function(){
index = (index - 1) >= 0 ? index -1 : index - 1 + len;
img.src = imgArr[index];
info.innerHTML = "一共有" + len + "张图片,这是第"+ (index + 1) + "张";
}
next.onclick = function(){
index = (index + 1)%len;
img.src = imgArr[index];
info.innerHTML = "一共有" + len + "张图片,这是第"+ (index + 1) + "张";
}

}
</script>
</head>
<body>
<div id="outer">
<p id="info"></p>
<img src="1.jpg" alt="大理寺日志" id="diary" width="300">
<br/>
<button id="prev">上一张</button>
<button id="next">下一张</button>
</div>

</body>
</html>

全选练习

image-20210213214849373 wi


基本步骤思路:

  1. 控制选项的属性是checkedtruefalse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function() {
var arr = document.getElementsByName("items");
//五个按钮
//1 全选
var checkedAllBtn = document.getElementById("checkedAllBtn");
checkedAllBtn.onclick = function() {

for(var i = 0; i < arr.length; i++) {
arr[i].checked = true;
}
}
//2 全部不选
var checkedNoBtn = document.getElementById("checkedNoBtn");
checkedNoBtn.onclick = function() {

for(var i = 0; i < arr.length; i++) {
arr[i].checked = false;
}
}
//3 反转选项
var checkedRevBtn = document.getElementById("checkedRevBtn");
checkedRevBtn.onclick = function() {

for(var i = 0; i < arr.length; i++) {
arr[i].checked = !(arr[i].checked);
}
}
//4 提交后,弹出提示框
var send = document.getElementById("send");
send.onclick = function() {

for(var i = 0; i < arr.length; i++) {
if(arr[i].checked){
alert(arr[i].value);
}
}
}
//5右上角的框选中时,四个全选
var checkAllBox = document.getElementById("checkAllBox");
checkAllBox.onclick = function() {
for(var i = 0 ; i < arr.length; i++){
arr[i].checked = this.checked;//妙妙妙啊
}
}
//6四个全选时,右上角的框也要被选中
for(var i = 0 ; i < arr.length; i ++){

arr[i].onclick = function(){
checkAllBox.checked = true;
for(var j = 0; j < arr.length; j ++){
if(!arr[j].checked){
checkAllBox.checked = false;
break;
}
}
}
}


}
</script>
</head>
<body>
<form action="" method="post">
你爱好的运动是 <input type="checkbox" id="checkAllBox" /> 全选或全不选
<br/>
<input type="checkbox" name="items" value="足球" />足球
<input type="checkbox" name="items" value="篮球" />篮球
<input type="checkbox" name="items" value="羽毛球" />羽毛球
<input type="checkbox" name="items" value="乒乓球" />乒乓球
<br/>
<input type="button" id="checkedAllBtn" value="全选" />
<input type="button" id="checkedNoBtn" value="全不选" />
<input type="button" id="checkedRevBtn" value="反选" />
<input type="button" id="send" value="提交" />
</form>
</body>
</html>

DOM增删改

image-20210214171009270

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<script>
//封装一个单击函数
function myClick(idStr,fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}

window.onload = function(){
//一、添加广州——方法1:
myClick("btn01",function(){
//创建元素节点
var li = document.createElement("li");
//创建文本节点
var text = document.createTextNode("广州");
//往li中添加text
li.appendChild(text);
//往ul中添加li
var ul = document.getElementById("city");
ul.appendChild(li);
});
//二、添加广州到北京前
myClick("btn02",function(){
var li = document.createElement("li");
var text = document.createTextNode("广州")
li.appendChild(text);

//获取北京与city
var beijing = document.getElementById("bj");
var city = document.getElementById("city");
//插入到北京前
city.insertBefore(li,bj); //(新节点,旧节点)
});
//三、使用广州节点替换北京节点
myClick("btn03",function(){
var li = document.createElement("li");
var text = document.createTextNode("广州")
li.appendChild(text);

//获取北京与city
var beijing = document.getElementById("bj");
var city = document.getElementById("city");
//替换
city.replaceChild(li,beijing);
});
//四、删除北京节点
myClick("btn04",function(){
//获取北京与city
// var beijing = document.getElementById("bj");
// var city = document.getElementById("city");
// //替换
// city.removeChild(beijing);

//或者!!!!!!!!我找我爸爸删我自己!!!!!!
var beijing = document.getElementById("bj");
//替换
beijing.parentNode.removeChild(beijing);
});
//五、读取
myClick("btn05",function(){
var city = document.getElementById("city");
alert(city.innerHTML);
});
//六、设置bj内的HTML代码
//这样也可以,一般两种方法结合使用
myClick("btn06",function(){
var city = document.getElementById("city");
city.innerHTML += "<li>广州</li>";
});
}



</script>

a的索引问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.onload = function(){
var allA = document.getElementsByTagName("a");
for(var i = 0; i < allA.length; i++){
//for 循环在页面加载完成后,立即执行
//而响应函数,在超链接被点击时才会执行.此时,i为allA.length
allA[i].onclick = function(){
var tr = this.parentNode.parentNode; //因此这里不能使用allA[i]
var flag = confirm("确认删除"+ name + "吗?");
if(flag){
...;
}
return false; //取消超链接的默认跳转行为
};
}
}

DOM与CSS样式

给出的材料如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box1{
width: 200px;
height: 200px;
background-color: red;
/* background-color:red !important; 添加! important后,拥有最高优先级*/
}
</style>
</head>
<body>
<button id="btn01">改变样式</button>
<button id="btn02">读取样式</button>
<div id="box1"></div>
</body>
</html>

修改样式方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.onload = function(){
var box1 = document.getElementById("box1");
var btn01 = document.getElementById("btn01");
btn01.onclick = function(){
/*
修改样式方法
语法: 元素.style.样式名 = 样式值(字符串)
*/
box1.style.width = "300px";
box1.style.height = "300px";
//box1.style.background-color = "yellow";错误,因为含有减号
box1.style.backgroundColor = "yellow";
};

};

读取样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
btn02.onclick = function(){
/*
通过style设置和读取都是内联样式,无法读取样式表中的样式,
简单来说就是只能读取程序里的变量或标签里设置的属性
*/
alert(box1.style.width);
/*
getComputedStyle()这个方法来获取元素的当前样式
这个方法是window的方法,可以直接使用
需要两个参数:
1. 获取样式的元素
2. 传递一个伪元素,一般为null
该方法会返回一个对象,该对象里封装了当前元素的对应样式
如果获取的样式没有设置,则会获取真实的值,而不是默认值
如:没有设置width,它不会获取auto,而是一个长度
*/
var obj = getComputedStyle(box1,null);
alert(obj.width);
};


getStyle()方法

1
2
3
4
5
6
7
function getStyle(obj,name){
if(window.getComputedStyle){//根据属性是否存在进行判断
return getComputedStyle(obj,null)[name]; //正常浏览器
}else{
return obj.currentStyle[name]; //IE8
}
}

制作一个读协议书的小功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#info{
width: 200px;
height: 400px;
overflow: auto;
}
</style>
<script>
window.onload = function(){
//onscroll 该事件会在元素的滚动条滚动时触发

var info = document.getElementById("info");
var inputs = document.getElementsByTagName("input");
info.onscroll = function(){
//已滚到底;由于谷歌浏览器的一些属性保留了小数位,所以需要使用1来判断,不能用等于0来判断
if(info.scrollHeight - info.scrollTop - info.clientHeight<1){
//变为可用
inputs[0].disabled = false;
inputs[1].disabled = false;
}
};
}
</script>
</head>
<body>
<h3>欢迎亲爱的用户注册</h3>
<p id = "info">
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
亲爱的用户,请仔细阅读以下协议,如果你不仔细阅读就别注册
</p>
<!-- 如果为表单项添加disabled="disabled",则表单项变成不可用状态 -->
<input type="checkbox" disabled = "disabled" />我已仔细阅读协议,一定遵守
<input type="submit" value = "注册" disabled = "disabled"/>
</body>
</html>

事件对象

image-20210215172917998

在div里移动鼠标,显示xy坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#areaDiv{
width:200px;
height:100px;
outline:#000000 solid 1px;
}
#showMsg{
width:200px;
height:30px;
outline:#000000 solid 1px;
}
</style>
<script>
window.onload = function() {
var areaDiv = document.getElementById("areaDiv");
var showMsg = document.getElementById("showMsg");
areaDiv.onmousemove = function(event){
//解决事件对象的兼容性问题
event = event || window.event;

var x = event.clientX;
var y = event.clientY;
showMsg.innerHTML = "x = " + x + " " + "y = " + y;
};
}

</script>
</head>
<body>
<div id="areaDiv"></div>
<div id="showMsg"></div>
</body>
</html>

div跟随鼠标移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width:100px;
height: 100px;
background-color: red;
/* 开启box1的绝对定位 */
position: absolute;
}
</style>
<script>
window.onload = function(){
var box = document.getElementById("box");
document.onmousemove = function(event){
event = event || window.event;
var st = document.body.scrollTop || document.documentElement.scrollTop;
var sl = document.body.scrollLeft || document.documentElement.scrollLeft;
var left = event.clientX;//clientX是相对于窗口的
var top = event.clientY;
// var left = event.pageX;
// var top = event.pageY; 可以直接获取页面坐标,但是这对IE8不兼容
box.style.left = left +sl + "px";
box.style.top = top +st+ "px";
};

};
</script>
</head>
<body style="height:1000px;width:2000px;">
<div id="box"></div>
</body>
</html>

事件的冒泡

所谓的冒泡指的是事件的向上传导,当其后代元素被触发时,其祖先元素也会被触发。

1
2
3
4
5
6
7
8
9
10
11
12
13
window.onload = function() {
var s1 = document.getElementById("s1");
s1.onclick = function() {
alert("我是s1");
}
var box1 = document.getElementById("box1");
box1.onclick = function() {
alert("我是div");
}
document.body.onclick = function() {
alert("我是body")
}
}

如上述代码,点击span时,三个alert会依次触发。

在开发中,大部分的冒泡都是非常有用的;如果不希望发生事件冒泡,可以通过事件对象取消冒泡。如下:

1
2
3
4
5
6
7
var s1 = document.getElementById("s1");
s1.onclick = function(event) {
//取消span的冒泡
event = event || window.event;
alert("我是s1");
event.cancelBubble = true;
}

事件的委派

——指将事件统一绑定给元素的共同祖先,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件

——事件委派利用了冒泡,通过委派可以减少事件的绑定次数

1
2
3
4
5
6
7
8
//这样可以快速绑定原有的li和新生成的li
u1.onclick = function(event){
event = event || window.event;
//target获取到响应函数触发的元素
if(event.target.className == "link"){
alert(666);
}
}

事件的绑定

1
2
3
4
5
6
7
8
9
10
/*通过这个方法也可以为元素绑定响应函数
- 参数:
1. 事件的字符串,不要on
2. 回调函数,事件触发时函数会被调用
3. 是否捕获阶段触发事件,需要一个布尔值,一般传false
*/

btn01.addEventListener("click",function(){
alert(1);
},false);

事件的捕获

关于事件的传播,网景公司和微软公司有不同的理解:

微软公司认为:事件应该是由内向外传播的,就是先触发当前元素上的事件——即在冒泡阶段执行

网景公司认为:事件应该是由外向内传播的,就是先触发最外层的祖先元素的事件,然后向内传播给后代元素

W3C综合了两个公司的方案,将事件传播分成了三个阶段:

  1. 捕获阶段
  2. 目标阶段
  3. 冒泡阶段

拖拽练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#box1 {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
#box2{
width: 100px;
height: 100px;
background-color:yellow;
position: absolute;
left: 300px;
top :300px;
}
</style>
<script>
window.onload = function () {
/*
拖拽box1元素
-拖拽流程:
1. 当鼠标在拖拽元素上按下时,开始拖拽 onmousedown
2. 当鼠标移动时,被拖拽元素跟随鼠标移动 onmousemove
3. 当鼠标松开时,被拖拽元素固定在当前位置 onmouseup

*/
var box1 = document.getElementById("box1");
//为box1绑定按下事件
box1.onmousedown = function () {
//div偏移量 = 鼠标.clientX - 元素.offsetLeft
var ol = event.clientX - box1.offsetLeft;
var ot = event.clientY - box1.offsetTop;

document.onmousemove = function (event) {
event = event || window.event;
//鼠标的坐标
var left = event.clientX ;
var top = event.clientY ;
//box1位置
box1.style.left = left- ol + "px";
box1.style.top = top - ot + "px";
};
document.onmouseup = function(){
document.onmousemove = null;
document.onmousedown = null;
}
return false;
};

/*当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
此时会导致拖拽功能的异常,这是浏览器提供的默认行为,简单的取消方法就是return false*/
};
</script>
</head>
<body>
<p>666666666</p>
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>

滚轮练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box1{
width:100px;
height:100px;
background-color:red;
}
</style>
<script>
window.onload = function(){
var box1 = document.getElementById("box1");
box1.onmousewheel = function(event){
event = event || window.event;
if(event.wheelDelta > 0){
box1.style.height = box1.clientHeight - 10 + "px";
}else{
box1.style.height = box1.clientHeight + 10 + "px";
}
return false;//取消滚动条默认行为
};

}
</script>
</head>
<body style = "height:2000px;">
<div id="box1"></div>
</body>
</html>

BOM

BOM(Browser Object Model)浏览器对象模型

BOM是我们可以通过JS来操作浏览器。提供了一组对象

  1. Window:代表的是整个浏览器的窗口,同时Window也是网页中的全局对象
  2. Navigator:代表了当前浏览器的信息,通过该对象来识别不同的浏览器。由于历史原因,大部分属性都不能帮助识别浏览器了,现在一般使用userAgent,但是IE11也隐藏了起来
  3. Location:代表了当前浏览器的地址栏信息
  4. History:代表浏览器的历史记录(由于隐私的原因,不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问有效)
  5. Screen:代表用户的屏幕信息,显示器的相关信息

这些BOM对象在浏览器中都是作为window对象的属性使用的。

定时器简介

涉及方法:

  1. clearInterval():取消由 setInterval() 设置的 timeout。
  2. clearTimeout():取消由 setTimeout() 方法设置的 timeout。
  3. setInterval():按照指定的周期(以毫秒计)来调用函数或计算表达式。
  4. setTimeout():在指定的毫秒数后调用函数或计算表达式。
1
2
3
4
5
6
7
8
9
10
window.onload = function(){
var h2 = document.getElementById("h2");
var time = 0;
var timer = setInterval(function(){
h2.innerHTML = time ++;
if(time == 10){
clearInterval(timer);//timer是一个数字,是定时器的唯一标识
}
},1000);
}

综合练习

轮播图制作

二级菜单制作

JSON

JS中的对象只有JS自己认识,其他语言都不认识;

JSON(JavaScript Object Notation JS对象表示法)就是一个特殊格式的字符串,这个字符串可以被任意语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互。

JSON分类:

  1. 对象{}
  2. 数组[]

JSON中允许的值:

  1. 字符串
  2. 数值
  3. 布尔值
  4. null
  5. 对象
  6. 数组
1
2
3
4
//创建一个对象
var obj = '{"name":"孙悟空","age":18 ,"gender":"男"}';
//创建一个数组
var arr = '[1,2,3,"hello",true]';

在JS中,提供了一个工具类,就叫JSON

这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON

1
2
3
4
5
6
7
8
9
10
11
/*    
JSON -> JS对象:
JSON.parse()
*/
var json = JSON.parse(str1);
/*
JS对象 -> JSON:
JSON.stringify()
*/
var str = JSON.stringify(obj);


JS学习之路
https://wuhlan3.github.io/2021/02/07/JS学习之路/
Author
Wuhlan3
Posted on
February 7, 2021
Licensed under