python项目开发——简易图书管理系统

项目名称:简易图书管理系统

  • 项目简介

开发一个简单的图书管理系统,帮助用户记录和管理图书信息。该系统应具备添加图书、查看图书、搜索图书、更新图书信息和删除图书等基本功能,并将数据存储在文件中。

  • 项目需求

1. 用户界面
  1. 提供简易的命令行界面供用户操作。
  2. 用户可以选择不同的操作:添加图书、查看图书、搜索图书、更新图书信息、删除图书和退出程序。
2. 功能模块
     a.添加图书

     - 用户输入书名、作者、出版年份和ISBN(也就是国际标准书号)。

     - 将图书信息保存到一个数据结构中(如列表)。

     b.查看图书

     - 显示所有已记录的图书信息。

     - 每条记录包括书名、作者、出版年份和ISBN。

     c.搜索图书

     - 用户可以按书名或作者搜索图书,显示匹配的结果。

     d.更新图书信息

     - 用户可以选择某本图书并更新其信息。

     e.删除图书

     - 用户可以按ISBN删除特定的图书记录。

     f.退出程序

     - 用户选择退出程序后,系统保存所有图书记录到一个文件中,以便下次启动时读取。

3. 数据存储

   - 使用文本文件(如.txt文件)保存和读取图书记录,确保数据在程序关闭后不丢失。

  •  项目步骤

1. 初始化项目

   - 创建一个新的Python项目文件。

   - 创建必要的函数和数据结构(如列表)。

2. 实现功能模块

   - 编写添加图书的函数,提示用户输入必要信息,并保存到数据结构中。

   - 编写查看图书的函数,遍历数据结构并打印所有记录。

   - 编写搜索图书的函数,根据用户输入的条件查询数据结构并显示匹配结果。

   - 编写更新图书信息的函数,根据用户选择更新数据结构中的记录。

   - 编写删除图书的函数,根据用户输入的ISBN从数据结构中删除相应记录。

   - 编写文件读写函数,在程序启动时读取文件并加载记录,在程序退出时保存记录到文件。

3. 用户交互界面

   - 使用循环结构创建用户交互界面,根据用户选择调用相应的功能模块。

   - 提供明确的提示信息和错误处理机制,确保用户输入的有效性。

4. 测试和调试

   - 对每个功能模块进行单独测试,确保其正确性。

   - 测试整个系统的工作流程,检查各功能模块之间的交互是否正常。

   - 处理可能出现的异常情况,如文件读写错误、用户输入错误等。

  •  项目扩展

完成基本功能后,可以考虑添加以下扩展功能,完成者将获得更高评分。

- 提供更复杂的搜索功能,例如按出版年份搜索图书。

- 添加用户登录功能,支持不同用户管理自己的图书列表。

- 提供图形用户界面(GUI)实现,使用如Tkinter等库。

实验器材、设备和平台

  1. 计算机
  2. 操作系统:Windows、macOS或Linux
  3. 编程语言:Python 3.x
  4. 开发环境:任意Python集成开发环境(IDE),例如PyCharm、VSCode,或文本编辑器如Sublime Text
  5. 必要的Python库:标准库Tkinter、json、os、hashlib

 接下来,将代码划分成各个模块,解释说明其功能与实现。

项目呈现

一、导入库和变量初始化的实现

import tkinter as tk
from tkinter import messagebox, simpledialog
import json
import os
import hashlibFILE_PATH_TEMPLATE = "{}_books.json"
current_user = None
books = []
  • 导入了 Tkinter 库用以创建图形用户界面。
  • 导入了 messagebox 和 simpledialog 模块用于消息对话框和简单对话框。
  • 导入了 json 库用于处理数据的序列化和反序列化。
  • 导入了 os 库用于文件操作。
  • 导入了 hashlib 库用于密码哈希处理。
  • 初始化文件路径的模板 FILE_PATH_TEMPLATE 以及当前用户变量 current_user 以及图书列表 books

二、数据加载和保存功能的实现

