事件

事件

一、事件概述:

用户在浏览器上触发一个操作,浏览器上会执行相关的函数进行处理称为事件。

事件是一个流程,就是一个监听一个触发,整个过程的描述。

二、事件的模式

1、内联模式

<div onclick='方法名()'></div>

2、脚本模式

document.queryseletor('div').onclick = function(){
//操作
} //也会被解析为内联

内联里面调用的方法的this会指向window(传递this)脚本模式的this会指向当前的调用者

三、事件的分类

1、鼠标事件(鼠标触发的 mouse开头的都是鼠标事件)

  • click 单击事件
  • dblclick 双击事件
  • mousemove 鼠标移动事件
  • mouseover 鼠标移进 (自己及自己里面的都能触发)
  • mouseout 鼠标移出
  • mouseenter 鼠标移进 (只会是自己可以触发)
  • mouseleave 鼠标移出
  • mousedown 鼠标按下
  • mouseup 鼠标弹起
 <style>
        div{
            width: 500px;
            height: 500px;background-color: pink;
        }
    </style>
     <div>
        <button>
            儿子
        </button>
    </div>
    <script>
        document.onclick = function(){
            console.log('单击了');
        }
        document.ondblclick = function(){
            console.log('双击了');
        }
        document.onmousemove = function(){
            console.log('鼠标移动');
        }
        var box = document.querySelector('div')
        box.onmouseover = function(){//对应的子元素也可以触发
            console.log('over移进');
        }
        box.onmouseout = function(){//对应的子元素也可以触发
            console.log('out移出');
        }
        box.onmouseenter = function(){//只有自己能触发
            console.log('enter移进');
        }
        box.onmouseleave = function(){//只有自己能触发
            console.log('leave移出');
        }
        box.onmousedown = function(){
            console.log('按下');
        }
        box.onmouseup = function(){
            console.log('弹起');
        }
        box.onclick = function(){
            console.log('点击');
        }
        // 鼠标右击事件(不会触发点击事件)
        box.oncontextmenu = function(){
            console.log('右键点击');
        }
        // 点里面会触发外面的元素的点击事件 这种叫事件冒泡(逐层向上冒泡)
        // 除非是输入框 不然是不能调用键盘事件 都是window的
        window.onkeydown = function(){
            console.log('键盘按下');
        }
        window.onkeyup = function(){
            console.log('键盘弹起');
        }
        window.onkeypress = function(){
            console.log('字符键按下');
        }
    </script>

2、键盘事件(键盘触发 key开头的都是键盘事件)

  • keyup 弹起
  • keydown 按下
  • keytpress 字符键按下
//除非是输入框 不然是不能调用键盘事件 都是window的
window.onkeydown = function(){
console.log('键盘按下');
}
window.onkeyup = function(){
console.log('键盘弹起');
}
window.onkeypress = function(){
console.log('字符键按下');
}

3、HTML事件(系统事件 被动触发的事件)

  • load 加载
  • close 关闭
  • change 输入框的value值发送表示
  • select 只有输入框才能触发 (选择里面的内容)
  • focus 获取焦点
  • blur 失去焦点
  • reset 重置
  • submit 提交
  • scorll 滚动条滚动
 <input type="text">
    <form action="">
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>
    <div style="height:1500px"></div>
<script>
    // load 窗口的加载 图片的加载 等等
    window.onload = function(){
        console.log('窗口的加载');
    }
    window.onunload = function(){//清除对应的内存 销毁
        console.log('窗口的卸载');
    }
    window.onclose = function(){
        console.log('窗口的关闭');
    }
    var input = document.querySelector('input')
    input.onchange = function(){
        console.log('value值变化了');
    }
    input.onselect = function(){
        console.log('当前内容被选择了');
    }
    input.onfocus = function(){
        console.log('获取焦点');
    }
    input.onblur = function(){
        console.log('失去焦点');
    }
    document.querySelector('form').onsubmit = function(){
        console.log('表单提交');
    }
    document.querySelector('form').onreset = function(){
        console.log('表单重置');
    }
    window.onscroll = function(){//每次滚动的距离
        console.log('滚动条滚动');
    }
</script>

四、事件的组成

触发者.on+对应的事件名 = 处理的函数 对应的事件组成
触发者 一般来说是对应的元素对象
事件名 就是上述分类的事件名
处理函数 由自己定义的函数(handler)(这个函数是事件驱动执行)

五、event(事件源)

