Javascript常用事件
JS 事件(event)是当用户与网页进行交互时发生的事情,例如单机某个链接或按钮、在文本框中输入文本、按下键盘上的某个按键、移动鼠标等等。当事件发生时,您可以使用 JavaScript 中的事件处理程序(也可称为事件监听器)来检测并执行某些特定的程序。
一般情况下事件的名称都是以单词on开头的,例如点击事件 onclick、页面加载事件 onload 等。下图中列举了一些 JavaScript 中常用的事件:
js中的事件分为0级事件和2级事件
0级事件表现形式如下:直接向元素添加事件,可以理解为带on的就是0级事件,0级事件存在覆盖问题,下边重新向元素绑定形同的事件,之前绑定的事件会被覆盖。
<div id="box"></div>
let box = document.queryseleter('#box');
box.onclick = () => {
console.log(1111);
};
box.onclick = () => {
console.log(2222);
};
2级事件表现形式如下:通过
addEventlistener方法添加的事件是唯一的,可以向元素添加多个相同的事件,不会被覆盖,addEventlistener接收三个参数,第一个参数为要绑定的事件(不用加on),第二个参数为一个回调函数,里面写事件触发要做的事情,第三个参数为true表示在捕获阶段触发,为false表示在冒泡阶段触发。
<div id="box"></div>
let box = document.queryseleter('#box');
box.addEventlistener('click',()=>{
console.log(666);
});
只有DOM2级事件包含三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,removeEventlistener:移除事件,需要将回调函数具名化
事件对象
事件对象为 event 对象,是一个内置全局对象,而 event 对象在 Firefox 不存在这个对象,对 Firefox 需要使用一个局部变量来接收有关事件的相关信息,在是事件对象中有很多属性,供我们使用.
使用event事件对象
<button id="btn"></button>
let btn = ducument.getElementById('#btn');
btn.addEventlistener('click',(ev)=>{
console.log(ev.target);//此处的ev就是事件对象
//ev.target指的就是点击的那个元素(实操的那个元素)也称为事件源
//client 是鼠标点击的位置 到浏览器视口的偏移量
//page 是鼠标点击的位置 到body的偏移量
})
事件的传播机制
当点击子元素的时候不单单会触发子元素的事件,还会触发父元素的事件。但是点击父元素就没有这种情况,事件冒泡是从里到外传播的,看的是节点之间的关系。在事件对象Event中的stoPpropagation可以阻止这一行为,
<div id="outer">
<div id="center">
<div id="inner">
</div>
</div>
</div>
//事件的冒泡传播 从里到外 看的是节点的关系
outer.onclick = function() {
console.log('点击了outer');
}
center.onclick = function() {
console.log('点击了centerr');
}
inner.onclick = function(e) {
e.stopPropagation(); //阻止冒泡
//当事件传播到outer之后 阻止继续向上冒泡
console.log('点击了inner');
}
阻止a标签的默认行为
<a href="baidu.com" id=“a”>
let a = document.getElementById('#a');
//先执行事件的回调函数 后走默认行为
a.onclick = (ev)=>{
ev.preventDefault();//点击a标签不再跳转
}
ev.preventDefault();与<a href="javascript:;"> 功能相同
事件对象练习
拖拽练习
<div id="box" style="width: 200px;height: 200px;background-color: pink;cursor: move;"></div>
//js部分
let x = 0,
y = 0; //用来存储盒子移动之前的偏移量的
let box = document.getElementById('box');
//鼠标按键按下
box.onmousedown = function(e) {
//pageX || pageY表示 鼠标距离body的偏移量
//startX || startY 表示盒子距离body的距离
this.startX = e.pageX;
this.startY = e.pageY;
//鼠标移动
document.onmousemove = function(e) {
let moveX = e.pageX - box.startX, // 鼠标的横向偏移
moveY = e.pageY - box.startY; // 鼠标的纵向偏移
box.style.transform = `translate(${moveX+x}px,${moveY+y}px)`
//盒子在移动的时候的偏移量 是她的基础偏移量+鼠标偏移量
}
//鼠标按键抬起
document.onmouseup = (e) => {
//按键抬起记录当前位置
x += e.pageX - this.startX;
y += e.pageY - this.startY;
//移除事件
document.onmousemove = null;
document.onmouseup = null;
}
}
京东放大镜
//css部分
<style>
#box {
width: 300px;
height: 300px;
border: solid 1px #ccc;
float: left;
position: relative;
}
#box img {
width: 100%;
height: 100%;
}
#box2 {
width: 600px;
height: 600px;
border: solid 1px pink;
float: left;
display: none;
overflow: hidden;
}
#box2 img {
width: 200%;
height: 200%;
}
.mask {
width: 100px;
height: 100px;
background: rgba(0, 0, 0, 0.3);
cursor: move;
position: absolute;
top: 0;
left: 0;
z-index: 30;
display: none;
}
</style>
//HTML部分
<div id="box">
<!-- 小图盒子 -->
<img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/121591/31/27770/108029/6264bf67E2566526f/0f6456a0160c2dae.jpg
">
<div class="mask"></div>
</div>
<div id="box2">
<!-- 大图盒子 -->
<img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/121591/31/27770/108029/6264bf67E2566526f/0f6456a0160c2dae.jpg
">
</div>
//js部分
<script>
(function() {
class magniFier {
constructor(id, id1) {
this.box1 = document.querySelector(id);
this.box2 = document.querySelector(id1);
this.img = this.box2.querySelector('img');
this.mask = this.box1.querySelector('.mask')
this.img.style.width = '300%';
this.img.style.height = '300%';
this.bindEvent();
}
bindEvent() {
this.box1.onmousemove = (e) => {
let obj = this.box1.getBoundingClientRect();
let x = e.clientX - obj.left - 50,
y = e.clientY - obj.top - 50;
if (x <= 0) x = 0;
if (y <= 0) y = 0;
if (x >= 200) x = 200;
if (y >= 200) y = 200;
this.mask.style.transform = `translate(${x}px,${y}px)`;
this.img.style.transform = `translate(${-x*6}px,${-y*6}px)`
}
this.box1.onmouseenter = () => {
this.box2.style.display = 'block';
this.mask.style.display = 'block';
}
this.box1.onmouseleave = () => {
this.box2.style.display = 'none';
this.mask.style.display = 'none';
}
}
}
window.magniFier = magniFier;
})();
new magniFier('#box', '#box2')
</script>
简易穿梭框
#box1 {
position: absolute;
width: 200px;
height: 400px;
background-color: antiquewhite;
top: 0;
left: 0
}
#box1 span {
display: inline-block;
padding: 10px;
cursor: move;
border-radius: 5px;
border: 1px solid #ccc;
}
#box2 {
position: absolute;
left: 300px;
width: 200px;
height: 400px;
top: 0;
background-color: aqua;
}
#box2 span {
display: inline-block;
padding: 10px;
border-radius: 5px;
border: 1px solid #ccc;
}
#btn {
width: 100px;
height: 50px;
border-radius: 15px;
background-color: cornflowerblue;
position: absolute;
top: 450px;
left: 200px;
}
<div id="box1">
</div>
<div id="box2">
</div>
<button id="btn">确定</button>
//js部分
let ary = [{
type: 'sex',
lable: '性别',
value: "男"
}, {
type: 'sex',
lable: '性别',
value: "女"
}, {
type: 'age',
lable: '年龄',
value: "10-30"
}, {
type: 'age',
lable: '年龄',
value: "30-60"
}, {
type: 'height',
lable: '身高',
value: ">180"
}, {
type: 'height',
lable: '身高',
value: "<180"
}, {
type: 'weight',
lable: '体重',
value: ">180"
}, {
type: 'weight',
lable: '体重',
value: "<180"
}]
let box2 = document.getElementById('box2'), //右侧容器
box = document.getElementById('box1'), //左侧容器
btn = document.getElementById('btn'), //按钮
moveTer = null; //被拖拽的元素
box.ondragstart = (e) => {
//拖拽事件 拖拽开始
moveTer = e.target
}
let obj = {};
box2.ondrop = function() {
//鼠标按键抬起
this.style.backgroundColor = 'aqua';
let ele = moveTer.cloneNode(true); //克隆当前节点(当前拖动的元素)
let n = ele.dataset.index; //获取元素自定义属性
ele.setAttribute('draggable', false); //设置拖动属性
//用新的把旧的顶替掉 防止标签重复
if (obj[ary[n].type]) {
let str = ary[n].lable; //二维数组属性名
let list = box2.querySelectorAll('span'); //已经在box2中的标签
[...list].forEach(item => {
if (item.innerText.includes(str)) {
//如果重复 删除旧的 添加新的
box2.removeChild(item);
box2.appendChild(ele);
}
})
} else {
//没有重复项 就直接添加
box2.appendChild(ele)
}
obj[ary[n].type] = ary[n].value;
console.log(obj);
}
box.ondragend = () => {
moveTer = null; //松手之后
}
box2.ondragenter = function() {
//鼠标进入 右侧容器变色
this.style.backgroundColor = 'pink'
}
box2.ondragleave = function() {
//鼠标离开 右侧容器变为初始颜色
this.style.backgroundColor = 'aqua'
}
box2.ondragover = function(e) {
//鼠标滑过
e.preventDefault();
}
let str = ``
ary.forEach((item, index) => {
str += `<span draggable="true" data-index="${index}">${item.lable}${item.value}</span>`;
box.innerHTML = str
})
事件委托
利用事件冒泡的机制我们可以只给父元素一个元素绑定事件,大大减少内存的消耗,事件委托的原理就是事件冒泡+事件源;
<ul id='ul'>
<li>1
<div>
<h2>wer</h2>
<div>
<div>666</div>
</div> <button>按钮<i>666</i></button></li>
<li>2
<div>
<h2>wer</h2>
<div>
<div>666</div>
</div> <button>按钮<i>666</i></button></li>
</ul>
let ul = document.queryselector('ul');
ul.onclick = function(e) {
let tar = e.target;
tar.qqq = 100
tar.setAttribute('qqq', 333)
while (true) {
console.log(tar);
if (tar.tagName.toLowerCase() == 'li') {
console.log(tar.innerHTML)
return;
} else if (tar.tagName.toLowerCase() == 'ul') {
return
} else {
tar = tar.parentNode
}
}
}
事件是js中非常重要的一个知识点,在我们日常的日常开发中使用非常频繁,事件是在编程时系统内发生的动作或者发生的事情,系统响应事件后,如果需要,可以用某种方式对事件做出回应。例如:如果用户在网页上单击一个按钮,您可能想通过显示一个信息框来响应这个动作。