實(shí)戰(zhàn):廈門(mén)旅游網(wǎng)14頁(yè)面完整開(kāi)發(fā)指南)
簡(jiǎn)介網(wǎng)頁(yè)制作是前端開(kāi)發(fā)學(xué)習(xí)的核心實(shí)踐而一份完整的HTML5期末作業(yè)往往需要綜合運(yùn)用HTML5語(yǔ)義化標(biāo)簽、CSS3布局與動(dòng)畫(huà)、JavaScript交互設(shè)計(jì)等技術(shù)。從頁(yè)面骨架搭建到公共模塊復(fù)用從Flex/Grid響應(yīng)式布局到輪播圖、表單驗(yàn)證等交互實(shí)現(xiàn)每個(gè)環(huán)節(jié)都體現(xiàn)著工程化思維與代碼組織能力。以廈門(mén)旅游網(wǎng)為例的14頁(yè)面項(xiàng)目完整展示了如何將旅游類(lèi)網(wǎng)站的視覺(jué)表現(xiàn)力與功能邏輯相結(jié)合在滿足作業(yè)要求的同時(shí)提升作品的專(zhuān)業(yè)度與答辯說(shuō)服力。本文圍繞網(wǎng)頁(yè)制作全流程拆解技術(shù)選型、常見(jiàn)布局坑點(diǎn)及答辯高頻問(wèn)題為學(xué)習(xí)者提供可落地的實(shí)踐參考。 期末周、課程設(shè)計(jì)、實(shí)訓(xùn)項(xiàng)目……每年這個(gè)時(shí)候都有一大波同學(xué)被“網(wǎng)頁(yè)制作成品”這幾個(gè)字折磨得頭大。如果你正好刷到這篇十有八九是在找一份拿得出手、能直接交差又不會(huì)被老師一眼看穿是模板的HTML5期末作業(yè)。今天這篇就結(jié)合“廈門(mén)旅游網(wǎng)”這個(gè)14頁(yè)面的完整項(xiàng)目把從頁(yè)面規(guī)劃、技術(shù)選型到具體實(shí)現(xiàn)的整個(gè)流程攤開(kāi)來(lái)講包括代碼怎么組織、CSS3和JS的高級(jí)特性怎么用、以及最后答辯時(shí)老師最?lèi)?ài)問(wèn)的幾個(gè)問(wèn)題怎么應(yīng)對(duì)。這份項(xiàng)目我前前后后帶過(guò)好幾屆學(xué)生落地整體難度適中既能體現(xiàn)H5CSS3JS三大塊的功底做出來(lái)的視覺(jué)效果又足夠唬人拿來(lái)當(dāng)期末作業(yè)或者課程設(shè)計(jì)都非常合適。1. 項(xiàng)目從哪下手先把14個(gè)頁(yè)面的骨架定下來(lái)1.1 為什么選“旅游類(lèi)網(wǎng)站”當(dāng)期末作業(yè)做網(wǎng)頁(yè)設(shè)計(jì)期末作業(yè)選題基本決定了一半的分?jǐn)?shù)。論壇、個(gè)人主頁(yè)、電商首頁(yè)這些題材要么交互太簡(jiǎn)單要么頁(yè)面結(jié)構(gòu)太過(guò)套路化老師看多了容易審美疲勞。旅游類(lèi)網(wǎng)站是我個(gè)人非常推薦的選題方向原因有三個(gè)第一旅游類(lèi)網(wǎng)站的視覺(jué)表現(xiàn)空間極大風(fēng)景圖、漸變色、卡片式布局都有天然的發(fā)揮余地最能直觀體現(xiàn)CSS3功底第二頁(yè)面類(lèi)型豐富既要有展示型的首頁(yè)也要有列表頁(yè)、詳情頁(yè)、表單頁(yè)方便你湊夠“14個(gè)頁(yè)面”這種硬性數(shù)量要求第三交互場(chǎng)景天然存在——輪播圖、Tab切換、回到頂部、搜索篩選、表單驗(yàn)證JS的活兒全都能安排上不用硬凹需求。廈門(mén)旅游網(wǎng)這個(gè)主題在旅游類(lèi)里屬于“穩(wěn)妥牌”。作為熱門(mén)旅游城市廈門(mén)在視覺(jué)上有鼓浪嶼、環(huán)島路、沙坡尾這些高辨識(shí)度的地標(biāo)圖片素材一搜一大把版權(quán)上也很少踩雷盡量用Unsplash、Pexels這類(lèi)免費(fèi)圖庫(kù)。內(nèi)容上既可以說(shuō)景點(diǎn)、說(shuō)美食、說(shuō)住宿也能延展出攻略、游記、留言板這些互動(dòng)型頁(yè)面14頁(yè)的填充難度大大降低。1.2 14個(gè)頁(yè)面到底怎么分配才合理有些同學(xué)一聽(tīng)到“14個(gè)頁(yè)面”就開(kāi)始焦慮以為要把14個(gè)頁(yè)面全做成完全不同布局的大型頁(yè)面。實(shí)際上14個(gè)頁(yè)面完全可以按照“首頁(yè) 頻道頁(yè) 內(nèi)容頁(yè) 功能頁(yè) 輔助頁(yè)”的邏輯來(lái)分層規(guī)劃很多頁(yè)面之間只需要復(fù)用公共模塊工作量沒(méi)有想象中大。我這份項(xiàng)目最終定下來(lái)的頁(yè)面結(jié)構(gòu)是首頁(yè)index.html、景點(diǎn)列表頁(yè)、景點(diǎn)詳情頁(yè)、美食列表頁(yè)、美食詳情頁(yè)、住宿列表頁(yè)、住宿詳情頁(yè)、旅游攻略列表頁(yè)、旅游攻略詳情頁(yè)、游記分享頁(yè)、留言板、關(guān)于我們、登錄頁(yè)、注冊(cè)頁(yè)正好是14個(gè)頁(yè)面。列表頁(yè)和詳情頁(yè)之間是重復(fù)的卡片結(jié)構(gòu)約等于一套模板換數(shù)據(jù)登錄頁(yè)和注冊(cè)頁(yè)共用一套表單樣式關(guān)于我們和留言板的側(cè)邊欄布局完全一致只換主體內(nèi)容。這樣算下來(lái)真正需要從零開(kāi)始設(shè)計(jì)的頁(yè)面其實(shí)只有首頁(yè)、列表頁(yè)、詳情頁(yè)、功能頁(yè)、輔助頁(yè)這五種模板每個(gè)模板再做兩到三個(gè)變體就夠了。1.3 公共模塊先行導(dǎo)航欄、頁(yè)腳、側(cè)邊欄網(wǎng)頁(yè)開(kāi)發(fā)里有一條很樸素的道理先搭公共模塊再做具體頁(yè)面。因?yàn)閷?dǎo)航欄、頁(yè)腳這些東西你在14個(gè)頁(yè)面里要用14遍如果每一頁(yè)都重新寫(xiě)一遍不僅效率低而且稍有不慎就是導(dǎo)航欄寬度對(duì)不齊、鏈接地址寫(xiě)錯(cuò)這種低級(jí)問(wèn)題。這套項(xiàng)目里導(dǎo)航欄我建議做成“通欄深色 半透明吸頂 下拉子菜單”的組合。半透明吸頂是CSS3的一個(gè)典型應(yīng)用點(diǎn)用position: sticky或者position: fixed都能實(shí)現(xiàn)配合backdrop-filter: blur()做出毛玻璃效果視覺(jué)上非常加分。導(dǎo)航結(jié)構(gòu)上可以規(guī)劃為“首頁(yè)、景點(diǎn)、美食、住宿、攻略、游記、留言板”七個(gè)一級(jí)欄目其中“景點(diǎn)、美食、住宿、攻略”四個(gè)欄目都可以加下拉菜單把二級(jí)頁(yè)面塞進(jìn)去這樣頁(yè)面之間的跳轉(zhuǎn)關(guān)系就從“平鋪”變成了“樹(shù)狀”網(wǎng)站的層級(jí)感一下就出來(lái)了。頁(yè)腳的話三欄布局是標(biāo)準(zhǔn)做法左側(cè)放網(wǎng)站的簡(jiǎn)介和logo中間放快速鏈接關(guān)于我們、聯(lián)系郵箱等右側(cè)放備案信息或版權(quán)聲明。頁(yè)腳這塊還有一個(gè)容易被忽略的點(diǎn)——要在頁(yè)腳上方加一條淺色的分割線或者利用背景色差進(jìn)行區(qū)分讓整頁(yè)的視覺(jué)結(jié)束感更清晰。2. 核心技術(shù)點(diǎn)拆解HTML5CSS3JS分別該把功夫下在哪里2.1 HTML5不要只把div當(dāng)萬(wàn)能工具現(xiàn)在很多同學(xué)寫(xiě)HTML還是“一div到底”這對(duì)期末作業(yè)的評(píng)分來(lái)說(shuō)是非常吃虧的。HTML5新增了header、nav、main、section、article、aside、footer這一批語(yǔ)義化標(biāo)簽它們不僅能替代div讓代碼結(jié)構(gòu)一目了然更能讓你的作業(yè)從“寫(xiě)出來(lái)了”躍升到“寫(xiě)得專(zhuān)業(yè)”。以首頁(yè)為例正確的結(jié)構(gòu)應(yīng)該是這樣組織的網(wǎng)頁(yè)最上方是header區(qū)域里面嵌套nav放主導(dǎo)航主體內(nèi)容放進(jìn)main按內(nèi)容區(qū)塊拆成若干個(gè)section比如“熱門(mén)景點(diǎn)”“當(dāng)?shù)孛朗场薄熬纷∷蕖薄坝瓮婀ヂ浴泵總€(gè)section用article來(lái)裝具體的景點(diǎn)卡片右側(cè)有推薦的用aside包起來(lái)最底部才是footer。這種寫(xiě)法一旦被老師看到印象分直接拉高一個(gè)檔次。另外一個(gè)常被忽略的H5標(biāo)簽是figure和figcaption用來(lái)包裹圖文組合比如景點(diǎn)卡片里的圖片加說(shuō)明文字語(yǔ)義上比div p正宗得多。另外表單是HTML5作業(yè)的另一個(gè)考點(diǎn)。登錄頁(yè)和注冊(cè)頁(yè)里input的type一定要用對(duì)郵箱用typeemail密碼用typepassword需要勾選的同意條款用typecheckbox。加上required必填屬性和placeholder提示文字瀏覽器端的基礎(chǔ)驗(yàn)證就有了這段代碼能直接證明你掌握了HTML5的表單新特性。2.2 CSS3用Flex和Grid把頁(yè)面結(jié)構(gòu)搭穩(wěn)CSS3是期末作業(yè)拿分的核心因?yàn)樗苯記Q定作品的“顏值”。我建議技術(shù)點(diǎn)這樣分配布局方式上主用Flexbox輔以Grid。Flex是解決一維布局的比如導(dǎo)航欄左右分布、卡片內(nèi)圖片和文字豎排、按鈕居中等用display: flex加justify-content和align-items就能搞定比f(wàn)loat好用十倍不止。Grid適合二維布局比如景點(diǎn)列表頁(yè)的三列九宮格用display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;一句話就能讓卡片均勻排布段間距整齊得像用尺子量過(guò)而且響應(yīng)式也比f(wàn)loat方案好做。圓角與陰影也是CSS3的重點(diǎn)。景點(diǎn)卡片的border-radius: 12px、按鈕的box-shadow: 0 4px 12px rgba(0,0,0,0.1)這類(lèi)細(xì)節(jié)能讓整個(gè)頁(yè)面瞬間擺脫“學(xué)生作業(yè)感”。用得好的陰影是懸浮提升層次感用不好的陰影就是一層發(fā)灰的模糊塊這里我的經(jīng)驗(yàn)是陰影參數(shù)里透明度不要超過(guò)0.15模糊半徑控制在10到20像素之間擴(kuò)撒半徑最好設(shè)置為0效果最自然。動(dòng)畫(huà)與過(guò)渡效果是拉開(kāi)差距的地方。建議在卡片上做hover上浮效果transform: translateY(-6px)transition: all 0.3s ease在按鈕上做背景漸變動(dòng)畫(huà)在 banner 的字幕上用比較克制的text-shadow做呼吸效果。CSS3的keyframes動(dòng)畫(huà)可以做一個(gè)頁(yè)面加載時(shí)的淡入效果但不要滿屏亂飛——期末作業(yè)不是電競(jìng)官網(wǎng)動(dòng)畫(huà)是為了輔助瀏覽體驗(yàn)而不是炫技做太多反而顯得廉價(jià)。2.3 JavaScript不抄插件也能做出夠用的交互說(shuō)實(shí)話期末作業(yè)階段的JS用不到太深的東西但如果你連JS都沒(méi)寫(xiě)老師很可能覺(jué)得你在“逃避”前端三件套里的核心一環(huán)。不用慌也不需要去抄什么復(fù)雜的插件原生JS做到這幾個(gè)交互就夠用了輪播圖也叫圖片幻燈片是旅游網(wǎng)站的標(biāo)配功能。實(shí)現(xiàn)原理無(wú)非是把圖片排成一行放在一個(gè)容器里通過(guò)切換transform: translateX()的值來(lái)左右移動(dòng)再配合定時(shí)器實(shí)現(xiàn)自動(dòng)播放點(diǎn)擊左右按鈕手動(dòng)切換。最簡(jiǎn)版大概40行代碼就能搞定建議不要用display: none切圖——那種實(shí)現(xiàn)太“原始”懂行的老師一眼就能看出來(lái)。Tab切換用在首頁(yè)“熱門(mén)景點(diǎn)/當(dāng)?shù)孛朗?精品住宿”這種板塊上或者攻略列表頁(yè)的篩選排序功能里。原理是給每個(gè)Tab綁定點(diǎn)擊事件切換時(shí)給當(dāng)前Tab加active類(lèi)同時(shí)控制對(duì)應(yīng)內(nèi)容區(qū)塊的顯隱。回到頂部按鈕這個(gè)雖然簡(jiǎn)單但非常顯眼是個(gè)性價(jià)比極高的加分項(xiàng)。監(jiān)聽(tīng)window.onscroll當(dāng)滾動(dòng)距離超過(guò)頁(yè)面一屏?xí)r顯示按鈕點(diǎn)擊后使用requestAnimationFrame或setInterval讓頁(yè)面平滑滾動(dòng)到頂部而不是直接用location.href #這種老掉牙的方式。表單驗(yàn)證注冊(cè)頁(yè)最好加上。用JS判斷密碼長(zhǎng)度是否大于6位、兩次輸入的密碼是否一致、郵箱格式是否匹配。這既是JS應(yīng)用點(diǎn)也是網(wǎng)頁(yè)交互嚴(yán)謹(jǐn)性的體現(xiàn)。我當(dāng)時(shí)做的時(shí)候還加了一個(gè)用戶名長(zhǎng)度判斷輸入少于2位就彈紅色提示且禁止提交這下JS的“存在感”直接拉滿。懶加載也可以安排上用在景點(diǎn)詳情頁(yè)的長(zhǎng)圖列表上。先給img的>:root { --primary-color: #1a9c8c; --secondary-color: #f5c451; --text-main: #333333; --text-light: #666666; --bg-page: #f8f8f8; --card-shadow: 0 4px 15px rgba(0, 0, 0, 0.08); }后面寫(xiě)頁(yè)面的時(shí)候直接color: var(--primary-color)調(diào)用既規(guī)范又方便統(tǒng)一調(diào)整頁(yè)面多了之后你會(huì)感謝這個(gè)決定。3. 實(shí)操全過(guò)程從零搭出廈門(mén)旅游網(wǎng)的完整流程3.1 初始化目錄結(jié)構(gòu)和共用文件在動(dòng)手寫(xiě)頁(yè)面之前先把目錄結(jié)構(gòu)規(guī)劃好。合理的目錄是既能讓你開(kāi)發(fā)時(shí)手不忙腳亂也能在答辯時(shí)讓老師覺(jué)得你工程素養(yǎng)不錯(cuò)。我建議這樣組織xiamen-travel/ ├── index.html ├── css/ │ ├── common.css │ ├── index.css │ ├── list.css │ ├── detail.css │ ├── form.css │ └── about.css ├── js/ │ ├── common.js │ ├── slider.js │ ├── tab.js │ ├── backtotop.js │ └── validate.js ├── images/ │ ├── banner/ │ ├── spots/ │ ├── food/ │ └── hotel/ └── pages/ ├── spots.html ├── spot-detail.html ├── foods.html ├── food-detail.html ├── hotels.html ├── hotel-detail.html ├── guides.html ├── guide-detail.html ├── travel-notes.html ├── message.html ├── about.html ├── login.html └── register.htmlcommon.css里放所有頁(yè)面通用的樣式——清浮動(dòng)、鏈接默認(rèn)樣式重置、導(dǎo)航欄、頁(yè)腳、返回頂部按鈕、通用卡片樣式。每個(gè)頁(yè)面通過(guò)自己的CSS文件覆蓋獨(dú)有的樣式。JS文件同理common.js里放回到頂部、下拉菜單這類(lèi)公共交互功能型的代碼拆分成獨(dú)立的文件是為了讓每個(gè)函數(shù)的職責(zé)清晰答辯時(shí)老師問(wèn)起來(lái)你能講明白“哪個(gè)文件干什么”。記得在pages目錄下的HTML里引用CSS時(shí)路徑要寫(xiě)成../css/common.css這是新手最容易翻車(chē)的地方。3.2 首頁(yè)開(kāi)發(fā)的具體實(shí)現(xiàn)步驟首頁(yè)是整份作業(yè)的門(mén)面也是工作量最大的頁(yè)面。我按區(qū)塊拆解步驟Banner輪播圖是最先動(dòng)的區(qū)塊。我在index.html里放了三個(gè)div.slide每個(gè)里面是一張背景圖加一個(gè)居中的標(biāo)題和副標(biāo)題然后通過(guò)CSS把.slider-container設(shè)置成display: flexoverflow: hidden。slider.js里定義一個(gè)let currentIndex 0每隔3秒讓currentIndex加1然后操作container.style.transform translateX(- currentIndex * 100 %)當(dāng)索引等于幻燈片數(shù)量時(shí)直接歸零實(shí)現(xiàn)無(wú)縫循環(huán)效果。景點(diǎn)推薦板塊我用Grid排了一個(gè)三列卡片布局。每一張卡片由圖片、標(biāo)題、簡(jiǎn)介、一個(gè)“查看詳情”的文字鏈接組成。卡片默認(rèn)狀態(tài)是普通的白色背景加陰影hover時(shí)上浮并展示一個(gè)半透明的遮罩層這個(gè)遮罩層用CSS3的position: absoluteopacity過(guò)渡來(lái)實(shí)現(xiàn)。登錄注冊(cè)入口放在導(dǎo)航欄右側(cè)是整站功能性的體現(xiàn)。做了兩個(gè)按鈕登錄按鈕是白底淡色邊框注冊(cè)按鈕是主色漸變底白色文字。這兩個(gè)按鈕直接鏈接到pages/login.html和pages/register.html保證14個(gè)頁(yè)面的跳轉(zhuǎn)關(guān)系是閉環(huán)的這是老師檢查“頁(yè)面完整性”時(shí)的必看內(nèi)容。3.3 列表頁(yè)與詳情頁(yè)的通用模板操作列表頁(yè)的核心工作是“復(fù)用”。寫(xiě)spots.html時(shí)我直接把首頁(yè)的“熱門(mén)景點(diǎn)”卡片區(qū)塊復(fù)制過(guò)來(lái)把6張卡片擴(kuò)充成9到12張?jiān)僭陧敳考右粋€(gè)篩選排序欄比如“按熱度 / 按評(píng)分 / 按價(jià)格”。這三個(gè)排序按鈕不需要真正的后臺(tái)數(shù)據(jù)排序用JS的數(shù)組排序就能模擬把卡片對(duì)應(yīng)的標(biāo)題、評(píng)分這些數(shù)據(jù)存在一個(gè)數(shù)組里點(diǎn)擊按鈕時(shí)對(duì)數(shù)組進(jìn)行排序然后用document.querySelectorAll操作DOM的順序這也是JS數(shù)組方法的實(shí)戰(zhàn)運(yùn)用。詳情頁(yè)的布局我建議做成“左側(cè)內(nèi)容 右側(cè)側(cè)邊欄”。左側(cè)放圖片大圖、文字介紹、行程安排這類(lèi)正文右側(cè)側(cè)邊欄放“熱門(mén)景點(diǎn)推薦”“相關(guān)美食”“聯(lián)系我們”等模塊。左右用Flex布局左側(cè)flex: 2右側(cè)flex: 1。右側(cè)的“熱門(mén)推薦”一般是4到5個(gè)小卡片點(diǎn)擊能跳到對(duì)應(yīng)的詳情頁(yè)。這樣詳情頁(yè)的跳轉(zhuǎn)關(guān)系又多了好幾層網(wǎng)站的整體連通性也變得更好。3.4 登錄注冊(cè)頁(yè)與表單樣式登錄和注冊(cè)頁(yè)的HTML結(jié)構(gòu)很簡(jiǎn)單一個(gè)居中的卡片容器里放一個(gè)form里面是label、input、button。漂亮的關(guān)鍵在于CSS細(xì)節(jié)——輸入框聚焦時(shí)的表現(xiàn)是老師會(huì)認(rèn)真看的地方我用input:focus設(shè)置了border-color: var(--primary-color)和box-shadow: 0 0 0 3px rgba(26, 156, 140, 0.15)這個(gè)光暈效果既現(xiàn)代又不會(huì)太突兀是很多優(yōu)秀UI的常用手法。注冊(cè)頁(yè)的JS驗(yàn)證我做了四個(gè)檢查項(xiàng)function validateForm() { var username document.getElementById(username).value.trim(); var password document.getElementById(password).value; var confirmPwd document.getElementById(confirmPwd).value; var email document.getElementById(email).value.trim(); if (username.length 2) { alert(用戶名不能少于2個(gè)字符); return false; } if (password.length 6) { alert(密碼長(zhǎng)度不能少于6位); return false; } if (password ! confirmPwd) { alert(兩次輸入的密碼不一致); return false; } var emailReg /^\w([-.]\w)*\w([-.]\w)*\.\w([-.]\w)*$/; if (!emailReg.test(email)) { alert(請(qǐng)輸入正確的郵箱格式); return false; } return true; }這是我實(shí)測(cè)過(guò)的經(jīng)典寫(xiě)法零依賴、邏輯清晰、答辯時(shí)就能直接說(shuō)“這里用了正則表達(dá)式校驗(yàn)郵箱格式”一句話就暴露不了你的真實(shí)水平。3.5 留言板和關(guān)于我們頁(yè)的布局套路留言板頁(yè)面是一個(gè)典型的“表單 展示列表”頁(yè)面。上面是一個(gè)textarea留言框和“提交留言”按鈕下面是已經(jīng)留言內(nèi)容的列表純靜態(tài)假數(shù)據(jù)。你可以在JS里加一個(gè)小功能點(diǎn)擊提交按鈕后把textarea里輸入的內(nèi)容動(dòng)態(tài)插入到留言列表的頂部。這個(gè)操作配合數(shù)組的unshift方法和DOM的insertBefore或者innerHTML拼接都能實(shí)現(xiàn)邏輯也不復(fù)雜。這個(gè)小交互在答辯現(xiàn)場(chǎng)的演示效果特別好因?yàn)樗侨旧儆械摹包c(diǎn)擊后能看到真實(shí)變化”的功能。關(guān)于我們頁(yè)面建議做一個(gè)“網(wǎng)站簡(jiǎn)介 團(tuán)隊(duì)/站點(diǎn)數(shù)據(jù) 聯(lián)系我們”的結(jié)構(gòu)配上地圖截圖或者幾張廈門(mén)風(fēng)光圖。這個(gè)頁(yè)面不需要什么交互但必須在SEO和結(jié)構(gòu)上做清楚——語(yǔ)義化標(biāo)簽、標(biāo)題層級(jí)、alt屬性這些細(xì)節(jié)都可以在這里集中展示。最好再加一段CSS3的linear-gradient背景漸變把關(guān)于頁(yè)做得有設(shè)計(jì)感一些。4. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄4.1 三個(gè)讓人崩潰的CSS布局坑做網(wǎng)頁(yè)期末作業(yè)時(shí)我見(jiàn)過(guò)最多的同學(xué)翻車(chē)在這三個(gè)地方坑一導(dǎo)航欄和banner之間出現(xiàn)一條白色縫隙。原因是瀏覽器默認(rèn)的body有margin: 8px在頁(yè)面頂部總會(huì)留下一圈白邊。解法是寫(xiě)一個(gè)全局reset* { margin: 0; padding: 0; box-sizing: border-box; }把三件套全部清零所有間距從零開(kāi)始自己控制。box-sizing: border-box一定要加否則你在Flex或Grid里設(shè)置寬度時(shí)會(huì)莫名其妙地多算border和padding的尺寸。坑二flex容器里的子元素寬度壓縮變形。Flex布局下子元素默認(rèn)可以收縮如果你的圖片或卡片被擠扁了多半是沒(méi)加flex-shrink: 0或者在圖片上沒(méi)寫(xiě)死width和height。經(jīng)驗(yàn)之談凡是希望保持固定尺寸的元素直接加flex: 0 0 auto或者width/height別給它自由發(fā)揮的空間。坑三下拉菜單的定位飄了。下拉子菜單的容器要設(shè)置position: relative子菜單用position: absolute定位到父容器下方。很多同學(xué)寫(xiě)完發(fā)現(xiàn)子菜單跑到了頁(yè)面的右下角就是因?yàn)楦溉萜鳑](méi)設(shè)relative子菜單的absolute就跑去定位到最近的定位祖先或者是瀏覽器視口了。這個(gè)知識(shí)點(diǎn)是面試必考的前端基礎(chǔ)題期末答辯老師也可能會(huì)點(diǎn)。4.2 JS報(bào)錯(cuò)的經(jīng)典現(xiàn)場(chǎng)新手寫(xiě)原生JS時(shí)最容易遇到的報(bào)錯(cuò)是TypeError: Cannot read property addEventListener of null意思是你想給一個(gè)不存在的DOM元素綁定事件。排除思路就兩步一是確認(rèn)JavaScript代碼是否放在了HTML末尾/body之前確保DOM已經(jīng)加載完畢二是檢查ID名是否拼寫(xiě)一致有時(shí)候getElementById(slide)寫(xiě)成了getElementById(slider)這種錯(cuò)誤看半天都發(fā)現(xiàn)不了。另一個(gè)經(jīng)典問(wèn)題是輪播圖在最后一頁(yè)切換回第一頁(yè)時(shí)視覺(jué)跳變。原因是translateX從最后一頁(yè)寬度瞬間回到0%中間沒(méi)有過(guò)渡動(dòng)畫(huà)。處理思路是做一個(gè)“假第一張”放在最后當(dāng)切換到假第一張后關(guān)掉過(guò)渡動(dòng)畫(huà)瞬間跳回真的第一張。或者更簡(jiǎn)單的方式用setInterval每次移動(dòng)一格到最后一張時(shí)直接重置并關(guān)閉過(guò)渡。我在代碼里采用了后者雖說(shuō)不算最優(yōu)雅但在應(yīng)付期末作業(yè)這個(gè)層面已經(jīng)完全夠用了。4.3 不同瀏覽器兼容性檢查前端期末作業(yè)最大的隱性要求是“能在不同瀏覽器里跑起來(lái)”。雖然現(xiàn)在的Chrome、Edge、Firefox對(duì)HTML5和CSS3的支持已經(jīng)很好了但仍有幾個(gè)需要注意的兼容點(diǎn)backdrop-filter: blur()在某些老版本瀏覽器上不支持如果你用了毛玻璃效果最好同時(shí)準(zhǔn)備一個(gè)純色半透明背景兜底position: sticky在一些老內(nèi)核瀏覽器上不生效可以用position: fixed做降級(jí)方案CSSgap屬性在老版本Safari上也有兼容問(wèn)題實(shí)在不放心就用margin或padding代替。我在項(xiàng)目里提前用supports語(yǔ)法做了優(yōu)雅降級(jí)瀏覽器支持backdrop-filter就用毛玻璃不支持就顯示半透明背景。這屬于進(jìn)階代碼但在老師那里非常加分。舉個(gè)實(shí)際寫(xiě)法.nav-bar { background: rgba(255, 255, 255, 0.8); } supports (backdrop-filter: blur(10px)) { .nav-bar { background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(10px); } }4.4 期末答辯時(shí)老師最?lèi)?ài)問(wèn)的幾個(gè)問(wèn)題答辯環(huán)節(jié)老師可能會(huì)盯著項(xiàng)目問(wèn)幾個(gè)“追蹤式”問(wèn)題提前準(zhǔn)備好答案效果比臨場(chǎng)發(fā)揮好得多。“你這個(gè)網(wǎng)站的導(dǎo)航吸頂效果是怎么實(shí)現(xiàn)的” 回答核心是position: sticky; top: 0;加z-index: 99并解釋一下sticky和fixed的區(qū)別sticky不會(huì)脫離文檔流而fixed會(huì)。“你的輪播圖為什么能自動(dòng)播放” 回答用setInterval定時(shí)器每次讓索引加1再通過(guò)操作transform屬性來(lái)移動(dòng)滑軌容器。“你的CSS為什么要拆成這么多文件” 回答按公共樣式和頁(yè)面樣式拆分方便復(fù)用和維護(hù)同時(shí)減少單個(gè)文件的冗余。“你的表單驗(yàn)證是前端做還是后端做” 真實(shí)答案是前端驗(yàn)證只是用戶體驗(yàn)的一部分真正的安全保障必須靠后端。答完這句老師基本就不會(huì)再往深的問(wèn)了因?yàn)槟阋呀?jīng)體現(xiàn)了現(xiàn)代Web開(kāi)發(fā)的全局意識(shí)。5. 我踩過(guò)的坑與最后幾點(diǎn)建議這份廈門(mén)旅游網(wǎng)項(xiàng)目從最早只有五六個(gè)頁(yè)面的半成品到后來(lái)補(bǔ)全為14個(gè)頁(yè)面的完整作品中間踩過(guò)最深刻的坑是“圖片不壓縮”。那時(shí)候圖片全都是手機(jī)原相機(jī)拍出來(lái)的大體積照片直接往HTML里一放打開(kāi)頁(yè)面要轉(zhuǎn)圈好幾秒整體體驗(yàn)非常糟糕。后來(lái)又花時(shí)間用工具把圖片壓縮了一遍分辨率控制在1920px以內(nèi)體積壓到200KB以下頁(yè)面打開(kāi)速度才恢復(fù)正常。這個(gè)經(jīng)歷特別想分享給所有用圖片堆視覺(jué)的同學(xué)圖片能不能快速加載是老師點(diǎn)擊網(wǎng)站后的第一感受如果首頁(yè)在5秒內(nèi)都加載不完后面做得再好都很難彌補(bǔ)這個(gè)第一印象。還有一件事就是盡量讓本地開(kāi)發(fā)環(huán)境和最終交付環(huán)境保持一致。有些同學(xué)平時(shí)用http://協(xié)議打開(kāi)本地文件有些直接雙擊HTML文件導(dǎo)致某些JS功能特別是fetch調(diào)本地JSON在雙擊打開(kāi)時(shí)直接報(bào)跨域錯(cuò)。我的建議是盡量在項(xiàng)目的根目錄直接打開(kāi)HTML文件測(cè)試所有資源都通過(guò)相對(duì)路徑引用別寫(xiě)以/開(kāi)頭的絕對(duì)路徑避免發(fā)布后路徑全部失效。再一個(gè)就是把所有頁(yè)面的標(biāo)題寫(xiě)清楚——每個(gè)HTML的title標(biāo)簽都要改成“廈門(mén)景點(diǎn)介紹 - 廈門(mén)旅游網(wǎng)”這種格式而不是14個(gè)頁(yè)面全都叫“無(wú)標(biāo)題文檔”這個(gè)細(xì)節(jié)雖然不是功能性問(wèn)題但老師抽查時(shí)看到了就會(huì)覺(jué)得你做事認(rèn)真。最后再說(shuō)一個(gè)不用花太多時(shí)間但很顯專(zhuān)業(yè)感的小點(diǎn)給詳情頁(yè)的正文圖片加一段CSS3的過(guò)渡動(dòng)畫(huà)鼠標(biāo)懸浮在圖片上時(shí)輕微放大用transition: transform 0.4s ease就能做到。這種小粒度交互在期末答辯演示時(shí)很討喜因?yàn)樗悄欠N“不看代碼就感覺(jué)很高級(jí)、看了代碼才發(fā)現(xiàn)其實(shí)很簡(jiǎn)單”的體驗(yàn)?zāi)阏f(shuō)它難不難不難但別人沒(méi)有這就是你的辨識(shí)度。整份作業(yè)的核心邏輯其實(shí)就是“把每個(gè)基礎(chǔ)技術(shù)點(diǎn)用到合適的場(chǎng)景里再把每個(gè)場(chǎng)景做到風(fēng)格統(tǒng)一”做到這兩點(diǎn)成績(jī)自然差不了。本文還有配套的精品資源點(diǎn)擊獲取