目录
一、事件event
1.insertBefore
【父元素.insertBefore(目标元素,参照元素)】:将目标元素添加至指定的参照节点之前
实例:oUl.insertBefore(oLi, oUl.children[2]);
2.滚动条事件【window.onscroll】
window.onscroll = function() {
// 如何获取滚动条高度?兼容性的获取浏览器滚动条高度===>
var _top = document.body.scrollTop || document.documentElement.scrollTop;
// }
应用:回到顶端
3.事件构成的三要素【事件元素、事件类型、事件对象】
// 事件元素:触发事件的元素
// 事件类型:是什么类型,onclick,ondblclick,onmouseover等等
// [事件对象]:不是必须的,但它携带者该事件相关的属性和方法,事件对象的产生必须有事件
兼容性获取事件对象===>
document.onclick = function(evt) {
var e = evt || event;
console.log(e);
}
4.鼠标事件对象的属性
page:针对页面【滚动条总页面】的左顶点【常用】
console.log("page:" + e.pageX + "," + e.pageY);
client:针对于局部窗口【当前窗口】的左顶点【不常用】
console.log("client:" + e.clientX + "," + e.clientY);
offset:针对于最近父元素的左顶点 通常和拖拽效果连用
console.log("offset:" + e.offsetX + "," + e.offsetY);
案例:图片跟随鼠标移动
//1.一个元素如果要在页面上发生位移,必须position: absolute
//2.一个元素如果发生位移,其本质改变的就是DOM对象.style.的left,top
//3.将鼠标坐标赋值给元素的left和top,元素位移就随着鼠标改变
实例:小老虎跳一跳 :oTiger.style.top = oTiger.offsetTop - 200 + "px";
5.键盘事件及对象
键盘事件所有的事件元素,通常默认为document
// 键盘弹起的时刻触发===>document.onkeyup
// 只要键盘按下,就触发该事件===>document.onkeydown
// 产生一个字符串时,触发事件===>document.onkeypress
兼容性的获取键盘按下字符的ascii码值===>
var key = e.keyCode || e.which || e.charCode;
console.log(key);
console.log(String.fromCharCode(key));
// 13 32 48 65 97 10
//回车 空格 "0" "A" "a" ctrl+回车
6.事件流
事件在传递时,父子同类型的事件,会由子元素向父元素, 或由父元素向子元素进行事件的传播。
// 冒泡: 子传父 (传递方式,默认就是冒泡)
// 捕获: 父传子 (用的很少,后续再去学习)
阻止事件流的传递
兼容性阻止事件冒泡===>
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
7.阻止浏览器默认事件
举例:a标签有默认点击行为,默认行为要刷新页面
// var oA = document.querySelector("a");
阻止浏览器默行为===>
e.preventDefault ? e.preventDefault() : e.returnValue = false;
在函数体中等价于===>return false;
补充:oncontextmenu:鼠标右键
8.事件绑定的方式
(1)通过HTML元素直接绑定
<button οnclick="fun()">点击</button>
// function fun() {
// console.log("油价又要涨了");
// }
(2)通过JS对象实现绑定
// var oBtn = document.getElementById("btn");
// oBtn.onclick = function() {
// console.log("春天到了,万物复苏...");
// }
缺陷
//a.不能为同一个元素多次绑定同样的事件
//b.无法决定事件流是冒泡还是捕获
(3)事件的监听
事件元素.addEventListener("去掉on的事件类型",回调函数,捕获?冒泡?)
备注:【true=捕获,false/省略=冒泡】
好处:1.可以为相同的元素多次绑定相同的事件
2.可以决定事件流的传递是冒泡还是捕获。 当捕获和冒泡同时存在,先捕获,后冒泡。
9.取消事件的绑定
注意事项,绑定和解绑必须是同一个方法
<button>点击</button>
var fun = function() {
console.log("heihei");
}
document.addEventListener("click", fun);//事件监听来进行事件的绑定
document.removeEventListener("click", fun);//事件解绑==针对事件的监听
10.事件委托
// 委托:你的事让别人干
事件委托:子元素的事件,由父元素完成功能实现,依赖于事件冒泡.
// 好处:1.可以为批量相同的元素快速绑定事件,提高运行效率
//好处2:通过事件委托,可以为未来的子元素,提前绑定事件
oUl.addEventListener("click", function(evt) {
//获取真实的操作源
var e = evt || event;
var target = e.srcElement || e.target;
//tagName:被点击的真实操作源的名字
console.log(target.tagName);
if (target.tagName == "LI") {
target.style.backgroundColor = "greenyellow";
}
});
11.拖拽案例【offsetX、offsetY边界问题】
οnmοusedοwn==========oBox要拖拽的盒子
οnmοusemοve========== document
οnmοuseup============ document
<script>
var oBox = document.querySelector("#box");
oBox.onmousedown = function(evt) { //鼠标按下盒子时
var e = evt || event;
//鼠标点击某个对象时的内部偏移量,为了获得内部元素距离其左顶点坐标
var offsetX = e.offsetX;
var offsetY = e.offsetY;
document.onmousemove = function(evt) { //跟随窗口移动
var e = evt || event;
// 真正距离父元素左侧的距离
var left = e.pageX - offsetX;
var top = e.pageY - offsetY;
if (left < 0) {
left = 0; //左边临界点
}
var maxLeft = innerWidth - oBox.offsetWidth; //页面宽度-盒子本身宽度
if (left >= maxLeft) {
left = maxLeft; //右边临界点
}
if (top < 0) {
top = 0; //上边临界点
}
var maxTop = innerHeight - oBox.offsetHeight; //页面高度-盒子本身高度
if (top >= maxTop) {
top = maxTop; //下边临界点
}
oBox.style.left = left + "px";
oBox.style.top = top + "px";
console.log(left, top);
oBox.innerHTML = "(" + oBox.style.left + "," + oBox.style.top + ")";
}
document.onmouseup = function() {
document.onmousemove = null;
}
}
//页面的宽和页面的高
console.log(innerWidth, innerHeight);
</script>
二、正则表达式
1.正则表达式的概念
即:字符串的规范格式
2. 正则的作用
正则表达式(regular expression)是一个描述字符规则的对象。如:只能出现字母,只能出现数字,前三个必须是数字等。
前端往往有大量的表单数据校验的工作,采用正则表达式会使得数据校验的工作量大大减轻,如邮箱验证,手机号码,等等。比起用字符串的函数来判断简单,易用。
3.正则对象的创建以及使用
(1)构造方法
// var reg = new RegExp("格式字符串","[修饰符]");
举例:
// var reg = new RegExp("a"); //至少包含一个a
// var reg1 = new RegExp("aaa"); //至少包含aaa,一定是连续的
(2)字面量
// var reg = /格式字符串/修饰符;
注意事项:以下场景必须用构造方法
var arr = ["heihei", "123", "haha"];
// var reg = /arr[0]/;错误
var reg = new RegExp(arr[0]);正确
4.格式字符串
格式字符串:普通字符+特殊字符
// 普通字符:看起来是啥就是啥
// 特殊字符:a.单个字符
// b.组合字符
// c.各种括号
单个字符
^:正则开始
$ : 正则结束
. : 元字符, 表示任意一个字符
\. : 表示转义字符 \.表示.
+: 表示其前面紧挨着的字符至少出现1次 等价{1,}
* :表示其前面出现的字符至少出现过0次 等价{0,}
?: 表示其前面出现的字符至少出现过0次,至多1次 等价{0,1}
| : 表示或者
组合字符:
\d : 0-9之间的任意一个数字 \d只占一个位置
\D : 除了\d
\w : 数字,字母 ,下划线 0-9 a-z A-Z _
\W : 除了\w
\s : 空格空白等
\S : 除了\s
各种括号
{m,n}表示括号前面紧挨着的字符至少出现m个,至多出现n个 :
{m}表示括号前面紧挨着的字符只能出现m个
{m,}表示括号前面紧挨着的字符至少出现m个
[] 表示括号内的任意一个字符
[a-z]表示任意一个小写字母 [a-zA-Z0-9]
[^ ]表示非括号内的任意一个字符
()一般与“或”连用 表示优先级
[\u4e00-\u9fa5] 任意一个中文字符
5.表单验证
action:提交数据的服务器文件
method:提交数据的方式
get默认:五菱宏光,效率高, 安全性低,携带数据量小 (查)
post:武装押运,效率低,安全性高,携带数据量大 (除了查)
6.正则中的相关方法及属性
(1)正则相关的方法只有test和exec
test
// 功能:判断目标字符串是否满足正则对象
// 参数:test(目标字符串)
// 返回值:布尔值
exec
// 功能:返回目标字符串符合正则对象的子串
// 参数:exec(目标字符串)
// 返回值:符合正则对象的子串,存储在长度为1的数组中
(2)修饰符: g全局,添加g的正则对象,可以对目标字符串按顺序执行
// var reg = /\d+/g;
// var str = "12ab34cd56ef";
// console.log(reg.exec(str)[0]);//12
// console.log(reg.exec(str)[0]);//34
// console.log(reg.exec(str)[0]);//56
(2)字符串的方法[search和match]
正则对象作为参数=====search和match
// var str = "dengyiwen de ge bi shi dengyiwen";
// str = str.replace(/dengyiwen/g, "老王");
// console.log(str);//老王 de ge bi shi 老王
search方法 返回与正则表达式查找内容匹配的第一个子字符串的位置
// 用法:str.search(reg)
// var str = "hellOWOrld";
修饰i:忽略大小写
// var reg = /owo/i;
// console.log(str.search(reg));
match方法
// 功能:返回所有符合正则对象的子串
// 参数:match(正则对象)
// 返回值:所有符合正则对象的子串,存放在数组中
var reg = /\d+/g;
var str = "12ab34cd56ef";
console.log(str.match(reg));
三、ES6新增语法
1.Let
let:它是用来定义变量的关键字(和var具备同样的功能)
// 1.let定义的变量必须先定义后使用
// 2.在同一作用域下,let修饰的变量不能重复定义
// 3.暂时性死区:当内部变量与外部变量同名时,内部变量屏蔽外部变量
//4.块级作用域:在当前作用域内的数值不会消失
for (let i = 0; i < oLis.length; i++) {
oLis[i].onclick = function() {
console.log(i);//取到每一个li元素
}
}
2.const
1.const:被const修饰的变量称为只读变量(有名字的常量)
// const PI = 3.1415926;
// console.log(PI);
2.被const修饰的变量必须初始化
// const A;//错误
// A = 1232;
// console.log(A);
后四点同Let====================>
3.块级作用域
4.暂时性死区
5.不能重复定义
6.先定义后使用,习惯上只读变量名全都大写
面试题:var,let,const的异同?
//1.都是用来修饰变量的
//2.var具备声明提升
//3.let4个特性
//4.const修饰的变量称为只读变量,必须初始化,其他4个特性,习惯上只读变量名全都大写
3.this和bind
this:函数体内的内置对象
// a.当this出现在事件函数体时,this代表触发该事件的元素
//b.与普通函数连用时(除了构造方法和事件体),代表调用该函数的对象本身
bind:是函数对象的函数,改变函数的this指向,主要针对于匿名函数
// 参数:bind(被修改的this指向)
// fun == function(){}
// fun.bind(参数) = function(){}.bind(参数)
4.JSON对象和字符串的相互转换
必须是标准格式的json对象和字符串:标准格式的json的key必须被双引号引起来
// JSON对象转字符串============================
//语法: JSON.stringify(json对象):返回json字符串
举例:let json = {
"name": "刘昊然",
"age": 88
};
let str = JSON.stringify(json);
console.log(typeof str, str);
//JSON字符串转对象===========================
//语法: JSON.parse(json字符串):返回json对象
举例:let str1 = '{"name": "刘昊然","age": 88}';
let json1 = JSON.parse(str1);
console.log(json1);
5.for...in...和for...of...
for...in 遍历下标 通常用来遍历json
let json = {
"name": "刘昊然",
"age": 88
};
for (let index in json) {
console.log(index); //name age
}
for...of 遍历内容(针对于没有下标的容器,set和map后续章节讲解)
// let arr = [6, 5, 7, 8, 4, 9, 0, 3];
// for (let item of arr) {
// console.log(item);//6 5 7 8 4 9 0 3
// }
6.字符串扩展方法
// str.includes(参数): 返回布尔值,表示是否找到了参数字符串。
// str.startsWith(参数):返回布尔值,参数是否在源字符串的头部。
// str.endsWith(参数): 返回布尔值,参数是否在源字符串的尾部。
举例:
let str = "jin tian bu da zhang le.txt";
console.log(str.includes("da1")); //fa1se
console.log(str.startsWith("jin")); //true
console.log(str.endsWith(".txt")); //true
生僻汉字的打印
//ES6之前打印汉字的方式是utf-16====== // 0~65535
// let str = "豆文博";
// console.log(str.charAt(0));
// let str = "𡱖";【21C56】
// //打印字符
// console.log("\u{21C56}");
// //打印unicode码
// console.log(str.codePointAt(0).toString(16));
7.箭头函数
箭头函数:匿名函数的另一种写法
箭头函数的特性:
1.如果匿名函数只有一个参数,则可以省略参数的小括号()
2.如果匿名函数的函数体只有一条语句,则可以省略{}
3.如果匿名函数的函数体只有一条语句,自带return
8.解构赋值
解构赋值:解析结构进行赋值
1.按照容器格式初始化对象:强调等号左边和右边必须类型一致
去掉json对象的前缀
let {
name,
age
} = json;
console.log(name); //迪丽热巴
console.log(age); //30
2.交换两个变量的值
let a = 1,
b = 2;
[a, b] = [b, a];
console.log(a, b);//2 1
9.ES6字符串模板
// ES6添加变量
// ``[英文状态下数字1前面的“波浪”]
// 支持换行, //``的变量必须用${变量}
for (let i = 0; i < 10; i++) {
//``的变量必须用${变量}
oUl.innerHTML += `<li>${i}</li>`;
}
10.兼容写法
1.事件对象的兼容:
var e = evt || event;
2.兼容性的获取浏览器滚动条高度
var _top = document.body.scrollTop || document.documentElement.scrollTop;
3.获取键盘asc码的兼容写法:
var key = e.keyCode || e.which || e.charCode;
4.阻止冒泡事件的兼容写法:
e.stopPropagation?e.stopPropagation():e.cancelBubble = true;
5.阻止浏览器的默认行为:
e.preventDefault?e.preventDefault():e.returnValue = false;
6.事件委托的兼容方法:
var target = e.srcElement || e.target;
11.set
set: 自动去重, 没有下标
语法:let set = new Set(数组);
// let set = new Set([1, 2, 3, 3, 2, 4, 5, 2, 4]);
set集合的方法:
// add(参数) 向集合中添加一个元素
// delete(值) 删除集合中某个数
// has(值) 判断集合中是否含有某个值
// clear() 清空集合
数组去重
// let arr = [1, 2, 3, 3, 2, 4, 5, 2, 4];
// let set = new Set(arr);
// // Array.from(set):将set转换为数组
// arr = Array.from(set);
// console.log(arr);
遍历
// let set = new Set([1, 2, 3, 3, 2, 4, 5, 2, 4]);
// for (let item of set) { //for...of...遍历内容
// console.log(item);
// }
11.map
map映射:通过简单的key操作较为复杂的value,只能通过key操作value,且key是唯一的
// set(key,value) 向集合中添加一个元素:key以存在,则为改,不存在则为增
// get(键) 根据键去取值
// delete(键) 删除集合中某个数
// has(键) 判断集合中是否含有某个值
// clear() 清空集合
12.运动
匀速、往返运动:通过obj.offsetLeft的边距随着定时器不断运动,成就了运动着的盒子
let time = null;
function startMove(obj, target) {
clearInterval(time);
time = setInterval(function() {
let speed = target > obj.offsetLeft ? 5 : -5;
obj.style.left = obj.offsetLeft + speed + "px";
if (obj.offsetLeft == target) {
clearInterval(time);
}
}, 50);
}
缓冲运动:
let time = null;
function startMove(obj, target) {
clearInterval(time);
time = setInterval(function() {
// 核心算法照抄
let speed = (target - obj.offsetLeft) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
obj.style.left = obj.offsetLeft + speed + "px";
}, 50);
}