您当前的位置: 首页 > 

知其黑、受其白

暂无认证

  • 0浏览

    0关注

    1250博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

JS基础 事件

知其黑、受其白 发布时间:2022-02-18 19:27:06 ,浏览量:0

阅读目录
  • 基础知识
  • 处理程序
    • HTML绑定
      • 绑定函数或方法时需要加上括号
      • 使用方法做为事件处理程序
      • 传递事件源对象与事件对象
    • DOM绑定
  • 事件监听
    • 绑定多个事件
    • 通过对象绑定
    • 移除事件
    • 事件选项
      • 使用 `once:true` 来指定事件只执行一次
      • 设置 ` { capture: true }` 或直接设置第三个参数为 true 用来在捕获阶段执行事件
      • 设置 { capture: false } 或直接设置第三个参数为 false 用来在冒泡阶段执行事件
  • 事件对象
  • 冒泡捕获
    • 冒泡行为
    • 阻止冒泡
    • 事件捕获
    • 事件代理
    • 未来元素
  • 默认行为
  • 窗口文档
    • 事件类型
      • window.onload
      • DOMContentLoaded
      • beforeunload *
      • unload
  • 鼠标事件
    • 事件类型
      • mouseenter 与 mouseleave 事件从子元素移动到父元素时不触发父元素事件
    • 事件对象
      • relatedTarget 是控制鼠标移动事件的来源和目标对象的
    • 禁止复制
  • 键盘事件
    • 事件对象
  • 表单事件

基础知识

在文档、浏览器、标签元素等元素在特定状态下触发的行为即为事件,比如用户的单击行为、表单内容的改变行为即为事件,我们可以为不同的事件定义处理程序。JS使用异步事件驱动的形式管理事件。

事件类型 JS为不同的事件定义的类型,也可以称为事件名称。

事件目标 事件目标指产生事件的对象,比如 a 标签被点击那么 a 标签就是事件目标。 元素是可以嵌套的,所以在进行一次点击行为时可能会触发多个事件目标。

处理程序

事件的目的是要执行一段代码,我们称这类代码为事件处理(监听)程序。当在对象上触发事件时就会执行定义的事件处理程序。

HTML绑定

可以在html元素上设置事件处理程序,浏览器解析后会绑定到DOM属性中

博客地址

往往事件处理程序业务比较复杂,所以绑定方法或函数会很常见

绑定函数或方法时需要加上括号
博客

  function show() {
    alert('wgchen.blog.csdn.net')
  }

使用方法做为事件处理程序


  class HD {
    static show() {
      console.log('wgchen.blog.csdn.net')
    }
  }

在这里插入图片描述

传递事件源对象与事件对象
技术文章

    function show(...args) {
        console.log(args)
    }

在这里插入图片描述

DOM绑定

也可以将事件处理程序绑定到DOM属性中

  • 使用 setAttribute 方法设置事件处理程序无效
  • 属性名区分大小写
wgchen.blog.csdn.net

  const app = document.querySelector('#app')
  app.onclick = function () {
    this.style.color = 'red'
  }

在这里插入图片描述 无法为事件类型绑定多个事件处理程序,下面绑定了多个事件处理程序,因为属性是相同的所以只有最后一个有效。

wgchen.blog.csdn.net

  const app = document.querySelector('#app')
  
  app.onclick = function () {
    this.style.color = 'red'
  }

  app.onclick = function () {
    this.style.fontSize = '55px'
  }

事件监听

通过上面的说明我们知道使用HTML与DOM绑定事件都有缺陷,建议使用新的事件监听绑定方式 addEventListener 操作事件

使用 addEventListener 添加事件处理程序有以下几个特点

  • transtionend / DOMContentLoaded 等事件类型只能使用 addEventListener 处理
  • 同一事件类型设置多个事件处理程序,按设置的顺序先后执行
  • 也可以对未来添加的元素绑定事件
方法说明addEventListener添加事件处理程序removeEventListener移除事件处理程序

addEventListener 的参数说明如下

1、参数一事件类型 2、参数二事件处理程序 3、参数三为定制的选项,可传递 objectboolean 类型。后面会详细介绍使用区别

绑定多个事件

