JavaScript网页设计高级案例:构建交互式图片画廊

JavaScript网页设计高级案例:构建交互式图片画廊

在现代Web开发中,交互式元素已成为提升用户体验的关键因素。本文将通过一个高级案例 - 构建交互式图片画廊,展示如何结合HTML和JavaScript创建引人入胜的网页应用。这个案例不仅涵盖了基础的Web开发技术,还融入了性能优化和现代设计模式。

项目概述

我们将构建的交互式图片画廊具有以下功能:

  • 响应式布局,适应不同设备尺寸
  • 图片类别筛选功能
  • 点击图片展示大图和详细信息的模态框
  • 平滑的动画和过渡效果
  • 懒加载技术提升性能
  • 本地存储保存用户的设置偏好

HTML结构

首先,我们需要建立一个清晰的HTML结构作为应用的骨架:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>交互式图片画廊</title><link rel="stylesheet" href="styles.css">
</head>
<body><header class="gallery-header"><h1>精美图片画廊</h1><div class="filter-container"><button class="filter-btn active" data-category="all">全部</button><button class="filter-btn" data-category="nature">自然风光</button><button class="filter-btn" data-category="architecture">建筑设计</button><button class="filter-btn" data-category="people">人物肖像</button></div></header><main class="gallery-container"><!-- 图片项将通过JavaScript动态加载 --></main><!-- 模态框 --><div class="modal" id="imageModal"><span class="close-modal">&times;</span><div class="modal-content"><img class="modal-img" id="modalImage"><div class="image-info"><h3 id="imageTitle"></h3><p id="imageDescription"></p><p id="imageAuthor"></p></div></div></div><footer><p>© 2025 交互式图片画廊 | 设计与开发</p></footer><script src="gallery.js"></script>
</body>
</html>

JavaScript实现

现在,让我们深入JavaScript部分,实现交互式功能:

