文章目录
- 整体顶层逻辑(先搞懂三者定位,彻底分清分工)
- 第一阶段:HTML(你就把它理解成搭空房子框架)
-
- [1. 做事原则(以后写HTML严格照这个来)](#1. 做事原则(以后写HTML严格照这个来))
- 简单一句话总结HTML阶段工作:
- [第二阶段 CSS(给房子刷漆,摆放家具位置)](#第二阶段 CSS(给房子刷漆,摆放家具位置))
- [第三阶段 JavaScript(房子的电路系统,控制交互、拿后端数据)](#第三阶段 JavaScript(房子的电路系统,控制交互、拿后端数据))
- 第四部分:完整开发流程(以后接到任何网页需求,严格按照这套步骤执行,这就是你的思考方式)
- 第五部分:原生JS之后框架原理(大白话讲Vue,你明白框架到底帮你干什么)
- 第六部分:给你一个极简实操案例,完整可运行代码,把上面整套流程落地
整体顶层逻辑(先搞懂三者定位,彻底分清分工)
核心定义
- HTML:负责内容(骨架)
只定义页面有什么东西:标题、按钮、图片、输入框、列表。只写结构,不管长什么样、能干什么;标签只是声明语义。 - CSS:负责外观(皮肤)
控制元素大小、颜色、位置、间距、动画。只管视觉展示,不能处理逻辑数据。 - JavaScript:行为(大脑)
实现交互逻辑:点击按钮、表单提交、发送后端请求、修改页面内容、运算判断。
一句话关系:HTML搭建页面结构,CSS渲染样式,JS动态修改HTML和CSS;HTML和CSS是静态文件,JS是编程语言 。
执行顺序:浏览器先解析HTML构建DOM树;解析HTML过程遇到CSS生成CSS‑OM树;两棵树合成渲染树,页面绘制出来;最后执行JS代码,JS可以修改DOM和CSSOM从而改变页面。
你的最终目标拆解为3件事:
- 拿到产品需求,会拆解页面;
- 按固定顺序编写代码;
- 页面出错,有一套固定排查步骤定位问题。
整个网页开发本质只有一条铁则:先搭建结构,再做外观,最后处理数据和交互,顺序永远不能颠倒。HTML只决定页面有什么东西,CSS只管长什么样子,JS只管数据和改变页面,三者职责绝不越界。
第一阶段:HTML(你就把它理解成搭空房子框架)
1. 做事原则(以后写HTML严格照这个来)
假设需求:做一个商品展示页面,页面分为顶部导航、商品列表区域、页脚。
第一步:大脑里先拆分模块,不要一上来就写标签
把页面拆成独立大块:头部、中间商品区、页脚。再拆分小块:商品区里面有很多商品卡片,每个卡片包含图片、商品名字、价格、购买按钮。
硬性规则:只划分层级,现在不去思考图片多大、字体颜色、按钮怎么排版,这些全部交给CSS处理,HTML阶段只决定页面里面有什么元素。
第二步:编写HTML代码
只用最少标签:外层容器用div;标题用h3;文字用p;图片用img;按钮用button。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- css文件在这里引入 -->
</head>
<body>
<!-- 头部模块 -->
<div class="header">
</div>
<!-- 商品区域模块 -->
<div class="goods-box">
<!-- 单个商品卡片 -->
<div class="goods-item">
<img src="图片地址">
<h3>商品名称</h3>
<p class="price">100元</p>
<button>立即购买</button>
</div>
</div>
<!-- 页脚 -->
<div class="footer">
</div>
<!-- js文件写在body末尾 -->
</body>
</html>
第三步:HTML里面唯一要做的事:给div起class名字
class命名只用语义英文,比如header、goods‑box、goods‑item。
class的作用:后面CSS靠class选中对应模块;JS也靠class找到对应标签。
禁忌:不要写id,id页面唯一,多个元素没法共用;不要写一堆没有意义的名字a1、bb。
简单一句话总结HTML阶段工作:
把页面拆分成大块、小块,用div包裹,给每个盒子起class名称,写完之后页面就是从上到下一堆内容,排版很乱属于正常情况,交给CSS处理。
第二阶段 CSS(给房子刷漆,摆放家具位置)
固定开发步骤,以后写CSS永远按这个顺序:
步骤1:全局初始化(每个项目开头复制这段代码)
清除浏览器自带默认外边距,开启box‑sizing:border‑box,只要写项目第一份CSS永远写下面代码:
css
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
解释人话:浏览器默认会给标签自带边距,我们手动清零;border‑box保证你设置的宽高不会被内边距撑大,以后布局80%盒子错乱问题直接消失。
步骤2:父盒子控制整体布局,子盒子控制自身样式(最重要的开发思想)
举例子:goods‑box里面有很多商品卡片,我想要4个商品并排摆放。
写法:父盒子goods‑box开启flex布局,子盒子goods‑item设置宽高。
css代码:
css
.goods-box{
display: flex;
gap:20px; /*商品之间的间距*/
}
.goods-item{
width:200px;
border:1px solid #ccc;
}
核心口诀:父级负责控制排列方式,子盒子负责自己大小、颜色。
- 横向并排全部使用
display:flex; - 页面整体划分行列布局用grid;
- 按钮固定在页面右下角用position定位。
步骤3:样式排错方法(以后样式不生效只用这套排查步骤)
- 打开浏览器按F12,选中你写class对应的标签;
- 看右侧css面板:你的代码上面被划掉 → 代表选择器优先级不够;
解决:把选择器层级写完整,.goods-box .goods-item,父class空格子class。 - 样式代码没有划掉,但是布局不对:
大概率是忘记设置box‑sizing:border‑box或者父盒子没有开启flex布局。 - 元素位置跑偏:开启绝对定位absolute时,父元素必须写
position:relative,否则元素会跑到浏览器角落。
CSS阶段完成之后达成效果:
页面静态样子全部做完,布局美观,但是点击按钮没有任何反应,想要点击按钮弹出提示、获取后端数据交给JS。
第三阶段 JavaScript(房子的电路系统,控制交互、拿后端数据)
JS开发强制遵守固定步骤,只要颠倒顺序就一定会出错
铁律:JS代码必须写在</body>结束标签之前。
原因:浏览器从上往下解析代码,如果JS写在head里面,HTML标签还没加载出来,JS找不到页面元素,获取元素得到null。
JS开发分固定3步:
第1步:页面加载完成后,提前把需要用到页面元素一次性获取出来
只获取一次DOM元素,不要每次点击按钮的时候再获取元素。
js
// 获取商品容器、购买按钮
const goodsBox = document.querySelector('.goods-box');
const buyBtn = document.querySelector('button');
const:固定不变的变量全部用const;会改变的数据用let;var彻底不要用。
第2步:写功能函数,一个函数只做一件事(重中之重,以后写代码的核心习惯)
遵循原则:获取后端数据单独一个函数;渲染页面单独一个函数;点击事件只调用函数。
举例子:分两个函数:
- getData:专门向服务器请求商品数据;
- renderGoods:拿到后端数据后把商品展示到页面。
js
//1. 获取后端数据
async function getData(){
//模拟从后端拿到商品数组,真实项目这里换成axios请求后端接口
let res = [
{name:"手机",price:2999},
{name:"电脑",price:5999}
]
renderGoods(res); //把数据传给渲染函数
}
//2. 根据数据渲染页面
function renderGoods(list){
let htmlStr = '';
list.forEach(item=>{
htmlStr +=`
<div class="goods-item">
<h3>${item.name}</h3>
<p>${item.price}</p>
</div>
`
})
goodsBox.innerHTML = htmlStr;
}
//页面加载完成调用获取数据函数
getData();
第3步:绑定事件,处理用户操作
点击购买按钮弹出提示:
js
buyBtn.addEventListener('click',function(){
alert('购买成功');
})
JS处理后端数据完整流程,以后前后端交互永远是这套模式:
- JS发送请求给后端;
- 后端返回JSON数组数据;
- JS拿到数组,循环拼接html字符串;
- 把拼接好的html放进页面容器里面。
JS出现问题,固定排查步骤,照着做一定能找到问题:
打开浏览器F12:
- 切换Console面板(控制台):这里会提示错误行数。
- 报错Cannot set properties of null:JS执行时页面元素还没有加载完毕;解决:js放到body末尾;
- 拿到的数据是undefined:后端数据还没返回,代码就执行完毕。
解决:请求函数前面加async,调用的时候加上await,等待后端数据返回再执行后续代码。
- 接口问题切换Network面板:
- 404:后端接口地址写错;
- 500:后端代码出错,问题不在前端;
- 查看Request Payload确认传给后端参数是否正确。
- 逻辑结果不对:
在代码可疑位置写上console.log(变量);打开控制台查看打印的值,值不符合预期就是错误根源;复杂问题使用Sources面板断点调试,一步一步查看变量。
动态生成标签坑:
如果商品是后端数据循环出来的按钮,直接绑定点击事件无效。
解决:事件委托,给父盒子绑定事件,由父盒子监听子元素点击。
js
goodsBox.addEventListener('click',function(e){
if(e.target.tagName === 'BUTTON'){
alert('购买商品');
}
})
第四部分:完整开发流程(以后接到任何网页需求,严格按照这套步骤执行,这就是你的思考方式)
步骤1:拆解需求(拿到需求第一件事,只用脑子思考不用写代码)
- 把页面切割成大块区域,再拆分成小块;区分静态内容(固定文字)和动态内容(后端返回);
步骤2:编写HTML
只用div、h、p、img、button,给所有盒子起class名字,只搭建结构,不写样式不写JS。
步骤3:编写CSS
- 全局初始化样式;
- 父盒子用flex或者grid布局控制排列方式;子盒子设置宽高颜色;
- F12调试样式问题,静态页面做完。
步骤4:编写JS(严格顺序)
- 获取页面DOM元素;
- 拆分函数:获取数据函数、渲染函数;
- 绑定点击事件;请求后端拿到数据循环渲染页面;
- 增加容错:后端返回空数据,页面显示暂无商品。
步骤5:排错(万能排错清单)
- CSS问题:F12‑Elements面板,查看样式是否被覆盖,盒子模型是否正确;
- JS语法报错:Console控制台看报错信息;
- 接口问题:Network查看请求参数和返回数据;
- 逻辑错误:console.log打印变量或者断点调试。
第五部分:原生JS之后框架原理(大白话讲Vue,你明白框架到底帮你干什么)
原生JS开发项目缺点:每次拿到数据,都需要自己拼接HTML字符串,代码量大而且繁琐。
Vue底层还是HTML+CSS+JS,它帮你省去手动拼接HTML:
你只需要定义数据,修改JS里面的数据,页面自动刷新,不用写innerHTML。
原理:Vue内部自动对比新旧数据,只修改页面变化部分,减少页面频繁刷新,提高性能。
以后写Vue的开发思路:
- template标签写页面结构;
- style标签写样式;
- script里面定义数据;修改数据页面自动更新。
第六部分:给你一个极简实操案例,完整可运行代码,把上面整套流程落地
新建一个文件夹,里面创建index.html,复制全部代码直接打开就能运行。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>商品页面</title>
<style>
*{
margin: 0;
padding:0;
box-sizing: border-box;
}
.header{
height:60px;
background:#222;
color:white;
font-size:20px;
line-height:60px;
padding-left:30px;
}
.goods-box{
display:flex;
gap:20px;
padding:30px;
}
.goods-item{
width:200px;
border:1px solid #eee;
padding:10px;
}
button{
width:100%;
height:35px;
background:#4096ff;
color:white;
border:none;
margin-top:10px;
}
</style>
</head>
<body>
<div class="header">商品商城</div>
<div class="goods-box">
<!--商品由js动态生成,这里不用手动写商品卡片-->
</div>
<script>
//1. 获取页面元素
const goodsBox = document.querySelector('.goods-box');
//2. 获取后端数据函数
async function getGoodsData(){
//模拟后端返回的数据,正式项目这里换成axios请求后端接口
const res = [
{name:"华为手机",price:4999},
{name:"笔记本电脑",price:6299}
]
render(res);
}
//3.渲染页面函数
function render(list){
let html = '';
list.forEach(item=>{
html +=`
<div class="goods-item">
<h3>${item.name}</h3>
<p>价格:${item.price}</p>
<button>立即购买</button>
</div>
`
})
goodsBox.innerHTML = html;
}
//4.绑定购买按钮事件(事件委托)
goodsBox.addEventListener('click',(e)=>{
if(e.target.tagName === 'BUTTON'){
alert('商品加入购物车成功');
}
})
//页面初始化调用函数
getGoodsData();
</script>
</body>
</html>
对照这个例子复盘整套开发逻辑:
- HTML搭建了header和goods‑box容器;
- CSS写全局样式,父盒子goods‑box开启flex布局实现横向排列;
- JS分函数获取数据、渲染页面,使用事件委托实现按钮点击;
- 如果以后后端返回更多商品,只需要修改数组数据,页面自动刷新。
以后你的学习顺序(不要去学零散知识点)
- 照着上面案例自己手写一遍;自己仿写一个新闻列表页面;熟练掌握HTML‑CSS‑JS开发步骤和排错方式;
- 学会axios发送后端请求,替换案例里面模拟的数据;
- 学习Vue框架,抛弃手动拼接HTML;
- 学习TypeScript给JS加上类型,减少出错。
最后浓缩成4句思考口诀,以后写代码默念这几句话即可:
- HTML只搭建页面层级结构,只用class命名;
- CSS父盒子控制布局,子盒子控制样式;样式问题F12查看Elements面板;
- JS提前获取DOM元素,功能拆分成独立函数,异步请求使用async‑await;JS报错看Console控制台;
- 前后端交互:后端返回数组,JS循环渲染页面。