使用 addEventListener 来多个事件处理程序

wgchen.blog.csdn.net

  const app = document.querySelector('#app')
  app.addEventListener('click', function () {
    this.style.color = 'red'
  })
  app.addEventListener('click', function () {
    this.style.fontSize = '55px'
  })

通过对象绑定

如果事件处理程序可以是对象,对象的 handleEvent 方法会做为事件处理程序执行。

下面将元素的事件统一交由对象处理

wgchen.blog.csdn.net

  const app = document.querySelector('#app')
  class HD {
    handleEvent(e) {
      this[e.type](e)
    }
    click() {
      console.log('单击事件')
    }
    mouseover() {
      console.log('鼠标移动事件')
    }
  }
  app.addEventListener('click', new HD())
  app.addEventListener('mouseover', new HD())

在这里插入图片描述

移除事件

使用 removeEventListener 删除绑定的事件处理程序

事件处理程序单独定义函数或方法,这可以保证事件处理程序是同一个

wgchen.blog.csdn.net
删除事件


  const app = document.querySelector('#app')
  const hd = document.querySelector('#hd')

  function show() {
    console.log('APP我执行了')
  }

  app.addEventListener('click', show)
  
  hd.addEventListener('click', function () {
    app.removeEventListener('click', show)
  })

事件选项

addEventListener 的第三个参数为定制的选项,可传递 object 或 boolean 类型

下面是传递对象时的说明

选项可选参数oncetrue/false只执行一次事件capturetrue/false事件是在捕获/冒泡哪个阶段执行,true:捕获阶段 false:冒泡阶段passivetrue/false声明事件里不会调用 preventDefault(),可以减少系统默认行为的等待 使用 once:true 来指定事件只执行一次
wgchen.blog.csdn.net

  const app = document.querySelector('#app')
  app.addEventListener(
      'click',
      function () {
          alert('wgchen.blog.csdn.net@博客')
      },
      { once: true }
  )

设置 { capture: true } 或直接设置第三个参数为 true 用来在捕获阶段执行事件

addEventListener 的第三个参数传递 true/false 和设置 {capture:true/false}是一样


    wgchen.blog.csdn.net


    const app = document.querySelector('#app')
    const bt = document.querySelector('#bt')
    app.addEventListener(
        'click',
        function () {
            alert('这是div事件 ')
        },
        { capture: true }
    )

    bt.addEventListener(
        'click',
        function () {
            alert('这是按钮事件 ')
        },
        { capture: true }
    )

在这里插入图片描述

设置 { capture: false } 或直接设置第三个参数为 false 用来在冒泡阶段执行事件

    wgchen.blog.csdn.net


  const app = document.querySelector('#app')
  const bt = document.querySelector('#bt')
  app.addEventListener(
      'click',
      function () {
          alert('这是div事件 ')
      },
      { capture: false }
  )

  bt.addEventListener(
      'click',
      function () {
          alert('这是按钮事件 ')
      },
      { capture: false }
  )

在这里插入图片描述

事件对象

执行事件处理程序时,会产生当前事件相关信息的对象,即为事件对事。系统会自动做为参数传递给事件处理程序。

  • 大部分浏览器将事件对象保存到 window.event
  • 有些浏览器会将事件对象做为事件处理程序的参数传递

事件对象常用属性如下:

属性说明type事件类型target事件目标对象,冒泡方式时父级对象可以通过该属性找到在哪个子元素上最终执行事件currentTarget当前执行事件的对象timeStamp事件发生时间x相对窗口的X坐标y相对窗口的Y坐标clientX相对窗口的X坐标clientY相对窗口的Y坐标screenX相对计算机屏幕的X坐标screenY相对计算机屏幕的Y坐标pageX相对于文档的X坐标pageY相对于文档的Y坐标offsetX相对于事件对象的X坐标offsetY相对于事件对象的Y坐标layerX相对于父级定位的X坐标layerY相对于父级定位的Y坐标path冒泡的路径altKey是否按了alt键shiftKey是否按了shift键metaKey是否按了媒体键window.pageXOffset文档参考窗口水平滚动的距离window.pageYOffset文档参考窗口垂直滚动的距离 冒泡捕获 冒泡行为