// 图片数据 - 使用公共链接
const galleryData = [{id: 1,src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e",thumbnail: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=400&h=300&auto=format&fit=crop",title: "森林小径",description: "阳光透过树叶,洒在蜿蜒的森林小径上",category: "nature",author: "张明"},{id: 2,src: "https://images.unsplash.com/photo-1486325212027-8081e485255e",thumbnail: "https://images.unsplash.com/photo-1486325212027-8081e485255e?w=400&h=300&auto=format&fit=crop",title: "现代建筑",description: "城市中心的现代玻璃建筑,反射着周围的景色",category: "architecture",author: "李华"},{id: 3,src: "https://images.unsplash.com/photo-1533738363-b7f9aef128ce",thumbnail: "https://images.unsplash.com/photo-1533738363-b7f9aef128ce?w=400&h=300&auto=format&fit=crop",title: "街头艺术家",description: "专注于表演的街头艺术家,吸引了众多观众",category: "people",author: "王芳"},{id: 4,src: "https://images.unsplash.com/photo-1472214103451-9374bd1c798e",thumbnail: "https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=400&h=300&auto=format&fit=crop",title: "山间湖泊",description: "清澈的湖水倒映着周围的群山和蓝天",category: "nature",author: "陈晓"},{id: 5,src: "https://images.unsplash.com/photo-1511818966892-d7d671e672a2",thumbnail: "https://images.unsplash.com/photo-1511818966892-d7d671e672a2?w=400&h=300&auto=format&fit=crop",title: "历史建筑",description: "古典风格的历史建筑,展示着精美的建筑细节",category: "architecture",author: "赵建"},{id: 6,src: "https://images.unsplash.com/photo-1504439904031-93ded9f93e4e",thumbnail: "https://images.unsplash.com/photo-1504439904031-93ded9f93e4e?w=400&h=300&auto=format&fit=crop",title: "都市人像",description: "忙碌的都市生活中,一位沉思的年轻人",category: "people",author: "林美"}
];// DOM 元素
const galleryContainer = document.querySelector('.gallery-container');
const filterButtons = document.querySelectorAll('.filter-btn');
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
const modalClose = document.querySelector('.close-modal');
const imageTitle = document.getElementById('imageTitle');
const imageDescription = document.getElementById('imageDescription');
const imageAuthor = document.getElementById('imageAuthor');// 当前选中的类别
let currentCategory = 'all';// 初始化函数
function initGallery() {// 加载用户上次选择的类别(如果有)const savedCategory = localStorage.getItem('preferredCategory');if (savedCategory) {currentCategory = savedCategory;// 更新按钮状态filterButtons.forEach(btn => {btn.classList.toggle('active', btn.getAttribute('data-category') === currentCategory);});} else {// 确保"全部"按钮处于激活状态filterButtons.forEach(btn => {btn.classList.toggle('active', btn.getAttribute('data-category') === 'all');});}// 加载图片renderGallery();// 添加延迟加载后的动画效果setTimeout(() => {animateGalleryItems();}, 100);// 添加事件监听器setupEventListeners();
}// 渲染画廊
function renderGallery() {// 清空画廊容器galleryContainer.innerHTML = '';// 筛选图片const filteredImages = currentCategory === 'all' ? galleryData : galleryData.filter(image => image.category === currentCategory);// 创建图片元素filteredImages.forEach((image, index) => {const galleryItem = document.createElement('div');galleryItem.className = 'gallery-item';galleryItem.setAttribute('data-id', image.id);// 所有图片都直接加载,不再使用懒加载// 这样可以确保无论是初始加载还是切换类别,图片都能显示galleryItem.innerHTML = `<img class="gallery-img" src="${image.thumbnail}" alt="${image.title}"><div class="image-overlay"><h3>${image.title}</h3></div>`;galleryContainer.appendChild(galleryItem);});// 初始加载后立即添加动画效果setTimeout(() => {animateGalleryItems();}, 50);
}// 实现懒加载implementLazyLoading();
}// 懒加载实现
function implementLazyLoading() {const lazyImages = document.querySelectorAll('img[data-src]');if ('IntersectionObserver' in window) {const imageObserver = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.target;img.src = img.getAttribute('data-src');img.removeAttribute('data-src');// 添加加载完成的类img.classList.add('loaded');observer.unobserve(img);}});}, {// 修改阈值,使图片在进入视口前就开始加载rootMargin: '50px',threshold: 0.1});lazyImages.forEach(img => {imageObserver.observe(img);});} else {// 降级处理:立即加载所有图片lazyImages.forEach(img => {img.src = img.getAttribute('data-src');img.removeAttribute('data-src');img.classList.add('loaded');});}// 如果没有图片加载,可能是首次加载出现问题,强制加载第一屏图片if (lazyImages.length === 0 || document.querySelectorAll('.gallery-item').length === 0) {console.log('强制重新渲染画廊');setTimeout(() => renderGallery(), 100);}
}// 设置事件监听器
function setupEventListeners() {// 筛选按钮点击事件filterButtons.forEach(button => {button.addEventListener('click', function() {const category = this.getAttribute('data-category');// 更新按钮样式filterButtons.forEach(btn => btn.classList.remove('active'));this.classList.add('active');// 更新当前类别并保存到本地存储currentCategory = category;localStorage.setItem('preferredCategory', category);// 为画廊添加转场动画类galleryContainer.classList.add('category-transition');// 短暂延迟后重新渲染画廊,创造平滑过渡效果setTimeout(() => {// 重新渲染画廊renderGallery();// 移除转场类setTimeout(() => {galleryContainer.classList.remove('category-transition');}, 50);}, 300);});});// 图片点击事件(使用事件委托)galleryContainer.addEventListener('click', function(e) {const galleryItem = e.target.closest('.gallery-item');if (galleryItem) {const imageId = parseInt(galleryItem.getAttribute('data-id'));openModal(imageId);}});// 关闭模态框事件modalClose.addEventListener('click', closeModal);window.addEventListener('click', function(e) {if (e.target === modal) {closeModal();}});// 键盘事件处理window.addEventListener('keydown', function(e) {if (e.key === 'Escape' && modal.style.display === 'flex') {closeModal();}});
}// 打开模态框
function openModal(imageId) {const image = galleryData.find(img => img.id === imageId);if (image) {// 设置模态框内容modalImage.src = image.src;imageTitle.textContent = image.title;imageDescription.textContent = image.description;imageAuthor.textContent = `摄影师: ${image.author}`;// 显示模态框并添加动画效果modal.style.display = 'flex';setTimeout(() => {modal.classList.add('show');}, 10);// 防止滚动document.body.style.overflow = 'hidden';}
}// 关闭模态框
function closeModal() {modal.classList.remove('show');setTimeout(() => {modal.style.display = 'none';// 恢复滚动document.body.style.overflow = 'auto';// 清除图片,减轻内存负担modalImage.src = '';}, 300); // 匹配CSS过渡时间
}// 添加画廊项目的动画效果
function animateGalleryItems() {const items = document.querySelectorAll('.gallery-item');items.forEach((item, index) => {item.style.animationDelay = `${index * 0.05}s`;item.classList.add('animate');});
}// 添加响应式支持
function handleResponsive() {const checkWidth = () => {// 根据窗口宽度调整显示样式if (window.innerWidth < 768) {galleryContainer.classList.add('mobile-view');} else {galleryContainer.classList.remove('mobile-view');}};// 初始检查checkWidth();// 窗口调整时检查window.addEventListener('resize', checkWidth);
}// 性能优化:去抖动函数
function debounce(func, wait) {let timeout;return function() {const context = this;const args = arguments;clearTimeout(timeout);timeout = setTimeout(() => func.apply(context, args), wait);};
}// 优化后的窗口调整处理
window.addEventListener('resize', debounce(function() {// 调整画廊布局const galleryItems = document.querySelectorAll('.gallery-item');// 根据视窗大小调整项目大小和布局if (window.innerWidth < 768) {galleryItems.forEach(item => {item.style.width = '100%';});} else if (window.innerWidth < 1024) {galleryItems.forEach(item => {item.style.width = 'calc(50% - 20px)';});} else {galleryItems.forEach(item => {item.style.width = 'calc(33.333% - 20px)';});}
}, 250));// 初始化画廊
document.addEventListener('DOMContentLoaded', function() {// 立即初始化画廊initGallery();handleResponsive();// 如果初次加载没有显示图片,在短暂延迟后重试一次setTimeout(() => {if (document.querySelectorAll('.gallery-item').length === 0) {console.log('初始化重试');renderGallery();animateGalleryItems();}}, 500);
});

CSS样式(核心部分)

虽然本文重点是JavaScript,但为了完整性,这里提供核心CSS样式:

/* 基础样式 */
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;line-height: 1.6;color: #333;background-color: #f9f9f9;
}/* 画廊容器样式 */
.gallery-container {display: flex;flex-wrap: wrap;justify-content: space-between;max-width: 1200px;margin: 2rem auto;padding: 0 20px;
}/* 画廊项目样式 */
.gallery-item {position: relative;width: calc(33.333% - 20px);margin-bottom: 30px;border-radius: 5px;overflow: hidden;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);cursor: pointer;transition: transform 0.3s ease, box-shadow 0.3s ease;opacity: 0;transform: translateY(20px);
}.gallery-item.animate {animation: fadeIn 0.5s forwards;
}.gallery-item:hover {transform: translateY(-10px);box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
}/* 图片样式 */
.gallery-img {width: 100%;height: 250px;object-fit: cover;transition: transform 0.5s ease;
}.gallery-item:hover .gallery-img {transform: scale(1.1);
}/* 图片叠加层 */
.image-overlay {position: absolute;bottom: 0;left: 0;right: 0;background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));padding: 15px;color: white;opacity: 0;transition: opacity 0.3s ease;
}.gallery-item:hover .image-overlay {opacity: 1;
}/* 筛选按钮 */
.filter-container {text-align: center;margin: 2rem 0;
}.filter-btn {background: none;border: 2px solid #3498db;color: #3498db;padding: 8px 20px;margin: 0 5px;border-radius: 30px;cursor: pointer;font-weight: bold;transition: all 0.3s ease;
}.filter-btn.active, .filter-btn:hover {background-color: #3498db;color: white;
}/* 模态框样式 */
.modal {display: none;position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.8);z-index: 1000;justify-content: center;align-items: center;opacity: 0;transition: opacity 0.3s ease;
}.modal.show {opacity: 1;
}.modal-content {display: flex;flex-direction: column;max-width: 900px;width: 90%;background-color: white;border-radius: 5px;overflow: hidden;box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);transform: scale(0.9);transition: transform 0.3s ease;
}.modal.show .modal-content {transform: scale(1);
}.modal-img {width: 100%;max-height: 70vh;object-fit: contain;
}.image-info {padding: 20px;
}.close-modal {position: absolute;top: 15px;right: 20px;color: white;font-size: 30px;cursor: pointer;z-index: 1001;
}/* 动画 */
@keyframes fadeIn {to {opacity: 1;transform: translateY(0);}
}/* 类别切换过渡效果 */
.category-transition {opacity: 0.6;transition: opacity 0.3s ease;
}/* 响应式设计 */
@media (max-width: 1024px) {.gallery-item {width: calc(50% - 15px);}
}@media (max-width: 768px) {.gallery-item {width: 100%;}.modal-content {flex-direction: column;}.filter-container {display: flex;flex-wrap: wrap;justify-content: center;}.filter-btn {margin-bottom: 10px;}
}

