DOM事件
DOM事件,就是浏览器或用户针对页面可以做出的某种动作,我们称这些动作为DOM事件。它是用户和页面交互的核心。当动作发生(事件触发)时,我们可以为其绑定一个或多个事件处理程序(函数),来完成我们想要实现的功能。
总结一下,事件有三个要素:事件源(是谁发生了事情),事件类型(发生了什么事),事件处理程序(怎么应对)。
-
事件三要素
-
事件源:触发(被)事件的元素
-
事件名称: click 点击事件
-
事件处理程序:事件触发后要执行的代码(函数形式)
为了方便理解下面即将要讲解的内容,在正式开始之前,让我们先来了解一个最常用的事件:click,点击事件:当我们用鼠标点击页面时,如果我们为页面绑定了事件处理程序(一般是一个函数),那么这时该程序将被执行。
- 下面提供案例来演示:
<div class="button-group">
<button id="btn" class="button">按钮</button>
</div>
<script>
// 获取按钮元素
var btn = document.getElementById('btn');
// 事件绑定
btn.onclik = function(){
console.log('你终于点中我了...');
}
</script>
变量button就是一个(某个)对象,而onclick是由DOM本身所提供的的事件,对象属性或方法或设置的语法结构,在这个浏览器窗口中创建了一个监听器,这个监听器用来监听用户是否点击了这个button按钮,当用户点击了这个按钮,就会触发监听器,监听器调用对应的那个函数或方法。
事件监听器
DOM 标准规范提供的 addEventListener() 方法,调用该方法表示向指定元素添加事件监听器。
element.addEventListener(eventName,functionName.capture)
| 参数名称 | 描述 |
|---|---|
| eventName | 为元素指定具体的事件名称(例如单击事件是 click 等) |
| functionName | 注册事件的句柄 |
| capture | 设置事件是捕获阶段还是冒泡阶段。false 为默认值,表示冒泡阶段 |
<div class="button-group">
<button id="btn" class="button">按钮</button>
</div>
<script>
var btn = document.getElementById('btn');
btn.onclik = function(){
console.log('你终于点中我了...');
}
</script>
为指定元素添加事件监听器:addEventListener(eventName,callback) 参数:
eventName - 表示绑定的事件名称(注意:没有 on) callback - 表示事件的处理函数(回调函数) DOM 对象提供的事件属性,无法同时为一个指定元素绑定相同事件多次
btn.onclick = function() {
console.log('test');
}
btn.onclick = function() {
console.log('test2');
}
但是 DOM 允许相同元素绑定相同事件多次
btn.addEventListener('click',function(){
comsole.log('test3');
});
btn.addEventListener('click',function(){
comsole.log('test4');
});
事件监听器在浏览器中存在兼容问题(IE8 以下浏览器版本不支持)
可以利用attachEvent(eventName,functionName) 方法
- eventName 表示事件名称(注意:必须有 on )
- functionName 表示事件的处理函数
用法示例:
btn.attachEvent('onclik',function(){
console.log('text5');
});
浏览器兼容解决方案:
function bind(element,eventName,functionName){
if (element.addEventListener){
element.addEventListener(eventName,functionName);
} else {
element.attachEvent('on' + eventName,functionName);
};
};
事件监听器中的 this
当使用 addEventListener() 方法为某个HTML页面元素注册事件的时候,this 就指代注册事件的元素。
btn.addEventListener('click',function(){
console.log(this.text.Content);
})
当使用 attachEvent() 方法为某个 HTML 页面元素注册事件的时候,this 指代的是 window 对象,而不是注册事件的元素。
var btn = document.getElementById('btn');
btn.addachEvent('onclick',function(){
console.log(this); // 输出 [Object window]
})
由于 addEventListener() 方法中的 this 与 attachEvent() 方法中的 this 的含义不同,我们需要将监听器的浏览器兼容方案进行优化:
function bind(elem,event,callbcak){
// 判断是否存在 addEventListener
if (elem.addEventListener){
elem.addEventListener(event,callback,false);
} else {
elem.attachEvent('on' + event,function(){
// 将 this 的指向修改为注册事件的元素
callback.call(elem);
});
};
};
事件绑定方式
-
- 直接在DOM中绑定事件(行内式)
<input type="button" onclick="hello()">
<script>
function hello(){
console.log(this);
}
</script>
缺点: 这类事件不能移除且此方法this指向window
image.png
-
- 在js中添加事件处理程序(DOM0级别事件处理程序)
<input type="text" id="input">
<script>
let _input = document.getElementById('input')
_input.onchange = function() {
console.log(this)
}
</script>
优点:使得HTML和js代码完全分离,方法可以移除(赋值为null)
缺点: 不能同时处理多个事件
此时的this指向当前元素
-
- DOM2级事件处理程序(addEventListener)
element.addEventListener(event, function, useCapture)
event : (必需)事件名,支持所有DOM事件。
function:(必需)指定要事件触发时执行的函数。
useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。
//给一个元素添加一个事件监听器
box.addEventListener("click",function(){
console.log(1111)
})
console.log()
优点:
- DOM2级事件处理方法可以添加多个事件处理程序,多个事件相互不影响
- 事件可以移除。移除公式:元素节点.removeEventListener(事件名,函数名,事件流)
注意:移除时,函数的参数要与添加时一致,相应事件的函数不能是匿名函数
this指向当前元素,与元素属性绑定this指向一样
事件解绑
//解绑 行内和属性
box.onclick=null;
//监听器DOM级别2 解绑
box.removeEventListener("click",fn) //对应的函数名字
var btn = document.getElementById('btn');
function listener(){
console.log('你终于点中了我');
}
btn.addEventListener('click',listener);
btn.removeEventListener('click',listener);
注意:箭头函数无函数名是无法通过DOM二级解绑的,需要将函数名提出来命名
var btn=document.querySelector(".btn");
btn.addEventListener("click",()=>{
})
//处理方法
var btnfn=()=>{
};
btn.addEventListener("click",btnfn)
box.removeEventListener("click",btnfn)
移除事件在 IE8 及之前版本的浏览器都不支持
removeEventListener() 方法,而是单独提供了 detachEvent 方法。
var btn = document.getElementById('btn');
function listener(){
console.log('你终于点中了我');
}
btn.attachEvent('click',listener);
btn.detachEvent('click',listener);
js中的常用事件
鼠标事件
/*
onclick:点击某个对象时触发
ondblclick:双击某个对象时触发
onmouseover:鼠标移入某个元素时触发
onmouseout:鼠标移出某个元素时触发
onmouseenter:鼠标进入某个元素时触发
onmouseleave:鼠标离开某个元素时触发
onmousedown:鼠标按下时触发
onmouseup:鼠标抬起时触发
onmousemove:鼠标被移动时触发
onwheel:鼠标滚轮滚动时触发
oncontextmenu:点击鼠标右键时触发
*/
键盘事件
/*
onkeydown:键盘的键按下时触发
onkeyup:键盘的键放开时触发
onkeypress:按下或按住键盘键时触发
*/
框架/对象事件
/*
onresize:浏览器窗口大小改变时触发
onabort:图形的加载被中断时触发
onload:元素加载完时触发
onerror:当加载文档或者图片时(没找到)发生的错误时触发
onscroll:文档滚动时触发
onpageshow:用户访问页面时触发
onunload:用户退出页面时触发
*/
表单事件
/*
onfocus:元素获得焦点时触发
onblur:元素失去焦点时触发
onchange:元素内容改变时触发
oninput:元素获取用户输入时触发
onsubmit:提交按钮时触发
onreset:重置按钮时触发
onselect:文本被选中时触发
*/
拖动事件
/*
ondrag:元素正在拖动时触发
ondragend:用户完成元素拖动时触发
*/
多媒体事件
/*
onplay:在视频/音频开始播放时触发
onended:在视频/音频播放结束时触发
onpause:在视频/音频暂停时触发
*/
下面便简单介绍一些事件的信息:
鼠标事件
1, click:点击事件
等同于mousedown+mouseup,不管这两个事件间隔多久,都会触发一次click事件。
2, mousedown:鼠标按下事件
3, mouseup:鼠标弹起事件
4, mouseover/mouseenter:鼠标移入事件
5, mouseout/mouseleave:鼠标移出事件
注意:ES5添加的mouseenter和mouseleave阻止了事件冒泡。
6, mousemove:鼠标移动事件
7, contextmenu:右键出现菜单事件
8, selectstart:选中文字事件
小技巧:通过事件对象的button属性可以判断鼠标左右键,0:左键;1滚轮;2,:右键。另外,click事件只能由左键触发,只有mousedown和mouseup可以触发右键点击事件。
键盘事件
1,keydown:按键按下事件
可以检测所有按键,但不会返回字符编码。
2,keypress:按键按下事件
只能响应字符类按键,可以返回字符的编码,charCode属性。
3,keyup:按键弹起事件
输入框事件
1, input
每输入一次就会触发一次,即只要输入框的内容有变化都会触发该事件。
2, change
聚焦和失去焦点两个时刻内容不同才触发。
3, focus,获取焦点
当输入框获取焦点时触发
4, blur,失去焦点
当输入框失去焦点时触发
其他事件
1、scroll scroll:常用于绑定在window对象上,滚动鼠标时触发 window.onscroll=function
//wheel 它是鼠标的
2、load load:等待网页资源下载完毕再执行
img.onload 图片节点加载完毕不会调用 要资源加载完毕就会调用
window.onload:等待页面所有资源下载完成才执行,包括图片资源的下载,所以它是最慢的 网页加载顺序:url-->下载页面-->domTree,cssTree并行-->渲染树renderTree-->绘制页面-->继续下载图片资源,下载完毕再放到页面上去onload domTree:domTree的形成,是先把元素翻译成的节点对象挂到 domTree上去,再把属性 img_src放到渲染树上去
每年都考的面试题:用户从地址栏输入网址按下回车到页面展示出来 整个过程发生了什么? 答案:前端=>网络=>后端=>网络=>前端 这4步都得分析
var box=document.querySelector(".box")
box.addEventListener("click",()=>{
console.log("鼠标按下和松开时,鼠标指针在被选元素区域内部")
})
box.addEventListener("dblclick",()=>{
console.log("鼠标第一次按下和第二次松开时,鼠标指针在被选中内部 并且时间间隔不能太长")
})
var box=document.querySelector(".box")
box.addEventListener("mousedown",()=>{
console.log("鼠标在被选区域按下")
})
var box=document.querySelector(".box")
box.addEventListener("mouseup",()=>{
console.log("鼠标在被选区域松开")
})
var box=document.querySelector(".box")
box.addEventListener("mouseover",()=>{
console.log("鼠标进入被选元素")
})
var box=document.querySelector(".box")
box.addEventListener("mouseout",()=>{
console.log("鼠标从被选元素出去")
})
var box=document.querySelector(".box")
box.addEventListener("mouseleave",()=>{
console.log("鼠标从被选元素出去")
})
var box=document.querySelector(".box")
box.addEventListener("mouseenter",()=>{
console.log("鼠标从被选元素进去")
})
box.onwheel=function(){
console.log("鼠标滚轴滚动时 鼠标指针在被选区域元素内部")
}
var box=document.querySelector(".box")
box.addEventListener("scroll",()=>{
console.log("元素自己的滚动条:单位时间内滚动条的位置发生变动就会触发")
})
var box2=document.querySelector(".box2")
box2.addEventListener("keydown",()=>{
console.log("输入框的键盘按下")
})
var box2=document.querySelector(".box2")
box2.addEventListener("keyup",()=>{
console.log("输入框的键盘松开")
})
var box2=document.querySelector(".box2")
box2.addEventListener("keypress",()=>{
console.log("输入框的键盘按下")
})
var box2=document.querySelector(".box2")
box2.addEventListener("input",()=>{
console.log("输入框在输入就触发")
})
var box2=document.querySelector(".box2")
box2.addEventListener("change",()=>{
console.log("输入框失焦并且value改变")
})
var box2=document.querySelector(".box2")
box2.addEventListener("focus",()=>{
console.log("输入框获取焦时触发")
})
var box2=document.querySelector(".box2")
box2.addEventListener("blur",()=>{
console.log("输入框失焦时触发")
})
box2.focus()
//onload 加载完毕时执行
window.onload()=function(){
console.log("浏览器加载完毕:5大BOM功能加载完成")
}
在三维场景中有时候需要判断鼠标的事件,除了使用的click事件,只有鼠标左键有效,而右键无效。而对于onmousedown、onmouseup的时候鼠标的事件左键/右键有效。详细请看w3c上的资料。
以下总结鼠标三个按键操作:
首先,需要为window绑定mousedown、mouseup事件
元素对象.addEventListener('mousedown', 处理函数fun);
1
然后,判断button的值,button 事件属性可返回一个整数,指示当事件被触发时哪个鼠标按键被点击。
button: 返回当事件被触发时,哪个鼠标按钮被点击。
| 参数 | 描述 |
|---|---|
| 0 | 规定鼠标左键 |
| 1 | 规定鼠标中键 |
| 2 | 规定鼠标右键 |
function onMouseDown(event){
if (event.button == 0) {
console.log("鼠标左键!")
}else if (event.button == 2){
console.log("鼠标右键!");
}else if(event.button == 1){
console.log("鼠标滚轮!");
}
事件对象
事件对象上存储着事件发生时的相关信息(例如:event.which)
a) 事件处理函数形参ev(event),W3C制定的标准,IE9以下不行
b) 全局对象 window.event用于IE9以下
// 兼容性写法 var event= ev|| window.event
事件源对象:
鼠标的事件源对象
div.onmousedown = function(e) {
e = e || window.event //e表示事件源对象
//鼠标点击的键 button 0表示左键 1表示滚轮 2表示右键
console.log(e.button);
console.log(e.target); //目标元素 显示是div
console.log(e.type); //事件类型 click
console.log(e.x); //获取鼠标的x坐标 基于可视区域
console.log(e.y); //获取鼠标的y坐标 基于可视区域
console.log(e.pageX); //获取鼠标的x坐标 基于页面的可视区域
console.log(e.pageY); //获取鼠标的y坐标 基于页面的可视区域
console.log(e.offsetX); // 获取鼠标的x坐标 基于div偏移的x 离div这个盒子的左上角顶点
console.log(e.offsetY); // 获取鼠标的y坐标 基于div偏移的y 离div这个盒子的左上角顶点
console.log(e.screenX); //screen获取屏幕信息 在屏幕上的x
console.log(e.screenY); //screen获取屏幕信息 在屏幕上的y
console.log(e.clientX); //获取鼠标的x坐标 基于当前可视区域的x
console.log(e.clientY); //获取鼠标的x坐标 基于当前可视区域的y
console.log(e.path); //元素路径
console.log(e.ctrlKey); //判断是否按着ctrl键 按着为true 没有为false
console.log(e.shiftKey); //判断是否按着shift键 按着为true 没有为false
console.log(e.altKey); //判断是否按着alt键 按着为true 没有为false
}
键盘的事件源对象
window.onkeydown = function(e) {
e = e || window.event
console.log(e.key); //获取按键的值
console.log(e.code); //获取按键
console.log(e.keyCode); //获取按键的ascii码 不区分大小写(只返回大写)
console.log(); //判断是否按着ctrl键 按着为true 没有为false
console.log(e.shiftKey); //判断是否按着shift键
console.log(e.altKey); //判断是否按着alt键
console.log(e.charCode); //字符编码 只有在按字符的时候才有 一般是加给keypress事件
console.log(e.target); //目标元素 显示是body
console.log(e.type); //事件类型 keyDown
}
charCode/keyCode 键码值 key 键码
37左
38上
39右
40下
13enter
盒子模型
js中的盒子模型
clientHeight 高度+上下填充
clientWidth 宽度+左右填充
clientLeft 左边框宽度
clientTop 上边框宽度
offsetWidth 宽度+左右填充+左右边框 ==> clientWidth+左右边框
offsetHeight 高度+上下填充+上下边框 ==> clientHeight+上下边框
offsetLeft 当前元素距离父元素左偏移量
offsetTop 当前元素的外边框距离父级元素的内边框的上偏移量
scrollWidth 区别于clientWidth 内容+左填充,如果没有发生溢出就是和clientWidth相等的
scrollHeight 区别于clientHeight 内容+上填充
scrollTop滚动条向下滚动的距离;
scrollLeft滚动条向右滚动的距离;
还有一些,等我老师讲了来再更新盒子模型深入的知识。