【Java Web学习 | 第13篇】JavaScript(7) – 事件绑定 + 事件

【Java Web学习 | 第13篇】JavaScript(7) – 事件绑定与事件机制(2026最新版)

恭喜你完成 DOM 操作!
现在进入 事件绑定与事件机制,这是 JavaScript 实现用户交互(点击、输入、提交、滚动等)的核心技术。在 Java Web 项目中,几乎所有动态功能(表单提交、按钮操作、实时验证、列表交互)都依赖事件系统。

掌握本篇后,你就能优雅地处理用户行为,并为后续 Fetch 调用 Spring Boot API 做好准备。

1. 事件绑定三种方式(推荐顺序)

方式1:推荐 —— addEventListener(现代标准)

const btn = document.querySelector('#submitBtn');

btn.addEventListener('click', function handler(e) {
    console.log('按钮被点击了');
    // e 是事件对象(Event)
});

优点

  • 可以绑定多个事件处理函数
  • 支持事件委托
  • 可以移除监听(removeEventListener
  • 推荐在所有生产项目中使用

方式2:HTML 内联(学习阶段可用,生产不推荐)

<button onclick="handleClick()">点击我</button>

<script>
function handleClick() {
    alert('点击了!');
}
</script>

方式3:DOM0 方式(旧方式,不推荐)

btn.onclick = function() {
    console.log('点击');
};
// 缺点:只能绑定一个,后绑定的会覆盖前面的

2. 事件对象(Event)常用属性与方法

element.addEventListener('click', (e) => {
    console.log(e.type);           // "click"
    console.log(e.target);         // 实际被点击的元素
    console.log(e.currentTarget);  // 当前绑定事件的元素(委托时很重要)

    console.log(e.clientX, e.clientY);   // 鼠标相对于视口的坐标
    console.log(e.pageX, e.pageY);       // 相对于文档的坐标

    e.preventDefault();   // 阻止默认行为(如表单提交、链接跳转)
    e.stopPropagation();  // 阻止事件冒泡
});

3. 常用事件类型速查(Java Web 高频)

事件类别常用事件典型使用场景
鼠标事件click, dblclick, mousedown, mouseup, mouseover, mouseout, mousemove按钮点击、悬停效果
键盘事件keydown, keyup, keypress快捷键、表单输入控制
表单事件input, change, focus, blur, submit实时验证、表单提交
页面事件load, DOMContentLoaded, resize, scroll页面初始化、懒加载
触摸事件touchstart, touchmove, touchend移动端交互
其他drag, drop, contextmenu拖拽、右键菜单

最常用事件组合

  • DOMContentLoaded:DOM 解析完就执行(比 load 更快)
  • input:实时监听输入框变化(搜索、防抖常用)
  • submit:表单提交

4. 事件冒泡与捕获(Event Bubbling & Capturing)

事件默认从目标元素向上冒泡到 document

// 事件委托(最高性能写法,推荐!)
document.getElementById('userList').addEventListener('click', (e) => {
    // 判断是否点击了删除按钮
    if (e.target.closest('.delete-btn')) {
        const item = e.target.closest('.user-item');
        console.log('删除用户', item.dataset.id);
        item.remove();
    }
});

事件委托优点

  • 只需绑定一个监听器
  • 新增的动态元素自动支持事件
  • 性能更好

5. 完整实战示例(用户列表 + 表单提交模拟)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>事件绑定实战 - Java Web</title>
    <style>
        .user-item { padding: 12px; margin: 8px 0; background: #f8f9fa; border-radius: 8px; }
        .delete-btn { color: #dc3545; margin-left: 15px; }
    </style>
</head>
<body>
    <h1>用户管理</h1>

    <form id="userForm">
        <input type="text" id="username" placeholder="用户名" required>
        <input type="number" id="age" placeholder="年龄" required>
        <button type="submit">添加用户</button>
    </form>

    <div id="userList"></div>

    <script>
        const users = [];
        const userList = document.getElementById('userList');
        const form = document.getElementById('userForm');

        // 渲染函数
        function renderUsers() {
            userList.innerHTML = users.map((user, index) => `
                <div class="user-item" data-index="${index}">
                    ${user.username}(${user.age}岁)
                    <button class="delete-btn" data-index="${index}">删除</button>
                </div>
            `).join('');
        }

        // 事件委托(推荐写法)
        userList.addEventListener('click', (e) => {
            if (e.target.classList.contains('delete-btn')) {
                const index = parseInt(e.target.dataset.index);
                users.splice(index, 1);
                renderUsers();
            }
        });

        // 表单提交事件
        form.addEventListener('submit', (e) => {
            e.preventDefault();                    // 阻止默认提交

            const username = document.getElementById('username').value.trim();
            const age = parseInt(document.getElementById('age').value);

            if (username && age) {
                users.push({ username, age });
                renderUsers();

                // 清空表单
                form.reset();
                console.log('用户添加成功,当前用户数:', users.length);
            }
        });

        // 输入实时提示(input 事件)
        document.getElementById('username').addEventListener('input', (e) => {
            if (e.target.value.length > 10) {
                e.target.style.borderColor = 'red';
            } else {
                e.target.style.borderColor = '#007bff';
            }
        });

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', () => {
            console.log('DOM 已加载完成,开始绑定事件');
            renderUsers();
        });
    </script>
</body>
</html>

6. 防抖与节流(实际项目必备)

// 防抖(用户输入停止后一段时间才执行,常用于搜索)
function debounce(fn, delay = 300) {
    let timer = null;
    return function(...args) {
        clearTimeout(timer);
        timer = setTimeout(() => fn.apply(this, args), delay);
    };
}

// 使用示例
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce((e) => {
    console.log('搜索关键词:', e.target.value);
    // 这里可以调用后端搜索 API
}, 500));

7. 小练习(建议立即完成)

  1. 在上面示例中添加“清空所有用户”按钮,点击后清空列表。
  2. 为年龄输入框添加 blur 事件:离开焦点时如果年龄 < 18,提示警告并清空。
  3. 使用事件委托实现:点击任意 .user-item 时,高亮该项(添加 active 类)。
  4. 实现键盘快捷键:按下 Esc 键时清空表单。

下一篇文章预告:《【Java Web学习 | 第14篇】JavaScript(8) – 异步编程(Promise + async/await)与 Fetch API》

我们将进入异步编程,学习如何使用 fetch 调用 Spring Boot 后端 REST 接口,实现真正的增删改查操作。


本篇核心总结

  • 绑定事件:优先使用 addEventListener
  • 处理事件:记住 e.preventDefault()e.stopPropagation()
  • 高性能:优先使用事件委托
  • 表单:一定要 preventDefault() 阻止默认提交

有问题随时问:

  • 想要防抖 + 节流完整工具函数
  • 需要更多表单验证事件示例
  • 或直接进入 异步 + Fetch 篇?

回复“给我练习答案”或“下一篇 Fetch”,我立刻继续!

事件机制是 JavaScript 与用户“对话”的方式,掌握后你的页面才能真正“动”起来。继续加油,下一章我们就要和后端真正交互了!🚀

文章已创建 5288

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部