一、JavaScript的组成
ECMAScript
JS基础语法
DOM
页面文档对象模型
BOM
浏览器对象模型
二、JavaScript基础语法
1.三种书写位置
行内式
<!--例-->
<input type="button" value="Zzl_desu" onclick="alert('PillowL_')">
<!--呈现效果:点击按钮,弹出对话框,内容为PillowL_-->
<!--规范:标签内使用双引号,JS内使用单引号-->
内嵌式
<script>
</script>
<!--*script标签中间不允许有标签外的单独内容-->
外部JS
在外部新建js后缀文件,引入HTML中
<script src="index.js"></script>
2.注释
//单行注释
/*
多行注释
多行注释
*/
3.输入输出语句
//浏览器弹出对话框
alert(msg);
//浏览器控制台打印输出
console.log(msg);
//浏览器弹出输入框,可输入
prompt(info);
4.变量
变量的声明
var a;
赋值
a = 5;
变量的初始化
var a = 5;
更新变量
一个变量被重新赋值后,原先的值会被覆盖
同时声明多个变量
var name = 'Zzl', age = 20, type = 'Student';
*特殊情况
情况 | 说明 | 结果 |
---|---|---|
var age; console.log(age); | 只声明不赋值 | undefined |
console.log(age); | 未声明 | 报错 |
age = 10; console.log(age) | 未声明直接赋值 | 10 |
*第三种情况允许但是不提倡,最好先声明后赋值
命名规范
- 字母、数字、下划线、美元符号
- 区分大小写
- 不能以数字开头
- 避免关键字、保留字
- 必须有意义
- 遵守驼峰命名法,如myFirstName
5.数据类型
JS是弱语言,不需要提前声明类型,在运行过程中自动确定
var a = 10;
var b = 'z';
JS拥有动态类型,相同的变量可用作不同的类型
var a = 10;
var a = 'z';
简单数据类型
简单数据类型 | 说明 | 默认值 |
---|---|---|
Number | 数字型(整型、浮点型) | 0 |
Boolean | 布尔型 | false |
String | 字符串 | ‘’ |
Undefined | var a; 声明变量但未赋值出现的类型 | undefined |
Null | var a = null; 空值 | null |
Number
数字型进制
var num1 = 010; //8进制,数字前加0,转化10进制值为8
var num2 = 0xa; //16进制,数字前加0x,转化10进制值为10
数值的最大值最小值
console.log(Number.MAX_VALUE); //最大值
console.log(Number.MIN_VALUE); //最小值
特殊值
console.log(Infinity); //无穷大
console.log(-Infinity); //无穷小
console.log(NaN); //Not a number 非数值
判断是否为非数字
console.log(isNaN('a')); //返回true
console.log(isNaN(10)); //返回false
String
加单引号或者双引号,推荐使用单引号
若需要嵌套,则混用
转义字符
转义字符 | 说明 |
---|---|
\n | 换行 |
\\ | 斜杠 |
\’ | 单引号 |
\" | 双引号 |
\t | tab缩进 |
\b | 空格 |
字符串长度
var str = 'Zzl_desu';
console.log(str.length);
字符串拼接
字符串 + 任意类型 都可以拼接成一个字符串,必须有一个字符串
console.log('Zzl' + 'Desu'); //返回值为ZzlDesu
console.log('Air' + 15); //返回值为Air15
Boolean
true相当于1,false相当于0
undefined
console.log(undefined + 'a'); //返回值为undefineda
console.log(undefined + 10); //返回值为NaN
null
null的返回值是一个空对象
console.log(null + 'a'); //返回值为nulla
console.log(null + 1); //返回值为1
复杂数据类型
引用类型,通过new关键字创建的对象,Object Array Date等
检测变量的数据类型
var num = 10;
console.log(typeof num); //返回值为number
var str = 'a';
console.log(typeof str); //返回值为string
var flag = true;
console.log(typeof str); //返回值为boolean
...
数据类型的转换
转换为字符串
//1.toString()
var num = 10;
console.log(num.toString());
//2.String()强制转换
var num = 10;
console.log(String(num));
//3.加号拼接转换(推荐)
var num = 10;
console.log(num + '');
转换为数字型
//1.转换成整型
var str = '10';
console.log(parseInt(str)); //返回值为10
console.log(parseInt('10.1')); //返回值为10
console.log(parseInt('10a')); //返回值为10
console.log(parseInt('a10')); //返回值为NaN
//2.转换成浮点型
var str = '10.1';
console.log(parseFloat(str));
//3.强制转换
var str = '10';
console.log(Number(str));
//4.隐式转换 利用 - * /
console.log('10' - 0);
//或者
console.log('10' * 1);
转换为布尔型
console.log(Boolean('')); //返回值为false
/*利用Boolean()方法,其中 空、否定的值,如'' 0 NaN null undefined
转换成false;非空为true*/
堆和栈
栈
由操作系统自动分配释放存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈
简单数据类型存放到栈里面
堆
存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收
复杂数据类型存放到堆里面
6.运算符
算数运算符
- + 加
- - 减
- * 乘
- / 除
- % 取余
*浮点数在算数运算中会出问题,也不能直接比较两个浮点数
自增自减运算符
- ++ 自增
- – 自减
比较运算符
-
< 小于
-
> 大于
-
<= 小于等于
-
>= 大于等于
-
== 判断等 (默认转换数据类型)
//例 console.log(5 == '5'); //返回值为true
-
!= 不等
-
=== !== 全等(值和数据类型都一致)
逻辑运算符
- && 逻辑与
- || 逻辑或
- ! 逻辑非
逻辑中断
当有多个表达式或值时,如果左边的表达式可以确定结果,则不再继续运算右边
逻辑与
//表达式1 && 表达式2
//例
console.log(5 && 10);
如果第一个表达式为真,则返回第二个表达式,反之返回第一个表达式
逻辑或
console.log(5 || 10);
如果第一个表达式为镇,则返回第一个表达式,反之返回第二个表达式
赋值运算符
- = 赋值
- += -= 先加再赋值 先减再赋值
- *= /= %= 同上
7.流程控制
顺序结构
分支结构
if语句
if(条件表达式) {
语句;
}else if(条件表达式) {
语句;
}else {
语句;
}
三元表达式
//条件表达式 ? 表达式1 : 表达式2
//表达式为真返回表达式1,反之返回表达式2
//例
console.log(3 > 5 ? 'yes' : 'no'); //返回值为no
switch语句
switch(条件表达式) {
case value1:
语句;
break;
case value2:
语句;
break;
default:
语句;
}
*括号的值必须和case的值全等,也就是值和类型都需要相等
循环结构
for循环
for(初始化变量; 条件表达式; 操作表达式) {
语句;
}
//例
for(var i = 0; i < 5; i++) {
语句;
}
while循环
while(条件表达式) {
语句;
}
do…while循环
do {
语句;
} while(条件表达式)
continue关键字
立即跳出本次循环,进行下一次循环
break关键字
立即跳出整个循环,即循环结束
8.数组
定义
//利用new创建数组
var arr = new Array();
//利用字面量来创建数组
var arr = [];
*数组中可以放任意类型的数据
var arr = [1, 'a', true];
数组的长度
数组名.length
数组中新增元素
通过修改length新增元素
var arr = [1, 2, 3];
arr.length = 5; //修改长度
通过修改索引新增元素
var arr = [1, 2, 3];
//可直接添加数组元素
arr[3] = 4;
9.函数
声明
//1.利用关键字声明
function 函数名() {
//函数体
}
//2.函数表达式
var 变量名 = function() {
//函数体
}
调用
函数名();
形参和实参的个数
function gerSum(num1, num2) {
console.log(num1 + num2);
}
个数一致
若形参和实参的个数一致,则正常输出结果
getSum(1, 2); //返回3
实参个数多
若实参个数大于形参个数,则也正常输出结果,只会取到形参的个数为止
getSum(1, 2, 3); //返回3
形参个数多
若形参个数大于实参个数,则输出NaN
getSum(1); //返回NaN
//因为形参num2没有得到值,所以变成了undefined
//则1+undefined结果为NaN
return注意事项
- return终止函数,return后面的语句不再执行
- return只能返回一个值
- 可以利用数组返回多个值
- 如果函数没有返回值,则输出undefined
arguments
不确定有多少个参数传递,可以用arguments来获取
arguments中存储了调用所传递的所有实参
//例
function func() {
console.log(arguments);
}
//调用
func(1, 1, 1);
//控制台输出
//Arguments(3) [1, 1, 1, ...]
*arguments展示形式是一个伪数组
- 具有length属性
- 按索引方式存储数据
- 不具有push pop等方法
10.作用域
代码名字在某个范围内起作用的效果
全局作用域
script标签内,或js文件内都是全局作用域
全局变量
在全局作用域下声明的变量
在浏览器关闭时才会销毁
*若直接赋值没有var声明,当全局变量
a = 1;
局部作用域
函数内部为局部作用域
局部变量
在局部作用域下声明的变量
在语句执行完毕之后就会销毁
11.预解析
JS代码是通过JS解析器执行的,执行时分:预解析和代码执行
- JS引擎会把JS中所有的var和function提升到作用域的最前面
- 按照代码的书写顺序执行
变量预解析
把变量声明提升到当前的作用域最前面,但不提升赋值操作
函数预解析
把函数声明提升到当前的作用域最前面,但不调用函数
12.对象
创建对象的方式
字面量
//创建一个空对象
var obj = {};
//创建一个有内容的对象
var obj = {
name: 'z',
age: 20,
func: function() {
console.log('obj');
}
}
属性和方法采用键值对的形式
多个属性和方法用逗号隔开
//调用对象的属性
//方法1 对象名.属性名
console.log(obj.name); //输出z
//方法2 对象名['属性名']
console.log(obj['name']); //输出z
//调用对象的方法
obj.func();
new Object
//创建一个空对象
var obj = new Object();
//添加属性
obj.name = 'z';
//添加函数
obj.func = function() {
console.log('obj');
}
构造函数
与Java中类的构造方法类似
把对象的相同属性和方法封装到函数里
function 构造函数名() {
this.属性 = 值;
this.方法 = function() {}
}
//使用构造函数
new 构造函数名();
构造函数名首字母大写
//例
function Stu(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.study = function(course) {
console.log(course);
}
}
var stu1 = new Stu('z', 20, '男'); //相当于创建了一个对象
console.log(stu1.name);
stu1.study('javascript');
遍历对象
利用for in遍历对象
for(变量 in 对象) {
}
//例
var stu = {
name: 'z',
age: 20,
sex: '男',
}
//遍历对象
for(k in stu) {
console.log(k); //返回属性名,即name age sex
console.log(stu[k]); //返回属性值,即z 20 男
}
13.内置对象
JS自带的一些对象供开发者直接使用
查阅文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
Math对象
//常用的Math属性和方法
Math.PI //圆周率
Math.floor() //向下取整
Math.ceil() //向上取整
Math.round() //四舍五入 就近取整
Math.abs() //绝对值
Math.max() //最大值
Math.min() //最小值
Math.random() //随机数
Date对象
构造函数,必须用new关键字来实例化对象
//使用Date
var date = new Date();
console.log(date); //返回当前系统的当前时间
//括号内有参数的写法
//常用字符串型写法
var date1 = new Date('2022-8-4 14:07:00');
日期格式化
var date = new Date();
console.log(date.getFullYear());
console.log(date.getMonth()); //0-11
console.log(date.getDate());
console.log(date.getDay()); //星期 周日为0
console.log(date.getHours());
console.log(date.getMinutes());
console.log(date.getSeconds());
时间戳
从1970年1月1日起的毫秒数
var date = new Date();
console.log(date.valueOf());
//或者
console.log(date.getTime());
//或者
var date1 = +new Date();
console.log(date1);
//或者 H5新增
console.log(Date.now());
时间戳的转换
//天
d = parseInt(秒数 / 60 / 60 / 24);
//时
h = parseInt(秒数 / 60 / 60 % 24);
//分
m = parseInt(秒数 / 60 % 60);
//秒
s = parseInt(秒数 % 60);
Array对象
var arr = new Array(); //空数组
var arr1 = new Array(5); //有5个空值的数组
var arr2 = new Array(5, 6); //[5, 6]
检测是否为数组
var arr = [];
//1
console.log(arr instanceof Array); //返回值为true
//2
console.log(Array.isArray(arr)); //返回值为true
//Array.isArray优先于instanceof
//Array.isArray是H5新增
添加数组元素
var arr = [];
//push() 在数组的末尾添加一个或多个元素
arr.push(5);
arr.push(6, 'z');
//push()的返回值为新数组的长度
//unshift() 在数组的开头添加一个或多个元素
arr.unshift(1);
arr.unshift(2, 'a');
//unshift()的返回值为新数组的长度
删除数组元素
var arr = [1, 2, 3, 4, 5];
//pop() 删除数组的最后一个元素
arr.pop();
//pop()的返回值是删除的元素本身
//shift() 删除数组的第一个元素
arr.shift();
//shift()的返回值是删除的元素本身
数组排序
//翻转数组
var arr = [1, 2, 3, 4, 5];
arr.reverse();
//冒泡排序
var arr = [5, 1, 2, 4, 3];
arr.sort();
//*注:此排序是按照字典顺序进行的排序,解决此问题,方法如下
arr.sort(function(a, b){
return a - b; //升序
})
arr.sort(function(a, b){
return b - a; //降序
})
获取数组元素索引
var arr = [5, 1, 2, 4, 3];
console.log(arr.indexOf(5)); //返回值是0
//只返回第一个满足条件的索引号
//若indexOf()里面的值在数组中没出现,则返回-1
console.log(arr.lastIndexOf(5)); //从后往前找,返回值是0
数组转化为字符串
var arr = [1, 2, 3, 4, 5];
console.log(arr.toString());
//或
console.log(arr.join()); //返回值为1,2,3,4,5
//join()括号中的参数可以是空,也可以是分隔符,空参数为逗号隔开
console.log(arr.join('-')); //返回值为1-2-3-4-5
String对象
根据字符返回位置
//与数组一样 indexOf() 或 lastIndexOf()
var str = 'Minecraft Onepiece';
console.log(str.indexOf('e')); //返回值为3
console.log(str.indexOf('e', 3)); //从索引号为3的位置往后查找 返回值为12
根据位置返回字符
var str = 'Minecraft Onepiece';
console.log(str.charAt(3)); //返回值为e
console.log(str.charCodeAt(3)); //返回值为ASCII码 101
console.log(str[3]); //H5新增 返回值为e
拼接、截取字符串
var str = 'Minecraft';
console.log(str.concat('Onepiece')); //拼接 返回值为MinecraftOnepiece
//截取
var str1 = 'Minecraft';
console.log(str1.substr(4, 5)); //截取从第5个字符开始的5个字符,返回值为craft 已不推荐使用
console.log(str1.substring(4,8)); //截取从第5个字符到第8个字符,第9个字符取不到
替换字符串
var str = 'Onepiece';
console.log(str.replace('e', 'a')); //返回值为Onapiece 只会替换第一个
字符串转化为数组
var str = 'a,b,c';
console.log(str.split(',')); //根据','来分割 转化成数组 返回值为[a, b, c]
var str1 = 'a|b|c';
console.log(str.split('|')); //返回值为[a, b, c]
三、DOM
处理HTML或XML的标准接口
1.DOM树
文档
一个页面就是一个文档,用document表示
元素
标签,用element表示
节点
网页的所有内容都是节点,用node表示
2.获取元素
此时如果用script标签,则要写在标签的下面
根据ID获取
<div id="test">测试</div>
var test = document.getElementById('test');
console.log(test); //返回值为 <div id="test">测试</div>
//注:id区分大小写
console.dir(test); //打印返回的元素对象 可以查看属性和方法
根据标签名获取
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
var test = document.getElementsByTagName('li');
console.log(test); //返回值为一个伪数组 存储li的值
获取父元素内部指定的子元素
*父元素必须指明是哪个对象
如有多个ul的时候,使用getElementsByTagName()返回的是一个伪数组,所以必须指定是数组中的哪个元素
<ul>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
<ol>
<li>1</li>
<li>1</li>
<li>1</li>
</ol>
var test = document.getElementsByTagName('ul');
console.log(test[0].getElementsByTagName('li')); //获取到了ul里的li
//还可以给ul加id的方式来指定
H5新增的获取元素
根据类名获取
<div class="test">1</div>
<div class="test">2</div>
var test = document.getElementsByClassName('test');
console.log(test); //返回的也是伪数组
根据指定选择器返回第一个元素对象
<div class="test">1</div>
<div class="test">2</div>
<div id="test1">id</div>
var test = document.querySelector('.test');
console.log(test); //返回值为 <div class="test">1</div>
var test1 = document.querySelector('#test1');
console.log(test1); //返回值为 <div id="test1">id</div>
根据指定选择器返回所有元素对象
<div class="test">1</div>
<div class="test">2</div>
var test = document.querySelectorAll('.test');
console.log(test); //返回值为伪数组
获取body元素
var test = document.body;
console.log(test);
获取html元素
var test = document.documentElement;
console.log(test);
3.事件
触发响应的机制
事件三要素
事件源
事件被触发的对象 如按钮
事件类型
触发的类型 如鼠标点击onclick 获得焦点onfocus 失去焦点onblur 鼠标经过onmouseover
鼠标离开onmouseout
事件处理程序
函数赋值的方式处理
//事件源为btn
var btn = document.getElementById('btn');
//事件类型为点击onclick
//事件处理程序如下
btn.onclick = function() {
//处理语句
}
4.操作元素
改变元素内容
<div>内容</div>
<button>点击</button>
//使用innerText或innerHTML
//获取元素
var btn = document.querySelector('button');
var div = document.querySelector('div');
//事件处理
btn.onclick = function() {
div.innerText = '改变内容'; //div内的文字被改变
}
//注:innerText不识别标签,而innerHTML识别标签,如
div.innerText = '<strong>1</strong>'; //div中显示的是<strong>1</strong>
div.innerHTML = '<strong>1</strong>'; //div中显示的是加粗的1
//innerHTML使用的更多
//innerText和innerHTML都是可读写的 可以修改标签内容也可以获取标签内容
常用元素的操作
<!--如 img的src属性-->
<img src = "img1.jpg">
<button>转换</button>
//获取元素
var img = document.querySelector('img');
var btn = document.querySelector('button');
btn.onclick = function() {
img.src = 'img2.jpg';
}
//点击按钮后,图片由img1转换为img2
//其他属性还有 herf id alt title等
表单元素的属性操作
表单的属性有 type value checked selected disabled
样式属性操作
使用style
div {
width: 100px;
height: 100px;
background-color: red;
}
<div></div>
//点击div 更改div的颜色
//获取属性
var div = document.querySelector('div');
//点击事件处理
div.onclick = function() {
this.style.backgroundColor = 'deepskyblue'; //样式采取驼峰命名法
}
使用className
样式较多,就打包到一个类里,统一书写
div {
width: 100px;
height: 100px;
background-color: red;
}
.change {
background-color: deepskyblue;
}
<div></div>
//点击div 更改div的颜色
//获取属性
var div = document.querySelector('div');
//点击事件处理
div.onclick = function() {
this.className = 'change';
}
*className会直接更改元素的类名,覆盖原先的类名
如果要保留原先的类名,则:this.className = ‘原先类名 改变样式的类名’
排他思想
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
//点击哪个按钮 哪个按钮就变颜色
//获取元素
var btns = document.querySelector('button');
for(var i = 0; i < btns.length; i++) {
btns[i].onclick = function() {
//把所有按钮的背景颜色清除
for(var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = '';
}
//点击的按钮更改样式
this.style.backgroundColor = 'red';
}
}
自定义属性操作
获取属性值
<div class="a"></div>
var div = document.querySelector('div');
console.log(div.className); //返回值为a
//或
console.log(div.getAttribute('class')); //返回值为a
//方法一多用来获取元素内部的属性值
//方法二多用来获取元素自定义的属性值
设置属性值
<div class="a"></div>
var div = document.querySelector('div');
div.className = 'b';
//或
div.setAttribute('class', 'b');
移除属性
<div class="a"></div>
var div = document.querySelector('div');
div.removeAttribute('class');
H5自定义属性
规定自定义属性以 data- 开头
<div data-index="1"></div>
新增获取属性值
var div = document.querySelector('div');
console.log(div.dataset.index); //返回值为1
//或
console.log(div.dataset['index']);
如果标签的自定义属性里有多个-连接 则js中获取属性值采用驼峰命名法
5.节点操作
节点至少拥有节点类型nodeType 节点名称nodeName 节点值nodeValue
- 元素节点的nodeType为1
- 属性节点的nodeType为2
- 文本节点(文字 空格 换行等)的nodeType为3
*主要操作元素节点
获取父节点
<div class="a">
<div class="b"></div>
</div>
//先获取子节点
var b = document.querySelector('.b');
//获取父节点
var a = b.parentNode;
console.log(a);
//得到的是离子元素最近的父节点
//如果找不到父节点就返回null
获取子节点
<ul>
<li></li>
<li></li>
</ul>
<ol>
<li></li>
<li></li>
</ol>
//获取ul的li
//先获取父元素
var ul = document.querySelector('ul');
//获取子节点
var li = ul.childNodes;
console.log(li); //获取的是所有子节点 包括元素节点和文本节点等 有换行所以出现了文本节点
//所以如果只想获取元素节点,则需专门处理,不提倡使用childNodes
//方法2 使用children即可获得所有子元素节点
var ul = document.querySelector('ul');
var li = ul.children;
console.log(li);
//*推荐
获取第一个/最后一个元素
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var ul = document.querySelector('ul');
console.log(ul.firstChild); //获取的是第一个子节点 并不是子元素节点
console.log(ul.lastChild); //获取的是最后一个子节点 并不是子元素节点
//方法2
var ul = document.querySelector('ul');
console.log(ul.firstElementChild);
console.log(ul.lastElementChild);
//此方法获取的就是第一个/最后一个子元素节点
//找不到返回null
//注意兼容性
//方法3 没有兼容性问题
var ul = document.querySelector('ul');
console.log(ul.children[0]); //第一个子元素节点
console.log(ul.children[ul.children.length - 1]); //最后一个元素节点
获取兄弟节点
<body>
<div>div</div>
<span>span</span>
</body>
var div = document.querySelector('div');
console.log(div.nextSibling); //获取下一个兄弟节点 找不到就返回null
//返回不是元素节点 因为有换行 返回值是文本节点
console.log(div.previousSibling); //获取上一个兄弟节点 找不到就返回null
var div = document.querySelector('div');
console.log(div.nextElementSibling); //获取的是下一个兄弟元素节点
console.log(div.previousElementSibling); //获取的是上一个兄弟元素节点
//有兼容性问题
创建和添加节点
<ul>
<li>1</li>
</ul>
<script>
//创建节点
//例 创建一个li然后添加到ul里面
var li = document.createElement('li'); //创建li
//先获取ul
var ul = document.querySelector('ul');
ul.appendChild(li); //将li添加到ul的末尾 也就是第一个li的末尾
var li2 = document.createElement('li');
ul.insertBefore(li2, ul.children[0]); //将li2添加到第一个li(指定元素)的前面
</script>
删除节点
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
//获取元素
var ul = document.querySelector('ul');
//删除元素 如删除第一个li
ul.removeChild(ul.children[0]);
</script>
复制节点
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
//获取元素
var ul = document.querySelector('ul');
//1.node.cloneNode();
//括号内为空或false 则只复制标签 并不复制里面的内容 若需要内容 则括号内添加true
//复制第一个li
var li1 = ul.children[0].cloneNode();
//粘贴
ul.appendChild(li1); //HTML页面中只增加了 ·
//复制第二个li并复制内容
var li2 = ul.children[1].cloneNode(true);
//粘贴
ul.appendChild(li2); //HTML页面中增加了 ·2
</script>
6.DOM前期总结
创建
- document.write
- innerHTML
- createElement
增
- appendChild
- insertBefore
删
- removeChild
改
-
元素属性 src / href / title …
-
元素内容 innerHTML / innerText …
-
表单元素 value / type / disabled …
-
元素样式 style / className …
查
查询DOM元素
- API方法 getElementById / getElementByTagName
- H5新方法 querySelector / querySelectorAll
- 节点操作 parentNode / children / previousElementSibling / nextElementSibling
属性操作
- setAttribute
- getAttribute
- removeAttribute
事件操作
- onclick - 左键点击
- onmouseover - 经过
- onmouseout - 离开
- onfocus - 获取焦点
- onblur - 失去焦点
- onmousemove - 移动
- onmouseup - 弹起
- onmousedown - 按下
7.事件高级
注册事件
新:方法监听注册方式
同一个元素同一个事件可以添加多个监听器
<!--例-->
<button>点击</button>
<script>
var btn = document.querySelector('button');
//监听注册事件
btn.addEventListener('click', function(){
//语句
})
//可以添加多个事件
btn.addEventListener('click', function(){
//语句
})
//则会先执行第一个事件 再执行第二个事件
</script>
删除事件
或解绑事件
<!--例-->
<button>点击</button>
<script>
var btn = document.querySelector('button');
//监听注册事件
btn.addEventListener('click', fn);
function fn() {
alert('1');
//解绑
btn.removeEventListener('click', fn);
}
//效果为点击一次弹出后,解绑事件,后点击事件无效
</script>
DOM事件流
- 捕获阶段:从document到所绑定的事件的元素逐级捕获
- 当前目标阶段
- 冒泡阶段:从当前元素传到document的阶段
捕获阶段
<!--样式布局为c1在c2下面-->
<div class="c1">
<div class="c2"></div>
</div>
<script>
var c2 = document.querySelector('.c2');
//当第三个参数设置为true时,表示捕获阶段
c2.addEventListener('click', function(){
alert('c2');
}, true);
var c1 = document.querySelector('.c1');
c1.addEventListener('click', function(){
alert('c1');
}, true);
//捕获阶段 即从document到所绑定的事件的元素逐级捕获
//则点击c2,结果为先弹出c1,再弹出c2
</script>
冒泡阶段
<!--样式布局为c1在c2下面-->
<div class="c1">
<div class="c2"></div>
</div>
<script>
var c2 = document.querySelector('.c2');
//当第三个参数设置为false时,表示冒泡阶段
c2.addEventListener('click', function(){
alert('c2');
}, false);
var c1 = document.querySelector('.c1');
c1.addEventListener('click', function(){
alert('c1');
}, false);
//点击c2,结果为先弹出c2,再弹出c1
</script>
注:onblur / onfocus / onmouseenter / onmouseleave 没有冒泡
事件对象
*与微信小程序相似
<div></div>
<script>
var div = document.querySelector('div');
div.onclick = function(e) {
console.log(e);
}
//或
div.addEventListener('click', function(e){
console.log)(e);
});
</script>
常见的属性和方法
属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 |
e.srcElement | 同上,但ie6-8 |
e.type | 返回事件的类型,如click等 |
e.stopPropagation() | 阻止冒泡 |
e.cancelBubble | 同上,但ie6-8 |
e.preventDefault() | 阻止默认事件,如不让链接跳转 |
e.returnValue() | 同上,但ie6-8 |
*e.target返回的是触发事件的对象,而this返回的是绑定事件的对象
*e.currentTarget返回的是绑定事件的对象,与this相似
事件委托
原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
鼠标事件
禁止鼠标右键菜单
//contextmenu控制何时显示上下文菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault(); //阻止默认操作
});
禁止鼠标选中
document.addEventListener('selectstart', function(e) {
e.preventDefault(); //阻止默认操作
});
鼠标事件对象
//MouseEvent
document.addEventListener('click', function(e) {
console.log(e);
});
鼠标事件对象 | 说明 |
---|---|
e.clientX | 鼠标相对于浏览器窗口可视区域的X |
e.clientY | 同上 |
e.pageX | 鼠标相对于文档页面的X |
e.pageY | 同上 |
e.screenX | 鼠标相当于电脑屏幕的X |
e.screenY | 同上 |
键盘事件
- onkeyup - 按键被松开时触发
- onkeydown - 按键被按下时触发
- onkeypress - 按键被按下时触发 但不识别功能键 如Ctrl Shift等
执行顺序:down->press->up
键盘事件对象
//KeyBoardEvent
document.addEventListener('keyup', function(e) {
console.log(e);
});
四、BOM
1.window常见事件
窗口加载事件
当文档内容完全加载完成后触发的事件
传统:
<script>
window.onload = function() {
//语句
}
</script>
<div></div>
*传统的方式只能写一次,若有多个则以最后一个为准
*也可以使用addEventListener
window.addEventListener('load', function() {
//语句
})
当DOM加载完成时,触发下面的事件(不包括样式表 图片等)比load快 有兼容性
window.addEventListener('DOMContentLoaded', function() {
//语句
})
调整窗口大小事件
只要窗口大小发生改变,就会触发此事件
window.addEventListener('resize', function() {
})
*window.innerWidth来获取当前屏幕的宽度
2.定时器
setTimeout
setTimeout(调用函数, 间隔时间/毫秒);
//例 5秒后打印Time
setTimeout(function() {
console.log('Time');
}, 5000);
//调用函数可以直接写函数,也可以写函数名
*setTimeout()也是回调函数
停止定时器
window.clearTimeout(timeoutID);
<button>按钮</button>
<script>
var btn = document.querySelector('button');
var timer = setTimeout(function() {
//语句
}, 5000);
btn.addEventListener('click', funtion() {
clearTimeout(timer);
})
</script>
setInterval
setInterval(调用函数, 间隔时间/毫秒);
//每间隔设置的时间就会调用一次函数,即反复调用回调函数
停止定时器
window.clearInterval(IntervalID);
3.this的指向
- 全局作用域或普通函数 和定时器,this指向全局对象window
- 方法调用中,谁调用,this指向谁
- 构造函数中this指向构造函数的实例
4.同步和异步
同步任务
在主线程执行,形成一个执行栈
异步任务
通过回调函数实现
普通事件:click / resize…
资源加载:load / error…
定时器:setTimeout / setInterval
异步任务相关回调函数添加到任务队列中
*先执行同步任务,遇到异步任务则房屋队列中,等同步任务执行完,再依次执行异步任务
5.location对象
获取或设置窗体的URL,可用于解析URL
location对象属性 | 说明 |
---|---|
location.href | 获取或设置整个URL |
location.host | 返回域名 |
location.port | 返回端口,未写则返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数(?后面的内容,用&隔开) |
location.hash | 返回片段(#后面的内容) |
常见方法
location方法 | 返回值 |
---|---|
location.assign() | 跳转页面(可以回退) |
location.replace() | 替换当前页面(不可回退) |
location.reload() | 重新加载页面 |
6.navigate对象
//判断是移动端还是PC端浏览器,自动适配
if ( (navigator.userAgent.match( /(phonelpad|pod| iPhone |iPod| ios|iPad|Android lMobile|BlackBerry|IEMobile |MQQBrowser| JUC| Fennec |wOSBrowser| BrowserNG| webosl symbian |windows Phone)/i) )) {
window . location.href = ""; //手机
}else {
window . location.href = ""; //电脑
}
7.history对象
history方法 | 作用 |
---|---|
back() | 后退 |
forward | 前进 |
go(参数) | 1表示前进 -1表示后退 |
五、网页特效
1.offset
可以动态的获取元素的位置 大小等
属性 | 作用 |
---|---|
offsetParent | 返回元素带有定位的父级元素,若没有则返回body |
offsetTop | 返回元素相对带有定位父级元素上方的偏移 |
offsetLeft | 返回元素相对带有定位父级元素左边框的偏移 |
offsetWidth | 返回自身包括padding等的宽度,没有单位 |
offsetHeight | 返回自身包括padding等的高度,没有单位 |
2.client
返回元素的边框大小,元素大小等
属性 | 作用 |
---|---|
clientTop | 返回上边框的大小 |
clientLeft | 返回左边框的大小 |
clientWidth | 返回自身包括padding等的宽度,不含边框,没有单位 |
clientHeight | 返回自身包括padding等的高度,不含边框,没有单位 |
3.立即执行函数
不需要调用,直接执行
(function() {})()
//或者
(function() {}())
//第二个括号可以理解为调用
作用:独立创建了一个作用域
4.scroll
获取元素的大小,滚动距离等
属性 | 作用 |
---|---|
scrollTop | 返回被卷去的上侧距离,没有单位 |
scrollLeft | 返回被卷去的左侧距离,没有单位 |
scrollWidth | 返回自身实际的宽度(内容的宽度),不含边框,没有单位 |
scrollHeight | 返回自身实际的高度(内容的高度),不含边框,没有单位 |
5.mouseover和mouseenter的区别
两者都是鼠标经过元素触发
不同点在于,mouseover事件是只要经过元素即可触发,无论是否经过子元素
而mouseenter在经过此元素的子元素时不会触发
因为mouseenter不会冒泡
mouseenter-mouseleave
6.动画
原理:通过setInterval()不断移动盒子的位置
案例
div在移动了500px之后停止
<!--div宽高100px 绝对定位 deepskyblue-->
<div></div>
<script>
//获取元素
var div = document.querySelector('div');
//定时器
var timer = setInterval(function() {
if(div.offsetLeft >= 500) {
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 50)
</script>
封装成函数
<!--div宽高100px 绝对定位 deepskyblue-->
<div></div>
<script>
//获取元素
var div = document.querySelector('div');
function animate(obj, target) {
//先清除一次定时器避免执行多次导致出虫
clearInterval(obj.timer);
//用对象.属性的方式给不同的对象赋予不同的定时器
obj.timer = setInterval(function() {
if(obj.offsetLeft >= target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 50)
}
//调用函数
animate(div, 500);
</script>
缓动动画
原理:让盒子每次移动的距离变小
(目标位置 - 现位置)/ 10 作为每次移动的距离
例:实现div由快变慢的移动
<!--div宽高100px 绝对定位 deepskyblue-->
<div></div>
<script>
//获取元素
var div = document.querySelector('div');
function animate(obj, target) {
//先清除一次定时器避免执行多次导致出虫
clearInterval(obj.timer);
//用对象.属性的方式给不同的对象赋予不同的定时器
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
//步长需要取整 判断正负
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target) {
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 50)
}
//调用函数
animate(div, 500);
</script>
添加回调函数
<!--div宽高100px 绝对定位 deepskyblue-->
<div></div>
<script>
//获取元素
var div = document.querySelector('div');
function animate(obj, target, callback) {
//先清除一次定时器避免执行多次导致出虫
clearInterval(obj.timer);
//用对象.属性的方式给不同的对象赋予不同的定时器
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
//步长需要取整 判断正负
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft == target) {
clearInterval(obj.timer);
//回调函数的调用
if(callback) {
callback();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 50)
}
//调用函数
animate(div, 500, function() {
//语句
});
</script>
7.节流阀
当上一个函数动画执行完毕再去执行下一个动画
在动画函数例子中,利用回调函数
var flag = true;
if(flag) {
flag = false;
//语句
}
//在回调函数执行flag = true;
8.返回顶部
window.scroll(x, y);
六、本地存储
相当于把数据缓存在本地浏览器中
只能存储字符串
1.window.sessionStorage
-
生命周期为关闭浏览器窗口
-
在同一页面数据共享
-
键值对的形式存储
存储
sessionStorage.setItem(key, value);
可以在浏览器调试中的Applecation的Session Storage中找到
获取
sessionStorage.getItem(key);
删除
sessionStorage.removeItem(key);
删除所有
sessionStorage.clear();
2.window.localStorage
- 生命周期为永久生效,手动删除
- 可以多页面共享
- 键值对的形式存储
存储
localStorage.setItem(key, value);
获取
localStorage.getItem(key);
删除
localStorage.removeItem(key);
删除所有
localStorage.clear();