def load_data(username):global booksfile_path = FILE_PATH_TEMPLATE.format(username)if os.path.exists(file_path):with open(file_path, "r", encoding="utf-8") as file:books = json.load(file)else:books = []def save_data(username):file_path = FILE_PATH_TEMPLATE.format(username)with open(file_path, "w", encoding="utf-8") as file:json.dump(books, file, ensure_ascii=False, indent=4)
  • load_data(username):根据用户名加载用户对应的图书数据文件,如果文件存在,则读取数据,否则将会初始化为空列表。
  • save_data(username):将当前用户的图书数据保存到文件中。

三、图书管理功能的实现

①添加图书
def add_book():book_name = simpledialog.askstring("添加图书", "所添书名:")author = simpledialog.askstring("添加图书", "何许人所著::")year = simpledialog.askstring("添加图书", "何时所著:")ISBN = simpledialog.askstring("添加图书", "图书的ISBN(国际标准书号):")if book_name and author and year and ISBN:books.append({"书名": book_name, "作者": author, "出版年份": year, "ISBN": ISBN})messagebox.showinfo("成功", "添加成功了哟!!!")save_data(current_user)cat_books()else:messagebox.showwarning("错误输入!", "添加失败!!!。")
  • 通过对话框来获取书名、作者、出版年份和以及ISBN 信息,并添加到图书列表中。
  • 检查是否为完整的输入,不完整则显示警告信息。
  • 添加成功后保存数据并刷新图书列表。
②查看图书
def cat_books():listbox.delete(0, tk.END)for idx, book in enumerate(books, 1):listbox.insert(tk.END, f"{idx}. 书名: {book['书名']}, 作者: {book['作者']}, 出版年份: {book['出版年份']}, ISBN: {book['ISBN']}")
  • 将所有图书信息显示在列表框中。
③搜索图书
def search_books():search_term = simpledialog.askstring("搜索图书", "请输入书名、作者或出版年份进行搜索:")if search_term:listbox.delete(0, tk.END)results = [book for book in books if search_term in book['书名'] or search_term in book['作者'] or search_term == book['出版年份']]if results:for idx, book in enumerate(results, 1):listbox.insert(tk.END, f"{idx}. 书名: {book['书名']}, 作者: {book['作者']}, 出版年份: {book['出版年份']}, ISBN: {book['ISBN']}")else:messagebox.showinfo("伤心", "没有找到/(ㄒoㄒ)/~~。")
  • 通过对话框获取搜索关键词,根据书名、作者或出版年份进行搜索。
  • 将搜索结果显示在列表框中,如果没有找到则显示信息框提示。
④更新图书信息
def update_book():isbn = simpledialog.askstring("更新图书", "请输入图书的ISBN来更新信息:")for book in books:if book['ISBN'] == isbn:book['书名'] = simpledialog.askstring("更新图书", f"请输入新的书名(当前是: {book['书名']}):")book['作者'] = simpledialog.askstring("更新图书", f"请输入新的作者(当前是: {book['作者']}):")book['出版年份'] = simpledialog.askstring("更新图书", f"请输入新的出版年份(当前是: {book['出版年份']}):")messagebox.showinfo("成功", "图书相关信息更新成功o(* ̄▽ ̄*)ブ!")save_data(current_user)cat_books()returnmessagebox.showwarning("未找到", "坏了,彻查无果!!")
  • 根据输入的 ISBN 查找图书并更新其信息,未找到则提示。
⑤删除图书
def delete_book():isbn = simpledialog.askstring("删除图书", "请输入要删除图书的ISBN:")global booksbooks = [book for book in books if book['ISBN'] != isbn]messagebox.showinfo("成功", "图书删除成功!")save_data(current_user)cat_books()
  • 根据输入的 ISBN 删除图书,删除成功后保存数据并刷新列表。

四、用户管理功能的实现

①用户登录
def login():global current_userusername = simpledialog.askstring("登录", "请输入用户名:")password = simpledialog.askstring("登录", "请输入密码:", show='*')if username and password:hashed_password = hashlib.sha256(password.encode()).hexdigest()if os.path.exists("users.json"):with open("users.json", "r", encoding="utf-8") as file:users = json.load(file)else:users = {}if username in users and users[username] == hashed_password:current_user = usernamemessagebox.showinfo("成功", "登录成功!")load_data(current_user)cat_books()enable_buttons()else:messagebox.showwarning("失败", "用户名或密码错误!")else:messagebox.showwarning("输入错误", "所有字段均为必填。")
  • 通过对话框获取用户名和密码,验证用户信息是否正确。
  • 如果验证成功则加载用户数据并启用功能按钮。
