我刚刚使用 HTML、CSS 和 vanilla JavaScript 创建了一个前端购物车 Web 应用程序。因为我喜欢在当地的杂货店购买蔬菜,所以我的想法是基于一家名为芬利农场商店的农场商店的想法。
要点击该项目,实时链接是:https://gabrielrowan.github.io/Finleys-Farm-Shop-FE/
使用此应用程序,您可以:
?将商店商品添加到购物车
?更改商店商品的数量
?在手推车模式上查看购物车中的所有商品
?查看购物车中所有商品的总价
?查看购物车中的商品数量
?即使您刷新页面或关闭选项卡然后重新打开它,仍将所有商品保留在购物车中
该项目的背景
到目前为止,我在工作中主要从事后端应用程序的工作。不过,今年夏天,我开始从事一个全栈项目,包括设计和实现前端。我真的很喜欢它,它让我想更多地发展我的前端技能。
我想挑战自己在不使用 CSS 库的情况下完成这个项目,不是因为我认为使用它们不好,而是因为像 Bootstrap 这样的东西通常是我前端的首选。
我之前从未在 JavaScript 中使用过浏览器本地存储,因此我决定创建一个项目将是我实际了解它的最佳方式。
我的项目目标
当我第一次开始这个项目时,我心中有几个目标。这些是:
?响应能力 - 我希望 UI 能够适应移动设备、ipad 和桌面视图
?不使用 CSS 库创建购物车模式
?熟悉在 JavaScript 中使用本地存储
未来目标
创建前端是我这个项目计划的第 1 部分。第二部分是使用 Django 将其转换为全栈应用程序,以便商店商品来自数据库,而不是硬编码在 HTML 中。
使其响应式
网格
为了使应用程序适应不同的屏幕尺寸,我使用了 Kevin Powell 视频中的响应式网格版本。
.shop-items { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
神奇之处在于 grid-template-columns 值。它的本质意思是:
在此父容器中容纳尽可能多的列,最小尺寸为 12rem,最大尺寸为可用空间的 1 分之一。
使用此网格,当从更宽的桌面视图到更窄的移动视图时,列数(以商店商品卡的数量表示)可以动态地从 4 减少到 1,而无需编写额外的媒体查询。
横幅字体大小
对于横幅标题“Finley's Farm Shop”,我使用了clamp(),以便字体大小能够自动缩放。如果不这样做,我发现适用于桌面的字体大小对于移动设备来说太大了。
.shop-items { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
这意味着字体大小的目标是 5vw(视口宽度 - 又称为总可见屏幕宽度的 5%)。
字体大小的最小值为 3.8rem,因此如果 5vw 等于小于 3.8rem,则字体大小将为 3.8rem。
字体大小的最大值可以设置为 5.6rem,因此如果 5vw 相当于大于 5.6rem,则字体大小将为 5.6rem。
有多种方法可以精确计算最小和最大字体大小之间的渐变,并使用它来选择您喜欢的中间值,但我使用检查器来观察它?
这里有一篇关于计算精确渐变的 CSS 技巧文章。
创建模态
不同的屏幕尺寸
对于手推车,我想要一个会从桌面屏幕右侧出现的模式:
在移动视图上,我决定它应该占据全屏尺寸:
购物车项目网格区域
当购物车项目被添加到购物车时,我的大部分时间都花在了 CSS 上。我使用网格模板区域,以便购物车项目的不同部分(项目标题,即“Apple”、价格、项目数量和图像)占用我为它们计划的分配空间。
.banner-title { font-size: clamp(3.8rem, 5vw, 5.6rem); }
JavaScript
对于模态 JavaScript,我的目标是:
- 单击购物车图标时隐藏模式
- 单击关闭图标时关闭模式
- 禁用页面滚动,以便在模式打开时无法向下滚动商店商品的主页
为了实现这一点,我向两个图标添加了事件监听器,调用了函数toggleModal。如果尚未将其添加到模态元素中,则会添加一个名为 .active 的类;如果已存在,则将其删除。
在CSS中,我将模态框设置为默认隐藏,并将.active类设置为显示它。
设置CSS:
.shop-items { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }
切换类以显示/隐藏模式:
.banner-title { font-size: clamp(3.8rem, 5vw, 5.6rem); }
这意味着关闭图标和购物车图标上的事件侦听器可以重用相同的功能,因为如果尚未显示,它将显示模态,如果已经打开,它将隐藏它。
使用本地存储
对于本地存储,我发现 Web Dev Simplified 的视频“JavaScript Cookies vs. Local Storage vs. Session Storage”特别有帮助。它讨论了这三种存储数据方式之间的差异、如何在开发工具的“应用程序”选项卡中查看数据以及如何为每种数据存储类型添加和删除项目。
这是我将 2 件商品添加到购物车后项目的“应用程序”选项卡的样子:
关注点分离
我决定将与修改 DOM(添加元素、删除元素、编辑元素)相关的函数与与本地存储相关的函数分开。例如,我有一个函数removeCartItemFromLocalStorage,它的功能与上面所说的一样,并且与removeCartItemFromModalDOM不同,它从模态中删除商店项目html。
.cart-item { display: grid; grid-template-areas: "image description description" "image price quantity"; grid-template-columns: min-content 1fr 1fr; grid-template-rows: 2.5rem 3.5rem; }
当商店商品从购物车中移除时,需要调用这两个函数,将它们作为单独的函数可以帮助我检查是否已完成该过程的两个所需部分。如果不从 DOM 中删除 html,网页将不会直观地反映出该商品已从购物车中删除。如果不从本地存储中删除该项目,刷新页面或关闭选项卡时更改将无法保留。
遇到问题
当我在研究 JavaScript 中的本地存储功能时,我遇到了一个让我非常困惑的问题。到目前为止我完成的步骤是:
- 在初始页面加载时将本地存储设置为空数组
- 当点击商店商品上的“添加”按钮时,将调用以下函数:
- 项目已添加到本地存储
- 购物车商品的 HTML 已添加到手推车模式
- 获取总价,即本地存储阵列中每个商品的数量*价格
- 将价格元素的innerText设置为从本地存储检索的价格
我点击了一下,看起来也很棒! ...直到我刷新页面。然后,价格设置为与之前相同的总价,但 DOM 已完全恢复为初始页面加载时的样子。从视觉上看,购物车中似乎没有商品(显示的是添加按钮,而不是数量输入控件),但总数超过 0 英镑。
添加到购物车和未添加到购物车的商品之间的差异
这真的让我很困惑,我花了一段时间才弄清楚。最终,我明白了。是的,我正在将这些项目添加到本地存储中。但是,当重新加载页面并触发 DOMContentLoaded 事件侦听器时,我没有根据本地存储中的内容渲染 DOM。事实上,现阶段我根本没有检查本地存储中的内容。
意识到这一点后,我创建了一个名为 DOMContentLoaded 的函数,该函数循环遍历本地存储中的产品数组中的所有产品,找到每个产品的 id,然后更新相关产品的 html 元素以显示已添加的产品到购物车。
该函数的简化版本是:
const loadCartState = () =>; { const cart = JSON.parse(localStorage.getItem("cart")); 如果(!购物车) { 购物车=[]; localStorage.setItem("购物车", JSON.stringify(cart)); } cart.forEach(产品 => { const shopItem = document.querySelector(`.shop-item[data- > <h2> 部署 </h2> <p>我使用 Github Pages 部署了这个应用程序。我之前没有使用它进行部署,但发现该过程非常简单。我遇到的唯一问题是起初没有显示任何图像。我意识到这是因为区分大小写:我的图像文件夹名为 Img 但图像路径是 html 中的 img/ 。修复此问题并清除缓存后,网站按预期显示。 </p> <h2> 结论 </h2> <p>我从这个项目中学到了很多东西,特别是关于 CSS 网格和通过 JavaScript 使用本地存储。我很想添加更多页面并将其变成一个完整的前端电子商务应用程序,但我决定暂时保留它的 MVP,以便我可以专注于下一阶段将其变成 Django 应用程序并挂钩它到数据库?</p>
以上是我的农场商店购物车项目的详细内容。更多信息请关注PHP中文网其他相关文章!

这是我们在形式可访问性上进行的小型系列中的第三篇文章。如果您错过了第二篇文章,请查看“以:focus-visible的管理用户焦点”。在

CSS盒子阴影和轮廓属性获得了主题。让我们查看一些在真实主题中起作用的示例,以及我们必须将这些样式应用于WordPress块和元素的选项。

本教程演示了使用智能表单框架创建外观专业的JavaScript表单(注意:不再可用)。 尽管框架本身不可用,但原理和技术仍然与其他形式的建筑商相关。

Svelte Transition API提供了一种使组件输入或离开文档(包括自定义Svelte Transitions)时动画组件的方法。

本文探讨了Envato Market上可用的PHP表单构建器脚本,比较了其功能,灵活性和设计。 在研究特定选项之前,让我们了解PHP形式构建器是什么以及为什么要使用一个。 PHP形式


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。