代码解析与最佳实践

1. 模块化与组织结构

我们的代码采用了功能模块化的组织方式:

  • 数据层:使用galleryData数组存储图片信息
  • 视图层:通过renderGallery()函数负责DOM渲染
  • 控制层:事件处理函数管理用户交互

这种分离关注点的方式使代码更易于维护和扩展。

2. 性能优化策略

本案例中实现了多种性能优化策略:

  • 懒加载:使用IntersectionObserver API实现图片懒加载,减少初始加载时间
  • 去抖动:通过debounce函数优化窗口调整事件,减少不必要的计算
  • 事件委托:为画廊容器而非每个图片项添加点击事件,提高性能
  • 清理资源:关闭模态框时清除图片源,减轻内存负担

3. 增强用户体验

  • 平滑动画:使用CSS过渡和动画创建流畅的视觉效果
  • 本地存储:通过localStorage保存用户的类别偏好
  • 键盘支持:添加键盘事件处理(Esc关闭模态框)
  • 响应式设计:根据设备尺寸调整布局

4. 无障碍性考虑

虽然未在代码中详细展示,但实际项目应考虑以下无障碍性改进:

  • 为所有图片添加有意义的alt属性
  • 确保可通过键盘导航操作所有功能
  • 添加适当的ARIA属性以支持屏幕阅读器
  • 维持足够的色彩对比度