②用户注册
def register():username = simpledialog.askstring("注册", "请输入用户名:")password = simpledialog.askstring("注册", "请输入密码:", show='*')if username and password:hashed_password = hashlib.sha256(password.encode()).hexdigest()if os.path.exists("users.json"):with open("users.json", "r", encoding="utf-8") as file:users = json.load(file)else:users = {}if username not in users:users[username] = hashed_passwordwith open("users.json", "w", encoding="utf-8") as file:json.dump(users, file, ensure_ascii=False, indent=4)messagebox.showinfo("成功", "注册成功,请登录!")else:messagebox.showwarning("失败", "用户名已存在!")else:messagebox.showwarning("输入错误", "所有字段均为必填。")
  • 通过对话框获取用户名和密码,检查用户名是否已存在,不存在则注册新用户。

③功能按钮的启动

def enable_buttons():button_add.config(state=tk.NORMAL)button_view.config(state=tk.NORMAL)button_search.config(state=tk.NORMAL)button_update.config(state=tk.NORMAL)button_delete.config(state=tk.NORMAL)
  • 登录成功后将开启各个功能按钮。

④主窗口的创建

window = tk.Tk()
window.title("图书管理系统")
window.geometry("600x400")tk.Button(window, text="登录", command=login).pack(fill=tk.X)
tk.Button(window, text="注册", command=register).pack(fill=tk.X)
tk.Button(window, text="退出程序", command=window.quit).pack(fill=tk.X)button_add = tk.Button(window, text="添加图书", command=add_book, state=tk.DISABLED)
button_view = tk.Button(window, text="查看图书", command=cat_books, state=tk.DISABLED)
button_search = tk.Button(window, text="搜索图书", command=search_books, state=tk.DISABLED)
button_update = tk.Button(window, text="更新图书信息", command=update_book, state=tk.DISABLED)
button_delete = tk.Button(window, text="删除图书", command=delete_book, state=tk.DISABLED)button_add.pack(fill=tk.X)
button_view.pack(fill=tk.X)
button_search.pack(fill=tk.X)
button_update.pack(fill=tk.X)
button_delete.pack(fill=tk.X)listbox = tk.Listbox(window)
listbox.pack(fill=tk.BOTH, expand=True)window.mainloop()
  • 创建主窗口并设置其标题和尺寸。
  • 添加登录、注册和退出按钮。
  • 添加功能按钮并初始化为禁用状态。
  • 创建列表框用于显示图书信息。
  • 启动事件循环,显示窗口。

完整代码呈现:

