Lecture 2 — Client-side Programming: CSS, Bootstrap, JavaScript
1. More on CSS Properties
1.1 HTML Table
<table>定义表格
<tr>定义row,
<th>定义header cell
<td>定义data cell
通过CSS设置width、border、padding、background-color和text-align
补充:table适合有行列关系的数据,一般页面布局可使用Flexbox或Grid
< table >
< tr >< th >Course</ th >< th >Week</ th ></ tr >
< tr >< td >EIE4432</ td >< td >3</ td ></ tr >
</ table >
table { width : 100 % ; border-collapse : collapse ; }
th , td { border : 1 px solid black ; padding : 10 px ; text-align : left ; }
1.2 Display using CSS
display决定元素如何生成layout box,常见值有block、inline、inline-block、flex、grid和none
display: none会隐藏元素,也不保留其layout space
Block
换行并默认单独占据一整行父容器可用宽度,如<div>、<p>
可以设置width、height和四个方向的margin、padding
.box { display : block ; width : 200 px ; padding : 10 px ; }
Inline
在文本中排列而不主动换行,宽度主要由内容决定,如<span>、<a>
普通inline element的width、height不生效;左右margin有效,上下margin不影响布局;上下padding可以绘制,但不会像block那样推开相邻行
.label { display : inline ; color : blue ; }
Inline-block
像inline一样在同一行排列,同时每一个box都允许单独设置尺寸和四周间距
默认按底部baseline对齐,不一定顶部齐平;可使用vertical-align: top
.box { display : inline-block ; width : 25 % ; vertical-align : top ; }
Absolute Positioning
更正:absolute positioning使用position: absolute,不是display: absolute
元素脱离normal flow,原来的位置不保留;用top、right、bottom、left控制位置
简单布局中,定位参照通常是最近的非static祖先;可在父元素设置position: relative
.parent { position : relative ; height : 200 px ; }
.badge { position : absolute ; top : 10 px ; right : 10 px ; }
Float
float: left/right让元素浮到容器一侧,后续文本或inline内容可以环绕它
clear控制元素是否避开前面的float;父容器可用display: flow-root包含浮动元素
img { float : left ; margin-right : 10 px ; }
.next-section { clear : both ; }
Flexbox
在parent设置display: flex将自己变为flex container,并将direct children变为flex items控制他们的排列(并不直接描述自己的排列)
适合处理同一方向上的排列内容, gap控制item间距;justify-content控制main axis上的分布,align-items控制cross axis上的对齐
flex-wrap: wrap允许换行;默认是nowrap
< div class = "container" >
< div >A</ div >
< div >B</ div >
< div >C</ div >
</ div >
.container {
display : flex ;
gap : 10 px ;
justify-content : center ;
align-items : center ;
flex-wrap : wrap ;
}
Flex-direction
row:沿inline方向排列,英文页面通常从左到右,默认值
column:从上到下排列;row-reverse、column-reverse反转排列方向
改变direction也会改变main axis与cross axis,不能始终把justify-content理解为水平对齐
.container { display : flex ; flex-direction : column ; }
.container > * { flex-basis : 100 px ; }
Grid
display: grid建立以rows和columns组织内容的二维布局
在parent定义tracks,direct children成为grid items
CSS Grid vs Flexbox
对比项 Flexbox CSS Grid 主要维度 1D:row或column 2D:rows和columns 适用场景 列表、navigation、一排组件 gallery、多行多列、复杂页面布局 布局重点 沿主轴分配空间 同时定义行列与item位置
Flexbox可以换行,但不同flex lines不会自动形成Grid那样统一的列轨道
两者可以嵌套使用,例如Grid组织整个页面,Flexbox排列card内部内容
Grid Layout
grid-template-columns定义列宽,grid-template-rows定义行高,gap定义轨道间距
fr按比例分配剩余空间;1fr 2fr中两列得到的flexible space比例是1:2
.container {
display : grid ;
grid-template-columns : 1 fr 2 fr ;
grid-template-rows : 1 fr 1 fr ;
gap : 10 px ;
}
auto会考虑内容和可用空间,不等同于固定比例的fr
.grid-container {
display : grid ;
grid-template-rows : 100 px auto ;
grid-template-columns : 200 px auto ;
}
@media根据设备特性(如屏幕尺寸)应用对应CSS,用于responsive design
min-width
min-width: 1025px表示viewport width 大于等于1025px
@media ( min-width : 1025 px ) {
body { background-color : #ccccff ; }
}
max-width
max-width: 600px表示viewport width 小于等于600px
@media ( max-width : 600 px ) {
body { background-color : #ffcccc ; }
}
min-width & max-width
and要求两项条件同时满足;下面覆盖601px至1024px,包含两端
@media ( min-width : 601 px ) and ( max-width : 1024 px ) {
body { background-color : #ccffcc ; }
}
手机页面应在<head>加入viewport meta:
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
1.4 CSS Combinators
Combinator描述两个selectors之间的结构关系;匹配目标是右侧selector所表示的元素
Descendant Selector
div p选择<div>内部所有<p>(任意深度)
div p { color : blue ; }
Child Selector >
ul > li仅选择<ul>的direct children,不选择更深层嵌套的<li>
ul > li { font-weight : bold ; }
Adjacent Sibling Selector +
div + p选择紧跟在<div>之后、且具有同一parent的<p>
如果紧邻的下一个element不是<p>,不会继续向后查找
div + p { margin-top : 0 ; }
General Sibling Selector ~
div ~ p选择同一parent下,位于<div>之后的所有<p>,不要求紧邻
不包含<div>之前的siblings或其内部descendants
div ~ p { color : green ; }
1.5 Basic Animation with CSS
Transition
当可动画的CSS property value发生变化时,在指定duration内平滑过渡(状态间的平滑变化)
常见触发条件为:hover、:focus或JavaScript修改class
.box { background-color : blue ; transition : background-color 0.3 s ease ; }
.box:hover { background-color : red ; }
translate()移动、rotate()旋转、scale()缩放(元素的形态/位置变化)
Transform本身是变换,不自动产生随时间变化的animation;通常配合transition或keyframes
.box { transition : transform 0.3 s ; }
.box:hover { transform : translateX ( 20 px ) rotate ( 10 deg ) scale ( 1.1 ); }
Keyframes
@keyframes定义animation不同阶段的property values(多个不同阶段)
from/to等价于0%/100%,也可定义中间阶段
@keyframes move {
0% { transform : translateX ( 0 ); }
50% { transform : translateX ( 100 px ); }
100% { transform : translateX ( 0 ); }
}
Animation
animation将keyframes name、duration、timing function、iteration count等组合(全过程)
不依赖hover等状态变化也可以开始;infinite表示无限重复
.box { animation : move 2 s ease-in-out infinite ; }
2. HTML Graphics
2.1 HTML Graphics Overview
HTML5 Canvas
通过<canvas>建立绘图区,使用JavaScript绘制2D graphics与animation
适用于games、image editing、data visualization和interactive graphics
SVG
SVG(Scalable Vector Graphics)使用XML markup描述矢量形状,可缩放而不因像素放大产生锯齿
Image Tag
< img src = "diagram.png" alt = "Web page layout diagram" width = "300" >
<audio>与<video>用于嵌入音频和视频,controls显示播放控制
< video controls width = "320" >
< source src = "demo.mp4" type = "video/mp4" >
Your browser does not support this video.
</ video >
2.2 Canvas
先取得canvas element,再通过getContext("2d")得到drawing context
坐标原点通常在左上角,x向右增加,y向下增加
补充:canvas 画出的 shape 不是 DOM element,更新画面需要重新绘制
< canvas id = "drawing" width = "300" height = "150" ></ canvas >
< script >
const canvas = document. getElementById ( "drawing" );
const ctx = canvas. getContext ( "2d" );
ctx.fillStyle = "blue" ;
ctx. fillRect ( 20 , 20 , 100 , 50 ); // x, y, width, height
</ script >
2.3 SVG
<svg>建立container,width/height控制显示尺寸
viewBox定义内部坐标范围,便于等比例缩放
常见shape有<rect>、<circle>、<polygon>
fill设置内部颜色,stroke设置轮廓颜色
Drawing Polygon using SVG
<polygon points="...">用多个vertices定义封闭多边形
每个vertex用x,y表示,各vertex之间用空格分隔,最后一点会自动连接第一点
< svg width = "200" height = "150" viewBox = "0 0 200 150" >
< polygon points = "100,10 180,60 150,130 50,130 20,60"
fill = "lightblue" stroke = "black" />
</ svg >
Drawing Circle using SVG
< svg width = "200" height = "150" viewBox = "0 0 200 150" >
< circle cx = "100" cy = "75" r = "40" fill = "red" />
</ svg >
Drawing Text using SVG
<text>内部放文字,x/y指定文字定位点;补充:y通常对应text baseline
< svg width = "200" height = "80" viewBox = "0 0 200 80" >
< text x = "20" y = "40" fill = "black" >Hello, SVG!</ text >
</ svg >
Interact with SVG Elements
通过DOM定位inline SVG element,注册event listener,再修改attributes
下例点击座位后将其颜色变为orange:
< svg width = "100" height = "80" >
< rect id = "seatA1" x = "20" y = "20" width = "30" height = "30" fill = "green" />
</ svg >
< script >
document. getElementById ( "seatA1" ). addEventListener ( "click" , function () {
this . setAttribute ( "fill" , "orange" );
});
</ script >
Applications of SVG Graphics
常见应用:seat map、data visualization、interactive maps 与 UI components 等交互式矢量图形
3. Bootstrap
3.1 What is Bootstrap?
Bootstrap是front-end framework,提供预定义HTML/CSS样式以及JavaScript components
用classes组合responsive layout和UI components,减少重复编写CSS
采用mobile-first设计,页面可以根据viewport width调整布局
3.2 Why Bootstrap?
Rapid development:复用现成components,节省开发时间
Responsive design:提供grid和responsive utilities
Cross-browser compatibility:减少常见浏览器样式差异
Consistent design:统一typography、colors和components,提高视觉一致性
3.3 Popular CSS Libraries
Bootstrap(完整 grid/components)、Tailwind CSS(utility-first 组合样式)、Material UI(基于 Material Design 的 React 组件库)
3.4 Setup for Bootstrap
Local Installation
下载compiled CSS与JS,放入project folder,再通过<link>和<script>引入
< link rel = "stylesheet" href = "css/bootstrap.min.css" >
< script src = "js/bootstrap.bundle.min.js" defer ></ script >
CDN
CDN(Content Delivery Network)通过分布式servers提供资源;直接使用在线CSS/JS links
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< link rel = "stylesheet"
href = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" >
< script src = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
defer ></ script >
npm
Node.js project可通过npm管理dependency;安装后还需在项目入口或build setup中引入资源
npm install bootstrap@5.3.8
以上三种为替代引入方式,同一页面一般不重复加载Bootstrap
3.5 Mechanism of Bootstrap
CSS Class Integration
将Bootstrap classes写入HTML的class属性,让预定义CSS selectors匹配元素
< p class = "text-primary text-center" >Hello, Bootstrap!</ p >
Grid System
用container、row和column classes组合responsive layout
Bootstrap默认grid以Flexbox实现
Component Styling
提供预先设计好的组件
Component通常需要base class与modifier class,如btn btn-primary
例如按钮:
< button class = "btn btn-primary" >Primary</ button >
有交互行为的组件还需要Bootstrap JS以及对应markup/data attributes
3.6 Container
.container
居中容器,带horizontal padding,max-width随breakpoints分阶段变化
.container-fluid
所有breakpoints下都使用width: 100%,同时保留container padding, 占满所在父容器宽度
3.7 Grid System
Rows and Columns
常见层级是.container → .row → .col-*
Column放在row内部,内容放在column内部;gutter控制columns之间的间距
12-column Grid
每个row按12份计算,.col-4占4/12,即约33.33%;.col-8占8/12,即约66.67%
同一row的列份数超过12时会换行;无需每次都刚好填满12份
< div class = "container" >
< div class = "row" >
< div class = "col-4" >4/12</ div >
< div class = "col-8" >8/12</ div >
</ div >
</ div >
Column Sizing
.col让同一row中的auto-layout columns均分可用宽度
.col-sm-2表示从small断点开始占2/12,并持续适用于更大屏幕,直到更大的breakpoint class覆盖(如col-md-8)
< div class = "row" >
< div class = "col-12 col-md-8 col-lg-4" >Responsive column</ div >
</ div >
Nesting and Offset
Nesting:在column内部再放一个.row,内层仍按自身可用宽度划分12份
Offset:.offset-md-2从medium起在column前留出2/12的空间
< div class = "row" >
< div class = "col-md-8 offset-md-2" >
< div class = "row" >
< div class = "col-6" >Nested A</ div >
< div class = "col-6" >Nested B</ div >
</ div >
</ div >
</ div >
3.8 Responsive Breakpoints
使用min-width的mobile-first规则;breakpoint name表示宽度范围,不严格对应某一类设备
Extra small:小于576px;classes没有xsinfix,使用.col-12而不是.col-xs-12
Small:从576px开始,如.col-sm-6
Medium:从768px开始,如.col-md-4
Large:从992px开始,如.col-lg-3
3.9 Bootstrap Utilities
Typography
提供heading、paragraph和text utilities,例如text-center、text-start、fw-bold
text-md-center表示从md起居中
< p class = "text-start text-md-center fw-bold" >Responsive text</ p >
Color Classes
text-primary等设置text color,bg-primary等设置background color
< div class = "p-3 mb-2 bg-primary text-white" >Primary background</ div >
Spacing
格式:{property}{sides}-{size}或{property}{sides}-{breakpoint}-{size}
m是margin,p是padding;t/b是top/bottom,x/y是水平/垂直两侧,不写side则表示四周
默认size为0–5,对应0、.25、.5、1、1.5、3倍$spacer;数字不是px
auto用于margin,例如mx-auto;没有p-auto
< div class = "mt-3 px-2 ms-md-4" >Top margin and horizontal padding</ div >
< div class = "mx-auto p-2" style = "width: 200px;" >Centered element</ div >
Visibility & Display
d-none对应display: none,d-block对应block,d-flex对应flex
d-none d-lg-block:小屏隐藏,从lg起显示为block
justify-content-center、align-items-center等用于flex alignment
Icons
Bootstrap Icons是独立icon library,需要单独引入SVG或icon font resources
引入icon font后可以使用<i class="bi bi-house"></i>等classes
3.10 Bootstrap Components
Navigation
.navbar建立navigation bar,.navbar-expand-lg让其从lg起展开
Mobile hamburger常配合collapse;button的data-bs-target则需要匹配目标element ID
.btn提供base styling,.btn-primary等提供variant;.btn-sm/.btn-lg控制size
< button type = "button" class = "btn btn-primary" >Primary</ button >
< button type = "button" class = "btn btn-secondary" disabled >Disabled</ button >
.form-label用于label,.form-control用于常见inputs/textarea,.form-select用于select,.form-check及相关classes用于checkbox/radio
< label for = "email" class = "form-label" >Email</ label >
< input id = "email" name = "email" type = "email" class = "form-control" required >
3.11 CSS Overriding
Selector Specificity
在同一cascade origin/layer、importance等条件下,specificity越高的selector通常优先
常见比较:ID > class/attribute/pseudo-class > element;specificity相同时,后加载的rule优先
< link rel = "stylesheet" href = "css/bootstrap.min.css" >
< link rel = "stylesheet" href = "css/custom.css" >
<!--将custom CSS放在Bootstrap之后,便于覆盖同等specificity的样式-->
Custom Classes
在组件上添加自己的class,针对目标组件修改,不必覆盖全站同名component
Bootstrap 5.3按钮可通过component CSS variables定制normal/hover等状态
< button type = "button" class = "btn btn-primary course-button" >Course</ button >
.btn.course-button {
--bs-btn-bg : coral ;
--bs-btn-border-color : coral ;
--bs-btn-hover-bg : tomato ;
--bs-btn-hover-border-color : tomato ;
}
!important
提高某个declaration在cascade中的importance,如果竞争的declarations都带!important,仍需进一步比较cascade条件、specificity和顺序
.course-title { color : orange !important ; }
4. JavaScript
4.1 What is JavaScript?
JavaScript是dynamic programming language,可用于client-side与server-side scripting
浏览器中常用于form validation、animation、event handling与DOM manipulation
DOM Introduction
DOM(Document Object Model)把网页表示为object tree
JavaScript通过DOM API读取或改变content、structure和style,使页面产生交互
4.2 Synchronous vs Asynchronous Programming
对比项 Synchronous Asynchronous 执行方式 当前操作完成后再继续后面的代码 发起操作后继续执行,完成后再处理结果 等待影响 耗时操作可能阻塞后续执行 可避免在等待网络等结果时阻塞主线程 常见组织方式 顺序statements callback、Promise、async/await 适用例子 简单计算和顺序处理 network request、timer、I/O
console. log ( "A" );
setTimeout (() => console. log ( "B" ), 0 );
console. log ( "C" );
// 输出顺序:A(sync) → C(sync) → B(async)
4.3 Versions of JavaScript
ES5
ECMAScript 5,2009年发布;常见写法为var和traditional functions
没有ES6 arrow functions、let/const和标准import/exportmodule syntax
ES6
ECMAScript 2015,新增let/const、arrow functions、classes、modules等
还包含template literals、destructuring、spread/rest等语法
4.4 Hello World to JavaScript
Internal Script
在HTML内使用<script>放JavaScript,可位于head或body
读取DOM的代码要等对应elements建立后执行,下例将script放在button之后
< button id = "helloButton" type = "button" >Click Me</ button >
< script >
function hello () { alert ( "Welcome to EIE4432!" ); }
document. getElementById ( "helloButton" ). addEventListener ( "click" , hello);
</ script >
External Script
将JavaScript保存在.js文件,使用src引入;defer让一般external script在HTML解析完成后执行
<!-- index.html的head内 -->
< script src = "main.js" defer ></ script >
// main.js
console. log ( "Hello, EIE4432!" );
4.5 JavaScript Basics
Variable Declaration
var
Traditional declaration,主要具有function scope
var x = 5 ;
x = 10 ;
let
ES6 declaration,区别于var其还具有block scope,可以reassign
同一scope内不能重复声明同名variable
let count = 0 ;
count += 1 ;
const
ES6 declaration,具有block scope,必须初始化,不能reassign binding
但object/array内部内容可以修改
const courses = [ "EIE4432" ];
courses. push ( "EIE3343" ); // 可以修改array内容
// courses = []; // TypeError:不能重新赋值
Hoisting
Hoisting描述声明在执行前被处理的行为,不是实际把source code搬到顶部
var在声明前读取会得到undefined,assignment本身不会提前
let/const在初始化前处于Temporal Dead Zone(TDZ),读取会产生ReferenceError
console. log (a); // undefined
var a = 20 ;
// console.log(b); // 若取消注释,将产生ReferenceError
let b = 20 ;
Data Types
String
表示character sequence,可用single/double quotes;ES6还可用backticks构造template literal
Number
常见integers和floating-point values都属于Number,还包含Infinity和NaN
NaN表示invalid numeric result;可用Number.isNaN()检测
Object
由key-value properties组成,可以保存不同类型的数据与functions
let person = { name: "John" , age: 25 , isStudent: true };
console. log (person.name); // John
console. log (person[ "age" ]); // 25
Null
null表示有意设置的“无值”,与未赋值variable的undefined不同
补充:typeof null返回"object"是历史行为(bug),null本身是primitive value
let selectedSeat = null ;
Boolean
只有true和false,用于conditions和logical operations
Operators
Logical Operators
&&为AND,||为OR,!为NOT;常用于组合conditions
补充:&&/||有short-circuit行为(在左边的值已能决定结果时就不再计算右边),并且返回operand,不一定返回Boolean
const age = 20 ;
const hasTicket = true ;
console. log (age >= 18 && hasTicket); // true
Comparison Operators
==/!=可能进行type conversion;===/!==比较时不进行这种转换
>、>=、<、<=比较大小
!是logical NOT,不是独立comparison operator
console. log ( 5 == "5" ); // true
console. log ( 5 === "5" ); // false
Assignment Operators
=赋值;+=、-=等为compound assignment
let x = 5 ;
x += 2 ; // x = x + 2,得到7
x -= 1 ; // 得到6
Conditional Statements
if
let score = 75 ;
if (score >= 50 ) { console. log ( "Pass" ); }
else
let score = 75 ;
if (score >= 50 ) { console. log ( "Pass" ); }
else { console. log ( "Fail" ); }
else if
从上到下判断,执行第一个满足条件的branch,不继续执行其余branches
let num = 0 ;
if (num > 0 ) { console. log ( "Positive number" ); }
else if (num < 0 ) { console. log ( "Negative number" ); }
else { console. log ( "Zero" ); }
switch
根据expression选择匹配case;default处理没有匹配的情况
通常用break结束case,避免继续执行后面的case(fall-through)
let day = 3 ;
switch (day) {
case 1 : console. log ( "Monday" ); break ;
case 2 : console. log ( "Tuesday" ); break ;
default : console. log ( "Other day" );
}
Debugger
浏览器DevTools可查看Console、设置breakpoints,以及检查variables和call stack
console.log()
在Console输出message/value,用于观察程序执行过程
console. log ( "Current count:" , 3 );
debugger
插入debugger;,在debugger启用时暂停执行,方便检查当前state
let total = 10 ;
debugger ;
console. log (total);
4.6 Arrays
Array Declaration
用一个variable保存有序elements,index从0开始,length表示element数量
可用array literal []或Array()constructor
const fruits = [ "apple" , "banana" , "orange" ];
const numbers = new Array ( 1 , 2 , 3 );
console. log (fruits[ 0 ]); // apple
console. log (fruits. length ); // 3
Array Methods
push()
将一个或多个elements加入末尾,返回新length
const a = [ 1 , 2 ];
console. log (a. push ( 3 )); // 3;a为[1, 2, 3]
pop()
移除并返回最后一个element;empty array返回undefined
const a = [ 1 , 2 , 3 ];
console. log (a. pop ()); // 3;a为[1, 2]
shift()
移除并返回第一个element,其余elements向前移
const a = [ 1 , 2 , 3 ];
console. log (a. shift ()); // 1;a为[2, 3]
unshift()
在开头加入一个或多个elements,返回新length
const a = [ 2 , 3 ];
console. log (a. unshift ( 1 )); // 3;a为[1, 2, 3]
4.7 Functions
Function Declaration
Named function定义可重复调用的operation;parameters位于圆括号中,body位于{}内
function greet ( name ) { console. log ( "Hello, " + name + "!" ); }
greet ( "John" ); // Hello, John!
Function Parameters
Required Parameters
课件中的required表示function正常工作所需的input
补充:JavaScript不自动强制传入所有arguments;缺少的普通parameter为undefined
function greet ( name ) { console. log ( "Hello, " + name + "!" ); }
greet (); // Hello, undefined!
Optional Parameters
可用default value处理省略或显式传入undefined的argument;传入null不会触发default
function greet ( name = "Friend" ) { console. log ( "Hello, " + name + "!" ); }
greet (); // Hello, Friend!
greet ( "John" ); // Hello, John!
Return Statement
return结束当前function,可将value交给调用方;后面的statements不再执行
没有返回value的function得到undefined
function add ( a , b ) { return a + b; }
console. log ( add ( 2 , 3 )); // 5
Variable Scope
Global Scope
课件以普通script中function外的variables说明global scope,可被其内部functions读取
Local Scope
Function内部声明的variables通常只在该function内可访问
let/const还具有block scope,而var没有独立的if/for block scope
Scope Hierarchy
Inner scope可以访问outer scope的variables;outer scope不能反向访问inner scope的local variables
查找variable时从当前scope开始,逐层向外查找
Variable Shadowing
Inner scope声明与outer scope同名的variable,会在inner scope内遮蔽outer variable
let value = "global" ;
function demo () {
let value = "local" ;
console. log (value); // local
}
demo ();
console. log (value); // global
// 函数 demo 内部访问被遮蔽后的 local;函数外部访问的是全局 value
Arrow Functions
使用=>定义function expression;单个expression可以implicit return
用{}包body时,若需要返回value应明确写return
arrow function没有自己的this
const add = ( a , b ) => a + b;
const double = x => { return x * 2 ; };
console. log ( add ( 2 , 3 )); // 5
4.8 Loops
While Loop
每次执行body前检查condition;满足条件就继续,需要更新state以避免infinite loop
let count = 5 ;
while (count >= 1 ) {
console. log (count);
count -- ;
}
// 5, 4, 3, 2, 1;最后count为0
For Loop
Basic for
顺序:initialization → condition → body → update → 再检查condition
for ( let i = 0 ; i < 5 ; i ++ ) { console. log (i); }
// 0, 1, 2, 3, 4
for...in
遍历enumerable property keys
const person = { name: "John" , age: 30 };
for ( const key in person) { console. log (key, person[key]); }
for...of
遍历iterable的values,如arrays和strings
普通object默认不可直接用for…of
const fruits = [ "apple" , "banana" , "orange" ];
for ( const fruit of fruits) { console. log (fruit); }
4.9 Advanced Array Methods
map()
对每个element应用callback,将callback返回值组成新array
const numbers = [ 1 , 2 , 3 , 4 , 5 ];
const doubled = numbers. map ( n => n * 2 );
console. log (doubled); // [2, 4, 6, 8, 10]
reduce()
将elements逐步累积为一个结果;callback接收accumulator与current value
下例提供initial value 0,使empty array也有明确结果
const numbers = [ 1 , 2 , 3 , 4 , 5 ];
const sum = numbers. reduce (( acc , n ) => acc + n, 0 );
console. log (sum); // 15
filter()
将通过callback condition的elements组成新array
const numbers = [ 1 , 2 , 3 , 4 , 5 ];
const even = numbers. filter ( n => n % 2 === 0 );
console. log (even); // [2, 4]
forEach()
对每个element执行callback,适合逐项执行side effects;返回undefined,不会收集callback results
const numbers = [ 1 , 2 , 3 , 4 , 5 ];
numbers. forEach ( n => console. log (n)); // 依次输出1至5
4.10 Document Object Model (DOM)
DOM Structure
浏览器解析HTML后建立node tree,包含document、elements和text nodes
Elements之间具有parent、child和sibling relationships,JavaScript可定位并修改这些nodes
Interact with DOM
常见流程:定位element → 注册event handler → 在event发生时读取/更新页面
Events
click:点击;focus/blur:获得/失去焦点;keydown/keyup:按下/释放按键;submit:提交form
HTML attribute常写onclick等,而addEventListener()的event name写"click",不加on
Update Content of HTML Elements
getElementById()
按唯一ID取得一个element;找不到时返回null
const output = document. getElementById ( "output" );
getElementsByClassName()
按class取得live HTMLCollection,需要index或遍历取得单个element
const cards = document. getElementsByClassName ( "card" );
if (cards. length > 0 ) { cards[ 0 ].textContent = "First card" ; }
getElementsByTagName()
按tag name取得live HTMLCollection
const paragraphs = document. getElementsByTagName ( "p" );
innerHTML
读取或写入element内部的HTML markup,写入时会解析tags
不要直接把未经处理的user input赋给innerHTML
仅显示文字时使用textContent
document. getElementById ( "output" ).innerHTML = "<strong>Hello</strong>" ;
textContent
读取或写入text,写入内容不会当作HTML tags解析
document. getElementById ( "output" ).textContent = "<strong>Hello</strong>" ;
// 页面显示这段字面文本,不产生加粗标签
Modify Style of HTML Elements
用element.style修改inline style
const output = document. getElementById ( "output" );
output.style.color = "red" ;
output.style.backgroundColor = "yellow" ;
常见text inputs和selects通过.value取得当前内容,通常返回string
例:
<!--读取输入并更新页面,`preventDefault()`阻止本次默认提交-->
< form id = "userForm" >
< label for = "username" >Username</ label >
< input id = "username" name = "username" required >
< button type = "submit" >Show</ button >
</ form >
< p id = "result" ></ p >
< script >
document. getElementById ( "userForm" ). addEventListener ( "submit" , function ( event ) {
event. preventDefault ();
const name = document. getElementById ( "username" ).value;
document. getElementById ( "result" ).textContent = name;
});
</ script >
Event Listener
Listener是event发生时执行的callback;同一element可以注册多个listeners
addEventListener()
element.addEventListener(eventType, callback)注册listener
const button = document. getElementById ( "myButton" );
const output = document. getElementById ( "output" );
function handleClick () { output.textContent = "Button clicked!" ; }
button. addEventListener ( "click" , handleClick);
removeEventListener()
移除时必须使用同一event type、同一callback reference,并匹配capture设置
setTimeout ( function () {
button. removeEventListener ( "click" , handleClick);
output.textContent = "Event listener removed." ;
}, 5000 );
4.11 Built-in JavaScript Utilities
Random
Random Number
Math.random()返回范围[0, 1)的pseudo-random number
闭区间[min, max]内随机integer
const oneToTen = Math. floor (Math. random () * 10 ) + 1 ;
const hundredToNineHundred = Math. floor (Math. random () * 801 ) + 100 ;
Random Array Item
Random index范围为0至array.length - 1,再通过index取value
const fruits = [ "apple" , "banana" , "orange" ];
const index = Math. floor (Math. random () * fruits. length );
console. log (fruits[index]);
Math
Method 作用 例子 Math.floor(x)向负无穷取整 Math.floor(-1.2) = -2Math.ceil(x)向正无穷取整 Math.ceil(-1.2) = -1Math.abs(x)绝对值 Math.abs(-3) = 3Math.round(x)取最近integer,恰好一半时向正无穷方向 Math.round(-1.5) = -1Math.max(...)取最大值 Math.max(1, 5, 3) = 5
const numbers = [ 1 , 5 , 3 ];
console. log (Math. max ( ... numbers)); // 5
Date Methods
new Date()取得当前date/time的Date object
getDate()取得月份中的日期(1–31);getMonth()为0–11;getFullYear()取得四位年份
toISOString()返回ISO格式,UTC时间以Z结尾;与local getters使用的时区可能不同
const now = new Date ();
console. log (now. getFullYear ());
console. log (now. getMonth () + 1 ); // 转成日常使用的1–12月
console. log (now. getDate ());
console. log (now. toISOString ());
4.12 Error Handling
try
包住可能throw error的operation;发生error时跳出当前try的后续代码,转到对应catch
catch
接收并处理try中抛出的error,可通过error.message取得说明
throw
主动抛出error,例如input不满足要求;常用throw new Error("message")
finally
无论try正常完成或进入catch,finally通常都会执行,适合cleanup等共同收尾
执行finally不代表operation成功;课件的“process completed”不等于registration successful
function validateRegistration ( username , password ) {
try {
if ( ! username) { throw new Error ( "Username is required." ); }
if (password. length < 8 ) {
throw new Error ( "Password must be at least 8 characters long." );
}
console. log ( "Validation passed." );
} catch (error) {
console. log ( "Validation failed:" , error.message);
} finally {
console. log ( "Validation check completed." );
}
}
validateRegistration ( "John" , "123" );
// Validation failed: Password must be at least 8 characters long.
// Validation check completed.
链接