JavaScript-4

事件监听

  • 什么是事件:
在编程时系统内发生的动作或者发生的事情。比如:用户在网页上单击一个按钮
  • 什么是事件监听:
让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应
也称为"绑定事件或者注册事件"	(比如:点击按钮可以切换图片)
  • 事件监听三要素
事件源:某个DOM元素触发了事件
事件类型:用什么方式触发(比如:鼠标单击click、鼠标经过mouseover等)
事件调用的函数:要做什么事情
  • 语法:
元素对象.addEventListener('事件类型', 要执行的函数)
  • 演示
<body>
    <button>点击button>

    <script>
        const btn = document.querySelector('button')
        btn.addEventListener('click', function () {
            alert('Hello World')
        })
    script>
body>

两种注册事件的区别

传统 on 注册

  • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
  • 直接使用 null 覆盖就可以实现事件的解绑
  • 都是冒泡阶段执行的

事件监听注册

  • 后面注册的事情不会覆盖到前面注册的事件
  • 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
  • 必须使用 removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段) 进行事件的解绑操作
  • 匿名函数无法被解绑

事件类型

鼠标事件

click 鼠标点击
mouseenter 鼠标进入
mouseleave 鼠标离开

焦点事件

focus 获得焦点
blur 失去焦点

键盘事件

keydown 键盘按下触发
keyup 键盘抬起触发

文本事件

input 用户输入事件

具体演示

  • 鼠标事件
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
    style>
head>

<body>
    <div>div>

    <script>
        const div = document.querySelector('div')
        div.addEventListener('mouseenter', function () {
            div.style.backgroundColor = 'green'
        })
        div.addEventListener('mouseleave', function () {
            div.style.backgroundColor = 'red'
        })
    script>
body>
  • 焦点事件

    请输入
    

    

  • 键盘事件
    
键盘当前状态: 弹起
  • 文本事件
<body>
    <input type="text">
    <div>
        当前输入: <span>span>
    div>

    <script>
        const input = document.querySelector('input')
        const span = document.querySelector('span')

        input.addEventListener('input', function () {
            span.style.color = 'red'
            span.innerHTML = input.value
        })
    script>
body>

事件对象

基本概念

事件对象是什么?
	它是一个对象,这个对象里有事情触发时的相关信息
	例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置的信息

使用场景:
	可以判断用户按下了哪个键,比如:按下回车键可以发布新闻
	可以判断鼠标点击了哪个元素,从而做出相应操作

事件对象在哪里?
	事件绑定的回调函数的第一个参数

具体演示

<body>
    <input type="text">

    <script>
        const input = document.querySelector('input')
        input.addEventListener('keyup', function (event) {
            if (event.key === 'Enter') {
                console.log('成功按下了回车键')
            }
        })
    script>
body>

环境对象

环境对象,指的是函数内部特殊的变量 this,它代表着当前函数运行时所处的环境
(粗略判断规则:谁调用,this 就是谁)
<body>
    <button>点击button>

    <script>
        const btn = document.querySelector('button')
        btn.addEventListener('click', function () {
            this.style.color = 'red'    // 等效于 btn.style.color = 'red'
        })
    script>
body>

回调函数

概念:如果将函数A做为参数,传递给函数B,我们称函数A为回调函数

事件流

基本概念

  • 事件流:指的是事件完整执行过程中的流动路径
  • 捕获阶段:Document =》Element html =》Element body =》Element div
  • 冒泡阶段:Element div =》Element body =》Element html =》Document
语法:
	元素.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)

注意:
	addEventListener第三个参数传入true:代表是捕获阶段(很少使用)
	addEventListener第三个参数传入false或者不写:代表是冒泡阶段

捕获

<body>
    <div class="father">
        <div class="son">
            点我
        div>
    div>

    <script>
        const father = document.querySelector('.father')
        const son = document.querySelector('.son')

        document.addEventListener('click', function () {
            alert('I am grandfather')
        }, true)

        father.addEventListener('click', function () {
            alert('I am father')
        }, true)

        son.addEventListener('click', function () {
            alert('I am son')
        }, true)
    script>
body>
当鼠标点击"点我"时候,弹出框弹出的先后顺序是:
    I am grandfather
    I am father
    I am son