# 导入必要的库以及变量初始化
import tkinter as tk
from tkinter import messagebox, simpledialog
import json
import os
import hashlibFILE_PATH_TEMPLATE = "{}_books.json"
current_user = None
books = []'''加载和保存数据'''# 加载图书数据
def load_data(username):global booksfile_path = FILE_PATH_TEMPLATE.format(username)if os.path.exists(file_path):with open(file_path, "r", encoding="utf-8") as file:books = json.load(file)else:books = []# 保存图书数据
def save_data(username):file_path = FILE_PATH_TEMPLATE.format(username)with open(file_path, "w", encoding="utf-8") as file:json.dump(books, file, ensure_ascii=False, indent=4)'''图书管理功能'''# 添加图书
def add_book():book_name = simpledialog.askstring("添加图书", "所添书名:")author = simpledialog.askstring("添加图书", "何许人所著::")year = simpledialog.askstring("添加图书", "何时所著:")ISBN = simpledialog.askstring("添加图书", "图书的ISBN(国际标准书号):")if book_name and author and year and ISBN:books.append({"书名": book_name, "作者": author, "出版年份": year, "ISBN": ISBN})messagebox.showinfo("成功", "添加成功了哟!!!")save_data(current_user)cat_books()else:messagebox.showwarning("错误输入!", "添加失败!!!。")# 查看图书
def cat_books():listbox.delete(0, tk.END)for idx, book in enumerate(books, 1):listbox.insert(tk.END,f"{idx}. 书名: {book['书名']}, 作者: {book['作者']}, 出版年份: {book['出版年份']}, ISBN: {book['ISBN']}")# 搜索图书
def search_books():search_term = simpledialog.askstring("搜索图书", "请输入书名、作者或出版年份进行搜索:")if search_term:listbox.delete(0, tk.END)results = [book for book in books ifsearch_term in book['书名'] or search_term in book['作者'] or search_term == book['出版年份']]if results:for idx, book in enumerate(results, 1):listbox.insert(tk.END,f"{idx}. 书名: {book['书名']}, 作者: {book['作者']}, 出版年份: {book['出版年份']}, ISBN: {book['ISBN']}")else:messagebox.showinfo("伤心", "没有找到/(ㄒoㄒ)/~~。")# 更新图书信息
def update_book():isbn = simpledialog.askstring("更新图书", "请输入图书的ISBN来更新信息:")for book in books:if book['ISBN'] == isbn:book['书名'] = simpledialog.askstring("更新图书", f"请输入新的书名(当前是: {book['书名']}):")book['作者'] = simpledialog.askstring("更新图书", f"请输入新的作者(当前是: {book['作者']}):")book['出版年份'] = simpledialog.askstring("更新图书", f"请输入新的出版年份(当前是: {book['出版年份']}):")messagebox.showinfo("成功", "图书相关信息更新成功o(* ̄▽ ̄*)ブ!")save_data(current_user)cat_books()returnmessagebox.showwarning("未找到", "坏了,彻查无果!!")# 删除图书
def delete_book():isbn = simpledialog.askstring("删除图书", "请输入要删除图书的ISBN:")global booksbooks = [book for book in books if book['ISBN'] != isbn]messagebox.showinfo("成功", "图书删除成功!")save_data(current_user)cat_books()# 用户登录
def login():global current_userusername = simpledialog.askstring("登录", "请输入用户名:")password = simpledialog.askstring("登录", "请输入密码:", show='*')if username and password:hashed_password = hashlib.sha256(password.encode()).hexdigest()if os.path.exists("users.json"):with open("users.json", "r", encoding="utf-8") as file:users = json.load(file)else:users = {}if username in users and users[username] == hashed_password:current_user = usernamemessagebox.showinfo("成功", "登录成功!")load_data(current_user)cat_books()enable_buttons()else:messagebox.showwarning("失败", "用户名或密码错误!")else:messagebox.showwarning("输入错误", "所有字段均为必填。")'''用户管理系统'''# 用户注册
def register():username = simpledialog.askstring("注册", "请输入用户名:")password = simpledialog.askstring("注册", "请输入密码:", show='*')if username and password:hashed_password = hashlib.sha256(password.encode()).hexdigest()if os.path.exists("users.json"):with open("users.json", "r", encoding="utf-8") as file:users = json.load(file)else:users = {}if username not in users:users[username] = hashed_passwordwith open("users.json", "w", encoding="utf-8") as file:json.dump(users, file, ensure_ascii=False, indent=4)messagebox.showinfo("成功", "注册成功,请登录!")else:messagebox.showwarning("失败", "用户名已存在!")else:messagebox.showwarning("输入错误", "所有字段均为必填。")'''功能按钮的启动'''def enable_buttons():button_add.config(state=tk.NORMAL)button_view.config(state=tk.NORMAL)button_search.config(state=tk.NORMAL)button_update.config(state=tk.NORMAL)button_delete.config(state=tk.NORMAL)'''主窗口的创建'''# 创建主窗口
window = tk.Tk()
window.title("图书管理系统")
window.geometry("600x400")# 登录和注册按钮
tk.Button(window, text="登录", command=login).pack(fill=tk.X)
tk.Button(window, text="注册", command=register).pack(fill=tk.X)
tk.Button(window, text="退出程序", command=window.quit).pack(fill=tk.X)# 添加按钮(在用户登录后启用)
button_add = tk.Button(window, text="添加图书", command=add_book, state=tk.DISABLED)
button_view = tk.Button(window, text="查看图书", command=cat_books, state=tk.DISABLED)
button_search = tk.Button(window, text="搜索图书", command=search_books, state=tk.DISABLED)
button_update = tk.Button(window, text="更新图书信息", command=update_book, state=tk.DISABLED)
button_delete = tk.Button(window, text="删除图书", command=delete_book, state=tk.DISABLED)button_add.pack(fill=tk.X)
button_view.pack(fill=tk.X)
button_search.pack(fill=tk.X)
button_update.pack(fill=tk.X)
button_delete.pack(fill=tk.X)# 列表示例显示
listbox = tk.Listbox(window)
listbox.pack(fill=tk.BOTH, expand=True)# 启动事件循环
window.mainloop()

