“你的网页现在像个漂亮的画框。”
“但画框里的画,是死的。”
墨尘的这两句话,像两枚钉子,把林小凡按在了屏幕前。
他盯着自己精心打磨的页面——渐变的标题、丝滑的过渡动画、响应式布局的导航栏……确实比最初的“HTML文档”强了百倍。
但墨尘说得对。
无论他如何刷新,页面永远静默如初。按钮不会弹出提示,轮播图不会自动切换,表单提交后只会粗暴地跳转——就像一本精美的画册,读者只能被动翻页,却无法与之对话。
“所以……JavaScript能让网页‘活过来’?”林小凡打字的手指有些发抖。
聊天窗口弹出墨尘的回复:
“准备好迎接真正的编程了吗?”
第一节:第一个交互——alert的震撼
按照教程,林小凡在HTML底部插入了一行:
html
<script src="script.js"></script>
然后在script.js
里写下了人生第一行JavaScript:
javascript
alert('你好,世界!');
保存。刷新。
——砰!
一个白色弹窗突然霸占整个屏幕,冷漠的系统字体显示着“你好,世界!”,右下角只有一个孤零零的【确定】按钮。
“卧槽!”林小凡吓得从椅子上弹起来,差点撞翻可乐。
王胖子从隔壁床探头:“你电脑中毒了?”
“不!这是我写的!”他声音发颤,“你看,它听我的话跳出来了!”
王胖子看智障似的瞥了他一眼,翻身继续打游戏。
但林小凡的心脏狂跳不止。
这是他第一次——真正命令计算机做某事。
第二节:DOM操作的魔法
三天后,林小凡的script.js
已经变成了这样:
javascript
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
const heading = document.querySelector('h1');
heading.style.color = 'red';
});
他屏住呼吸点击页面上的按钮——
唰!
原本蓝色的标题瞬间变成刺目的猩红。
“成功了!我操控了DOM!”他挥舞拳头,像个刚学会魔法的学徒。
墨尘适时发来警告:
“别高兴太早。直接操作style是新手行为,CSS应该写在样式表里。”
“那该怎么改?”
“用classList。”
于是代码变成了:
javascript
heading.classList.add('error-text');
配套的CSS:
css
.error-text {
color: red;
animation: shake 0.5s;
}
这次点击按钮时,标题不仅变红,还剧烈摇晃起来,像在抗议被随意摆布。
林小凡突然理解了墨尘的坚持——
JavaScript不该是野蛮的操纵,而应是优雅的协作。
第三节:定时器的陷阱
“我想做个轮播图!”林小凡雄心勃勃地宣布。
墨尘只回了一个词:
“setInterval。”
两小时后,林小凡的代码长这样:
javascript
let currentIndex = 0;
const images = document.querySelectorAll('.slider img');
setInterval(() => {
images[currentIndex].classList.remove('active');
currentIndex = (currentIndex + 1) % images.length;
images[currentIndex].classList.add('active');
}, 3000);
效果完美——图片每3秒自动切换,伴有淡入淡出动画。
直到……他在某个页面停留了十分钟。
“为什么轮播越来越快?!”他惊恐地发现图片切换速度变成了每秒三次,像发了疯的走马灯。
墨尘发来一个捂脸表情:
“你忘了清除定时器。每次离开页面都该用clearInterval。”
林小凡查了文档才明白:
SPA(单页应用)时代,页面切换时旧JavaScript仍在后台运行,多个定时器叠加导致灾难。
“原来代码也会‘闹鬼’……”他瑟瑟发抖地加上了清理逻辑。
第四节:异步之痛
真正的噩梦始于“天气预报小插件”项目。
“API返回数据了!”林小凡看着控制台打印出的JSON数据手舞足蹈。
但当他试图把数据展示到页面上时:
javascript
const data = fetch('weather.api');
console.log(data); // 输出 Promise {<pending>}
“为什么是Promise?!我要的数据呢?!”他抓狂地摇晃显示器。
墨尘发来一段语音,背景音里隐约有咖啡杯轻碰的声音:
“JavaScript是单线程语言,fetch是异步操作。它不会傻等服务器响应,而是先给你个‘欠条’(Promise),等数据到了再‘兑现’。”
解决方案是:
javascript
fetch('weather.api')
.then(response => response.json())
.then(data => {
console.log(data); // 真正的数据
});
林小凡盯着这个链式调用看了足足五分钟,突然拍桌:
“这不就是外卖订单!
- 下单(fetch)
- 接到骑手电话(then拿到response)
- 拆包装(json()解析)
- 最后才吃到饭(拿到data)!”
墨尘罕见地发了个点赞表情:
“虽然比喻恶心,但理解正确。”
终节:觉醒之夜
凌晨三点,林小凡完成了他的第一个动态项目——
一个能添加、删除、标记完成的待办事项列表。
核心代码不过百行,却实现了:
- 本地存储(localStorage)持久化
- 防抖搜索(debounce)
- 动态排序(sort)
当他测试删除最后一条任务时,页面优雅地显示“暂无任务”的提示图——这是他用JavaScript动态插入的<div>
。
没有刷新,没有跳转,一切如呼吸般自然流畅。
窗外传来早鸟的第一声啼鸣,晨光微熹中,林小凡突然想起墨尘最初的话:
“没有JavaScript,你的网页永远是个哑巴。”
而现在,它学会了歌唱。
(第三章 完)
下一章预告:
第四章:第一个项目——企业官网的挑战
“你以为Todo List就是实战?客户会让你知道什么叫‘五彩斑斓的黑’。”——某匿名前端工程师