效果

构建交互式图片画廊

进一步扩展

这个交互式图片画廊还可以进一步扩展:

  1. 搜索功能:添加关键词搜索能力
  2. 无限滚动:实现无限滚动或分页加载更多图片
  3. 分享功能:允许用户分享特定图片到社交媒体
  4. 主题切换:添加暗/亮模式切换
  5. 后端集成:连接到真实API获取图片数据
  6. 图片上传:允许用户上传自己的图片

总结

本文通过构建交互式图片画廊的案例,展示了如何结合HTML和JavaScript创建一个功能丰富的Web应用。我们不仅实现了基本的图片展示和筛选功能,还融入了现代Web开发的最佳实践,包括懒加载、事件优化、本地存储和响应式设计。

这个案例可作为中高级JavaScript开发者的学习参考,也可以作为实际项目的起点进行扩展和定制。通过理解和应用这些技术,开发者可以创建既美观又高效的Web应用,提供出色的用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令大全:从入门到高效运维

适合人群&#xff1a;Linux新手 | 运维工程师 | 开发者 目录 一、Linux常用命令&#xff08;每天必用&#xff09; 1. 文件与目录操作 2. 文件内容查看与编辑 二、次常用命令&#xff08;按需使用&#xff09; 1. 系统管理与监控 2. 网络与通信 3. 权限与用户管理 三、…