项目特色

1. 用户管理系统

  • 注册和登录:系统具备用户注册和登录功能,通过用户名和密码确保每个用户的数据独立和安全。密码采用SHA-256哈希加密存储,增加了系统的安全性。
  • 数据隔离:每个用户的图书数据存储在独立的JSON文件中,保证了数据的隔离和隐私性。

2. 图书管理功能

  • 全面的图书管理:提供添加、查看、搜索、更新和删除图书的功能,满足了基本的图书管理需求。
  • 搜索功能:支持按书名、作者和出版年份进行搜索,方便用户快速查找图书。

3. 友好的用户界面

  • 命令行界面:通过简单直观的命令行界面与用户交互,操作方便。
  • 图形用户界面(GUI):使用Tkinter库开发的图形界面,使用户体验更加友好和直观。

4. 数据持久化

  • 文件存储:所有数据均保存在本地JSON文件中,保证了数据的持久化。每次操作后自动保存数据,确保不会丢失。

5.未来小改进方向

  • 引入数据库:在数据存储方面,未来可以考虑使用数据库来管理数据,以此提高数据处理的效率和安全性。

谢谢观看,点个小赞~~~o(* ̄▽ ̄*)ブ

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

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

相关文章

uniapp+h5 ——微信小程序页面截屏保存在手机

web-view 需要用到 web-view ,类似于iframe, 将网页嵌套到微信小程序中,参数传递等; 示例(无法实时传递数据),页面销毁时才能拿到h5传递的数据,只能利用这点点击跳转到小程序另一个…

制作ARM架构 docker镜像

docker简介 docker客户端 Docker 客户端有两种替代选项:名为 docker 的命令行应用程序或名为 Docker Desktop 的基于图形用户界面 (GUI) 的应用程序。 CLI 和 Docker Desktop 均与 Docker 服务器交互。 来自 CLI 或 Docker Desktop 的 docker 命令使用 Docker REST API 将指…

KAN(Kolmogorov-Arnold Network)的理解 1

系列文章目录 第一部分 KAN的理解——数学背景 文章目录 系列文章目录前言KAN背后的数学原理:Kolmogorov-Arnold representation theorem 前言 这里记录我对于KAN的探索过程,每次会尝试理解解释一部分问题。欢迎大家和我一起讨论。 KAN tutorial KAN背…

NVIDIA AGX Orin/Jetson 平台+GMSL 车载AI视觉方案——索尼车载1700万超高像素前视摄像头

推出“1700万超高像素前视摄像头”以及基于该摄像头的“智驾超级视觉5V方案”,该摄像头采用索尼1700万像素IMX735车载图像传感器,搭载水平120度超大广角镜头和出色的超高速传输技术,是行业革命性创新产品,在车展上备受关注。 索尼…

mysql实战——mysql5.7保姆级安装教程

1、上传 上传5.7压缩包到/usr/local目录下 2、解压 cd /usr/local tar -zxvf mysql--5.7.38-linux-glibc2.12-x86_64.tar.gz mv mysql-5.7.38-linux-glibc2.12-x86_64/ mysql 3、创建mysql用户组和用户 groupadd mysql useradd -g mysql mysql 4、创建数据目录data&#xf…

git冲突

git冲突的产生: 首先用户A新建一个文件conflict,并在里面添加内容 然后通过add,commit,push将该文件上传到远端仓库 然后用户B通过pull将程序拉下来之后,也在这个文档里面进行编辑,并且内容不一样 如果这个时候其中一个人push&…

从alpine构建预装vcpkg的docker image用于gitea actions CI

动机 想要构建一个基于vcpkg的交叉编译容器平台用于cpp项目的CI(自动集成),此处仅提供最基础的image,amd64的机子上构建完成后大小为533兆(着实不小😓),各位看官可以在此基础上自行…

