JavaScript
本文件已定稿,最后修改时间 20240511 03:20
- 浏览器由渲染引擎(解析HTML和CSS,俗称内核)和js引擎(读取网页中的js代码并运行)两部分组成。
- JavaScript由三部分组成:
- JavaScript语法。
- DOM:页面文档对象模型,是W3C推荐的处理可扩展标记语言的标准编程接口,通过DOM可以对页面上的各种元素进行操作。
- BOM:浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,通过BOM可以操作浏览器窗口。
一、语法
1、书写位置
JavaScript有3种书写位置,分别是行内、内部、外部(js不建议写分号,但立即执行函数和数组解构交换值时必须写,否则报错)。
行内:
<body>
<input type="button" value="点我试试" onclick="alert('hello world')">
</body>内部:
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
alert('hello world');
</script>
</head>外部:
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src=""></script>
</head>
2、注释
<head> |
3、变量
3.1、命名规范
- 由字母、数字、下划线、$组成。
- 区分大小写。
- 不能以数字开头。
- 不能是关键字、保留字。
- 遵循小驼峰命名法。
3.2、定义方式
- var 定义的是全局变量(可重复定义同名变量,后定义的覆盖先定义的)。
- let 定义的是局部变量(不可重复定义同名变量)。
- const 定义常量。
//1、只声明不赋值,直接使用变量,结果是undefined |
3.3、简单数据类型
简单数据类型包括:
- Number——默认值0,包含整型和浮点型,有3个特殊值:
- Infinity——正无穷大。
- -Infinity——负无穷大。
- NaN——代表一个非数值。
- Boolean——默认值false,包含true和false(等价于1和0)。
- String——默认值 “”。
- Undefined——默认值undefined。
- Null——var a = null;
var a = 10;
var b = true;
//1、字符串需要用单引号或双引号定义,但在html中双引号表示属性,故推荐单引号定义字符串
var str1 = 'wo';
var str2 = "wo";
//2、字符串的长度
console.log(str1.length); //2
//3、判断变量的数据类型
console.log(typeof a); //number
//4、判断变量是不是数值
console.log(isNaN(b)); //false- Number——默认值0,包含整型和浮点型,有3个特殊值:
3.4、数组
定义方式:
- 利用字面量创建数组。
- 利用new创建数组。
增加元素:
- 不能直接给数组名赋值,否则会覆盖掉以前的数据。
- 可以通过数组索引的方式给数组追加元素(推荐)。
- 使用数组名.length可以访问数组长度。
- length属性是可读写的,可通过修改length长度实现数组扩容的目的。
注意:
- 数组里可存放任意类型的数据。
<body>
<script>
//1、利用字面量创建数组
//(1)空数组
var arr1 = [];
//(2)带初值的数组
var arr2 = [1, 2, 3];
//给arr2增加元素
arr2[3] = 4;
//2、利用new创建数组
var arr3 = new Array();
//3、给arr1增加元素
//(1)
arr1 = [1, 2];
//(2)push方法将一个或多个元素添加到数组末尾,并返回该数组的新长度
arr1.push(3);
//(3)unshift方法将一个或多个元素添加到数组开头,并返回该数组的新长度
arr1.unshift(0);
console.log(arr1); //[0,1,2,3]
//4、删除arr2的元素
//(1)pop方法删除数组中最后一个元素,并返回该元素的值
arr2.pop();
//(2)shift方法删除数组中第一个元素,并返回该元素的值
arr2.shift();
//(3)splice(start,deleteCount)方法,删除指定元素
arr2.splice(0, 2);
console.log(arr2); //[]
</script>
</body>
展开运算符:…
//... 展开运算符的作用就是将数组展开
let arr = [1, 2, 3];
console.log(...arr); //1 2 3forEach遍历数组:
const color = ['red', 'black', 'white']
//index可以不写
color.forEach((item, index) => console.log(item, index))数组解构:
//1)变量多,单元值少,undefined
const [a, b, c] = [1, 2]
console.log(a)
console.log(b)
console.log(c)
//2)变量少,单元值多
const [d] = [3, 4]
console.log(d)
//3)剩余参数接多余的单元值
const [e, ...f] = [5, 6, 7]
console.log(e)
console.log(f)
//4)设置默认值 防止undefined传递
const [g = 0] = []
console.log(g)
//5)按需导入值
const [h, i, , j] = [8, 9, 10, 11]
console.log(h)
console.log(i)
console.log(j)
//6)支持多维数组的解构
const [k, [l, m]] = [12, [13, 14]]
console.log(k)
console.log(l)
console.log(m)
3.5、数据类型转换
转换为数字型:
var a = '10';
var b = '10.2';
var c = '20';
var d = '20.2';
//1、将String类型转换为整型
a = parseInt(a);
console.log(typeof a); //number
//2、将String类型转换为浮点型
b = parseFloat(b);
console.log(typeof b); //number
//3、强制转换,将String类型转换为数值型
c = Number(c);
console.log(typeof c); //number
//4、js隐式转换(- * /)
d = d - 0;
console.log(typeof d); //number转换为布尔型:代表空和否定的值(false,0,null,undefined,NaN)都会被转换成false,其余值都转换成true。
var a = false;
a = Boolean(a);
console.log(a); //false转换为字符串:
var a = 1;
var b = 2;
var c = 3;
//1、toString转成字符串
a = a.toString();
console.log(typeof a); //string
//2、String强制转成字符串
b = String(b);
console.log(typeof b); //string
//3、任何类型 +字符串 == 字符串
c = c + '';
console.log(typeof c); //string数组转换为字符串:
var arr = [1, 2, 3];
console.log(arr.toString()); //1,2,3
console.log(arr.join('')); //123
3.6、Object
- Object是由属性和方法组成的,现阶段创建对象的3种方式:
- 利用字面量创建对象。
- 利用new Object创建对象。
- 利用构造函数创建对象(是一种用来初始化对象的特殊函数,总与new一起使用,约定函数名第一个字母大写)。
- 对象属性或方法的调用:
- 属性使用 对象名.属性名 或 对象名[‘属性名’] 调用。
- 方法使用 对象名.方法名() 调用。
- 增:和改属性值是一样的,直接对象名.属性名=xx;
- 删:delete 对象名.属性名
- 遍历对象:for (变量名 in 对象名) {}
- 变量名——得到的是属性名。
- 对象名[属性名]——得到的是属性值。
//1、利用字面量创建对象 |
3.7、内置对象
JavaScript中的对象分为3种,内置对象、浏览器对象、自定义对象。
Math对象:
var a = 3.1;
//1、圆周率
console.log(Math.PI); //3.1415926
//2、向下取整
console.log(Math.floor(a)); //3
//3、向上取整
console.log(Math.ceil(a)); //4
//4、四舍五入,就近取整
console.log(Math.round(-3.5)); //注意 -3
console.log(Math.round(3.2)); //3
//5、绝对值
console.log(Math.abs(-3)); //3
//6、求最大值和最小值
console.log(Math.max(1, 2)); //2
console.log(Math.min(1, 2)); //1Date对象:
//1、获取系统当前时间(必须实例化)
var now = new Date();
console.log(now);
//2、获取日期对象的指定部分
console.log(now.getFullYear()); //获取年
console.log(now.getMonth()); //获取月(0-11)
console.log(now.getDate()); //获取月中的第几天
console.log(now.getDay()); //获取周中的第几天(0-6)
console.log(now.getHours()); //时
console.log(now.getMinutes()); //分
console.log(now.getSeconds()); //秒
//3、构造函数构造指定日期的Date对象
var a = new Date('2011-1-1');
console.log(a.getFullYear()); //2011
//4、获取系统当前时间毫秒值
console.log(Date.now());字符串对象:JavaScript中的字符串同Java一样,具有不可变的特点。
//1、根据字符查找,返回第一个匹配字符的索引(找不到返回-1)
var str1 = 'hello';
//(1)0代表从索引0开始查找
console.log(str1.indexOf('l', 0)); //2
//(2)倒着查找
console.log((str1.lastIndexOf('o'))); //4
//2、根据索引返回字符
console.log(str1.charAt(0)); //h
console.log(str1.charCodeAt(0)); //104(ASCII)
//3、字符串操作方法
//(1)拼接字符串 == + (+更常用)
console.log(str1.concat(' world')); //hello world
//(2)截取字符串 start end 包前不包后
console.log(str1.slice(0, 1)); //h
console.log(str1.substring(0, 1)); //h数组对象:
//1、检测是否为数组
var arr1 = [1, 2, 3];
console.log(arr1 instanceof Array); //true
console.log(Array.isArray(arr1)); //true
//2、增删数组元素
//(1)末尾添加一个或多个元素,返回新的长度
arr1.push(3, 5);
//(2)删除数组最后一个元素,返回删除的值
arr1.pop();
//(3)向数组的开头添加一个或多个元素,返回新的长度
arr1.unshift(-1, 0); //注意,-1会后添加到数组中
//(4)删除数组的第一个元素
arr1.shift();
console.log(arr1); //[0, 1, 2, 3, 3]
//3、数组索引方法(不存在返回-1)
//(1)查找给定元素在数组中的第一个索引
console.log(arr1.indexOf(3)); //3
//(2)查找给定元素在数组中的最后一个索引
console.log(arr1.lastIndexOf(3)); //4
//4、连接多个数组,不影响原数组,返回新数组
console.log(arr1.concat([4])); //[0, 1, 2, 3, 3, 4]
//5、截取数组,不影响原数组,返回新数组,start end 包前不包后
console.log(arr1.slice(0, 2)); //[0, 1]
//6、删除数组元素,影响原数组,start deleteCount
arr1.splice(3, 2);
console.log(arr1); //[0, 1, 2]
//7、数组排序
//(1)反转数组
arr1.reverse();
//(2)冒泡排序
arr1.sort(function (a, b) {
return a - b; //升序
// return b - a; //降序
});
console.log(arr1); //[0, 1, 2]
3.8、自定义对象
var myObject = { |
3.9、对象解构
//4、多级对象解构 |
4、输入输出
JavaScript常用输入输出语句如下:
//1、浏览器弹出警示框
alert('hello');
//2、浏览器控制台打印输出信息
console.log('hello');
//3、浏览器弹出输入框,用户可以输入
prompt('请输入');
//4、直接将内容写入页面的内容流,但是文档流执行完毕,它会导致页面全部重绘。
document.write('hello');转义字符:
// \n
// \\
// \'
// \"
// \t
// \b
5、运算符
5.1、算术运算符
- 浮点数值的最高精度是17位小数,不要直接判断两个浮点数是否相等。
- 比如 0.1 + 0.2 不等于 0.3,而是0.30000000000000004
5.2、比较运算符
5.3、赋值运算符
赋值运算符包括:
=
+=
-=
*=
/=
%=
5.4、自增自减运算符
++ –:
++ – 在前:先自增自减,再参与运算。
++ – 在后:先参与运算,再自增自减。
5.5、逻辑运算符
逻辑运算符包括:
- &&——与
- ||——或
- ! ——非
与、或的短路现象:
console.log(1 && 2); //2
console.log(0 || 2); //2
console.log(1 > 0 && 2 < 3); //true
var a = 2;
console.log(1 || (a = a - 1));
console.log(a); //2,或短路
5.6、优先级
6、流程控制
6.1、if分支
var a = 3; |
6.2、switch分支
var a = 3; |
6.3、三元表达式
var a = 3; |
6.4、for循环
for (var i = 0; i < 3; i++) { |
6.5、while循环
var i = 0; |
6.6、do-while循环
var i = 0; |
6.7、跳转
- continue —— 跳出本次循环,开始下次循环。
- break —— 跳出循环。
7、函数
7.1、定义方式
- 实参个数应与形参个数保持一致。
- 实参个数多于形参个数,只接收形参的个数。
- 实参个数小于形参个数,多的形参定义为undefined,结果为NaN。
- return只能返回一个值。
- 如果有多个被逗号隔开的值,只返回最后一个值。
- 函数没有写return则返回undefined。
//可以为参数设置默认值 |
7.2、匿名函数
//1、定义匿名函数 |
7.3、立即执行函数
- 匿名函数和有名字的函数都可以。
- 内部定义的var变量是局部变量。
<script> |
7.4、不定参数
//1、定义函数 |
7.5、剩余参数
//...表示剩余参数,是真数组 |
7.6、箭头函数
目的:为了更简短的函数写法,并且不绑定this,适用于需要匿名函数的地方。
区别:箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this
// const fn = function () {
// console.log(100);
// }
//1)箭头函数基本语法
const fn = () => {
console.log(100);
}
fn();
// 2)只有一个形参可以省略小括号,只有一行代码体可以省略大括号
const fn2 = x => console.log(x);
fn2(101);
//3)如果只有一行返回值,可以省略大括号和return
const fn3 = x => x + x;
console.log(fn3(100));
//4)箭头函数可以直接返回一个对象
const fn4 = uname => ({ uname: uname });
console.log(fn4("hello"));
7.7、作用域
作用域分为局部作用域和全局作用域,作用域链本质上就是变量的查找机制(就近原则)。
闭包:函数中嵌套函数,且嵌套函数用到了外层函数的变量。
<body>
<script>
//闭包的作用,封闭数据,提供操作,外部也可以访问函数内部的变量
function func1() {
let a = 1;
function func2() {
console.log(a);
}
return func2;
}
let f = func1();
f();
</script>
</body>变量提升:
8、正则表达式
8.1、语法
<body> |
8.2、元字符
元字符可以使正则表达式更加灵活和简洁,而普通字符只能表示它本身。
① 边界符:^ 表示以谁开始;$ 表示以谁结束;^ 和 $ 一起写表示是精确匹配
② 量词:* 重复零次或多次;+ 重复1次或多次;? 重复零次或1次;{n} 重复n次;{n,} 重复n次或多次;{n,m} 重复n到m次
③ 字符类:[] 匹配字符集合,包含[]中其中一个就是true;[a-zA-Z0-9]表示这个范围都行;[^a -z] ^表示取反,除了小写字母都行
④ 预定义:
⑤ 修饰符和替换:
<body>
<script>
//1、定义规则
let str = 'helLo';
const reg = /l/ig;
//2、修饰符 i 表示忽略大小写;g 表示全局搜索(否则只会匹配一个)
console.log(str.replace(reg, 'a')); //heaao
</script>
</body>
9、异常处理
10、节流防抖
10.1、节流
10.2、防抖
二、DOM
- DOM树(DOM把以下内容都看作对象):
- 文档,一个页面就是一个文档(文档从上往下加载),DOM中使用document表示。
- 元素,页面中的所有标签都是元素,DOM中使用element表示。
- 节点,网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示。
1、获取元素
1.1、根据标签获取
|
1.2、根据类名获取
|
1.3、根据ID获取
|
1.4、特殊元素获取
|
1.5、其它
|
2、事件
2.1、事件三要素
事件由三要素组成:事件源、事件类型、事件处理程序。
- 事件源:事件被触发的对象,按钮?
- 事件类型:什么事件,如何触发,鼠标经过?键盘按下?
- 事件处理程序:通过一个函数赋值的方式完成。
|
2.2、注册事件
给元素添加事件称为注册事件或者绑定事件,注册事件分为传统方式和方法监听注册(推荐)两种。
- 传统方式:
- 比如 btn.onclick = function () {alert(‘hello world’);};
- 注册事件的唯一性——同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的。
- 方法监听注册(推荐):
- 同一个元素同一个事件可以注册多个监听器。
- addEventListener有3个参数:
- type —— 事件类型字符串,比如click、mouseover,注意不要带on。
- listener —— 事件处理函数。
- useCapture —— 可选参数,布尔类型,默认值为false。
<body>
<form>
<input type="button" value="点我试试1">
<input type="button" value="点我试试2">
</form>
<script>
//1、传统方式
var btns = document.querySelectorAll('input');
btns[0].onclick = function () {
alert('hello world');
};
//2、方法监听注册
btns[1].addEventListener('click', function () {
alert(22);
});
btns[1].addEventListener('click', function () {
alert(33);
});
</script>
</body>- 传统方式:
2.3、删除事件
删除事件(解绑事件)有传统方式和removeEventListener两种方式。
<body>
<form>
<input type="button" value="点我试试1">
<input type="button" value="点我试试2">
</form>
<script>
//1、传统方式
var btns = document.querySelectorAll('input');
btns[0].onclick = function () {
alert('hello world');
};
//删除事件
btns[0].onclick = null;
//2、removeEventListener方式
function fn() {
alert(22);
}
btns[1].addEventListener('click', fn);
//删除事件(匿名函数无法解绑)
btns[1].removeEventListener('click', fn);
</script>
</body>
2.4、事件对象
event对象代表事件的状态,触发事件后,会得到相关的属性,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
- 事件对象只有有了事件才会存在(系统自动创建),event写到事件处理函数的()里,可自定义命名(e、evt)。
- 事件对象的属性方法:
- event.target —— 返回触发事件的对象(标准)(this代表的是绑定事件的对象)。
- event.type —— 返回事件的类型。
- event.preventDefault() —— 该方法阻止默认事件(标准),比如不让链接跳转。
- event.stopPropagation() —— 阻止冒泡(标准)。
<body>
<form>
<input type="button" value="点我试试">
</form>
<script>
//以注册事件的传统方式举例
var btn = document.querySelector('input');
btn.onclick = function (event) {
alert('hello world');
console.log(event.target);
};
</script>
</body>
2.5、鼠标事件
- 常用的鼠标事件有:
onclick —— 鼠标点击左键触发。
onmouseover —— 鼠标经过触发。
onmouseout —— 鼠标离开触发。
onfocus —— 获得鼠标焦点触发。
onblur —— 失去鼠标焦点触发。
onmousemove —— 鼠标移动触发。
onmouseup —— 鼠标弹起触发。
onmousedown —— 鼠标按下触发。
禁止鼠标右键和选中文字,代码见下:
<body>
<p>我是一段文字</p>
<script>
document.addEventListener('contextmenu', function (e) {
//1、禁止右键菜单
e.preventDefault();
});
document.addEventListener('selectstart', function (e) {
//2、禁止选中文字
e.preventDefault();
});
</script>
</body>
- 常用的鼠标事件对象属性:
- event.clientX —— 相对于浏览器可视区的X坐标。
- event.clientY —— 相对于浏览器可视区的Y坐标。
- event.pageX —— 相对于文档页面的X坐标。
- event.pageY —— 相对于文档页面的Y坐标。
- event.screenX —— 相对于电脑屏幕的X坐标。
- event.screenY —— 相对于电脑屏幕的Y坐标。
2.6、键盘事件
- 常用的键盘事件有:
- onkeyup —— 某个键盘按键被松开时触发(不区分大小写)。
- onkeydown —— 某个键盘按键被按下时触发(不区分大小写)。
- 常用的键盘事件对象属性:
- event.key —— 键的字母值。
2.7、事件流
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
DOM事件流分为3个阶段:
- 捕获阶段(DOM最顶层节点➡具体元素)、当前目标阶段(具体元素)、冒泡阶段(具体元素➡DOM最顶层节点)。
注意:
- js代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick 和 attachevent只能得到冒泡阶段。
- addEventListener第三个参数是true表示在事件捕获阶段调用事件处理程序,默认是false,表示在冒泡阶段调用事件处理程序。
- 有些事件是没有冒泡的,比如onfocus、onblur。
- 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
<!--事件委托:利用冒泡原理在父节点上设置事件处理程序,可以影响每个子节点,只操作一次DOM,提高性能-->
<body>
<ul>
<li>第1个li标签</li>
<li>第2个li标签</li>
<li>第3个li标签</li>
</ul>
<script>
var uls = document.querySelectorAll('ul');
uls[0].onclick = function () {
alert('ul标签');
};
</script>
</body>
3、操作元素
3.1、修改元素内容
修改元素内容有两种方式:
- innerText —— 非标准,不识别html标签,可读写,读取其内容时会去掉空格和换行。
- innerHTML —— w3c标准,识别html标签,可读写,读取其内容时会保留空格和换行。
<body> |
3.2、修改元素属性
<body> |
3.3、修改表单属性
表单里面的值是通过value属性来控制的。
想要表单被禁用,可以将disabled属性设置为true。
<body> |
3.4、修改样式属性
通过js修改样式属性有两种方式:
- element.style —— 行内样式操作。
- element.className —— 类名样式操作。
注意:
- js里面的样式采用小驼峰命名法,比如fontSize。
- element.style产生的是行内样式,CSS权重高。
- className会直接更改元素的类名,从而覆盖原类名。
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.change {
width: 200px;
height: 200px;
background-color: springgreen;
}
</style>
</head>
<body>
<form>
<input type="button" value="点我试试">
</form>
<div></div>
<script>
//当我们点击按钮,div盒子大小会变化
//element.style在修改元素属性时已演示,此处只演示element.className的方式
var btn = document.querySelector('input');
var div = document.querySelector('div');
btn.onclick = function () {
div.className = 'change';
}
</script>
</body>
3.5、自定义属性
自定义属性目的:是为了保存并使用数据,有些数据可以保存在页面中而不用保存到数据库中。
获取属性值:
- element.属性 —— 获取属性值(内置属性值)。
- element.getAttribute(‘属性’) —— 获取属性值(主要获得自定义的属性)。
设置属性值:
- element.属性 = ‘值’ —— 设置属性值(内置属性)。
- element.setAttribute(‘属性’, ‘值’) —— 设置属性值(自定义属性)。
移除属性:
- element.removeAttribute(‘属性’)
H5设置和获取自定义属性值:
- element.setAttribute(‘属性’, ‘值’) —— 设置属性值(必须以 data- 开头)。
- element.getAttribute(‘属性’) —— 兼容性获取。
- element.dataset.index 或 element.dataset[‘index’] —— 新增获取方式(只能获取 data- 开头的属性值)。
<body>
<form>
<input type="button" value="点我试试">
</form>
<script>
var btn = document.querySelector('input');
btn.onclick = function () {
//1、H5设置自定义属性
btn.setAttribute('data-index', '1');
//2、H5获取自定义属性
console.log(btn.getAttribute('data-index'));
console.log(btn.dataset.index);
console.log(btn.dataset['index']);
//3、移除属性
btn.removeAttribute('data-index');
btn.removeAttribute('type');
}
</script>
</body>
4、节点
4.1、概述
- 获取元素的两种方式比较:
- 利用DOM提供的方法获取元素——逻辑性不强,比较繁琐。
- 利用节点层级关系获取元素——逻辑性强,操作更简单,但对老版本浏览器兼容性较差。
- 节点至少拥有nodeType、nodeName、nodeValue这三个基本属性。
- 元素节点,nodeType为1。
- 属性节点,nodeType为2。
- 文本节点,nodeType为3(包括文字、空格、换行等)。
- 在实际开发中,主要操作的是元素节点。
4.2、父节点
node.parentNode —— 获取node节点的父节点(是获取最近的一个父节点,没有返回null)。
<body>
<form>
<input type="button" value="点我试试">
</form>
<script>
var btn = document.querySelector('input');
//1、获取btn的父节点
console.log(btn.parentNode);
</script>
</body>
4.3、子节点
parentNode.childNodes(标准) —— 返回指定节点的子节点集合,该集合为即时更新的集合。返回值包含了所有的子节点(元素节点、文本节点等),只要元素节点则须专门处理,所以我们不提倡这种方式。
parentNode.children(非标准) —— 只读,返回所有的子元素节点,重点掌握。
parentNode.firstElementChild —— 返回第一个子元素节点,找不到则返回null。
parentNode.lastElementChild —— 返回最后一个子元素节点,找不到则返回null。
<body>
<form>
<input type="button" value="点我试试">
</form>
<script>
var form = document.querySelector('form');
console.log(form.childNodes); //[text, input, text]
console.log(form.children); //[input]
console.log(form.firstElementChild); //<input type="button" value="点我试试">
console.log(form.lastElementChild); //<input type="button" value="点我试试">
</script>
</body>
4.4、兄弟节点
nextSibling —— 下一个兄弟节点(包括元素节点或者文本节点等)。
nextElementSibling —— 下一个兄弟元素节点。
<body>
<form>
<input type="button" value="按钮">
<input type="text" value="文本框">
</form>
<script>
var btn = document.querySelector('input');
console.log(btn.nextSibling);
console.log(btn.nextElementSibling);
</script>
</body>
4.5、创建和添加节点
<body> |
4.6、删除节点
<body> |
4.7、复制节点
- 复制节点分为浅拷贝和深拷贝两种:
- 浅拷贝——参数为空或false,只复制节点本身,不复制里面的子节点。
- 深拷贝——参数为true,会复制节点本身及里面所有的子节点。
<body> |
4.8、动态创建元素
动态创建元素有3种方式:
- document.write() —— 直接将内容写入页面的内容流,但是文档流执行完毕,它会导致页面全部重绘。
- element.innerHTML —— 将内容写入某个节点,不会导致页面全部重绘,创建多个元素效率更高(不拼接字符串,拼接数组),但结构稍微复杂。
- createElement() —— 创建多个元素,效率稍微低一点,但结构更清晰。
<body>
<ul></ul>
<script>
//element.innerHTML 创建 1000个li的效率(采用数组拼接的形式)
var d1 = Date.now();
var ul = document.querySelector('ul');
var arr = [];
for (var i = 0; i < 1000; i++) {
arr[i] = '<li></li>';
}
ul.innerHTML = arr.join('');
var d2 = Date.now();
console.log(d2 - d1); //1ms
</script>
</body>
三、BOM
- window对象是浏览器的顶级对象,它具有双重角色:
- 它是js访问浏览器窗口的一个接口。
- 它是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
- window有一个特殊属性window.name
1、JS执行队列
JavaScript是单线程,因为它是为操作DOM和处理页面交互而诞生的,比如对某个DOM元素进行添加和删除,必须先添加才能删除,不能同时进行。但单线程可能会导致js执行时间过长➡页面渲染不连贯,为了解决这个问题,HTML5提出允许JavaScript创建多个线程,于是js中出现了同步和异步:
- 同步——前一个任务结束后再执行后一个任务 ,程序的执行顺序与任务的排列顺序是一致的。
- 异步——在处理一个任务时,可以同时处理其它任务。一般来说,异步任务有以下三种类型:
- 普通事件,如click、resize等。
- 资源加载,如load、error等。
- 定时器,setTimeout、setInterval等。
同步任务和异步任务的执行过程:
- 先执行执行栈中的同步任务。
- 异步任务(回调函数)放入任务队列中。
- 一旦执行栈中的同步任务执行完毕,系统会按次序读取任务队列中的异步任务,并进入执行栈执行。
- 由于主线程不断地获取任务、执行任务,这种机制被称为事件循环。
<body>
<script>
//演示 同步 问题 (单线程顺序执行)
//1 3 2
console.log('1');
window.setTimeout(function () {
console.log('2');
}, 10000);
console.log('3');
</script>
</body><body>
<script>
//演示 同步任务 和 异步任务 执行过程
//仍然是 1 3 2
console.log('1');
window.setTimeout(function () {
console.log('2');
}, 0);
console.log('3');
</script>
</body>
2、window对象
2.1、页面加载事件
- 页面加载事件就是给window或document绑定事件,分为两种:
- onload(load) —— 当文档内容全部加载完毕(图像、脚本、css等),才调用处理函数。
- DOMContentLoaded —— 当DOM加载完成(不包括图片、css、flash等)就调用处理函数。
- 注意:
- 有了onload就可以把js代码写到页面元素的上方。
- onload的传统注册方式只能写一次,如果有多个,以最后一个为准。
- 页面图片较多时,从用户访问到onload触发可能需要较长时间,交互效果就不能实现,此时用DOMContentLoaded比较合适。
<body> |
2.2、调整窗口大小事件
onresize(resize) —— 当窗口大小发生像素变化,就会触发事件处理函数。
- 我们经常利用此完成响应式布局,window.innerWidth当前屏幕的宽度,window.innerHeight当前屏幕的高度。
<body>
<p>我是一段文字</p>
<script>
window.addEventListener('resize', function () {
console.log('窗口大小变化了');
});
</script>
</body>
3、navigator对象
navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回userAgent值。
下面前端代码可以判断用户的终端是什么类型,并跳转不同的页面。
待续
4、location对象
window对象给我们提供了一个location属性(对象)用于获取或者设置窗体的url,并且可以用于解析url。
- 一般语法:protocol://host[:port]/path/[?query]#fragment
- query —— 键值对形式的参数,通过&分隔开。
- fragment —— 片段,#后面内容常见于链接锚点。
- 一般语法:protocol://host[:port]/path/[?query]#fragment
location对象属性:
- window.location.href —— 获取或者设置整个url。
- window.location.host —— 返回主机(域名)。
- window.location.port —— 返回端口号。
- window.location.pathname —— 返回路径。
- window.location.search —— 返回参数。
- window.location.hash —— 返回片段。
location对象方法:
- window.location.assign( url ) —— 跳转页面(同设置href),也称为重定向,记录历史,可后退。
- window.location.replace( url ) —— 替换当前页面,不记录历史,不能后退。
- window.location.reload( ) —— 刷新页面,参数为true表示强制刷新。
<body>
<div></div>
<script>
//1、实现5s后自动跳转
var count = 5;
var div = document.querySelector('div');
window.setInterval(function () {
div.innerHTML = '您将在' + count + 's之后跳转到首页';
count--;
if (count == -1) {
// window.location.href = 'http://www.baidu.com';
// window.location.assign('http://www.baidu.com');
window.location.replace('http://www.baidu.com');
window.location.reload(true);
}
}, 1000);
</script>
</body>
5、history对象
- window对象给我们提供了history对象,可以与浏览器历史记录进行交互。
- window.history.back() —— 后退。
- window.history.forward() —— 前进。
- window.history.go( 参数 ) —— 正整数前进几,负整数后退几。
6、定时器
6.1、setTimeout定时器
- window.setTimeout(调用函数, 延迟的毫秒数) —— 设置一个定时器,定时器到期后执行调用函数。
- 调用函数可以直接写函数、函数名、’函数名()’(不推荐)。
- 延迟的毫秒数默认值是0,单位是ms。
- 通常要给定时器赋值一个标识符。
- window.clearTimeout(定时器标识符) —— 取消setTimeout定时器。
<body> |
6.2、setInterval定时器
- window.setInterval(回调函数, 间隔的毫秒数) —— 每隔一段时间,就调用一次回调函数。
- 调用函数可以直接写函数、函数名、’函数名()’(不推荐)。
- 延迟的毫秒数默认值是0,单位是ms。
- 通常要给定时器赋值一个标识符。
- **window.clearInterval(定时器标识符)**—— 取消setInterval定时器。
<body> |
7、网页特效
7.1、元素偏移量offset系列
- 我们使用offset系列相关属性可以动态地得到该元素的位置、大小等。
- 获得元素距离带有定位父元素的位置。
- 获得元素自身的大小(宽度高度)。
- 返回的数值都不带单位。
- offset系列常用属性:
- element.offsetParent —— 返回该元素带有定位的父元素,如果父级都没有定位则返回body。
- element.offsetTop —— 返回元素相对带有定位父元素上方的偏移。
- element.offsetLeft —— 返回元素相对带有定位父元素左边的偏移。
- element.offsetWidth —— 返回自身宽度(padding+border+width)。
- element.offsetHeight —— 返回自身高度(padding+border+height)。
- offset 和 style 对比:
- offset —— 可以得到任意样式表中的样式值。获取数值没有单位。获取元素大小位置用offset合适。
- style —— 只能得到行内样式表中的样式值。获取数值有单位。可读写,给元素更改值用style。
7.2、元素可视区client系列
- 元素可视区client系列常用属性:
- element.clientTop —— 返回元素上边框的大小。
- element.clientLeft —— 返回元素左边框的大小。
- element.clientWidth —— 返回 padding + width,不带单位。
- element.clientHeight —— 返回 padding + height,不带单位。
7.3、元素滚动scroll系列
- 元素滚动scroll系列常用属性:
- element.scrollTop —— 返回被卷去的上侧距离,不带单位。
- element.scrollLeft —— 返回被卷去的左侧距离,不带单位。
- element.scrollWidth —— 返回自身实际的宽度,不含边框,不带单位。
- element.scrollHeight —— 返回自身实际的高度,不含边框,不带单位。
7.4、触屏touch事件
- 常见的触屏touch事件:
- touchstart —— 手指触摸到一个DOM元素时触发。
- touchend —— 手指从一个DOM元素上移开时触发。
- touchmove —— 手指在一个DOM元素上滑动时触发。
- 触摸列表:
- touches —— 正在触摸屏幕的所有手指的一个列表。
- targettouches —— 正在触摸当前DOM元素的手指列表。
- changedtouches —— 手指状态发生了改变的列表。
7.5、click延时解决方案
移动端click事件会有300ms的延迟,原因是移动端屏幕双击会缩放页面,解决方案:
禁用缩放。浏览器禁用默认的双击缩放行为并且去掉300ms的点击延迟。
<meta name="viewport" content="user-scalable=no">
利用touch事件解决:
- 当我们手指触摸屏幕时,记录当前触摸时间。
- 当我们手指离开屏幕时,用离开的时间减去触摸的时间。
- 如果时间小于150ms,并且没有滑动屏幕,那么我们就定义为点击。
8、本地存储
- 本地存储特性:
- 数据存储在用户浏览器中。
- 容量较大,sessionStorage 约 5M,localStorage 约 20M。
- 只能存储字符串,可以将对象 JSON.stringify()编码后存储。
- window.sessionStorage:
- 特点:
- 生命周期为关闭浏览器窗口。
- 在同一个页面下数据可以共享。
- 以键值对的形式存储使用。
- 存储数据:
- sessionStorage.setItem(key,value)
- 获取数据:
- sessionStorage.getItem(key)
- 删除数据:
- sessionStorage.removeItem(key)
- 删除所有数据:
- sessionStorage.clear()
- 特点:
- Window.localStorage:
- 特点:
- 生命周期永久生效,除非手动删除,否则关闭页面也会存在。
- 可以多页面共享(同一浏览器)。
- 以键值对的形式存储使用。
- 存储数据:
- localStorage.setItem(key,value)
- 获取数据:
- localStorage.getItem(key)
- 删除数据:
- localStorage.removeItem(key)
- 删除所有数据:
- localStorage.clear()
- 特点: