事件下

event (事件源)

关于事件的组成:元素.on事件名 = 处理函数处理函数 是一个function 作为一个function 他具备一个arguments(参数数组)

因为arguments[0] 是获取第一个参数 那么我在对应的处理函数里面写一个参数这个参数不就是对应的arguments[0]

我们发现对应的arguments[0] 返回的对应对象是一个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);  //alt键按下事件
console.log(e.key);  //键盘的按键按下事件
}

属性

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

不经常用:

x 得到鼠标的x坐标(不包含不可视区域)
y 得到鼠标的y坐标 (不包含不可视区域)
screenX 得到鼠标在屏幕的上的x坐标
screenY 得到鼠标在屏幕上的y坐标

按键的相关属性
altKey 是否长按alt键
ctrlKey 是否长按ctrl键
shiftKey 是否长按shift键
鼠标相关的内容(只有鼠标触发的事件有)
button 返回的值为number类型(0 表示左键 1表示中间 2表示右键,鼠标上三个键)
事件触发的相关属性
type 事件类型 返回对应的事件名
target 目标元素(要执行事件的元素)返回真实触发的事件元素
currentTarget 目标元素 返回当前添加事件的元素
bubbles 事件是否冒泡 (冒泡就是子元素也会触发父元素的事件)
键盘事件相关的内容(需要键盘来触发的事件)
key 属性 (当前按下的键)
keycode 属性 (获取当前按下键大写的ascii码)
charCode 属性(字符键 press事件 字符键的ascii码)

事件流
概述:事件流指代的是事件的执行流程,多个盒子嵌套相同事件,这个时候你触发一个盒子的事件,并不会只执行一个盒子的事件的处理函数,而是全部执行。
事件流的俩种模式
冒泡模式(浏览器采用的)
冒泡模式指代的是事件从里到外逐个执行

阻止事件冒泡
e.stopPropagation() 函数 (推荐使用)
e.cancelBubble = true 属性设置(现在虽然都可以用 但是未来可能会废弃)
兼容写法

e.stopPropagation?e.stopPropagation():e.cancelBubble = true //三目运算符

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

默认行为

默认行为就是一个元素自己带有的行为,比如a标签点击后,会进行跳转页面,form表单的submit按钮点击会提交数据(刷新页面),右键会出现一个菜单栏等行为。

有些时候我们不需要这些行为的产生 那么我们就需要阻止默认行为

阻止默认行为的js代码实现

e.preventDefault() 函数 
e.returnValue = false ie的兼容
return false 直接结束对应的操作 (不推荐,一个函数如果return后,函数会被回收)

e.preventDefault?e.preventDefault():e.returnValue = false //兼容,意思是如果浏览器能识别e.preventDefault,就使用问号后面的式子;如果不能识别,就使用冒号后面的式子

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

//获取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
//给document添加mousemove事件
document.onmousemove = function(e){
e = e || event
//记录每次的位置 在document里面的位置
var currentX = e.pageX
var currentY = e.pageY
//并且设置div的位置
box.style.left = currentX - x + "px"
box.style.top = currentY - y + "px"
}
//给document添加mouseup事件
document.onmouseup = function(){
//清除对应的mousemove事件
document.onmousemove = null
}
}

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

( 注意:getComputedStyle(元素)获取的是一个元素的所有style属性,所以如果你要具体获取一个属性,就要在后面加具体的属性;如getComputedStyle(元素).width->获取元素的宽度

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

ie兼容

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

兼容封装

//方法的封装
function getStyle(el) {
  if(window.getComputedStyle) {
    return window.getComputedStyle(el)
  }else {
       return el.currentStyle //ie写法
   }
}
getStyle(el).width
 事件委托

概述: 将对应的子元素的事件添加给父元素,用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
}
}

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

拖拽(区间拖拽)

//拖拽的方法实现 第一个是移动的盒子 第二个在哪移动
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
}
}
}

获取对应的盒子离最外层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}
}

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

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

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)

兼容写法

//移除函数
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 @ 2022-08-13 09:41  B1NGO  阅读(20)  评论(0编辑  收藏  举报