冒泡

<body>
    <div class="father">
        <div class="son">
            点我
        div>
    div>

    <script>
        const father = document.querySelector('.father')
        const son = document.querySelector('.son')

        document.addEventListener('click', function () {
            alert('I am grandfather')
        }, false)

        father.addEventListener('click', function () {
            alert('I am father')
        }, false)

        son.addEventListener('click', function () {
            alert('I am son')
        }, false)
    script>
body>
当鼠标点击"点我"时候,弹出框弹出的先后顺序是:
	I am son
	I am father
    I am grandfather

阻止冒泡

问题:
	因为默认就有冒泡模式的存在,所以容易导致事情影响到父级元素

需求:
	若想把事情就限制在当前元素内,就需要阻止事件冒泡

语法:
	事件对象.stopPropagation()

注意:
	此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
<body>
    <div class="father">
        <div class="son">
            点我
        div>
    div>

    <script>
        const father = document.querySelector('.father')
        const son = document.querySelector('.son')

        document.addEventListener('click', function () {
            alert('I am grandfather')
        }, false)

        father.addEventListener('click', function () {
            alert('I am father')
        }, false)

        son.addEventListener('click', function (event) {
            alert('I am son')
            
            // 阻止事件冒泡
            event.stopPropagation()
            
        }, false)
    script>
body>

事件解绑

  • 解绑方式一
<body>
    <button>确认button>

    <script>
        const btn = document.querySelector('button')
        btn.onclick = function () {
            alert('用户点击了确认')
            btn.onclick = null  // 解绑操作
        }
    script>
body>
  • 解绑方式二(常见)

    

    

事件委托

基本理解

情景带入

需求:
	要求点击某个li,那个li就变成红色。	
	
    
  • 1
  • 2
  • 3
  • 4
  • 5
解决办法: 方式一:给每个li都添加一个事件(太麻烦) 方式二:使用事件委托,将事件委托给ul进行处理

事件委托的优点:减少注册事件的次数,可以提供程序性能

事件委托的原理:利用事件冒泡的特点(给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件)

具体演示

<body>
    <ul>
        <li>li-1li>
        <li>li-2li>
        <li>li-3li>
        <li>li-4li>
        <li>li-5li>
        <p>我是p标签p>
    ul>

    <script>
        // 需求:点击小li,当前li文字变红色,点击其他标签不变色

        const ul = document.querySelector('ul')
        ul.addEventListener('click', function (event) {
            if (event.target.tagName === 'LI') {
                event.target.style.color = 'red'    // 找到点击所触发的元素:event.target
            }
        })
    script>
body>

阻止默认行为

<body>
    <form action="https://www.baidu.com">
        <input type="submit" value="免费注册">
    form>
    
    <script>
        const form = document.querySelector('form')
        form.addEventListener('submit', function (event) {
            // 阻止默认行为,此处的默认行为是"提交"
            event.preventDefault()
        })
    script>
body>

    点击跳转
    
    

其他事件

页面加载事件

  • 基本认识
作用:
	可以控制:先加载外部资源(如:图片、CSS、JS等)加载完毕时触发的事件

意义:
	1.有些时候,我们需要等页面所有资源全部加载完了,再做一些事情
	2.一些老项目的代码,往往把 script 写在 head 中
  • 监听整个页面资源是否加载完成
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <script>
        // 等待页面所有资源加载完毕,才会去执行回调函数
        window.addEventListener('load', function () {
            // ......
            // 请在此处写当前这个回调函数具体要实现的功能
            // ......
        })
    script>
head>
  • 注意:load 不仅可以监听整个页面资源加载完成,也可以针对某个资源绑定 load 事件
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <script>
        // 等待图片加载完毕,才会去执行回调函数
        img.addEventListener('load', function () {
            //......
        })
    script>
head>
  • 当初始的 HTML 文档被完全加载和解析完成后,DOMContentLoaded 事件被触发,而无需等待CSS样式表、图像等完全加载(此方法更快加载事件)
// 监听页面 DOM 加载完毕
        document.addEventListener('DOMContentLoaded', function () {
			// ......
        })

页面滚动事件

