Flutter系列的文章我會(huì)持續(xù)更新一個(gè)月左右,力求利用1個(gè)月帶大家入門Flutter,抓住這波技術(shù)風(fēng)口,歡迎大家關(guān)注。同時(shí)如果覺得這里代碼排版不是很舒服的讀者可以關(guān)注我的微信公眾號(hào)“IT工匠”,我會(huì)同步更新,另外微信公眾號(hào)上還有很多互聯(lián)網(wǎng)必備資源(涉及算法、數(shù)據(jù)結(jié)構(gòu)、java、深度學(xué)習(xí)、計(jì)算機(jī)網(wǎng)絡(luò)、python、Android等互聯(lián)網(wǎng)技術(shù)資料),歡迎大家關(guān)注、交流。
文的主要內(nèi)容:
Flutter中按照是否自身可直接響應(yīng)用戶交互可以將Widget分為兩類:
由于第一類比較簡(jiǎn)單,本文重點(diǎn)介紹一下第二類,即如何為非交互性(不能直接響應(yīng)用戶交互)的Widget添加交互性, 具體來說,我們將通過創(chuàng)建一個(gè)自定義的Statful Widget來讓Icon具有交互性。
在上一篇文章中我們介紹了如何構(gòu)建一個(gè)下面這樣的UI頁面:
當(dāng)這個(gè)app第一次運(yùn)行的時(shí)候那個(gè)星星是紅色的,代表這個(gè)屏幕中展示的那個(gè)圖片被用戶點(diǎn)擊了喜歡,星星后面的數(shù)字47代表一共有47個(gè)用戶點(diǎn)擊了喜歡。本文將實(shí)現(xiàn),點(diǎn)擊星星后移除喜歡狀態(tài),用空心星星替換實(shí)心星星并減少星星后面的計(jì)數(shù)。 再次點(diǎn)擊空心星星代表添加喜歡,會(huì)繪制一顆實(shí)心的星星并增加星星后的數(shù)字。
要實(shí)現(xiàn)此功能,您將創(chuàng)建一個(gè)包含星星和計(jì)數(shù)的自定義Widget, 點(diǎn)擊星星會(huì)更改兩個(gè)子Widget的狀態(tài),因此自定義的Widget應(yīng)該同時(shí)管理這兩個(gè)子Widget(星星和計(jì)數(shù))。
首先我將會(huì)介紹一點(diǎn)前備知識(shí),如果你只對(duì)最終的代碼實(shí)現(xiàn)感興趣,你可以直接跳到第2步:創(chuàng)建StatefulWidget的子類,如果你想嘗試其他的管理狀態(tài)的方法,可以直接跳到管理狀態(tài)一節(jié)。
一個(gè)Widget要么是有狀態(tài)(stateful)的,要么是無狀態(tài)(stateless)的,如果一個(gè)Widget是可改變的,比如當(dāng)用戶與其交互的時(shí)候其會(huì)產(chǎn)生變化,這個(gè)Widget就是有狀態(tài)的(stateful)。
一個(gè)無狀態(tài)(stateless)的Widget是永遠(yuǎn)不會(huì)發(fā)生改變的,Icon、IconButton、Text都是典型的無狀態(tài)的Widget,無狀態(tài)(stateless)的Widget都是StatelessWidget的子類。
一個(gè)有狀態(tài)(stateful)的Widget是動(dòng)態(tài)的,比如它可以更改其外觀以響應(yīng)用戶交互或接收數(shù)據(jù)時(shí)觸發(fā)的事件。CheckBox、Radio、Slider、InkWell、Form、TextField都是典型的有狀態(tài)的Widget,有狀態(tài)(stateful)的Widget都是StatefulWidget的子類。
Widget的狀態(tài)都是保存在State對(duì)象中的,從外觀上分析小部件的狀態(tài)。 狀態(tài)由可以更改的值組成,例如滑塊(slider)的當(dāng)前值、是否選中復(fù)選框(CheckBox)。 當(dāng)Widget的狀態(tài)發(fā)生變化時(shí),State對(duì)象調(diào)用會(huì)setState()方法來告訴框架重繪該Widget。
明確幾點(diǎn)概念:
本節(jié)將創(chuàng)建一個(gè)自定義的有狀態(tài)(Stateful)的Widget,我們將用我們自定義的包含一個(gè)IconButton和一個(gè)Text的Widget來替代原有的紅色星星Widget和計(jì)數(shù)Widget。
實(shí)現(xiàn)一個(gè)自定義的Widget需要?jiǎng)?chuàng)建2個(gè)類:
我們通過簡(jiǎn)單的幾步來構(gòu)建一個(gè)名為FavoriteWidget的自定義Widget:
第1步:決定由那個(gè)對(duì)象來管理Widget的狀態(tài)(State)
Widget的狀態(tài)(State)可以有多種管理方式,在此處由于切換星星的狀態(tài)(實(shí)心還是空心)是一個(gè)獨(dú)立的操作,不會(huì)影響父Widget或UI的其余部分,所以我們讓W(xué)idget自己管理自己的狀態(tài)(State)。
關(guān)于詳細(xì)的狀態(tài)管理的內(nèi)容,我會(huì)在后面的管理狀態(tài)一節(jié)介紹。
<span id="subclass-statefulWidget">第2步:創(chuàng)建StatefulWidget的子類</span>
由于第1步我們已經(jīng)決定了FavoriteWidget自己管理自己的狀態(tài)(State),所以我們應(yīng)該重寫createState()方法來創(chuàng)建一個(gè)State對(duì)象。Flutter框架會(huì)在構(gòu)建Widget的時(shí)候調(diào)用對(duì)應(yīng)Widget的createState()方法。在這個(gè)例子中,我們應(yīng)該在createState()方法中返回一個(gè)我們將在下一步定義的_FavoriteWidgetState類的實(shí)例對(duì)象:
class FavoriteWidget extends StatefulWidget { @override _FavoriteWidgetState createState() => _FavoriteWidgetState(); }
注意:這里的_開頭指的是定義的對(duì)應(yīng)類是私有的。
第3步:創(chuàng)建State類的子類
我們定義一個(gè)_FavoriteWidgetState類來存儲(chǔ)會(huì)在Widget不同生命周期變化的數(shù)據(jù),當(dāng)app第一次運(yùn)行的時(shí)候,UI界面應(yīng)該展示紅色的實(shí)心星星,代表當(dāng)前已經(jīng)選擇了”喜歡”狀態(tài),并且傍邊展示的文字為”41”,我們本別使用bool _isFavorited和int _favoriteCount變量來存儲(chǔ)這兩個(gè)狀態(tài):
class _FavoriteWidgetState extends State<FavoriteWidget> { bool _isFavorited = true; int _favoriteCount = 41; // ··· }
_FavoriteWidgetState類同樣也定義了一個(gè)build()方法,在該方法中創(chuàng)建一個(gè)Row(行),Row中包含有一個(gè)Iconbutton和一個(gè)Text,我們使用Iconbutton而不是Icon的原因是IconButton有onPressed屬性,我們可以通過這個(gè)onPressed屬性定義處理點(diǎn)擊事件的回調(diào)函數(shù)(_toggleFavorite),我們將在后面具體定義這個(gè)_toggleFavorite函數(shù):
class _FavoriteWidgetState extends State<FavoriteWidget> { // ··· @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ Container( padding: EdgeInsets.all(0), child: IconButton( icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)), color: Colors.red[500], onPressed: _toggleFavorite, ), ), SizedBox( width: 18, child: Container( child: Text('$_favoriteCount'), ), ), ], ); } }
注意:我們這里將Text作為子Widget放置在了SizedBox中,并且設(shè)置了SizedBox的寬度,這樣做的作用是固定Text的寬度,設(shè)想一下,當(dāng)Text中只顯示1位數(shù)字的時(shí)候Text的寬度和顯示2位數(shù)字的寬度一定是不一樣的,如果不固定Text的寬度,當(dāng)數(shù)字變化的時(shí)候就會(huì)出現(xiàn)Text寬度發(fā)生跳變的情況,導(dǎo)致視覺效果很不好。
當(dāng)IconButton被點(diǎn)擊的時(shí)候?qū)?huì)調(diào)用_toggleFavorite()方法,我們?cè)赺toggleFavorite()方法中調(diào)用setstate()方法并更新狀態(tài),這樣Flutter框架就會(huì)知道需要重新繪制當(dāng)前Widget了,從而達(dá)到更新界面的效果:
void _toggleFavorite() { setState(() { if (_isFavorited) { _favoriteCount -= 1; _isFavorited = false; } else { _favoriteCount += 1; _isFavorited = true; } }); }
setState()方法中的代碼邏輯很簡(jiǎn)單,首先判斷當(dāng)前_isFavorited的狀態(tài),然后對(duì)_isFavorited和_isFavorited的值進(jìn)行更新。
第4步:將我們自定義的Stateful Widget加入到Widget樹中
我們應(yīng)該在app的build()方法中將我們自定義的Stateful Widget加入到Widget 樹中,首先找到原先Icon和Text的位置,然后刪除原來的代碼,加入新的我們創(chuàng)建的Stateful Widget:
Widget titleSection = Container( padding: const EdgeInsets.all(32), child: Row( children: [ Expanded( /*1*/ child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /*2*/ Container( padding: const EdgeInsets.only(bottom: 8), child: Text( 'Oeschinen Lake Campground', style: TextStyle( fontWeight: FontWeight.bold, ), ), ), Text( 'Kandersteg, Switzerland', style: TextStyle( color: Colors.grey[500], ), ), ], ), ), FavoriteWidget(), ], ), );
然后運(yùn)行代碼(推薦使用熱更新),可以看到效果圖:
在我們的設(shè)計(jì)中,到底應(yīng)該由誰來管理Widget的狀態(tài)(State)?是Widget本身?是Widget的父Widget?還是二者共同管理?還是另一個(gè)對(duì)象來管理? 事實(shí)上有不止一種有效的方法可以使你的Widget小部件具有交互性, 作為Widget的設(shè)計(jì)者,你可以根據(jù)預(yù)期的Widget的使用方式做出決策。 以下是幾種最常用的管理狀態(tài)的方法:
你可能會(huì)有疑問,你應(yīng)該如何決定具體使用哪一種狀態(tài)管理方法?這里提供幾個(gè)原則供你參考:
如果你不太確定自己的場(chǎng)景屬于以上哪種,可以直接使用父級(jí)Widget管理的方法,因?yàn)檫@個(gè)方法是通用的。
接下來我將通過創(chuàng)建三個(gè)簡(jiǎn)單示例(TapboxA,TapboxB和TapboxC)來舉例說明管理狀態(tài)的不同方法。 這幾個(gè)示例的工作方式類似: 每個(gè)都創(chuàng)建了一個(gè)Container,當(dāng)點(diǎn)擊時(shí),可以在綠色或灰色框之間切換, _active布爾值確定顏色:true代表綠色,false代表灰色。
Widget自己管理自己本身的State
有時(shí),由Widget自己管理自己的狀態(tài)可以產(chǎn)生很強(qiáng)大的功能。例如,ListView在其內(nèi)容的總尺寸超出其最大渲染框的尺寸時(shí)會(huì)自動(dòng)進(jìn)行滾動(dòng),這個(gè)滾動(dòng)的狀態(tài)是由ListView自己管理的,不需要我們開發(fā)人員去手動(dòng)設(shè)置它什么時(shí)候應(yīng)該開始滾動(dòng)、什么時(shí)候應(yīng)該停止?jié)L動(dòng)。
我們通過一個(gè)示例來進(jìn)行說明,我們創(chuàng)建一個(gè)_TapboxAState類:
代碼如下:
// TapboxA 自己管理自己的狀態(tài) //------------------------- TapboxA ---------------------------------- class TapboxA extends StatefulWidget { TapboxA({Key key}) : super(key: key); @override _TapboxAState createState() => _TapboxAState(); } class _TapboxAState extends State<TapboxA> { bool _active = false; void _handleTap() { setState(() { _active = !_active; }); } Widget build(BuildContext context) { return GestureDetector( onTap: _handleTap, child: Container( child: Center( child: Text( _active ? 'Active' : 'Inactive', style: TextStyle(fontSize: 32.0, color: Colors.white), ), ), width: 200.0, height: 200.0, decoration: BoxDecoration( color: _active ? Colors.lightGreen[700] : Colors.grey[600], ), ), ); } } //------------------------- MyApp ---------------------------------- class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: Scaffold( appBar: AppBar( title: Text('Flutter Demo'), ), body: Center( child: TapboxA(), ), ), ); } }
運(yùn)行效果如下圖所示:
Widget的父級(jí)Widget管理其State
父Widget管理子Widget狀態(tài)的最大用處是在合適的時(shí)機(jī)通知子Widget進(jìn)行UI更新。 例如,IconButton允許你將Icon視為可點(diǎn)擊的按鈕, IconButton是一個(gè)無狀態(tài)的Widget,所以我們應(yīng)該通過父Widget來確定Iconutton是否已被點(diǎn)擊。
在以下例子中,TapboxB將其狀態(tài)回調(diào)給父Widget,因?yàn)門apboxB不管理任何狀態(tài),所以它是StatelessWidget的子類。
在這個(gè)示例中我們應(yīng)該實(shí)現(xiàn)2個(gè)類:ParentWidgetState(代表父Widget)、TapboxB(代表子Widget)
ParentWidgetState的主要功能:
TapboxB的主要功能:
代碼實(shí)現(xiàn)如下:
// ParentWidget為TapboxB管理狀態(tài). //------------------------ ParentWidget -------------------------------- class ParentWidget extends StatefulWidget { @override _ParentWidgetState createState() => _ParentWidgetState(); } class _ParentWidgetState extends State<ParentWidget> { bool _active = false; void _handleTapboxChanged(bool newValue) { setState(() { _active = newValue; }); } @override Widget build(BuildContext context) { return Container( child: TapboxB( active: _active, onChanged: _handleTapboxChanged, ), ); } } //------------------------- TapboxB ---------------------------------- class TapboxB extends StatelessWidget { TapboxB({Key key, this.active: false, @required this.onChanged}) : super(key: key); final bool active; final ValueChanged<bool> onChanged; void _handleTap() { onChanged(!active); } Widget build(BuildContext context) { return GestureDetector( onTap: _handleTap, child: Container( child: Center( child: Text( active ? 'Active' : 'Inactive', style: TextStyle(fontSize: 32.0, color: Colors.white), ), ), width: 200.0, height: 200.0, decoration: BoxDecoration( color: active ? Colors.lightGreen[700] : Colors.grey[600], ), ), ); } }
代碼的運(yùn)行效果如下:
混合使用前兩種管理方法
對(duì)于某些Widget,使用混合的方法管理其狀態(tài)很有有意義。 在這種情況下,有狀態(tài)(stateful)的Widget和其父Widget分別管理其一部分狀態(tài)(State)。
在TapboxC示例中,在點(diǎn)擊時(shí),框周圍會(huì)出現(xiàn)深綠色邊框,點(diǎn)擊后,邊框消失,框的顏色也會(huì)改變。 TapboxC將其 _active狀態(tài)導(dǎo)出到其父Widget,在內(nèi)部管理只其 _highlight狀態(tài),所以 此示例有兩個(gè)State對(duì)象,_ParentWidgetState和_TapboxCState:
_ParentWidgetState的功能:
_TapboxCState的功能:
//---------------------------- ParentWidget ---------------------------- class ParentWidget extends StatefulWidget { @override _ParentWidgetState createState() => _ParentWidgetState(); } class _ParentWidgetState extends State<ParentWidget> { bool _active = false; void _handleTapboxChanged(bool newValue) { setState(() { _active = newValue; }); } @override Widget build(BuildContext context) { return Container( child: TapboxC( active: _active, onChanged: _handleTapboxChanged, ), ); } } //----------------------------- TapboxC ------------------------------ class TapboxC extends StatefulWidget { TapboxC({Key key, this.active: false, @required this.onChanged}) : super(key: key); final bool active; final ValueChanged<bool> onChanged; _TapboxCState createState() => _TapboxCState(); } class _TapboxCState extends State<TapboxC> { bool _highlight = false; void _handleTapDown(TapDownDetails details) { setState(() { _highlight = true; }); } void _handleTapUp(TapUpDetails details) { setState(() { _highlight = false; }); } void _handleTapCancel() { setState(() { _highlight = false; }); } void _handleTap() { widget.onChanged(!widget.active); } Widget build(BuildContext context) { // This example adds a green border on tap down. // On tap up, the square changes to the opposite state. return GestureDetector( onTapDown: _handleTapDown, // Handle the tap events in the order that onTapUp: _handleTapUp, // they occur: down, up, tap, cancel onTap: _handleTap, onTapCancel: _handleTapCancel, child: Container( child: Center( child: Text(widget.active ? 'Active' : 'Inactive', style: TextStyle(fontSize: 32.0, color: Colors.white)), ), width: 200.0, height: 200.0, decoration: BoxDecoration( color: widget.active ? Colors.lightGreen[700] : Colors.grey[600], border: _highlight ? Border.all( color: Colors.teal[700], width: 10.0, ) : null, ), ), ); } }
運(yùn)行效果如下所示:
替代實(shí)現(xiàn)可能已將高亮狀態(tài)導(dǎo)出到父級(jí),同時(shí)保持活動(dòng)狀態(tài)為內(nèi)部,但如果您要求某人使用該分接框,他們可能會(huì)抱怨它沒有多大意義。 開發(fā)人員關(guān)心該框是否處于活動(dòng)狀態(tài)。 開發(fā)人員可能并不關(guān)心如何管理突出顯示,并且更喜歡點(diǎn)按框處理這些細(xì)節(jié)。
Flutter提供了很多按鈕和類似的交互式Widget。 這些Widget中的大多數(shù)都實(shí)現(xiàn)了Material Design準(zhǔn)則,該準(zhǔn)則定義了一組具有固定用戶界面的組件。
如果您愿意,可以使用GestureDetector在任何自定義的Widget中構(gòu)建交互性。 您可以在管理狀態(tài)一節(jié)中找到GestureDetector的使用示例。
提示:Flutter還提供了一些IOS風(fēng)格的Widget,稱之為Cupertino,具體地址:https://api.flutter.dev/flutter/cupertino/cupertino-library.html
當(dāng)您需要交互性時(shí),最簡(jiǎn)單的方法是使用Flutter已經(jīng)給我提供好的Widget,下面是一個(gè)部分列表:
標(biāo)準(zhǔn)庫中的Widget
Material庫中的Widget
單標(biāo)簽
網(wǎng)頁(程序)如果要和用戶產(chǎn)生互動(dòng),則必須借助一定的中介,這個(gè)中介一般是:文本輸入框、按鈕、多選框、單選框。而表單則是這些中介和放置這些中介的空間(<form action=”” methon=””></form>)。
在網(wǎng)頁中,這些文本輸入框、按鈕等等必須放置在由<form></form>這個(gè)標(biāo)簽所定義的空間中,否則沒有實(shí)際意義。所以,由<form></form>標(biāo)簽所定義的空間就是表單存在的空間。
【各種輸入類型】
呈現(xiàn)結(jié)果
姓名:
原始碼
<form action=http://www.baidu.com/nameproject.aspmethon=”post”>
姓名:<input type="text" name="name" size="20">
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
性別:男 女
原始碼
<form>
性別:
男 <input type="radio" name="sex" value="boy">
女 <input type="radio" name="sex" value="girl">
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
喜好: 電影 看書
原始碼
<form>
喜好:
<input type="checkbox" name="sex" value="movie">電影
<input type="checkbox" name="sex" value="book">看書
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
請(qǐng)輸入密碼:
原始碼
<form>
請(qǐng)輸入密碼:<input type="password" name="input">
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
原始碼
<form>
<input type="submit" value="送出資料">
<input type="reset" value="重新填寫">
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
請(qǐng)按下按鈕:
原始碼
<form>
請(qǐng)按下按鈕:<input type="button" name="ok" value="我同意">
</form>
它有下列可設(shè)定之屬性:
呈現(xiàn)結(jié)果
隱藏欄位:
原始碼
<form>
隱藏欄位:<input type="hidden" name="nosee" value="看不到">
</form>
它有下列可設(shè)定之屬性:
【大量文字輸入元件】
呈現(xiàn)結(jié)果
請(qǐng)輸入您的意見:
原始碼
<form>
請(qǐng)輸入您的意見:<br>
<textarea name="talk" cols="20" rows="3"></textarea>
</form>
它有下列可設(shè)定之屬性:
【下拉式選單】
呈現(xiàn)結(jié)果
您喜歡看書嗎?:
非常喜歡
還算喜歡
不太喜歡
非常討厭
原始碼
<form>
您喜歡看書嗎?:
<select name="like">
<option value="非常喜歡">非常喜歡
<option value="還算喜歡">還算喜歡
<option value="不太喜歡">不太喜歡
<option value="非常討厭">非常討厭
</select>
</form>
它有下列可設(shè)定之屬性:
multiple,是設(shè)定此一欄位為復(fù)選,可以一次選好幾個(gè)選項(xiàng)。
....................................................................
我的微信公眾號(hào):UI嚴(yán)選 —越努力,越幸運(yùn)
TMl 的標(biāo)簽可以分為單個(gè)標(biāo)簽和成對(duì)標(biāo)簽。
單個(gè)標(biāo)簽:html4 規(guī)定單個(gè)標(biāo)簽要有一個(gè) / 表示結(jié)尾, html5 則不用
<!--單個(gè)標(biāo)簽-->
<meta>
<!--成對(duì)標(biāo)簽 -->
<div></div>
以下是HTMl中常用的一些標(biāo)簽
div 標(biāo)簽 主要用來將相關(guān)的內(nèi)容組合到一塊,就像菜市場(chǎng)把各個(gè)蔬菜分成不同種類區(qū)分?jǐn)[放是一個(gè)道理。
div 是最常見也是比較重要的標(biāo)簽,網(wǎng)頁布局中經(jīng)常使用的一類標(biāo)簽。通常布局被稱為 DIV + CSS 布局
<div>
div 就是一個(gè)分類的存儲(chǔ)箱子
</div>
p標(biāo)簽表示段落, 在網(wǎng)頁文字中應(yīng)用的比較多
<!--段落和段落間會(huì)換行-->
<p>第一段</p>
<p>第二段</p>
h標(biāo)簽分為六個(gè)
標(biāo)簽 | 語義 |
h1 | 一級(jí)標(biāo)題 |
h2 | 二級(jí)標(biāo)題 |
h3 | 三級(jí)標(biāo)題 |
h4 | 四級(jí)標(biāo)題 |
h5 | 五級(jí)標(biāo)題 |
h6 | 六級(jí)標(biāo)題 |
引用標(biāo)題標(biāo)簽后,字體會(huì)加粗、字號(hào)一會(huì)變大
無序標(biāo)簽是沒有顯示順序的列表,無序列表前面通常會(huì)有一個(gè)“小點(diǎn)”, 這個(gè)小點(diǎn)可以用type屬性控制。其中有三個(gè)展示方式(不過這種方式比較固定,不夠靈活和美觀, 已經(jīng)被CSS的效果代替),如下:
值(type屬性) | 描述 |
disc | 默認(rèn)值,實(shí)心圓 |
circle | 空心圓 |
square | 實(shí)心方框 |
舉例:
<!--ul標(biāo)簽內(nèi)部只能放置li標(biāo)簽-->
<!--li標(biāo)簽內(nèi)部可以放其他的標(biāo)簽-->
<ul type=">
<li>無序列表元素1</li> <!--列表項(xiàng)-->
<li>無序列表元素2</li>
</ul>
實(shí)心圓
<ul type="disc">
<li>西紅柿</li>
<li>黃瓜</li>
</ul>
空心圓
<ul type="circle">
<li>西紅柿</li>
<li>黃瓜</li>
</ul>
實(shí)心方框
<ul type="square">
<li>西紅柿</li>
<li>黃瓜</li>
</ul>
type屬性值 | 意義 |
a | 小寫英文字母編號(hào) |
A | 大寫英文字母編號(hào) |
i | 小寫羅馬數(shù)字編號(hào) |
I | 大寫羅馬數(shù)字編號(hào) |
1 | 數(shù)字編號(hào)(默認(rèn)) |
有序列表, 從2開始
<ol start="2">
<li>元素1</li>
<li>元素2</li>
</ol>
小寫字母表示
<ol type="a">
<li>元素1</li>
<li>元素2</li>
<li>元素3</li>
</ol>
倒敘
<ol reversed>
<li>元素1</li>
<li>元素2</li>
<li>元素3</li>
</ol>
dl標(biāo)簽表示自定義列表
dt表示數(shù)據(jù)項(xiàng),dd表示數(shù)據(jù)定義, dd是dt標(biāo)簽的解釋
<dl>
<dt>西紅柿</dt>
<dd>紅、酸</dd>
<dt>黃瓜</dt>
<dd>綠、澀</dd>
</dl>
img 用來插入圖片,包括但不限于以下圖片格式
圖片格式 | 備注 |
.jpg、.jpeg | 通常用于照片,是一種有損壓縮格式 |
.png | 通常用于logo、背景,支持透明和半透明。便攜式網(wǎng)絡(luò)圖像 |
.svg | 矢量圖片 |
<!-- src(source)屬性, 圖片地址,可以為相對(duì)路徑,也可以為絕對(duì)路徑-->
<!-- alt 如果遇到圖片無法加載的情況,網(wǎng)頁上會(huì)展示 alt的 值 -->
<!-- width 和 height 表示 寬和高, 如果只設(shè)置一個(gè), 那么另外一個(gè)就會(huì)跟著成比例縮放-->
<img src="./images/images.jpg" alt="星期一" width="120" height="20">
用a標(biāo)簽來制作超級(jí)鏈接
<!-- href 屬性 表示 其他頁面的鏈接,支持相對(duì)路徑和絕對(duì)路徑,還可以鏈接到其它網(wǎng)站 -->
<!--target 屬性表示 打開其他鏈接的方式-->
<!-- title 屬性表示 鏈接的標(biāo)題, 當(dāng)鼠標(biāo)移動(dòng)到鏈接上,會(huì)展示出來-->
<a href="http://www.baidu.com" target="blank" title="文字標(biāo)題">百度</a>
<!--也可以用a標(biāo)簽作為錨點(diǎn) 錨點(diǎn)可以是本頁面的錨點(diǎn),也可以是其他頁面的錨點(diǎn)-->
<h1 id="title">頭部標(biāo)題</h1>
... 此處省略一些代碼
<a href="#title">返回標(biāo)題</a>
<!--下載鏈接,指向 doc, zip, zip等文件格式時(shí),a標(biāo)簽將成為自動(dòng)下載鏈接-->
<a href="./download/halou.zip">發(fā)郵件</a>
<!-- mailto:前綴的鏈接是郵件鏈接,系統(tǒng)將自動(dòng)打開email相關(guān)軟件-->
<a href="mailto:halouworld@126.com">發(fā)郵件</a>
<!-- tel: 前綴鏈接是電話鏈接,系統(tǒng)將自動(dòng)打開撥號(hào)鍵-->
<a href="tel:11111111111">打開撥號(hào)鍵盤</a>
audio標(biāo)簽用來插入音頻標(biāo)簽
<!--添加 controls 后才會(huì)顯示 播放控件-->
<!--常用音頻格式 mp3 和 ogg格式-->
<!--autoplay 自動(dòng)播放屬性-->
<!--loop 屬性表示循環(huán)播放-->
<audio controls src="./video/demo.mp3">
您的瀏覽器不支持 audio標(biāo)簽,請(qǐng)升級(jí)
</audio>
<audio controls src="./video/demo.mp3" autoplay loop>
您的瀏覽器不支持 audio標(biāo)簽,請(qǐng)升級(jí)
</audio>
video 標(biāo)簽用于插入一段視頻
<!--有的視頻不能播放 ,詳見 https://blog.csdn.net/weixin_34272308/article/details/94614657 -->
<!-- controls 顯示視頻播放控件 -->
<!-- autoplay 自動(dòng)播放 -->
<!-- loop 循環(huán)播放 -->
<!-- 常見的 視頻格式 mp4 ogv webm 等-->
<video controls autoplay loop src="./video/5-4 RDB2.mp4" >
您的瀏覽器不支持 video標(biāo)簽,請(qǐng)升級(jí)
</video>
以前的區(qū)塊標(biāo)簽只有div,現(xiàn)在為了更好的方便搜索引擎抓取網(wǎng)站,因此有了以下語義更加明確的區(qū)塊標(biāo)簽
<section> | 文檔的區(qū)域,比div語義上還要大一點(diǎn) |
<header> | 頁頭 |
<main> | 網(wǎng)頁核心部分 |
<footer> | 頁腳 |
表單用來收集信息并且可以完成和后端的數(shù)據(jù)傳輸
表單中大致可以分為三種標(biāo)簽
一些表單的示例
<!--action 表示要提交到后端的網(wǎng)址-->
<!--method 表示表單提交的方式,通常有 get 、 post 、put、delete等-->
<form action="/save" meththo="post"></form>
<!--<form> 標(biāo)簽中 input 文本框 type="text" 表示文本框-->
<!-- value 表示文本框中的值 -->
<!--planceholder表示提示文字,在沒任何輸入值的情況下,作為提示信息-->
<!--disabled 表示禁用-->
<input type="text" value="123" planceholder="提示文字" disabled>
<!---單選按鈕,name相等,表示選擇了一個(gè),另一個(gè)就不能選擇了-->
<!--checked 表示默認(rèn)被選中-->
<!-- value 屬性表示要提交到后端服務(wù)器的值-->
<input type="radio" name="radio_group" checked>
<input type="radio" name="radio_group">
<label>
<input type="radio" name="sex"> 男
</label>
<label>
<input type="radio" name="sex"> 女
</label>
<!--html4 中的標(biāo)簽 通過for 屬性 和 其他標(biāo)簽的id屬性進(jìn)行綁定-->
<input type="radio" name="sex" id="nan">
<label for="nan">男</label>
<input type="radio" name="sex" id="nv">
<label for="nv">女</label>
<!--復(fù)選框 type="checkbox" 同一組的的復(fù)選框,name值應(yīng)該相同 ,復(fù)選框也有value值, 用于向服務(wù)器提交數(shù)據(jù)-->
<input type="checkbox" name="hobby" value="soccer" > 足球
<input type="checkbox" name="hobby" value="basket" > 籃球
<!--密碼框-->
<input type="password" placeholder="請(qǐng)輸入密碼">
<!-- 下拉菜單 -->
<select>
<option value="alipay">支付寶</option>
<option value="wxpay">微信支付</option>
</select>
<!--多文本框 rows 和 clos 分別用于設(shè)置 行數(shù) 和 列數(shù)-->
<textarea rows="3" cols="5"></textarea>
<!--三種按鈕 submit 提交按鈕 button 普通按鈕 可以簡(jiǎn)寫為 <button></button> reset 按鈕 重置按鈕-->
<input type="button" value="普通按鈕">
<input type="reset" value="重置按鈕">
<input type="submit" value="提交表單">
<!--像 email 和 url 等格式,如果點(diǎn)擊提交按鈕,不符合格式,會(huì)有提示-->
<form>
日期空間: <input type="date"> <br/>
時(shí)間空間: <input type="time"> <br/>
日期時(shí)間空間 <input type="datetime-local"> <br/>
文件:<input type="file"> <br/> <br/>
數(shù)字控件: <input type="number"> <br/>
拖拽條: <input type="range"> <br/>
搜索框: <input type="search"> <br/>
網(wǎng)址控件: <input type="url"> <br/>
郵箱控件: <input type="email" >
<input type="submit" value="提交">
</form>
<!-- datalist 備選項(xiàng)示例 -->
<input type="text" list="province">
<datalist id="province">
<option value="陜西"></option>
<option value="山西"></option>
<option value="河北"></option>
<option value="山東"></option>
</datalist>
可以用html渲染表格
<!--表格示例-->
<table border="1">
<caption>我是標(biāo)題</caption>
<tr>
<th>第一列標(biāo)題</th>
<th>第二列標(biāo)題</th>
</tr>
<tr>
<td>第一行第一列</td>
<td>第一行第二列</td>
</tr>
<tr>
<td>第二行第一列</td>
<td>第二行第二列</td>
</tr>
</table>
<!--跨列示例-->
<table border="1">
<caption>我是標(biāo)題</caption>
<tr>
<th>第一列標(biāo)題</th>
<th>第二列標(biāo)題</th>
</tr>
<tr>
<td colspan="2">跨兩行</td>
</tr>
<tr>
<td>第二行第一列</td>
<td>第二行第二列</td>
</tr>
</table>
<!--跨行示例-->
<table border="1">
<caption>我是標(biāo)題</caption>
<tr>
<th>第一列標(biāo)題</th>
<th>第二列標(biāo)題</th>
</tr>
<tr>
<td rowspan="2">第一行第一列</td>
<td>第一行第二列</td>
</tr>
<tr>
<td>第二行第二列</td>
</tr>
<tr>
<td>第三行第一列</td>
<td>第三行第二列</td>
</tr>
</table>
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。