第7课:JavaScript事件处理——JS的“感官系统”

不要害怕前方的黑暗,因为你每走一步,光明就会更靠近你一分。勇敢地迈出今天这一步,用努力点亮未来的路,你比想象中更强大!

欢迎来到「JavaScript 魔法学院」第 7 课!如果说网页是人体,那么事件就是 JS 的"感官"------它能感知用户的点击、输入、滑动等行为,让网页"活"过来!今天我们将解密事件机制,并开发「图片画廊」交互特效,代码可直接嵌入个人网站!

1. addEventListener 基础

html 复制代码
  <button id="myBtn">点我</button>
  <script>
      const btn = document.getElementById("myBtn");
      // 标准写法:事件类型 + 处理函数
      btn.addEventListener("click", function () {
          console.log("click:按钮被点击了!");
      });
  </script>

三要素:

  • 监听谁:DOM 元素(按钮、输入框等)

  • 听什么:事件类型(click、input 等)

  • 做什么:回调函数(事件触发时执行的代码)

2. 移除监听

html 复制代码
<button id="myBtn">点我</button>
<script>
    const btn = document.getElementById("myBtn");
    btn.addEventListener("click", handleClick);
    // 移出事件--需要具名函数才能移除
    function handleClick() {
        console.log("只会触发一次");
        btn.removeEventListener("click", handleClick);
    }
</script>

二、常见事件类型

1. 鼠标事件

事件类型 触发场景
click 点击(按下并释放)
dblclick 双击
mouseover 鼠标悬停
mousemove 鼠标在元素上移动

2. 键盘事件

js 复制代码
const input = document.getElementById("myInput");
input.addEventListener("keyup", (e) => {
    console.log('输入内容:',e.key);  // 获取按下的键
});

3. 表单事件

  • input:输入框内容变化时触发(实时监听)
  • submit:表单提交时触发
  • focus/blur:获取/失去焦点

4. 页面生命周期事件

js 复制代码
  function initApp() {
      return console.log("假设我是初始化程序initApp");
  }
  window.addEventListener("load", () => {
      // 页面完全加载后执行
      initApp();
  });

  window.addEventListener("resize", () => {
      console.log("窗口大小改变了!");
  });

三、事件对象与冒泡机制

1. 事件对象:e 的秘密

每个事件处理函数都会接收 事件对象(Event),包含关键信息:

js 复制代码
document.addEventListener("click", function (e) {
    console.log('坐标:', e.clientX, e.clientY);// 点击坐标
    console.log('事件元素:', e.target);// 触发事件的元素
});

2. 事件冒泡与阻止

冒泡机制: 事件从子元素向父元素逐层传递

html 复制代码
<div class="parent">
  <button class="child">点击我</button>
</div>

→ 点击按钮时,会依次触发 button → div → body 的点击事件

阻止冒泡:

javascript 复制代码
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');
child.addEventListener("click", function(e) {
  e.stopPropagation();  // 阻止事件向上传递
});

事件委托: 利用冒泡优化多元素监听

js 复制代码
const child = document.querySelector('.child');
// 给父元素绑定一次,管理所有子元素点击
parent.addEventListener("click", function(e) {
  if (e.target.classList.contains("child")) {
    handleChildClick(e.target);
  }
});

四、实战:交互式图片画廊

1. 功能需求

  • 点击缩略图显示大图
  • 鼠标悬停显示图片标题
  • 按 ESC 键关闭大图

2. 完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>交互式图片画廊</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f9;
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        .gallery {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            justify-content: center;
            margin-bottom: 20px;
        }

        .thumb {
            width: 150px;
            height: auto;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            cursor: pointer;
        }

        .thumb:hover {
            transform: scale(1.05);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
        }

        .modal {
            display: none;
            position: fixed;
            z-index: 1;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto;
            background-color: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(5px);
        }

        .modal-content {
            background-color: #fff;
            margin: 15% auto;
            padding: 20px;
            border-radius: 12px;
            width: 80%;
            max-width: 800px;
            text-align: center;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
        }

        .close {
            color: #aaa;
            position: absolute;
            top: 10px;
            right: 10px;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
            transition: color 0.3s ease;
        }

        .close:hover {
            color: #fff;
        }

        .image-title {
            margin-top: 10px;
            font-size: 18px;
            font-weight: bold;
            color: #333;
        }

        .modal img {
            width: 100%;
            border-radius: 8px;
        }
    </style>
</head>

<body>

    <div class="gallery">
        <img src="http://img1.baidu.com/it/u=48167685,603517373&fm=253&app=138&f=JPEG?w=800&h=1066" class="thumb"
            title="河流">
        <img src="http://img1.baidu.com/it/u=2000570628,3369378537&fm=253&app=138&f=JPEG?w=800&h=1201" class="thumb"
            title="小溪">
        <img src="http://img0.baidu.com/it/u=1447699437,883024997&fm=253&app=138&f=JPEG?w=800&h=1200" class="thumb"
            title="森林">
    </div>

    <div id="myModal" class="modal">
        <div class="modal-content">
            <span class="close">&times;</span>
            <div class="image-title"></div>
            <img id="img01" style="width:100%">
        </div>
    </div>

    <script>
        // 获取缩略图和模态框元素
        const thumbnails = document.querySelectorAll('.thumb');
        const modal = document.getElementById('myModal');
        const modalImg = document.getElementById('img01');
        const title = document.querySelector('.image-title');
        const span = document.getElementsByClassName('close')[0];

        // 点击缩略图显示大图
        thumbnails.forEach(thumb => {
            thumb.addEventListener('click', function () {
                modal.style.display = 'block';
                modalImg.src = this.src;
                title.textContent = this.title;
            });
        });

        // 点击关闭按钮关闭模态框
        span.onclick = function () {
            modal.style.display = 'none';
        };

        // 按 ESC 键关闭模态框
        window.addEventListener('keydown', function (event) {
            if (event.key === 'Escape') {
                modal.style.display = 'none';
            }
        });
    </script>

</body>

</html>

3. 代码亮点

  • 事件组合:结合点击、键盘、冒泡事件实现复杂交互
  • 性能优化:使用事件委托管理缩略图点击
  • 数据属性:用 data-* 存储图片标题

下节预告

第 8 课:实战-简易计算器------JS 入门阶段成果验收

  • 结合 DOM 与事件实现加减乘除

  • 处理用户输入与异常

回复【JS】获取本课源码+工具包!

相关推荐
南囝coding6 分钟前
关于我的第一个产品!
前端·后端·产品
iOS阿玮12 分钟前
别等了,今天是Xcode15时代的最后一天。
前端·app·apple
沙尘暴炒饭18 分钟前
vuex持久化vuex-persistedstate,存储的数据刷新页面后导致数据丢失
开发语言·前端·javascript
2401_8370885021 分钟前
CSS清楚默认样式
前端·javascript·css
zwjapple32 分钟前
React 的 useEffect 清理函数详解
前端·react.js·前端框架
Jewel10542 分钟前
如何配置Telegram Mini-App?
前端·vue.js·app
s11show_1631 小时前
hz修改后台新增keyword功能
android·java·前端
二个半engineer2 小时前
Web常见攻击方式及防御措施
前端
co松柏2 小时前
程序员必备——AI 画技术图技巧
前端·后端·ai编程
前端大白话2 小时前
前端人速码!10个TypeScript神仙技巧,看完直接拿捏项目实战
前端·javascript·typescript