标签元素是嵌套的,在一个元素上触发的事件,同时也会向上执行父级元素的事件处理程序,一直到HTML标签元素。

  • 大部分事件都会冒泡,但像 focus 事件则不会
  • event.target 可以在事件链中最底层的定义事件的对象
  • event.currentTarget == this 即当前执行事件的对象

以下示例有标签的嵌套,并且父子标签都设置了事件,当在子标签上触发事件是会冒泡执行父级标签的事件。

在这里插入图片描述


#app {
    background: #34495e;
    width: 300px;
    padding: 30px;
}
#app h2 {
    background-color: #f1c40f;
    margin-right: -100px;
}



https://wgchen.blog.csdn.net



const app = document.querySelector('#app')
const h2 = document.querySelector('h2')

app.addEventListener('click', (event) => {
    console.log(`event.currentTarget:${event.currentTarget.nodeName}`)
    console.log(`event.target:${event.target.nodeName}`)
    console.log('app event')
})

h2.addEventListener('click', () => {
    console.log(`event.currentTarget:${event.currentTarget.nodeName}`)
    console.log(`event.target:${event.target.nodeName}`)
    console.log(`h2 event`)
})

阻止冒泡

冒泡过程中的任何事件处理程序中,都可以执行 event.stopPropagation() 方法阻止继续进行冒泡传递。

  • event.stopPropagation() 用于阻止冒泡
  • 如果同一类型事件绑定多个事件处理程序 event.stopPropagation() 只阻止当前的事件处理程序。
  • event.stopImmediatePropagation() 阻止事件冒泡并且阻止相同事件的其他事件处理程序被调用。

下例中为 h2 的事件处理程序添加了阻止冒泡动作,将不会产生冒泡,也就不会执行父级中的事件处理程序了。


#app {
    background: #34495e;
    width: 300px;
    padding: 30px;
}
#app h2 {
    background-color: #f1c40f;
    margin-right: -100px;
}



wgchen.blog.csdn.net



const app = document.querySelector('#app')
const h2 = document.querySelector('h2')

app.addEventListener('click', (event) => {
    console.log(`event.currentTarget:${event.currentTarget.nodeName}`)
    console.log(`event.target:${event.target.nodeName}`)
    console.log('app event')
})

h2.addEventListener('click', (event) => {
    event.stopPropagation()
    console.log(`event.currentTarget:${event.currentTarget.nodeName}`)
    console.log(`event.target:${event.target.nodeName}`)
    console.log(`h2 event`)
})

h2.addEventListener('click', (event) => {
    console.log('h2 的第二个事件处理程序')
})

在这里插入图片描述

事件捕获

事件执行顺序为 捕获 > 事件目标 > 冒泡,在向下传递到目标对象的过程即为事件捕获。 事件捕获在实际使用中频率不高。

通过设置第三个参数为 true{ capture: true } 在捕获阶段执行事件处理程序。


#app {
    background: #34495e;
    width: 300px;
    padding: 30px;
}

#app h2 {
    background-color: #f1c40f;
    margin-right: -100px;
}



    wgchen.blog.csdn.net



const app = document.querySelector('#app')
const h2 = document.querySelector('h2')

app.addEventListener(
    'click',
    (event) => {
        console.log('app event')
    },
    { capture: true }
)

h2.addEventListener('click', (event) => {
    console.log(`h2 event`)
})

在这里插入图片描述

事件代理

借助冒泡思路,我们可以不为子元素设置事件,而将事件设置在父级。 然后通过父级事件对象的 event.target 查找子元素,并对他做出处理。

  • 这在为多个元素添加相同事件时很方便
  • 会使添加事件变得非常容易

下面是为父级 UL 设置事件来控制子元素 LI 的样式切换。

在这里插入图片描述


.hd {
    border: solid 2px #ddd;
    background-color: red;
    color: white;
}



    https://wgchen.blog.csdn.net
    博客



'use strict'
const ul = document.querySelector('ul')
ul.addEventListener('click', () => {
    if (event.target.tagName === 'LI') event.target.classList.toggle('hd')
})

可以使用事件代理来共享事件处理程序,不用为每个元素单独绑定事件。