Windows 10/11 使用 VSCode + SSH 免密远程连接 Ubuntu 服务器(指定端口)

摘要&#xff1a; 本文详细介绍如何在 Windows 系统上通过 VSCode Remote-SSH 免密登录远程 Ubuntu 服务器&#xff08;SSH 端口 2202&#xff09;&#xff0c;避免每次输入密码的繁琐操作&#xff0c;提高开发效率。 1. 环境准备 本地系统&#xff1a;Windows 10/11远程服务…

一些需要学习的C++库:CGAL和Eysshot

写在前面&#xff1a; 从开始工作到现在&#xff0c;去过多家公司&#xff0c;多个行业&#xff0c; 虽然大部分时间在通信业&#xff0c;但也有其它的行业的工作没有做完&#xff0c;但也很感兴趣。每次想要研究一下时&#xff0c;总是想不起来。 这里写一些信息&#xff0c;…

蓝桥杯16天刷题计划一一Day01

蓝桥杯16天刷题计划一一Day01&#xff08;STL练习&#xff09; 作者&#xff1a;blue 时间&#xff1a;2025.3.26 文章目录 蓝桥杯16天刷题计划一一Day01&#xff08;STL练习&#xff09;[P1540 [NOIP 2010 提高组\] 机器翻译 - 洛谷 (luogu.com.cn)](https://www.luogu.com.…

相对位置2d矩阵和kron运算的思考

文章目录 1. 相对位置矩阵2d2. kron运算 1. 相对位置矩阵2d 在swin-transformer中&#xff0c;我们会计算每个patch之间的相对位置&#xff0c;那么我们看到有一连串的拉伸和相减&#xff0c;直接贴代码&#xff1a; import torch import torch.nn as nntorch.set_printoptio…

Redis 版本演进及主要新特性