基本认识

含义:
	滚动条在滚动的时候持续触发的事件

意义:
	很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏、返回顶部

监听滚动

  • 监听页面滚动
<body>
    <div style="height: 2000px;">div>
    
    <script>
        // 页面滚动事件
        window.addEventListener('scroll', function () {
            console.log('我滚动了');
        })
    script>
body>
  • 监听某个元素内部的滚动
<body>
    <div style="width: 50px; height: 150px; overflow: scroll;">
        哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
    div>

    <script>
    	// 监听div元素内部的滚动
        const div = document.querySelector('div')
        div.addEventListener('scroll', function () {
            console.log('我滚动了');
        })
    script>
body>

获取位置

  • 基本认识
属性:
	scrollLeft 和 scrollTop

作用:
    获取元素内容往左、往上滚动出去的距离

注意:
	1.此属性既可以读取当前距离,也可以给它进行距离的赋值!
	2.本文只通过两个"向上滚动的距离"进行演示
  • 演示一:输出 div 元素向上滚动的距离
<body>
    <div style="width: 50px; height: 150px; overflow: scroll;">
        哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
    div>

    <script>
        const div = document.querySelector('div')
        
        // 输出: div元素向上滚动的距离
        div.addEventListener('scroll', function () {
            console.log(div.scrollTop);
        })
    script>
body>
  • 演示二:输出窗口向上滚动的距离
<body>
    <div style="height: 2000px;">div>

    <script>
        // 补充知识:获取html元素对象的写法是 document.documentElement

        // 输出: 窗口向上滚动距离
        window.addEventListener('scroll', function(){
            console.log(document.documentElement.scrollTop);
        })

    script>
body>
  • 扩展
跳转到窗口的某个滚动距离:
	
	方法一:利用 scrollTop 的可赋值性,document.documentElement.scrollTop = 100px
	
	方法二:windows.scrollTO(x, y)

页面尺寸事件

  • 尺寸改变,触发事件
<body>

    <script>
    	// 窗口尺寸改变的时候,触发事件
        window.addEventListener('resize', function () {
            console.log("窗口尺寸改变了!");
        })
    script>
body>
  • 获取元素宽高
注意:
	通过获取元素的可见部分宽高,不包含边框,margin,滚动条

属性:
	clientWidth 和 clientHeight
<body>
    <div style="display: inline-block;">
        随着内容的变化,span标签的宽度也随之变化
    div>

    <script>
        const div = document.querySelector('div')
        console.log(div.clientWidth);
    script>
body>

元素的尺寸与位置

获取宽高

介绍:
	1.获取元素的自身宽高、包含元素自身设置的宽高、padding、border
	2.获取出来的是数值,方便计算

属性:
	offsetWidth 和 offsetHeight

注意:
	获取的是可视宽高,如果盒子是隐藏的,获取的结果是0
<body>
    <div style="width: 100px;height: 100px; background-color: pink; margin: 100px auto;">div>
    <script>
        const div = document.querySelector('div')
        console.log(div.offsetWidth);
        console.log(div.offsetHeight);
    script>
body>

获取位置

介绍:
	获取元素距离自己"有定位的"父级元素的左、上距离

属性:
	offsetLeft 和 offsetTop

注意:
	这两个属性是只读属性,不能赋值。
<body>
    <div style="width: 100px;height: 100px; background-color: pink; margin: 100px auto;">div>
    
    <script>
        const div = document.querySelector('div')
        // div 与它"有定位"的父级的距离
        console.log(div.offsetTop);
        console.log(div.offsetLeft);
    script>
body>

速查(属性总结)

属性 作用 说明
scrollLeft 和 scrollTop 被卷去的头部和左侧 配合页面滚动使用(可读写)
clientWidth 和 clientHeight 获得元素宽度和高度 不包含border、margin、滚动条,用于js获取元素大小(只读属性)
offsetWidth 和 offsetHeight 获取元素宽度和高度 包含border、padding,滚动条等(只读属性)
offsetLeft 和 offsetTop 获取元素距离自己定位父级元素的左、上距离 在获取元素定位的时候使用(只读属性)

你可能感兴趣的:(前端-JavaScript,javascript)