在这里插入图片描述


    https://wgchen.blog.csdn.net
    博客



class HD {
    constructor(el) {
        el.addEventListener('click', (e) => {
            const action = e.target.dataset.action
            this[action](e)
        })
    }

    hidden() {
        event.target.hidden = true
    }
    
    color() {
        event.target.style.color = event.target.dataset.color
    }
}
new HD(document.querySelector('ul'))

下面是使用事件代理实现的 TAB 面板效果

在这里插入图片描述


    
        博客
        https://wgchen.blog.csdn.net
    
    
        技术文章
        wgchen
    



    class HD {
        constructor(el) {
            this.el = el
            el.addEventListener('click', this.handle.bind(this))
        }
        handle() {
            const action = event.target.dataset.action
            if (action) this[action]()
        }
        hidden() {
            event.target.hidden = true
        }
        toggle() {
            this.el.querySelectorAll(`[data-action='hidden']`).forEach((e) => (e.hidden = true))
            event.target.nextElementSibling.hidden = ''
        }
    }
    new HD(document.querySelector('.tab'))

下面实现通过代理事件行为,在表单提交时禁用提交按钮,并记录提示次数。

在这里插入图片描述


    
    提交表单


class FORM {
    constructor(form) {
        this.form = form
        this.form.counter = 0
        this.form.addEventListener('click', this.handle.bind(this))
    }
    handle() {
        const actions = event.target.dataset.action
        
        actions.split(',').forEach((action) => {
            if (this[action]) this[action]()
        })
    }
    submit() {
        event.preventDefault()
        this.disableButton(true)
        console.log('提交中')
        setTimeout(() => {
            this.disableButton(false)
            console.log('提交结束')
        }, 1000)
    }
    disableButton(state) {
        this.form.querySelectorAll(`[data-submit-disabled]`).forEach((bt) => {
            bt.disabled = state
        })
    }
    counter() {
        this.form.counter++
        console.log(this.form.counter)
    }
}

document.querySelectorAll(`form`).forEach((form) => {
    new FORM(form)
})

未来元素

下面使用事件代理来对未来元素进行事件绑定


    https://wgchen.blog.csdn.net



function show() {
    console.log(this.textContent)
}

const app = document.querySelector('#app')
const h2 = document.querySelectorAll('h2')

app.addEventListener('click', () => {
    show.call(event.target)
})

let newH2 = document.createElement('h1')

newH2.textContent = '博客'

app.append(newH2)

在这里插入图片描述

默认行为

JS中有些对象会设置默认事件处理程序,比如 A 链接在点击时会进行跳转。

一般默认处理程序会在用户定义的处理程序后执行,所以我们可以在我们定义的事件处理中取消默认事件处理程序的执行。

  • 使用 onclick 绑定的事件处理程序,return false 可以阻止默认行为
  • 推荐使用 event.preventDefault() 阻止默认行为

下面阻止超链接的默认行为 在这里插入图片描述

博客

document.querySelector('a').addEventListener('click', () => {
    event.preventDefault()
    alert(event.target.innerText)
})

窗口文档

下面来学习针对窗口和文档的事件的处理。

事件类型 事件名说明window.onload文档解析及外部资源加载后DOMContentLoaded文档解析后执行,不需要等待图片/样式文件等外部资源加载,该事件只能通过addEventListener设置window.beforeunload文档刷新或关闭时window.unload文档卸载时scroll页面滚动时 window.onload

window.onload 事件在文档解析后及图片、外部样式文件等资源加载完后执行


    window.onload = function () {
        alert('https://wgchen.blog.csdn.net')
    }

技术文章

在这里插入图片描述

DOMContentLoaded

DOMContentLoaded事件在文档标签解析后执行,不需要等外部图片、样式文件、JS文件等资源加载。


    window.addEventListener('DOMContentLoaded', (event) => {
        console.log('https://wgchen.blog.csdn.net')
    })

https://wgchen.blog.csdn.net

在这里插入图片描述

beforeunload *

当浏览器窗口关闭或者刷新时,会触发 beforeunload 事件,可以取消关闭或刷新页面。

  • 返回值为非空字符串时,有些浏览器会做为弹出的提示信息内容
  • 部分浏览器使用 addEventListener 无法绑定事件