Python库之PyQuery的简介、安装、使用方法详细攻略

Python库之PyQuery的简介、安装、使用方法详细攻略 简介 PyQuery是一个Python库,它提供了一种类似于jQuery的方式来解析和操作HTML文档。jQuery是一个广泛使用的JavaScript库,它简化了HTML文档的遍历、操作、事件处理等操作。PyQuery使得在Python中处理…

产品公告 | MemFire Cloud认证服务支持微信扫码登录

前言 为了满足国内用户日益增长的操作习惯需求,并进一步提升用户体验,MemFire Cloud认证服务已集成微信扫码登录功能。微信,作为国内广受欢迎的社交平台,其扫码登录功能以其便捷性和快速性赢得了广大用户的青睐。现在&#xff0c…

SQL 语言:完整性约束

文章目录 概述主键 ( Primary Key ) 约束外键(Foreign Key)约束属性值上的约束全局约束总结 概述 数据库的完整性是指数据库正确性和相容性,是防止合法用户使用数据库时向数据库加入不符合语义的数据。保证数据库中数据是正确的,…

不可变且透明地建模数据 - 面向数据编程 v1.1

以不变且透明的方式对数据进行建模是面向数据编程的四大原则之一。我们将探讨为何不变性和透明性在数据建模时如此重要,以及如何使用 Java 的功能(尤其是记录(Record))来实现这一点。 1.不变性和透明度 软件错误的一…

pytorch_trick(4) 模型本地保存与读取方法

模型本地保存与读取方法 同时,借助state_dict()方法,我们可以实现模型或优化器的本地保存于读取。此处以模型为例,优化器的本地保存相关操作类似。   对于模型而言,其实也有state_dict()方法。通过该方法的调用,可以…

2024年03月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 运行如下代码,若输入整数3,则最终输出的结果为?( ) def f(x):if x==1:s=1else:s

记录关联(笛卡尔积)——kettle开发24

一、记录关联(笛卡尔积) 记录关联就是对两个数据流进行笛卡尔积操作。如下图所示,我们有两组数据分别为aaa和bbb,笛卡尔积后我们生成了4种结果,即2*24条记录。 记录关联(笛卡尔积)需要注意的是我们需要指定一个主步骤。即参考基准的数据 : 二…

分布式锁的设计与实现:基于Redis的方案

在分布式系统中,保证资源的同步访问是一个常见且重要的问题。分布式锁提供了一种解决方案,而Redis作为一种高性能的内存数据库,是实现这种锁的理想选择。本文详细介绍了Redis分布式锁的实现原理,包括其优势、实现机制以及潜在的问…

leetCode.82. 删除排序链表中的重复元素 II

leetCode.82. 删除排序链表中的重复元素 II 题目思路: 代码 class Solution { public:ListNode* deleteDuplicates(ListNode* head) {auto dummy new ListNode(-1);dummy->next head;auto p dummy;while(p->next){auto q p->next->next;while(q …

vue3项目使用pinia状态管理器----通俗易懂

1、首先安装pinia yarn add pinia # 或使用npm npm install pinia 2、在项目的src目录下新建store文件夹,然后store目录下新建index.js / index.ts : 我这里是index,js import { createPinia } from "pinia"// 创建 Pinia 实例 const pini…

【C语言】10.C语言指针(2)

文章目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.冒泡排序算法步骤 5.二级指针6.指针数组7.指针数组模拟二维数组 1.数组名的理解 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0];这里我们使用 &arr[0] 的方式拿到了数组第一个元素的地址&am…

约翰·舒尔曼访谈解读:2027年AGI将成现实?

随着人工智能技术的不断进步,AGI(通用人工智能)的实现似乎不再是遥不可及的梦想。近日,OpenAI联合创始人兼首席架构师约翰舒尔曼(John Schulman)在访谈中分享了他对AI模型未来发展的看法,并预言…

判断dom元素是否滚动到底、是否在可视区域

概览 我们日常开发中,在面对懒加载、虚拟列表需求时,经常需要判断dom元素是否滚动到底、是否在可视区域。但是由于涉及的属性太多了,比如scrollTop、clientHeight、scrollHeight、getBoundingClientRect()等属性,现根据这两个场景…