js中DOM——事件

116 阅读11分钟

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);
             });   
         };
};

事件绑定方式

    1. 直接在DOM中绑定事件(行内式)
<input type="button"  onclick="hello()">
<script>
function hello(){
    console.log(this);
}
</script>

缺点: 这类事件不能移除且此方法this指向window

image.png

image.png

    1. 在js中添加事件处理程序(DOM0级别事件处理程序)
<input type="text" id="input">

<script>
    let _input = document.getElementById('input')
    _input.onchange = function() {
        console.log(this)
    }
</script>

优点:使得HTML和js代码完全分离,方法可以移除(赋值为null)
缺点: 不能同时处理多个事件

此时的this指向当前元素

image.png

    1. DOM2级事件处理程序(addEventListener)

element.addEventListener(event, function, useCapture)
event : (必需)事件名,支持所有DOM事件。
function:(必需)指定要事件触发时执行的函数。
useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。

//给一个元素添加一个事件监听器
        box.addEventListener("click",function(){
            console.log(1111)
        })
        console.log()

优点:

  1. DOM2级事件处理方法可以添加多个事件处理程序,多个事件相互不影响
  2. 事件可以移除。移除公式:元素节点.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  键码
37383940下 
13enter

盒子模型

js中的盒子模型
clientHeight 高度+上下填充
clientWidth 宽度+左右填充
clientLeft 左边框宽度
clientTop 上边框宽度
offsetWidth 宽度+左右填充+左右边框 ==> clientWidth+左右边框
offsetHeight 高度+上下填充+上下边框 ==> clientHeight+上下边框
offsetLeft 当前元素距离父元素左偏移量
offsetTop 当前元素的外边框距离父级元素的内边框的上偏移量
scrollWidth 区别于clientWidth 内容+左填充,如果没有发生溢出就是和clientWidth相等的
scrollHeight 区别于clientHeight 内容+上填充
scrollTop滚动条向下滚动的距离;
scrollLeft滚动条向右滚动的距离;

还有一些,等我老师讲了来再更新盒子模型深入的知识。