ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

免费代码训练营「构建个人作品集网页」完整通关指南:从用户故事到自动化测试

免费代码训练营「构建个人作品集网页」完整通关指南:从用户故事到自动化测试 免费代码训练营「构建个人作品集网页」完整通关指南从用户故事到自动化测试【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCampfreeCodeCamp「响应式网页设计」认证经典项目——构建个人作品集网页Build a Personal Portfolio Webpage要求用纯 HTML 与 CSS 从零搭建一个含欢迎区、作品区、固定导航栏和个人主页链接的作品集页面并逐条通过内置自动化验收测试。阅读本文你将吃透该项目全部 11 条用户故事User Stories与对应的 JS 断言Hints校验逻辑掌握position: fixed吸顶导航、100vh满屏欢迎区、媒体查询与锚点菜单等关键实现手法并拿到一份可直接通过全部测试的完整代码。本文主体基于 freeCodeCamp 开源仓库中的课程文件 bd7158d8c242eddfaeb5bd13.md并结合仓库内的课程结构配置与官方 Solution 做深度拆解。一、项目定位这是一道怎样的挑战从仓库的课程结构可以确认它的地位与运行方式Block 级配置见 build-a-personal-portfolio-webpage-project.json该 Block 的challengeOrder仅包含本挑战一个条目usesMultifileEditor: true表示在多功能编辑器中以「HTML CSS 两个文件」的形式编辑helpCategory: HTML-CSS标注其归类。超级模块级配置见 responsive-web-design-22.jsonbuild-a-personal-portfolio-webpage-project是responsive-web-design-22超级模块含 22 个 Block的收官项目排在learn-css-transforms-by-building-a-penguin等课程块之后。挑战文件头部的元数据challengeType: 14与saveSubmissionToDB: true说明它属于会记录进认证进度的「项目型」提交。原文档给出的 Objective 只有一句话构建一个与官方演示站点功能相似的 App不要复制该演示项目并加上自己的个人风格Give it your own personal style。同时原文档有一条重要 Note务必在 HTML 中加入link relstylesheet hrefstyles.css来关联样式表否则 CSS 全部不生效测试无法通过。这是新手最常见的「零样式」事故根源。二、需求规格11 条 User Stories 逐条精读原文档把验收标准描述为 11 条用户故事本质上是「作品集必须能做什么」的行为契约作品集应有一个welcome section欢迎区其id为welcome-section欢迎区应包含一个含文本的h1元素作品集应有一个projects section作品区其id为projects作品区应包含至少一个class为project-tile的元素来容纳某个项目作品区应包含至少一个指向项目的链接作品集应有一个navbar导航栏其id为navbar导航栏应包含至少一个可点击、能在页面各区块间页内跳转的链接作品集应有一个id为profile-link的链接点击后在新标签页打开你的 GitHub 或 freeCodeCamp 主页作品集应至少使用一个媒体查询media query欢迎区的高度应等于视口高度导航栏应始终保持在视口顶部页面滚动也不离开。表面看这些都是基础能力但真正决定成败的是隐藏在 Hints 段落里那套浏览器端 JS 断言——下面逐条翻译这些「阅卷标准」。三、测试机制Hints 里的 JS 断言是如何验收的原文档在--hints--段给出了与每条 User Story 对应的 JS 断言。读懂它们就等于拿到了精确到像素的评分标准。3.1 关键区块必须真实存在const el document.getElementById(welcome-section); assert.isNotNull(el);projects、navbar两条断言结构完全相同。结论welcome-section、projects、navbar三个id必须一字不差地存在任何拼写偏差大小写、连字符、换行都会直接失败。3.2 欢迎区的语义与内容约束assert.isAbove( document.querySelectorAll(#welcome-section h1).length, 0, Welcome section should contain an h1 element ); assert.isAbove( document.querySelectorAll(#welcome-section h1)?.[0]?.innerText?.length, 0, h1 element in welcome section should contain your name or camper name );两条断言合起来的意思是#welcome-section内至少有一个h1且其中第一个h1的innerText长度大于 0。建议直接写姓名或 camp 昵称只放注释或空白不算「有文本」。3.3 作品区结构与链接约束assert.isAbove(document.querySelectorAll(#projects .project-tile).length, 0); assert.isAbove(document.querySelectorAll(#projects a).length, 0);作品区#projects内至少要有一个classproject-tile的容器并且至少存在一个a链接指向某个真实项目可以指向外部托管页或仓库内页面。3.4 导航栏必须是「锚点菜单」const links [...document.querySelectorAll(#navbar a)].filter( nav (nav?.getAttribute(href) || ).substring(0, 1) # ); assert.isAbove(links.length, 0, Navbar should contain an anchor link );测试会遍历#navbar内所有a过滤出href以#开头的链接并断言其数量大于 0。也就是说导航栏里只放外链不算数必须要有href#projects、href#welcome-section这类页内锚点链接。3.5 个人主页链接标签与打开方式双重校验const el document.getElementById(profile-link); assert.isNotNull(el); assert.strictEqual(el.tagName, A); // 必须是 a assert.strictEqual(el.target, _blank); // 必须新标签页打开#profile-link必须挂在真正的a元素上用div冒充无效且必须显式书写target_blank。3.6 至少一个媒体查询const htmlSourceAttr Array.from(document.querySelectorAll(source)).map(el el.getAttribute(media)) const cssCheck new __helpers.CSSHelp(document).getCSSRules(media) assert.isTrue(cssCheck.length 0 || htmlSourceAttr.length 0);验收方式有两种样式表中存在media规则通过CSSHelp.getCSSRules(media)探测或文档中存在带media属性的source元素。常规做法是在 CSS 中书写media (max-width: ...)若link没写对导致 CSS 未被加载这里会拿不到任何media规则而失败——这也印证了原文档 Note 强调关联样式表的原因。3.7 吸顶导航唯一带「滚动后复检」的动态断言const timeout milliseconds new Promise(resolve setTimeout(resolve, milliseconds)); const navbar document.getElementById(navbar); assert.approximately( navbar?.getBoundingClientRect().top, 0, 15, Navbars parent should be body and it should be at the top of the viewport ); window.scroll(0, 500); await timeout(1); assert.approximately( navbar?.getBoundingClientRect().top, 0, 15, Navbar should be at the top of the viewport even after scrolling ); window.scroll(0, 0);这条断言隐藏了三个关键信息两次采样先检查初始状态再把页面滚动到y500、等待 1ms 后复检。「初始在顶、一滚就跑」的实现例如仅把导航放在文档顶部而不做固定定位会在第二次断言失败判定基准getBoundingClientRect().top是导航栏相对当前视口的坐标滚动后仍须近似为0容差 15px。只有position: fixed或sticky等效布局能持续满足父级约束断言消息提示 Navbars parent should be body即#navbar最好作为body的直接子元素避免被滚动容器包裹产生额外偏移。四、从零实现HTML 骨架与 CSS 关键布局原文档的--seed-contents--提供的种子是两个空文件也就是说官方不给任何起始代码HTML 与 CSS 都要你自己写。下面给出按测试要求整理、可直接运行的最小完整实现讲解用建议在此基础上加入你的真实内容与个人风格。4.1 index.html语义化骨架!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 link relstylesheet hrefstyles.css titlePersonal Portfolio/title /head body nav idnavbar a href#welcome-sectionHome/a a href#projectsProjects/a a href#contactContact/a /nav main section idwelcome-section h1Hi, Im Camper/h1 pA front-end learner from freeCodeCamp/p /section section idprojects h2These are some of my projects/h2 div classproject-tile a hrefhttps://your-demo-link.example/tribute target_blankTribute Page/a /div div classproject-tile a hrefhttps://your-demo-link.example/survey target_blankSurvey Form/a /div /section section idcontact h2Lets work together.../h2 a idprofile-link hrefhttps://www.freecodecamp.org/your-username target_blank relnoopener noreferrerfreeCodeCamp Profile/a /section /main /body /html对照需求自查需求编号落实位置1、2section idwelcome-section内含非空h13、4、5section idprojects内有.project-tile与指向项目的a6、7#navbar为body直接子元素内含href#...锚点链接8a idprofile-link target_blank指向 freeCodeCamp/GitHub 主页4.2 styles.css吸顶、满屏与媒体查询/* 全局重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* ---------- 导航栏固定于视口顶部 ---------- */ #navbar { position: fixed; /* 相对视口固定是 3.7 断言的前提 */ top: 0; left: 0; width: 100%; display: flex; justify-content: flex-end; background-color: #be3144; z-index: 10; } #navbar a { color: #fff; padding: 1rem 1.5rem; text-decoration: none; } #navbar a:hover { background-color: #45567d; } /* ---------- 欢迎区高度 视口高度 ---------- */ #welcome-section { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100vh; /* 需求 10满屏 */ background: linear-gradient(45deg, #3a3d40 0%, #181719 100%); color: #f0f0f0; } /* ---------- 作品区 ---------- */ #projects { text-align: center; padding: 6rem 1rem; background-color: #45567d; color: #f0f0f0; } .project-tile { display: inline-block; margin: 1rem; background: #303841; } .project-tile a { display: block; padding: 1.5rem; color: #f0f0f0; text-decoration: none; } .project-tile a:hover { background: #be3144; } /* ---------- 联系区 ---------- */ #contact { text-align: center; padding: 6rem 1rem; background-color: #303841; color: #f0f0f0; } /* ---------- 媒体查询需求 9小屏适配 ---------- */ media (max-width: 720px) { #navbar { justify-content: center; } .project-tile { display: block; width: 90%; margin: 1rem auto; } }三处与断言的强对应关系#navbar { position: fixed; top: 0; }—— 满足 3.7 的动态滚动断言getBoundingClientRect().top ≈ 0#welcome-section { height: 100vh; }—— 满足需求 10100vh 视口高度的 100%文件末尾存在media—— 满足 3.6 的CSSHelp.getCSSRules(media)探测。4.3 原文档官方 Solution 中的设计手法原文档在--solutions--给出了一套官方参考实现HTML CSS 双文件其导航与满屏布局的核心片段如下/* 官方 Solution导航栏固定 */ nav { position: fixed; width: 100%; text-align: right; font-size: 24pt; top: 0%; right: 5px; background-color: #000000; color: #ffffff; } /* 官方 Solution媒体查询 */ media (max-width: 500px) { nav { display: none; /* 小屏隐藏导航的响应式策略 */ } }/* 官方 Solution各 section 满屏并垂直居中 */ #welcome-section { display: table-cell; vertical-align: middle; width: 100vw; height: 100vh; }官方实现的可提炼手法有三点用position: fixedtop: 0%实现吸顶再辅以right调整位置借助100vh/100vw让区块占满一屏用display: table-cell; vertical-align: middle或 flex 做内容垂直居中将nav idnavbar放在body的首层直接子元素位置满足 3.7 断言对父容器的约束。此外原文档还附赠了一个最简可通过样例第二份 Solution直观展示「过测」的下限headstylemedia (max-width: 500px){nav{display: none;}}/style/headbodynav idnavbara href#projectstext/a | /navmainsection idwelcome-sectionh1text/h1/sectionhrsection idprojectsh1Projects/h1h2 classproject-tilea idprofile-link target_blank hrefhttps://freecodecamp.orgtext/a/h2/sectionhr/body/html有趣的是这份最简实现把#profile-link放进了#projects内部、把media直接内联进style标签——说明测试只检查存在性、位置与关键行为并不限制结构归属或要求内联/外联写法。但认证的意义不止于「过测」请务必在满足断言的基础上写出有完整配色、真实项目链接与个人品牌的成品页面。五、常见失败点与排查对照表结合前文断言把最容易翻车的点整理成「症状 → 根因 → 对应断言」对照表症状根因对应断言welcome-section/projects/navbar报 nullid拼写不一致大小写、连字符、空格getElementById(...)h1 断言不通过#welcome-section内无h1或h1内容为空querySelectorAll(#welcome-section h1)、innerText.length导航栏有链接却报错href不以#开头放了外链过滤后links.length 0滚动后导航栏掉出视口未用position: fixed或#navbar被包在滚动容器内getBoundingClientRect().top二次断言media query 断言失败CSS 未通过link正确加载或确实没写mediaCSSHelp(...).getCSSRules(media)profile-link断言失败挂在非a元素上或漏写target_blankel.tagName、el.target页面整体无样式忘记link relstylesheet hrefstyles.css原文档 Note 强调项排查技巧直接在浏览器 DevTools Console 中执行与断言等价的命令例如document.getElementById(welcome-section)、document.querySelectorAll(#projects .project-tile).length验证吸顶则手动window.scrollTo(0, 500)后读取document.getElementById(navbar).getBoundingClientRect().top。六、在仓库内继续深挖与自行验证本挑战完整保存在仓库课程目录中可继续查阅挑战全文需求、User Stories、Hints 断言、空种子、官方 Solution 双版本bd7158d8c242eddfaeb5bd13.mdBlock 结构信息challengeOrder、usesMultifileEditor、helpCategory、blockLayoutbuild-a-personal-portfolio-webpage-project.json超级模块 Block 顺序可看到该项目前的课程块序列responsive-web-design-22.json。本地练习建议新建一个独立文件夹放入上面 4.1/4.2 的index.html与styles.css直接双击打开即可预览若浏览器阻止了某些加载方式可用任意静态服务器如python3 -m http.server起一个本地服务访问。请始终保留原文档 Note 强调的link relstylesheet hrefstyles.css这是外部样式表在多功能编辑器中生效、并被测试读取到的前提。结语「构建个人作品集网页」是整个响应式网页设计课程体系中的收官项目也是对语义化 HTML、id/class选择器、固定定位、视口单位与媒体查询的一次综合验收。把它当作一份「可执行的契约」User Stories 定义需求Hints 断言定义可验证的验收标准官方 Solution 与最简样例则分别代表「参考质量」与「过测下限」。在这两者之间留出空间注入你自己的项目、配色与故事——你得到的将不止是一张认证而是一个可以长期维护、真正上线的个人主页。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表