关于事件的组成    元素.on事件名 = 处理函数

  • 处理函数 是一个function 作为一个function 他具备一个arguments(参数数组
  • 因为arguments[0] 是获取第一个参数 那么我在对应的处理函数里面写一个参数这个参数不就是对应的arguments[0]
  • 我们发现对应的arguments[0] 返回的对应对象是一个event类型的对象 所以我们可以猜出来他设计了一个名event的对象 而这个对象同时又是全局的对象 所以他归属于window 所以我们可以写成 window.event 或者 省略对应的window(event)
//e是形参 相当于第一个形参 常见的写法 这个形参名字叫 e 或者 event
window.onkeydown = function(e){
console.log(e); //这个就是arguments[0] event类型对象
//他设计一个event对象 他是一个全局的变量 window.event
//ie为了兼容 我们会写出
e = e || window.event //兼容写法
console.log(e.altKey);
console.log(e.key);
}

六、属性

1、坐标相关的属性

  • x 得到鼠标的x坐标(不包含不可视区域)
  • y 得到鼠标的y坐标 (不包含不可视区域)
  • pageX 得到鼠标在页面上的x坐标 (包含不可视区域)
  • pageY 得到鼠标在页面上的y坐标 (包含不可视区域)
  • clientX 得到鼠标在可视区域内的x坐标 (不包含不可视区域)
  • clientY 得到鼠标在可视区域内的y坐标 (不包含不可视区域)
  • offsetX 得到鼠标在偏移元素内容的x坐标 (当前添加事件的元素里面的坐标 不包含border)
  • offsetY 得到鼠标在偏移元素内容的y坐标 (当前添加事件的元素里面的坐标 不包含border)
  • layerX 默认是得到鼠标基于页面的x坐标 当你添加定位以后他是基于定位元素的坐标
  • layerY 默认是得到鼠标基于页面的y坐标 当你添加定位以后他是基于定位元素的坐标
  • screenX 得到鼠标在屏幕的上的x坐标
  • screenY 得到鼠标在屏幕上的y坐标

 

 

<style>
    *{
        padding: 0;
        margin: 0;
    }
    .box{
        width: 300px;
        height: 300px;
        background-color: skyblue;
        position: relative;
        left: 20px;
        top: 30px;
    }
    .btn{
        width: 50px;
        height: 50px;
        background-color: pink;
        position: absolute;
        left: 70px;
        top: 80px;
    }
</style>
<div class="box">
        <div class="btn">
            我是按钮
        </div>
    </div>
<script>
    document.querySelector('.btn').onclick = function(){
        console.log(arguments);
        console.log(arguments[0]);//取出里面的第一个元素
        // 这个对象他具备一些属性 可以获取
        console.log(arguments[0].x);//鼠标的x坐标 不包含不可视区域
        console.log(arguments[0].y);//鼠标的y坐标
        console.log(arguments[0].pageX);//页面上的x 包含不可视区域
        console.log(arguments[0].pageY);//页面上的y
        console.log(arguments[0].layerX);//layer默认以body作为位置定位 当你加上定位以后就是基于自己
        console.log(arguments[0].layerY);
        console.log(arguments[0].clientX);//当前页面的鼠标x坐标 不包含不可视区域
        console.log(arguments[0].clientY);
        console.log(arguments[0].offsetX);//偏移的鼠标x坐标 没有算上对应的父元素的margin以及自身的border
        // 得到当前点击元素内容的坐标(当前添加事件的元素里面的坐标,基于自身)
        console.log(arguments[0].offsetY);//偏移的鼠标x坐标
        // 屏幕坐标
        console.log(arguments[0].screenX);//屏幕的x坐标
        console.log(arguments[0].screenY);//屏幕的y坐标
        
        </script>

2、按键相关的属性

  • altKey 是否长按alt键
  • ctrlKey 是否长按ctrl键
  • shiftKey 是否长按shift键
// 按键相关的属性 有没有按下(长按不松开)对应的键(布尔类型)
        console.log(arguments[0].altKey);//有没有按下alt键
        console.log(arguments[0].ctrlKey);//有没有按下ctrl键
        console.log(arguments[0].shiftKey);//有没有按下shift

3、鼠标相关的内容(只有鼠标触发的事件有)


button 返回的值为number类型(0 表示左键 1表示中间 2表示右键)

// 鼠标相关的内容
        // button 返回的值为number类型(0表示左键 1表示中建 2表示右键(默认右键触发菜单,不会触发3))
        console.log(arguments[0].button);

4、事件触发的相关属性

  • type 事件类型 返回对应的事件名
  • target 目标元素
  • 返回真实触发的事件元素
  • currentTarget 目标元素 返回当前添加事件的元素
  • bubbles 事件是否冒泡
// 事件触发的相关属性
        console.log(arguments[0].type);// 事件触发类型 返回对应事件名
        console.log(arguments[0].target);//目标对象 表示事件触发真实的触发元素 子元素,自己本身
        console.log(arguments[0].currentTarget);//目标对象 表示事件触发的元素(对应的加事件的元素 父元素)
       console.log(arguments[0].bubbles);//是否冒泡

5、键盘事件相关的内容(需要键盘来触发的事件)

  • key 属性 (当前按下的键)
  • keyCode 属性 (获取当前按下键大写的ascii码)
  • charCode 属性(字符键 press事件 ascii码)
 // 打印完,我们可以看到argements具备一个参数 是一个对象(pointterEvent)
     // 键盘相关的内容(需要键盘来触发的事件)
    window.onkeydown = function(){
        console.log(argumengts[0]);
        console.log(arguments[0].key);//当前按下的键
        console.log(arguments[0].keyCode);//当前按下的键的大写的ASCII码
        console.log(arguments[0].charCode);//字符键 press 按下的是36个英文字母显示0
    }

另一种写法

 // e是形参 相当于第一个形参 常见的写法 这个形参的名字叫e或者叫event
    window.onkeydown = function(e){
        console.log(e);//这个就是arguments[0] event类型对象
        // 他设计了一个event对象 他是一个全局的变量 window.event
        // ie为了兼容 我们会写出
        console.log(e.altKey);//兼容写法
        console.log(e.key);
    }

七、事件流

1、概述:

事件流指代的是事件的执行流程,多个盒子嵌套相同事件,这个时候你触发一个盒子的事件,并不会只执行一个盒子的事件的处理函数,而是全部执行。

2、事件流的两种模式

(1)冒泡模式(浏览器采用的)

冒泡模式指代的是事件从里到外逐个执行
阻止事件冒泡

  • e.stopPropagation() 函数 (*)(stop)
  • e.cancelBubble = true 属性设置(现在虽然都可以用 但是未来可能会废弃)

兼容写法

e.stopPropagation?e.stopPropagation():e.cancelBubble = true

(2)捕获模式
捕获模式指代的是事件从外到里逐个执行

3、默认行为

(1)概述:

就是一个元素或者标签自身带的行为称为默认行为。比如a标签的跳转,form标签的submit按钮提交之后会自动刷新页面,鼠标右击会出现一个菜单栏等一系列

有些时候我们不需要这些默认行为是产生,我们就需要阻止默认行为

(2)阻止默认行为的js实现

  • e.preventDefault() 函数 (*) (prevent)
  • e.returnValue = false ie的兼容
  • return false 直接结束对应的操作
e.preventDefault?e.preventDefault():e.returnValue = false //兼容

4、拖拽

(1)思路

  • 给拖拽的元素添加mousedown的事件 记录当前点击的位置
  • 给对应的容器添加mousemove事件 记录每次移动的位置
  • 给对应的容器添加mouseup 事件 清除上述mousemove事件

(2)代码实现

<style>
    div{
        width: 200px;
        height: 200px;
        background-color: pink;
        position: absolute;
    }
</style>
<div id="box"></div>
<script>
    // 获取div
    var box = document.getElementById('box')
    // 给div添加mousedown事件
    box.onmousedown = function(e){
        e = e||event
        // 记录鼠标在div里面的位置
        // 在mousedown里面记录按下的位置
        // var x = e.offsetX
        // var y = e.offsetY
        var x = e.pageX-box.offsetLeft
        var y = e.pageY-box.offsetTop
        box.onmousemove = function(e){
            e=e||event
            var currentX = e.pageX
            var currentY = e.pageY
            box.style.left = currentX-x + 'px'
            box.style.top = currentY-y + 'px'
        }
        box.onmouseup = function(){
            box.onmousemove = null
    
        }
    }
</script>

5、样式获取

style属性 只能获取标签内容style属性里面存在的一些样式
如果你需要获取对应的全局所有地方设置样式 我们就需要采用一些方法

(1)getComputedStyle 方法属于window的方法

window.getComputedStyle(元素对象,null) //返回给你的是一个样式对象

(2)ie兼容

element.currentStyle //返回给你一个样式对象

(3)兼容封装

//方法的封装
function getStyle(element,attr){
var style = window.getComputedStyle?window.getComputedStyle(element):element.currentStyle
return style[attr]
}
//调用
console.log(getStyle(box,'height'));

八、事件回顾总结

1、事件委托

概述: 将对应的子元素的事件添加给父元素,用e.target来获取真实操作的元素 从而完成相关的操作(不能用到事件委托的 mouseenter 和 mouseleave 以及 mousemove..)

//事件委托 利用父元素添加事件 通过e.target获取真实的操作元素来进行相关的操作
//当你有许多需要同时添加一个事件行为的同级元素 这个时候我们不给这些元素加事件
// 而是给他的父元素添加事件 称为事件委托
gameList.onmouseover = function(e){
e = e || event
//控制对应的li标签的背景颜色变化 得到实际的触发对象 target
if(e.target.nodeName == 'LI'){
//先排他
for(var i=0;i<games.length;i++){
this.children[i].style.backgroundColor = 'black'
}
e.target.style.backgroundColor = 'red'
}
}
// 5, 选择某一项, 将顶部的名称改成你选择的游戏名称
gameList.onclick = function(e){
e = e || event
if(e.target.nodeName == 'LI'){ //如果当前的e.target是li的话 才执行对应的操作
title.innerText = e.target.innerText
}
}

2、offset家族

  • offsetParent 偏移的父元素(一层一层的向上找 找到定位的元素就是对应的父元素 有定位的上层元素
  • 就他的父元素 找不到的就是body)
  • offsetLeft 基于偏移的父元素的左偏移量
  • offsetTop 基于偏移的父元素的上偏移量
  • offsetHeight 获取偏移元素的高度(包含border以及padding)
  • offsetWidth 获取偏移元素的宽度(包含border以及padding)

3、拖拽(区间拖拽)

//拖拽的方法实现 第一个是移动的盒子 第二个在哪移动
function touch(moveBox,box){
//给moveBox添加按下事件 记录一下当前鼠标在moveBox里面点击的位置
moveBox.onmousedown = function(e){
e = e || window.event
//获取对应的第一次按下的位置
var firstX = e.offsetX
var firstY = e.offsetY
// console.log(document.body.offsetParent); //偏移的父元素
//给box添加move事件 记录每次的位置 在box的位置 设置moveBox在box的定位
box.onmousemove = function(e){
e = e || event
//这个108是对应的box离body的距离 这个距离就是box偏移的距离
//offsetLeft 得到基于父元素左偏移量 offsetTop 得到基于父元素的上偏移量
//offsetParent 基于的父元素 基于定位的 他会一层层往上找 找到定位的父元素就基于
他 如果没有找到就基于body
//有奶便是娘 谁有定位他就基于谁
var currentX = e.pageX - getOffset(this).left
var currentY = e.pageY - getOffset(this).top
var targetX = currentX - firstX
var targetY = currentY - firstY
//判断边界 offsetWidth 得到盒子的宽度 offsetHeight得到盒子的高度
if(targetX<0){
targetX = 0
}
if(targetY<0){
targetY = 0
}
if(targetX>this.offsetWidth-moveBox.offsetWidth){
targetX = this.offsetWidth-moveBox.offsetWidth
}
if(targetY>this.offsetHeight-moveBox.offsetHeight){
targetY = this.offsetHeight-moveBox.offsetHeight
}
// 设置moveBox在box的定位
moveBox.style.left = targetX + 'px'
moveBox.style.top = targetY + 'px'
}
//给box添加弹起事件 清除box的move事件
document.onmouseup = function(){
box.onmousemove = null
}
}
}

4、获取对应的盒子离最外层body的left值及top值

//获取对应的元素离body的距离 传入一个元素
function getOffset(element){
var left = 0
var top = 0
while(element){
left += element.offsetLeft
top += element.offsetTop
element = element.offsetParent
}
return {left,top}
}

5、事件监听器

(1)addEventListener (添加事件监听)任何元素都能调用(观察者模式 observer)

element.addEventListener('事件名',处理函数,'是否捕获')

(2)removeEventListener (移除事件监听)任何元素都能调用

element.removeEventListener ('事件名',处理函数)

示例:

//是否捕获 默认为不捕获(冒泡)
// 同时给一个事件加多个处理函数 (事件只会调用一次)
btn.addEventListener('click',function(){
console.log('点击了');
},true)
btn.addEventListener('click',function(){
console.log('点击了1');
},true)
btn.addEventListener('click',function(){
console.log('点击了2');
},true)
btn.addEventListener('click',function hello(){
console.log('点击了3');
})
btn.removeEventListener('click',function hello(){
console.log('点击了3');
})//不能被移除
//移除事件监听器 移除事件监听器根据对应的处理函数来的
//这个俩个函数对象不是一个对象 比对出不来 所以就删不掉
//所以我们如果需要删除对应的处理函数的话 那么必须在监听的时候 就要保证这个处理函数和对应的删除的
时候的处理函数是一个
//正确示例
function sayHello(){
console.log('hello');
}
div.addEventListener('click',sayHello)
div.removeEventListener('click',sayHello)

(3)兼容写法

//移除函数
function removeEvent(obj, type, fn, useCapture){
if (obj.removeEventListener) {
obj.removeEventListener(type, fn, useCapture);
}
else {
obj.detachEvent("on"+type, fn);
}
//三元的写法 obj.removeEventListener?
obj.removeEventListener(type,fn,useCapture):obj.detachEvent("on"+type, fn);
}
//添加函数
function addEvent(obj, type, fn, useCapture){
if (obj.addEventListener) {
obj.addEventListener(type, fn, useCapture);
}
else {
obj.attachEvent("on"+type, fn);
}
//三元的写法 obj.addEventListener?
obj.addEventListener(type,fn,useCapture):obj.attachEvent("on"+type, fn);
}

 

posted @   木木子夕  阅读(214)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示