SCAU学习笔记 - 自科三面前端方向实战演示
本来是准备写完二面直接开始写算法三面的,maimai那个封面图我都做好了。但是可恶的出题人说要等我出完解析再针对性避开出题,所以swan决定把那个先搁置,本文我们先以2023年的自科三面前端方向题为例带各位快速入门前端三件套(因为前端我也不太会所以只能说告诉你有些什么东西)
需要声明的是,本文仅是抛砖引玉,介绍大部分基础概念以及开发过程中找bug修bug的流程以及实现思路,具体代码实现不会在文中有体现,文末会有完整代码的链接,但还是希望各位能借助AI(这点很重要,AI对自学帮助很大的,任何不会的都不要犹豫马上去问)顺着我的思路来独立的实现
搁置算法题解,我们休息一下,读个加载进度条吧
原题题面
2023年的CSDN主页和现在的不太一样,pdf里面的文件已经失效了,我就懒得去找当时主页长什么样子了,直接复刻现在这个吧
环境搭建
相信很多小朋友都还是第一次接触开发,简单来说,代码需要用一些程序来编写和运行,本文使用的是Pycharm,我们的Python专业课用的也是这个IDE来编写代码,你可以使用免费版本,对本文内容来说已经够用了,或者看我这篇文章最前面的部分了解如何申请学生认证以免费使用完全体的Pycharm。
可能就有同学要问了,我们不是写前端吗,也没有使用Python啊,为什么要使用Pycharm呢?因为我这里使用的是Flask架构来方便调试,方便我直观地看到我网页写成了什么样子。
配置Python
首先我们来到Python的官网,点击上面导航栏的Download
直接点这个很显眼的Download下载安装包就行了,打开安装包记得先勾上这个
这个选项是把Python加到你系统的环境变量里面的,然后就点Install Now一路下一步就行了
配置Pycharm
Pycharm就没啥好说的了,在官网下载,然后一路下一步,需要的话记得把安装目录改到D盘就行了
新建项目
打开安装好的Pycharm,注册登录之后直接点击这个显眼的新建项目
选择左边的Flask项目,选择你创建项目的目录,然后创建即可
如果你的电脑没有安装Flask则会在第一次创建时自动下载,需要一段时间(或者科学上网),耐心等待即可
好了,我们现在已经成功创建了我们的项目,和学习C语言时一样,他已经填充了一些代码,我们先运行一下试试看,点击左上角的运行按钮,然后下面会弹出一大堆提示,点击这个蓝色的链接就会弹出浏览器打开刚刚写出来的网页了
默认的代码出来的网页应该是长这个样子,需要提一嘴的是这个网页是跑在你本地端口的,所以不要奢望说别人输入一样的网址也能打开这个网页
框架介绍
虽然我们前面配置Python配了老半天,但是我们还是要回去写前端三件套的,但是我的文件要去哪里新建?这是个问题,让我们观察下左边的文件结构
现在跟着我的这个模式来新建一些文件,并修改app.py
那个python文件里面的代码(仅有的几步需要敲python代码的地方)
接下来,我们就可以打开home.html
开始编写我们的网页代码了!
开码部分
打开home.html
我们可以直接在两个body中间的部分写上我们想要的内容,就会直接显示在网页上(记得每次修改之后要重新点运行而不是刷新网页就有变化)
顶部导航栏
我们再尝试导入一些图片,我们把CSDN的Logo下载到image目录下,然后这样写
这个效果不太对啊,我需要的是把这个logo和搜索框放在同一行,这个时候就需要写CSS样式了,我们还不着急新建文件,我们直接把这两个元素再用一层包起来
我们可以通过定义style的方式来修改样式,但是假如style特别多,我们可以类似C语言里面的结构体,把一大堆style封装在一起起个名字然后调用,写在最上面,比如说我现在要完善搜索框的格式,就像这样
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Home</title><style>.search-container {display: flex;align-items: center;justify-content: flex-start;width: 100%;}.search-input {flex: 1;padding: 10px;font-size: 16px;border: 1px solid #ccc;border-radius: 8px 0 0 8px;background-color: #F5F6F7;color: #867888;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);outline: none;}.search-input::placeholder {color: #867888;}.search-button {padding: 10px 20px;font-size: 16px;border: none;border-radius: 0 8px 8px 0;background-color: #FC5531;color: #fff;cursor: pointer;display: flex;align-items: center;justify-content: center;}.search-button:hover {background-color: #e04a28;}.search-button span {margin-left: 5px;}</style>
</head>
<body><div class="search-container"><input type="text" id="search-box" class="search-input" placeholder="输入到此处搜索"><button class="search-button" onclick="performSearch()">🔍<span>搜索</span></button></div>
</body>
</html>
运行出来的效果就是这样的了(反正现在带火都有AI,具体每个参数啥意思就不细讲了)
但是我的网页那么多东西,写在一个文件里面太臃肿了,所以我们解锁模块化开发,我们把刚才写好的顶端部分单独写在一个文件里面,之后遇到再调用就行,HTML的调用语法如图所示,但是css的样式还是必须写在home.html
里面
现在home.html
还是很长,所以我们考虑把样式也压到一个css文件里面去,我们写成这样就可以了
然后简单调整一下(不会就去问AI大人让他改,只要你认真看了AI的解释答辩的时候能说清楚怎么实现的就行)
需要你自己解决的问题:
- 如何保证这个顶部导航栏始终位于页面顶端
- 如何保证这个搜索框分为了两个部分
- 如何保证搜索框的长度合适并且居中
- (附加题)能否实现点击搜索框跳转到搜索页面(不用具体实现)
目标是实现到这样的效果,左边那个收起按钮涉及js,我们留到最后再作为可选项说一嘴
左侧导航栏
左侧导航栏就很好写了,反正我们只需要写一个壳子,就直接把所有图标并排摆就行了
但是现在发现一个问题注意到没有,咱们这个第一个选项被headbar盖住了,我们使用一个简单粗暴的方法,直接进行一个整体下移就搞定了,然后我们在这一趴在上点小花活,CSDN是有选中对应的图标的,他是进入对应的页面图标才会变色,我们可以把这个素材利用起来,鼠标碰到就变色,这个就属于页面的动态效果,需要我们写js来实现
我们现在html里面给每个图标两个状态属性,分别为选中和未选中
<a href="/home" class="nav-item"><img src="{{ url_for('static', filename='image/leftbar/Unselect/home.png') }}"data-unselect="{{ url_for('static', filename='image/leftbar/Unselect/home.png') }}"data-select="{{ url_for('static', filename='image/leftbar/Select/home.png') }}"alt="首页图标" class="nav-icon">首页</a>
然后我们来写js代码
document.addEventListener("DOMContentLoaded", () => {// 1. 添加一个事件监听器,监听 DOMContentLoaded 事件。// 这个事件会在 HTML 文档完全加载并解析完成后触发,// 确保脚本在页面的 DOM 元素可用时执行。const navItems = document.querySelectorAll(".nav-item");// 2. 使用 querySelectorAll 方法选择所有带有类名 "nav-item" 的元素。// 这些元素是导航栏中的每个 <a> 标签,存储在 navItems 变量中。// querySelectorAll 返回的是一个 NodeList(类似数组的对象)。navItems.forEach(item => {// 3. 遍历 navItems 中的每个导航项(item)。// forEach 是 NodeList 的方法,用于对每个元素执行回调函数。const img = item.querySelector(".nav-icon");// 4. 在当前导航项中,使用 querySelector 方法选择类名为 "nav-icon" 的 <img> 标签。// 这个 <img> 标签是导航项的图标,存储在 img 变量中。const unselectSrc = img.getAttribute("data-unselect");// 5. 使用 getAttribute 方法获取 <img> 标签的 "data-unselect" 属性值。// 这个值是未选中状态的图标路径,存储在 unselectSrc 变量中。const selectSrc = img.getAttribute("data-select");// 6. 使用 getAttribute 方法获取 <img> 标签的 "data-select" 属性值。// 这个值是选中状态的图标路径,存储在 selectSrc 变量中。item.addEventListener("mouseenter", () => {// 7. 为当前导航项添加一个 "mouseenter" 事件监听器。// 当鼠标悬停在导航项上时,会触发这个事件。img.setAttribute("src", selectSrc);// 8. 在事件触发时,使用 setAttribute 方法将 <img> 的 "src" 属性设置为 selectSrc。// 这会将图标切换为选中状态的图标。});item.addEventListener("mouseleave", () => {// 9. 为当前导航项添加一个 "mouseleave" 事件监听器。// 当鼠标移出导航项时,会触发这个事件。img.setAttribute("src", unselectSrc);// 10. 在事件触发时,使用 setAttribute 方法将 <img> 的 "src" 属性设置为 unselectSrc。// 这会将图标切换回未选中状态的图标。});});// 11. 结束 forEach 循环,确保每个导航项都绑定了鼠标事件监听器。
});
最后不要忘了在home.html
里面引入一下刚写的这个js文件就大功告成啦~
<script src="{{ url_for('static', filename='js/leftbar.js') }}"></script>
既然学了js,我们现在就可以搞一搞刚才搁置的只显示左边栏图标功能了,类似刚才的写法,我们给左边的这个leftbar加一个收起形态的标签,给收起形态下的文字内容设置为不显示
.leftbar.collapsed .nav-item span {display: none; /* 隐藏文字 */
}
在这里我们学了一些基础的动效的相关知识,简单来说就是css里面打标记,然后js控制什么时候在不同标记之间切换
主体部分
现在来到主体部分,我们从上往下看,首先需要实现的就是原本网页的标签页效果,点击不同的页签就会进入不同的页面,但是我们的网址没有改变
这同样也是用我们刚才学习的js实现的,不过我们不妨直接看看题目上附赠的资料里面的标签页插件的链接,所谓的插件其实就是写好的一些css和js文件,我们只需要直接调用它们的样式即可,我们来带bootstrap的官网下载他的压缩包,解压到我们的static文件夹,然后就可以直接引用使用了(甚至可以不下载,我们直接引用在线的库,然后网页在加载的时候就会自动下载这些库进行渲染)
我们按照规则导入这个页签的库并写几个页签出来,实现了这样的效果
但是在测试的过程中,又发现了新的问题
发现了没有,我们在收缩左边的leftbar的时候,我们的主体部分没有跟着移动,所以我们还需要继续完善我们刚才写的js文件,不过在此之前,我们要先继续推进我们代码的模块化,我们把整个页面的主体部分写到一个html文件里面,然后每个页签的内容再分为三个页签里面,然后我们就可以给这个主体部分也打一个标记,在leftbar收缩和不收缩的时候修改他的宽度,然后我们再重载一下这个页签按钮的样式,一通操作猛如虎之后,我们就搞定了
轮播图
虽然现在的CSDN没有轮播图,但是当年应该是有的,否则也不可能在这个做题要求里面给一个轮播图的插件链接,那么我们就在全部这个页签里面加一个轮播图试一下吧
<div class="carousel-container"><div id="carouselExample" class="carousel slide" data-bs-ride="carousel"><div class="carousel-inner"><div class="carousel-item active"><img src="{{ url_for('static', filename='image/ad/1.jpg') }}" class="d-block w-100" alt="Ad Image 1"></div><div class="carousel-item"><img src="{{ url_for('static', filename='image/ad/2.jpg') }}" class="d-block w-100" alt="Ad Image 2"></div><div class="carousel-item"><img src="{{ url_for('static', filename='image/ad/3.jpg') }}" class="d-block w-100" alt="Ad Image 3"></div><div class="carousel-item"><img src="{{ url_for('static', filename='image/ad/4.jpg') }}" class="d-block w-100" alt="Ad Image 4"></div><div class="carousel-item"><img src="{{ url_for('static', filename='image/ad/5.jpg') }}" class="d-block w-100" alt="Ad Image 5"></div><div class="carousel-item"><img src="{{ url_for('static', filename='image/ad/6.jpg') }}" class="d-block w-100" alt="Ad Image 6"></div></div><button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev"><span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="visually-hidden">Previous</span></button><button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next"><span class="carousel-control-next-icon" aria-hidden="true"></span><span class="visually-hidden">Next</span></button></div>
</div>
于是这个效果我们就完成啦(记得关掉adblock,这个元素可能会被adb干掉)
写在最后
最后再随便填充一些东西我们的项目就完成啦!三件套齐活,插件也用上了,最终效果就长这个样子(当然你觉得空的话还可以继续加一些信息框啥的,排版你也可以随便改)
虽然这个题今年肯定不会再出,但是希望你能学习到一些有用的东西,顺利进入自科,暴打swan喵~我们就下期算法三面通关笔记再见!
哦对了,还有源代码仓库链接,在这里