window.onbeforeunload = function (e) {
    return '真的要离开吗?'
}

在这里插入图片描述

unload

window.unload 事件在文档资源被卸载时执行,在 beforeunload 后执行

  • 不能执行 alert、confirm 等交互指令
  • 发生错误也不会阻止页面关闭或刷新

window.addEventListener('unload', function (e) {
  localStorage.setItem('name', 'ycc')
})

鼠标事件 事件类型

针对鼠标操作的行为有多种事件类型。

鼠标事件会触发在 Z-INDEX 层级最高的那个元素上。

事件名说明click鼠标单击事件,同时触发 mousedown/mouseupdblclick鼠标双击事件contextmenu点击右键后显示的所在环境的菜单mousedown鼠标按下mouseup鼠标抬起时mousemove鼠标移动时mouseover鼠标移动时mouseout鼠标从元素上离开时mouseup鼠标抬起时mouseenter鼠标移入时触发,不产生冒泡行为mosueleave鼠标移出时触发,不产生冒泡行为oncopy复制内容时触发scroll元素滚动时,可以为元素设置overflow:auto; 产生滚动条来测试 mouseenter 与 mouseleave 事件从子元素移动到父元素时不触发父元素事件

在这里插入图片描述


  #app {
    background: red;
    padding: 80px;
    width: 500px;
  }
  #cms {
    background: teal;
    padding: 30px;
  }


  https://wgchen.blog.csdn.net
  博客



  const app = document.querySelector(`#app`)
  const cms = document.querySelector(`#cms`)

  app.addEventListener('mouseenter', () => {
    console.log('app')
  })
  cms.addEventListener('mouseenter', () => {
    console.log('cms')
  })

事件对象

鼠标事件产生的事件对象包含相对应的属性。

属性说明which执行mousedown/mouseup时,显示所按的键 1左键,2中键,3右键clientX相对窗口X坐标clientY相对窗口Y坐标pageX相对于文档的X坐标pageY相对于文档的Y坐标offsetX目标元素内部的X坐标offsetY目标元素内部的Y坐标altKey是否按了alt键ctrlKey是否按了ctlr键shiftKey是否按了shift键metaKey是否按了媒体键relatedTargetmouseover事件时从哪个元素来的,mouseout事件时指要移动到的元素。当无来源(在自身上移动)或移动到窗口外时值为null relatedTarget 是控制鼠标移动事件的来源和目标对象的

如果移动过快会跳转中间对象

https://wgchen.blog.csdn.net
博客

const app = document.querySelector(`#app`)
const cms = document.querySelector(`#cms`)
app.addEventListener('mouseout', () => {
  console.log(event.target)
  console.log(event.relatedTarget)
})

在这里插入图片描述

禁止复制

在这里插入图片描述


https://wgchen.blog.csdn.net


document.addEventListener('copy', () => {
  event.preventDefault()
  alert('禁止复制内容')
})



键盘事件

针对键盘输入操作的行为有多种事件类型。

事件名说明Keydown键盘按下时,一直按键不松开时keydown事件会重复触发keyup按键抬起时 事件对象

键盘事件产生的事件对象包含相对应的属性。

属性说明keyCode返回键盘的ASCII字符数字code按键码,字符以Key开始,数字以Digit开始,特殊字符有专属名子。左右ALT键字符不同。不同布局的键盘值会不同key按键的字符含义表示,大小写不同。不能区分左右ALT等。不同语言操作系统下值会不同altKey是否按了alt键ctrlKey是否按了ctlr键shiftKey是否按了shift键metaKey是否按了媒体键 表单事件

下面是可以用在表单上的事件类型。

事件类型说明focus获取焦点事件blur失去焦点事件element.focus()让元素强制获取焦点element.blur()让元素失去焦点change文本框在内容发生改变并失去焦点时触发,select/checkbox/radio选项改变时触发事件inputInput、textarea或 select 元素的 value 被修改时,会触发 input 事件。而 change 是鼠标离开后或选择一个不同的option时触发。submit提交表单
关注
打赏
1665558895
查看更多评论
立即登录/注册

微信扫码登录

0.1643s