Redis 版本发布历史 稳定版本时间线 Redis 2.6 (2012年)Redis 2.8 (2013年11月)Redis 3.0 (2015年4月) - 首次支持集群Redis 3.2 (2016年5月)Redis 4.0 (2017年7月)Redis 5.0 (2018年10月)Redis 6.0 (2020年4月)Redis 6.2 (2021年2月)Redis 7.0 (2022年4月) - 最新稳定版(截至…

HTML5 Geolocation(地理定位)学习笔记

一、HTML5 Geolocation简介 HTML5 Geolocation&#xff08;地理定位&#xff09;API用于获取用户的地理位置信息。通过这个API&#xff0c;可以获取用户的纬度、经度、海拔等信息。由于地理定位可能涉及用户隐私&#xff0c;因此只有在用户同意的情况下&#xff0c;才能获取其…

爱普生VG3225EFN压控晶振5G基站低噪声的解决方案

在 5G 通信网络的高速发展中&#xff0c;系统噪声的控制成为保障网络可靠性与数据吞吐量的关键。爱普生 VG3225EFN 压控晶振凭借其卓越的低噪声特性&#xff0c;成为 5G 基站时钟系统的理想选择。通过创新的技术设计&#xff0c;这款晶振不仅为基站提供了稳定的时钟基准&#x…

【问题解决】Linux安装conda修改~/.bashrc配置文件后,root 用户下显示 -bash-4.2#

问题描述 在Linux安装conda下的python环境时候&#xff0c;修改了~/.bashrc文件&#xff0c;修改完成后&#xff0c;再次进入服务器后&#xff0c;登录时候显示的不是正常的[rootlocalhost ~]#&#xff0c;而是-bash-4.2# 原因分析&#xff1a; 网上原因有&#xff1a;/root下…

机器学习knnlearn5

import numpy as np from os import listdir from sklearn.neighbors import KNeighborsClassifier as kNN# 此函数用于将一个32x32的文本文件转换为一个1x1024的一维向量 def img2vector(filename):"""将32x32的文本文件转换为1x1024的向量:param filename: 要…

git revert 用法实战:撤销一个 commit 或 merge

git revert 1 区别 • 常规的 commit &#xff08;使用 git commit 提交的 commit&#xff09; • merge commit 2 首先构建场景 master上的代码 dev开发分支上&#xff0c;添加一个a标签&#xff0c;并commit这次提交 切到master上&#xff0c;再次进行改动和提交 将de…

自然语言处理|高效法律助手:AI如何解析合同条款?

引言&#xff1a;法律 AI 的崛起 在数字化浪潮快速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是一个陌生的概念&#xff0c;它正以快速发展渗透到各个领域&#xff0c;法律行业也不例外。从智能合同审查到法律风险预测&#xff0c;AI 技术为法律工作带来…

【数据分享】2000—2024年我国乡镇的逐年归一化植被指数(NDVI)数据(年最大值/Shp/Excel格式)

之前我们分享过2000-2024年我国逐年的归一化植被指数&#xff08;NDVI&#xff09;栅格数据&#xff0c;该逐年数据是取的当年月归一化植被指数&#xff08;NDVI&#xff09;的年最大值&#xff01;另外&#xff0c;我们基于此年度栅格数据按照行政区划取平均值&#xff0c;得到…

办公网络健康监控(域名健康监控)

需求 办公室访问一些网络经常出现故障 现需要时时观察监控这些网络的健康 包含专线网等其他网络 实施 支持 SNMP 且支持 Webhook 发送报警的开源监控系统 hertzbeat:关系型数据库+时序数据库; Zabbix:关系型数据库; LibreNMS:关系型数据库; Prometheus(包含ale…

蓝桥杯 合并数列

问题描述 小明发现有很多方案可以把一个很大的正整数拆成若干个正整数的和。他采用了其中两种方案&#xff0c;分别将它们列为两个数组&#xff1a; {a₁, a₂, ..., aₙ}{b₁, b₂, ..., bₘ} 两个数组的元素和相同。 定义一次合并操作为&#xff1a;将某个数组中相邻的两…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

个人学习编程(3-29) leetcode刷题

最后一个单词的长度&#xff1a; 思路&#xff1a;跳过末尾的空格&#xff0c;可以从后向前遍历 然后再利用 while(i>0 && s[i] ! ) 可以得到字符串的长度&#xff0c; int lengthOfLastWord(char* s) {int length 0;int i strlen(s) - 1; //从字符串末尾开始//…

PAT甲级(Advanced Level) Practice 1028 List Sorting

原题 1028 List Sorting - PAT (Advanced Level) Practice 题目大意 输入n个学生的id、姓名、分数&#xff0c;再输入C表示对C列进行排序。 id&#xff1a;从小到大排 姓名&#xff1a;姓名不同时从小到大排&#xff0c;相同时id从小到大排 分数&#xff1a;不同时从小到…

UE4学习笔记 FPS游戏制作20 重写机器人和玩家死亡 切换相机和模型

定义父类中的死亡方法 在父类中定义OnDie方法&#xff0c;不需要实现&#xff0c;由子类实现各自的死亡逻辑 新建一个Die方法&#xff0c;处理公共的死亡逻辑 Die的实现&#xff1a; 以前的分离控制现在要延迟做&#xff0c;如果分离了控制器&#xff0c;就无法再获取到玩家的…

Linux信号的诞生与归宿:内核如何管理信号的生成、阻塞和递达?

个人主页&#xff1a;敲上瘾-CSDN博客 个人专栏&#xff1a;Linux学习、游戏、数据结构、c语言基础、c学习、算法 目录 一、认识信号 二、信号的产生 1.键盘输入 2.系统调用 3.系统指令 4.硬件异常 5.软件条件 三、信号的保存 1.block 2.pending 3.handler 四、信号…