1.課程體系javascript
階段1(服務器開發): 項目導入/數據庫/JS基礎/NodeJScss
階段2(前端核心技術): HTML/AJAX/CSS/bootstraphtml
階段3(前端進階技術):JS高級/DOM&BOM/jquery/VueJS前端
階段4(H5移動開發):VueJS組件庫/HTML5技術/微信開發/HybirdAPPvue
階段5(框架技術):AngularJS/ReactJS/Pythonhtml5
2.Window操做系統中經常使用的快捷鍵java
Alt+Tab: 切換窗口(向右)node
Alt+Shift+Tab: 切換窗口(向左)python
Window+d 顯示/隱藏桌面mysql
Window+r 打開「運行」窗口 輸入cmd打開命令行窗口
Window+e 打開「資源管理器」
Alt+F4 關閉當前窗口
練習:不使用鼠標——進入C:/xampp/htdocs,建立demo.html,使用編輯器打開,輸入內容;保存使用瀏覽器打開該文件;最後刪除demo.html
3.軟件工程
無軟件階段 bug -> debug
軟件做坊 IBM ->Dos->Microsoft->Windows->Bill Gates
軟件工程
軟件過程(開發流程)
軟件測試
軟件度量
軟件質量保證
4.軟件的開發流程
軟件過程/軟件的生命週期
1)軟件定義期
(1)可行性研究階段
技術、人力、設備、時間、資金、回報、政策、風俗...
(2)需求分析階段
功能性需求、非功能性需求
2)軟件開發期
(1)概要設計階段——設計師
子系統、模塊、各自功能、模塊間的接口
(2)詳細設計階段——架構師
頁面、主題內容、對象、屬性、方法
(3)編碼實現階段
UI設計:效果圖
前端:把效果圖轉換爲html/css/js代碼
後端:爲前端提供頁面須要的數據
(4)測試階段——軟件測試工程師
3)軟件維護期
(1)項目部署階段
將項目部署到服務器
(2)項目維護階段
5.學子商城功能性需求
前臺:www.codeboy.com 後臺:www.codeboy.com/admin/login.html (1)前臺子系統: 商品模塊、用戶模塊、購物車模塊 (2)後臺子系統: 商品模塊、用戶模塊、訂單模塊 (3)移動端子系統: 商品模塊、用戶模塊、購物車模塊 |
6.web項目中的服務器
Server: 爲客戶端提供各類服務的功能強大的計算機。
訪問服務器:
(1)服務器地址: 域名/IP地址
(2)對應的服務的端口號
(3)提供該服務全部使用的協議
http://www.codeboy.com:80
協議 域名/IP地址 端口
7.訪問本身電腦上的web服務器
啓動web服務器 /webServer/start.cmd
http://127.0.0.1:80 經過本身電腦的IP地址
http://localhost:80 經過本身電腦服務器的域名
練習:在public下建立4.html,隨便輸入內容,分別使用域名和IP地址訪問該文件。
獲取本身電腦在局域網的IP地址
在命令行下輸入 ipconfig
http://172.163.100.134:80 經過局域網IP來訪問服務器
練習:同桌之間互相訪問對應的服務器
day01
關係型數據庫
Server->Database->Table->Row->Column
mysql
服務器端:開啓服務
客戶端:鏈接
鏈接
mysql.exe -h127.0.0.1 -P3306 -uroot -p
mysql -uroot
mysql -uroot < c:/....
交互模式
腳本模式
經常使用管理命令
show databases;
use 名字;
show tables;
desc 表名;
quit;
sql命令
增刪改查
drop database if exists ...
create database..
use ...
create table
insert into
select * from ...
update ... set ... where
delete from ... where
標準SQL語句分類
DDL: Data Define Language 定義數據結構 CREATE/DROP/ALTER DML: Data Manipulate Language 操做數據 INSERT/UPDATE/DELETE DQL: Data Query Language 查詢數據 SELECT DCL: Data Control Language 控制用戶權限 GRANT(受權)/REVOKE(收權) |
1.計算機存儲字符
(1)如何存儲英文字符
ASCII: 總共有128個,對全部的英文字母和符號進行編碼。
hel 104101108
Latin-1: 總共有256,兼容ASCII碼,同時對歐洲符號進行了編碼。MySQL默認使用這種編碼。
(2)如何存儲中文字符
GB2312: 對經常使用6千多漢字進行了編碼,兼容ASCII
GBK: 對2萬多漢字進行了編碼,兼容GB2312
BIG5: 臺灣繁體字編碼,兼容ASCII
Unicode: 對世界上主流國家經常使用的語言進行了編碼,兼容ASCII,不兼容GB2312,GBK,BIG5。具體分爲UTF-8,UTF-16,UTF-32存儲方案。
(3)解決mysql存儲中文亂碼
sql腳本文件另存爲的編碼
客戶端鏈接服務器的編碼(SET NAMES UTF8)
服務器端建立數據庫使用的編碼(CHARSET=UTF8)
練習:編寫腳本文件01_sina.sql,建立數據庫sina,設置存儲編碼爲UTF8,進入該數據庫,建立數據表news保存新聞數據,包含nid,title(標題),ctime(發表時間),content(內容),author(做者),cfrom(來源);插入若干條數據。在交互模式下查詢數據。
2.mysql中的列類型
建立數據表的時候,指定的列能夠存儲的數據類型
CREATE TABLE t1( nid 列類型 );
(1)數值型 引號可加可不加
TINYINT 微整型,佔1個字節 範圍-128~127
SMALLINT 小整型,佔2個字節,範圍-32768~32767
INT 整型,佔4個字節,範圍
-2147483648~2147483647
BIGINT 大整型,佔8個字節
FLOAT 單精度浮點型,佔4個字節,最多3.4E38,可能產生計算偏差。
DOUBLE 雙精度浮點型,佔8個字節,範圍比BIGINT大的多,也可能查收計算偏差。
DECIMAL(M,D) 定點小數,不會產生計算偏差;M表明總的有效位數,D表明小數點後的有效位數。
BOOL 布爾型,只有兩個值TRUE/1、FALSE/0,TRUE和FALSE不能加引號;真正存儲數據的時候,會變成TINYINT,數據是1和0
(2)日期時間型 必須加引號
DATE 日期型 '2018-10-31'
TIME 時間型 '14:30:50'
DATETIME 日期時間型 '2018-10-31 14:30:50'
(3)字符串型 必須加引號
VARCHAR(M) 變長字符串,不會產生空間浪費,操做速度相對慢,M最大值時65535。
CHAR(M) 定長字符串,可能產生空間浪費,操做速度相對快,M最大值是255;用於存儲手機號碼、身份證號碼等固定長度的字符串。
TEXT(M) 大型變長字符串,M最多2G
|
CHAR(5) |
VARCHAR(5) |
a |
a\0\0\0\0 |
a\0 |
ab |
ab\0\0\0 |
ab\0 |
abcde |
abcde |
abcde |
一二三 |
一二三\0\0 |
一二三\0 |
CREATE TABLE t1(
id INT,
age TINYINT,
commontCount INT,
price DECIMAL(6,2), #9999.99
phone CHAR(11),
article VARCHAR(5000),
sex BOOL, # 1->男 0->女
pubTime DATE
);
練習:編寫02_xuezi.sql文件,先丟棄再建立數據庫xuezi,設置存儲的編碼爲UTF8,進入該數據庫,建立保存筆記本數據的表laptop,包含lid,title(標題),price(價格),stockCount(庫存量),shelfTime(上架時間),isIndex(是否顯示在首頁);插入4條數據
練習:編寫腳本文件03_tedu.sql,建立數據庫tedu,設置存儲的編碼爲UTF8;進入該數據庫,建立保存部門數據的表dept,包含did,dname(部門名稱),empCount(員工數量);插入如下數據
10 研發部 3
20 運營部 2
30 市場部 2
建立保存員工數據的表emp,包含eid,ename(姓名),sex(性別),birthday(生日),salary(工資)
插入若干條數據。
3.列約束
mysql能夠對要插入的數據進行特定的驗證,只有知足條件才容許插入到數據表中,不然被認爲非法的插入。
例如:一我的的性別只能是男或者女,一我的的年齡0~100
(1)主鍵約束——PRIMARY KEY
聲明瞭主鍵約束的列上的值不能出現重複,一個表中只能有一個主鍵,一般加在編號列。設置了主鍵約束就不能使用NULL值。
表中查詢的記錄會按照主鍵由小到大的順序排序——加快查找速度。
NULL 表示空,在插入數據時,沒法肯定要保存的數據。例如:沒法肯定員工的工資,生日均可以使用NULL |
(2)非空約束——NOT NULL
聲明瞭非空約束的列上不能插入NULL值
課後任務
(1)複習今天內容,從新編寫代碼
(2)練習
編寫腳本文件xz.sql,建立數據庫xz,進入該數據庫;
建立保存筆記本家族的表laptop_family,包含fid,fname,laptopCount筆記本數量
10 聯想 2 20 戴爾 2 30 小米 3
建立保存筆記本數據的表laptop,包含lid,title,price,spec規格,detail商品介紹,shelfTime,isOnsale是否在售,familyId所屬家族編號;插入若干條數據。
(3)預習列約束
複習
ASCII/Latin-1/GB2312/GBK/BIG5/Unicode
腳本/客戶端鏈接/服務器端
列類型
數值型
TINYINT/SMALLINT/INT/BIGINT
FLOAT/DOUBLE/DECIMAL/BOOL
日期時間型
DATE/TIME/DATETIME
字符串型
VARCHAR/CHAR/TEXT
1.列約束
(1)主鍵約束——PRIMARY KEY
(2)非空約束——NOT NULL
(3)惟一約束——UNIQUE
聲明瞭惟一約束的列上不能插入重複的值,容許插入NULL,並且容許插入多個NULL
(4)檢查約束——CHECK
檢查約束能夠對插入的數據進行自定義驗證
CREATE TABLE student(
score TINYINT CHECK(score>=0 AND score<=100)
);
mysql不支持檢查約束,會下降數據的插入速度。
(5)默認值約束——DEFAULT
能夠使用DEFAULT關鍵字聲明默認值,有兩種方式能夠應用默認值
INSERT INTO family VALUES(50, '華碩', DEFAULT);
INSERT INTO family(fid,fname) VALUES(60,'榮耀');
練習:設置筆記本的默認價格爲6999,分別應用兩種默認值插入數據。
(6)外鍵約束——FOREIGN KEY
聲明瞭外鍵約束的列,取值必須在另外一個表的主鍵列上出現過,二者的列類型要保持一致,容許使用NULL或者多個NULL
FOREIGN KEY(列) REFERENCES 數據表(主鍵列)
2.mysql中的自增列
AUTO_INCREMENT: 自動增加,假如一個列聲明瞭自增列,無需手動賦值;直接賦值爲NULL,會獲取當前的最大值,而後加1插入。
注意:
只適用於整數型的主鍵列上
自增列容許手動賦值
練習:建立腳本文件01_tedu.sql,建立數據庫tedu;進入該數據庫
建立部門表dept,包含(did,dname)
10 研發部 20 市場部 30 運營部 40 測試部
建立員工表emp,包含(eid,ename,sex,birthday,salary,deptId 所屬部門編號)
插入15條記錄
3.簡單查詢
(1)查詢特定的列
示例:查詢全部員工的姓名、工資
SELECT ename,salary FROM emp;
練習:查詢全部員工的編號,姓名,性別,生日
SELECT eid,ename,sex,birthday FROM emp;
(2)查詢全部的列
SELECT * FROM emp;
SELECT eid,ename,sex,birthday,salary,deptId FROM emp;
(3)給列起別名
示例:查詢全部員工的姓名和工資,使用漢字別名
SELECT ename AS 姓名,salary AS 工資 FROM emp;
練習:查詢全部員工的編號,姓名,性別,生日,使用漢字別名
SELECT eid AS 編號,ename AS 姓名,sex 性別,birthday 生日 FROM emp;
練習:查詢全部員工編號和姓名,使用一個字母做爲別名
SELECT eid a,ename b FROM emp;
在起別名的時候,AS關鍵字能夠省略,保留空格。 |
(4)顯示不一樣的記錄/合併相同的記錄
示例:查詢出員工都在哪些部門
SELECT DISTINCT deptId FROM emp;
練習:查詢出都有哪些性別的員工
SELECT DISTINCT sex FROM emp;
(5)在查詢時執行計算
示例:計算2+3*5+7.4*3.5
SELECT 2+3*5+7.4*3.5 AS 結果;
練習:查詢全部員工的姓名及其年薪
SELECT ename,salary*12 FROM emp;
練習:假設每一個員工工資增長500,年終獎5000,查詢全部員工的姓名及其年薪,給列別起中文別名。
SELECT ename AS 姓名,(salary+500)*12+5000 AS 年薪 FROM emp;
(6)查詢結果集排序
示例:查詢全部的部門,結果集按照部門編號升序排列
SELECT * FROM dept ORDER BY did ASC;#ascendant
示例:查詢全部的部門,結果集按照部門編號降序排列
SELECT*FROM dept ORDER BY did DESC;#descendant
練習:查詢全部員工,結果集按照工資的降序排列
SELECT * FROM emp ORDER BY salary DESC;
練習:查詢全部員工,結果集按照年齡從小到大排列
SELECT * FROM emp ORDER BY birthday DESC;
練習:查詢全部員工,結果集按照姓名升序排列
SELECT * FROM emp ORDER BY ename;
練習:查詢全部員工,結果集按照工資降序排列,若是工資相同,按照姓名排序
SELECT * FROM emp ORDER BY salary DESC,ename;
練習:查詢全部員工,結果集按照性別升序排列,若是性別相同,按照生日降序排列。
SELECT * FROM emp ORDER BY sex,birthday DESC;
ORDER BY能夠按照數值、日期/時間、字符串來排序 默認按照ASC升序排列 |
(7)條件查詢
示例:查詢出編號爲5的員工全部列
SELECT * FROM emp WHERE eid=5;
練習:查詢出姓名叫King的員工的編號,工資,姓名
SELECT eid,salary,ename FROM emp WHERE ename='king';
練習:查詢出20號部門下員工全部的列
SELECT * FROM emp WHERE deptId=20;
練習:查詢出女員工全部的列
SELECT * FROM emp WHERE sex=0;
練習:查詢出工資爲5000以上的員工全部列
SELECT * FROM emp WHERE salary>=5000;
比較運算符:> < >= <= = !=(不等於) |
練習:查詢出1991-1-1後出生的員工全部列
SELECT * FROM emp WHERE birthday>'1991-1-1';
練習:查詢出不在10號部門的員工全部列
SELECT * FROM emp WHERE deptId!=10;
練習:查詢出沒有明確部門的員工全部列
SELECT * FROM emp WHERE deptId IS NULL;
練習:查詢出有明確部門的員工全部列
SELECT * FROM emp WHERE deptId IS NOT NULL;
練習:查詢出工資在6000以上男員工全部列
SELECT * FROM emp WHERE salary>6000 AND sex=1;
練習:查詢出工資在5000~7000之間員工全部列
SELECT * FROM emp WHERE salary>=5000 AND salary<=7000;
SELECT * FROM emp WHERE salary BETWEEN 5000 AND 7000;
練習:查詢出工資在5000如下和7000以上的員工全部列
SELECT * FROM emp WHERE salary<5000 OR salary>7000;
SELECT * FROM emp WHERE salary NOT BETWEEN 5000 AND 7000;
練習:查詢出1990年以前和1993以後出生的員工全部列
SELECT * FROM emp WHERE birthday<'1990-1-1' OR birthday >'1993-12-31';
SELECT * FROM emp WHERE birthday NOT BETWEEN '1990-1-1' AND '1993-12-31';
練習:查詢出1993年出生的員工全部列
SELECT * FROM emp WHERE birthday>='1993-1-1' AND birthday<='1993-12-31';
SELECT * FROM emp WHERE birthday BETWEEN '1993-1-1' AND '1993-12-31';
練習:查詢出20號部門和30號部門的員工全部列
SELECT * FROM emp WHERE deptId=20 OR deptId=30;
SELECT * FROM emp WHERE deptId IN(20,30);
練習:查詢出不在20號部門和30號部門員工全部列
SELECT * FROM emp WHERE deptId NOT IN(20,30);
IS NULL/IS NOT NULL AND/OR BETWEEN ... AND../NOT BETWEEN...AND... IN( )/NOT IN ( ) |
(8)模糊條件查詢
示例:查詢姓名中含有字母e的員工全部列
SELECT * FROM emp WHERE ename LIKE '%e%';
練習:查詢姓名中以e結尾的員工全部列
SELECT * FROM emp WHERE ename LIKE '%e';
練習:查詢姓名中倒數第2個字符爲e的員工全部列
SELECT * FROM emp WHERE ename LIKE '%e_';
% 能夠匹配任意多個字符 >=0 _ 能夠匹配任意1個字符 =1 以上兩個匹配必須使用LIKE關鍵字 |
(9)分頁查詢
假如查詢的結果集中有太多的數據,一次顯示不完,能夠分頁顯示。
須要有兩個條件:當前的頁碼、每頁的數據量
SELECT * FROM emp LIMIT start,count;
start: 是一個數字,表示從哪一條開始讀取;
start=(當前的頁碼-1)*每頁的數據量 |
count:是一個數字,表示每頁的數據量
注意:start和count的值必須是整數,不能是字符串形式。
假設每頁顯示5條記錄
第1頁:SELECT * FROM emp LIMIT 0,5;
第2頁:SELECT * FROM emp LIMIT 5,5;
第3頁:SELECT * FROM emp LIMIT 10,5;
第4頁:SELECT * FROM emp LIMIT 15,5;
第5頁:SELECT * FROM emp LIMIT 20,5;
課後任務:
(1)複習今天內容,刪除代碼保留註釋,從新編寫SQL語句
(2)查詢出工資在8000以上的女員工的姓名、性別、生日,結果集按照按照工資降序排列,取前3我的。
(3)查看學子商城資料,編寫數據庫(見文件)
查詢出工資在8000以上的女員工的姓名、性別、生日,結果集按照按照工資降序排列,取前3我的。
SELECT ename,sex,birthday,salary FROM emp
WHERE salary>8000 AND sex=0
ORDER BY salary DESC
LIMIT 0,3;
項目中的時間
2019-3-4 2019年3月4日 3/4/2019 2019/3 2019-3 9:53 9:53:30
距離計算機元年(1970-1-1 0:0:0)的毫秒數
1秒=1000毫秒
2019-1-1 --10:14
49*365*24*60*60*1000
性別 男/女 woman/man boy/girl
1/0
1.複雜查詢
(1)聚合查詢/分組查詢
示例:查詢全部員工的數量
SELECT COUNT(eid) FROM emp;
SELECT COUNT(*) FROM emp; #推薦寫法
練習:使用員工的姓名來查詢數量
SELECT COUNT(ename) FROM emp;
練習:使用員工的部門編號來查詢數量
SELECT COUNT(deptId) FROM emp;
練習:查詢全部女員工的數量
SELECT COUNT(*) FROM emp WHERE sex=0;
聚合函數 函數是一個功能體,提供若干數據,產出結果——餃子機 COUNT(..)/SUM(..)/AVG(..)/MAX(..)/MIN(..) |
練習:查詢全部員工的工資總和是多少
SELECT SUM(salary) FROM emp;
練習:查詢出男員工的平均工資是多少
SELECT SUM(salary)/COUNT(*) FROM emp WHERE sex=1;
SELECT AVG(salary) FROM emp WHERE sex=1;
練習:查詢出工資最高的員工
SELECT MAX(salary) FROM emp;
練習:查詢出工資最低的員工
SELECT MIN(salary) FROM emp;
練習:查詢年齡最大的員工的生日
SELECT MIN(birthday) FROM emp;
分組查詢:只能查詢分組條件和聚合函數 |
示例:查詢出每一個部門工資最高的員工的工資
SELECT deptId,MAX(salary) FROM emp GROUP BY deptId;
練習:查詢出男女員工的數量,最高工資,平均工資
SELECT sex,COUNT(*),MAX(salary),AVG(salary) FROM emp GROUP BY sex;
YEAR(..) 獲取日期中的年份 MONTH(..) 獲取日期中的月份 |
練習:查詢出1991年出生的員工全部列
SELECT * FROM emp WHERE YEAR(birthday)=1991;
練習:查詢3月份出生的員工全部列
SELECT * FROM emp WHERE MONTH(birthday)=3;
(2)子查詢
把一個SQL語句的查詢結果做爲另外一個SQL語句的查詢條件 |
示例:查詢出研發部全部的員工
步驟1:查詢出研發部的部門編號——10
SELECT did FROM dept WHERE dname='研發部';
步驟2:查詢出10號部門全部的員工
SELECT * FROM emp WHERE deptId=10;
綜合:
SELECT * FROM emp WHERE deptId=(SELECT did FROM dept WHERE dname='研發部');
練習:查詢出工資比tom高的員工有哪些
步驟1:查詢出tom的工資是多少——6000
SELECT salary FROM emp WHERE ename='tom';
步驟2:查詢出比6000高的員工
SELECT * FROM emp WHERE salary>6000;
綜合:
SELECT * FROM emp WHERE salary>( SELECT salary FROM emp WHERE ename='tom');
練習:查詢出和tom同一年出生的員工有哪些
步驟1:查詢出tom的出生年份——1990
SELECT YEAR(birthday) FROM emp WHERE ename='tom';
步驟2:查詢出1990年出生的員工有哪些
SELECT * FROM emp WHERE YEAR(birthday)=1990;
綜合:
SELECT * FROM emp WHERE YEAR(birthday)=(
SELECT YEAR(birthday) FROM emp WHERE ename='tom'
);
(3)多表查詢
示例:查詢出全部的員工姓名及其部門名稱
SELECT ename,dname FROM emp,dept;
錯誤:產生笛卡爾積
解決方法:添加查詢條件
SELECT ename,dname FROM emp,dept WHERE did=deptId;
上述多表查詢結果是SQL-92的查詢語法,沒法查詢出沒有部門的員工,沒有員工的部門 SQL-99中提出了新的多表查詢語法 |
(1)內鏈接——和SQL-92查詢結果一致
SELECT ename,dname FROM emp INNER JOIN dept ON deptId=did;
(2)左外鏈接——顯示左側表中全部的記錄
SELECT ename,dname FROM emp LEFT OUTER JOIN dept ON deptId=did;
OUTER 關鍵字能夠省略
(3)右外鏈接——顯示右側表中全部的記錄
SELECT ename,dname FROM emp RIGHT OUTER JOIN dept ON deptId=did;
OUTER 關鍵字能夠省略
(4)全鏈接
顯示左側和右側表中全部的記錄——FULL JOIN
mysql不支持全鏈接
UNION 合併相同的記錄
UNION ALL 不合並相同的記錄
(SELECT ename FROM emp_us)
UNION
(SELECT ename FROM emp_cn);
把左外鏈接的結果和右外鏈接的結果合併
(SELECT ename,dname FROM emp LEFT OUTER JOIN dept ON deptId=did)
UNION
(SELECT ename,dname FROM emp RIGHT OUTER JOIN dept ON deptId=did);
2.學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
程序員必作50題
https://wenku.baidu.com/view/af66e2f14afe04a1b071de42.html
3.JS概述
(1)歷史
1995年,JS最先出如今Netscape的瀏覽器中
1996年,IE3中也出現JS,稱爲JScript
1997年,ECMA組織,制定標準 ECMAScript
2009年,遵循CommonJS規範,開始向服務端發展
(2)現狀
既能夠運行在客戶端瀏覽器,也能夠運行在服務器端
(3)特色
跨平臺,支持全部的操做系統
解釋型語言,編譯一行執行一行
基於對象
弱類型類型
(4)應用場景
製做瀏覽器端的交互效果
建立web服務器,操做數據庫等
4.JS的開發環境
(1)瀏覽器端自帶的JS解釋器
(2)服務器端NodeJS解釋器
https://nodejs.org nodejs下載地址
node -v 查看當前安裝的nodejs版本
(3)執行JS代碼
瀏覽器
建立01.js和01.html兩個文件
在01.html中引入01.js文件
<script src="01.js"></script> |
NodeJS
node C:/xampp/..../01.js 回車
5.JS語法規範
(1)區分大小寫
(2)每行代碼結尾的分號可加可不加,建議都加
(3)分爲單行註釋(//...)和多行註釋(/*...*/)
6.變量
用於存儲數據的容器
x=1
(1)聲明變量
var x=1;
使用關鍵字var聲明瞭一個變量,名稱叫x,存儲的值是1
(2)變量的命名規則
變量名稱能夠使用字母、數字、下劃線、美圓符號,其中不能以數字開頭。
不能使用關鍵字和保留字做爲變量名稱,例如:var、if、break...
user_name userPwd isLogin cityName
(3)變量的注意
var z;
變量只是聲明未賦值,此時的值是undefined
能夠爲變量屢次賦值,而且賦不一樣類型的值
(4)一次性聲明多個變量
var a=1,b=2,c;
多個變量之間用逗號隔開
練習:聲明語文、數學、和總成績三個變量;總成績爲空,而後把語文和數學的和賦值給總成績;打印三個變量。
7.常量
一旦聲明不能再從新賦值
const PI=3.14;
8.數據類型
分爲原始類型和引用類型
原始類型分爲數值型、字符串型、布爾型、未定義型(undefined)、空(null)
(1)數值型
分爲整型和浮點型
整型在內存中佔4個字節,浮點型佔8個字節
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習:
使用變量保存圓的半徑,常量保存圓周率;聲明兩個變量保存面積和周長;最後打印面積和周長。
聲明多組變量保存商品的單價和數量,最後計算商品的總價。
(3)預習JS的數據類型
JS
瀏覽器端和服務器端
var $_a1=1,b=2;
const pi=3.14;
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.數據類型
原始類型和引用類型
(1)數值型
整型
8進制 0 1 ... 7 10, 以0開頭,例如 010->8
16進制 0 1 .... 9 a b c d e f 10
a~f 表明10~15,以0X開頭,例如0XC->12
字母不區分大小寫
0XFF -> 255
浮點型
分爲普通小數和指數型小數
3.14 3.14e3->3140 3.14e-2 ->0.0314
(2)字符串型
任意的數據被引號包含就是字符串型,不區分單雙引號
typeof 數據 檢測數據類型
查看任意一個字符的Unicode碼
'a'.charCodeAt() //97
練習:查看本身名字的Unicode碼
(3)布爾型
在程序中表示真或者假
true/false
經常使用於存儲一些是否的結果,例如是否註冊,是否登陸,是否爲會員
isLogin=true isVip=false
(4)未定義型
聲明瞭變量未賦值,結果就是undefined
(5)空
只有一個值null,用於引用類型數據中
2.數據類型轉換
(1)隱式轉換
數字+字符串 數字被轉成了字符串類型
2+'3' // '23'
數字+布爾值 布爾值被轉成了數字 true->1 false->0
2+true //3
2+false //2
字符串+布爾值 布爾值被轉成字符串
'b'+true //'btrue'
JS中加號(+)的做用
執行加法運算
執行字符串拼接
練習:查看一下程序的執行結果
var a=2,b=true,c='tedu'; console.log(a+b+c); //'3tedu' console.log(b+c+a);//'truetedu2' console.log(c+a+b);//'tedu2true' |
使用 - * / 執行運算
將運算符兩端的非數字轉爲數字,最終運算結果仍是數字;轉數字的過程當中自動調用Number
(2)強制轉換
①將任意類型轉爲數值型
Number(數據)
若是要轉的字符串中含有非數字,則返回NaN(Not a Number)
undefined -> NaN
null -> 0
②將任意數據轉爲整型
parseInt(數據)
parseInt('2.3c') //2
若是字符串以非數字開頭,則返回NaN,布爾型,undefined,null返回NaN
③將任意數據轉爲浮點型
parseFloat(數據)
parseFloat('2.3c') //2.3
和parseInt用法幾乎一致,只是返回時浮點型。
④將數值型轉爲字符串類型
toString()
var num=12;
num.toString() //'12'
num.toString(16) // c
轉換爲字符串的同時,能夠設置要轉換的進制
3.運算符
由運算符鏈接的操做數據,所組成的形式稱爲表達式
(1)算術運算符
+ - * / % ++ --
% 取餘
++ 自增,在原來的基礎之上加1
-- 自減,在原來的基礎之上減1
console.log(num++); 先打印num的值,再執行自增
console.log(++num); 先執行自增,而後打印num的值
練習:
var a=2; console.log(a++ + ++a); //6 var b=7; console.log(--b + b--); //12 |
(2)比較運算符
> < >= <= == != ===(全等於) !==(全不等於)
返回一個布爾型的值
== 只是比較值是否相同
=== 不只比較值,還會比較類型是否相同
3>'10' //false
數字和字符串比較,字符串會轉成數字
'3'>'10' //true
兩個字符串比較,比較首字符的Unicode碼
'3' ->51 '1'->49
3>'10a' //false
'10a'隱式轉爲了NaN,NaN和任何值比較(> < == === >= <=)都返回false
NaN==NaN false
(3)邏輯運算符
|| 或者 && 而且 ! 非
返回一個布爾型的結果
|| 關聯的兩個條件只須要知足其一,結果就是true,不然false
&& 關聯的兩個條件都知足,結果是true,不然false
! 取反 !true ->false !false->true
練習:聲明兩個變量保存用戶名和密碼,若是用戶名是'root',而且密碼是'123456',打印true,不然打印false
練習:聲明一個變量保存年齡,若是年齡大於90歲,或者小於3歲,打印true,不然打印false
邏輯短路
&& 當第1個條件爲false的時候,就不須要再執行第2個條件
|| 當第1個條件爲true的時候,就不須要再執行第2個條件
練習:如下程序運行是否報錯
var num=3; num>5 && console.log(a); num<1 || console.log(a); |
(4)位運算符
在執行位運算符的時候,會把數字轉成二進制進行運算。
1 10 11 100 101 110 111 1000 1001 1010
2 4 8
85=64+16+4+1
1000000+10000+100+1
1010101
按位與(&) 上下兩位都是1,結果是1,不然是0
按位或(|) 上下兩位含有1,結果是1,不然是0
按位異或(^) 上下兩位不一樣爲1,相同爲0
按位右移(>>) 刪除二進制的最後的位數
按位左移(<<) 在二進制的最後補0
(5)賦值運算符
= += -= *= /= %=
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
聲明一個變量保存年份,判斷這個年份是否爲閏年,若是是打印‘閏年’——邏輯短路
閏年:4年一閏(能被4整除),還有兩個
(3)預習if、if-else、switch-case語句
複習
數值、字符串、布爾型、未定義、空
數據類型轉換
隱式轉換 + - * / 3>'2' 3>null
強制轉換 Number/parseInt/parseFloat/toString(8)
運算符
算術運算符 + - * / % ++ --
比較運算符 > < >= <= == != === !==
邏輯運算符 || && ! 邏輯短路
位運算符 & | ^ >> <<
賦值運算符 = += -= *= /= %=
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.三目運算符
由三組操做數據或表達式組成的形式
條件表達式 ? 表達式1 : 表達式2
若是條件表達式爲true,執行表達式1;
若是條件表達式爲false,執行表達式2
練習:聲明變量保存用戶名和密碼,若是用戶名是root,而且密碼是123456,打印登陸成功,不然打印登陸失敗
2.瀏覽器端函數
alert() 彈出警示框
prompt() 彈出提示框(輸入框),須要使用變量保存輸入的值;值的類型是字符串型
練習:兩次彈出提示框,使用變量保存後,計算兩個數字相加的和,並將和使用警示框彈出。
3.流程控制
程序分爲順序執行、選擇執行、循環執行
程序 = 數據 + 算法
(1)if語句
滿30減15
if(條件表達式){ 語句1; } 語句2; |
若是if後的大括號中只有一行語句,能夠省略大括號。
false的幾種狀況,一般會和取反(!)一塊兒使用。
0 '' undefined null NaN
(2)if-else語句
if(條件表達式){ 語句1; }else{ 語句2; } |
練習:使用彈出提示框分別輸入商品的單價和數量,若是商品的總價滿500,則打八折;假如當前卡內的餘額爲600,若是足夠支付總價,打印pay success,不然打印pay error。
06_exercise.html 06_exercise.js
(3)if-else嵌套
if(條件表達式1){ 語句1; }else if(條件表達式2){ 語句2; }else...if(條件表達式n){ 語句n; }else{ 語句n+1; //以上全部的條件表達式都是false } |
(4)switch-case語句
switch(表達式){ case 值1: //若是表達式的值爲值1 語句1; break; case 值2: 語句2; break; ... case 值n: 語句n; break; default: 語句n+1;//以上全部的結果都是false } |
注意:在case中表達式和值在比較的時候使用的是全等於(===),要求值和類型都知足結果纔是true
對比if-else嵌套和switch-case語句
相同點:二者均可以用於多項分支語句
不一樣點:if-else能夠判斷相等或者不等的狀況,使用範圍更廣;switch-case只能用於全等於(===)的狀況,結構上更爲清晰合理,執行效率更高。
4.循環執行
循環:就是一遍又一遍執行相同或者類似的代碼
循環的兩個要素:
循環的條件:控制循環的次數
循環體:重複執行的相同或者類似代碼
(1)while循環
while(循環條件){ //結果是布爾型的值 循環體 } |
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習:
使用switch-case來根據成績判斷標準
使用while循環打印 11~20之間全部整數
使用while循環打印1~100之間全部奇數
使用while循環打印20 22 24 26 28 30
(3)預習do-while循環,for循環,循環嵌套
複習
瀏覽器端函數 alert()/prompt()
流程控制
順序執行、選擇執行、循環執行
if(條件表達式){ 語句1; }
if(條件表達式){ 語句1; }else{ 語句2; }
條件表達式 ? 語句1 : 語句2;
if(條件表達式1){ 語句1; }else if(條件2){ }...else{ }
switch(表達式){
case 1:
語句1;
break;
default:
語句..
}
循環: 循環條件 循環體
1.break關鍵字
能夠結束任何形式的循環
練習:使用變量保存一個數字,無限循環彈出提示框,獲取輸入的值,用輸入的值和保存的數字比較,若是猜大了,彈出警示框'big',若是猜小了,彈出警示框'small',不然彈出警示框 'right'。
03_break.js 03_break.html
2.do-while循環
do{ 循環體; }while(循環條件); |
練習:打印50~1之間全部的整數
練習:打印1~100之間全部的偶數
練習:打印50~30之間全部能被5整除的數字
練習:計算1~100之間全部能被3整除的數字的和
練習:計算10的階乘 !10 10*9....1
練習:聲明一個變量保存密碼'123456',無限循環彈出提示框,在提示框中輸入密碼,若是輸入正確,結束循環。
05_dowhile.js 05_dowhile.html
3.for循環
for(表達式1;表達式2;表達式3){ 循環體 } 表達式1:初始值 表達式2:循環的條件 表達式3:循環的增量 |
練習:計算1~100全部能被7整除的數組的和
練習:打印72~39之間全部的奇數
練習:計算1~20之間全部能被3整除的數的乘積
練習:打印本世紀(2000~2100)全部的閏年
練習:假設本金10000,年利率是4%,5年後本金和利息一共有多少
4.break和continue
break:結束循環,不會再執行循環體以及增量等。
continue,跳過本次循環體,還會繼續執行增量以及循環條件
練習:計算1~100之間全部偶數的和(遇到奇數跳過)
練習:打印1~100之間全部的數組,若是能被3或者4整除跳過。1 2 5 7 10 11 13...
練習:打印本世紀前10個閏年
5.循環嵌套
*
**
***
****
*****
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*9....
課後任務:
(1)複習今天內容,整理思惟導圖
(2)練習
打印倒着的九九乘法表
9*9=81 8*9=72
8*8=64
1*1
計算1~100之間的和,當和大於4000的時候,提早結束循環,打印當前的和是多少
(3)預習js中的自定義函數
複習
while(循環條件){ 循環體 }
do{ 循環體 }while(循環條件);
for(初始值;循環條件;循環增量){ 循環體 }
循環嵌套
任意循環之間均可以相互嵌套
break/continue
var i=0,sum=0; do{ i++; if(i%2==0){ continue; } if(i%5==0){ break; } sum+=i; }while(i<=10); |
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.函數
parseInt()/parseFloat()...
分爲系統函數和自定義函數
函數:function,是一個功能體,能夠接收若干個數據,返回特定的結果。用於封裝反覆執行的代碼——餃子機
(1)建立普通函數
function 函數名稱(){ 函數體——封裝的反覆執行的代碼 } |
調用:函數名稱()
練習:建立函數,封裝10+20的計算結果並打印出來,調用3次。
練習:建立函數,封裝計算1~100之間全部整數的和並打印結果,調用3次
(2)建立帶有參數的函數
function 函數名稱(參數列表){ //形參 -> 用於接收數據 函數體 } |
調用: 函數名稱(參數列表) //實參 ->實際要傳遞的數據
參數列表:建立函數時的參數稱爲形參,調用函數時的參數稱爲實參,在調用的時候實參會賦值給形參;多個參數之間用逗號隔開;若是實參的個數小於形參的個數,則未賦值的形參爲undefined。
練習:建立函數getSum,傳遞1個參數,計算1~任意數字之間全部整數的和,調用3次。
練習:建立函數getRun,傳遞2個參數,計算任意兩個年份之間的閏年個數,調用3次。
(3)建立帶有返回值的函數
function 函數名稱(參數列表){ 函數體 return 返回值; //函數的返回結果 } |
調用:函數名稱(參數列表)
函數調用後會獲得return的值。
注意事項:
若是沒有return或者return後沒有返回值,則返回undefined
return後的全部代碼不會被執行
練習:建立函數getMax,傳遞2個參數,返回兩個數字中的最大值。
練習:建立函數getMax,傳遞3個參數,返回三個數字中的最大值。
練習:建立函數getStatus,傳遞1個參數,根據狀態碼返回對應的中文
1-等待付款 2-等待發貨 3-運輸中 4-已簽收 5-已取消
練習:建立函數getDays,傳遞1個參數(年份),返回任意年份的天數365/366。
2.變量的做用域
做用域:變量或者函數可訪問範圍。
全局做用域:在全局做用域下聲明的變量,能夠在任意合法位置訪問到。
函數做用域:在函數中使用var聲明的變量,只能在函數內部訪問到。
變量的提高
JS程序執行前,當前做用域下使用var聲明的變量,會將聲明提高到最前,可是賦值仍是在原來的位置
3.函數的做用域
和變量做用域同樣,也分爲全局做用域和函數做用域
函數聲明提高
和變量提高同樣,使用function關鍵字建立的函數,聲明也會提高到所在做用域最前邊。在任意合法均可以調用。
4.遞歸(掌握)
在函數的內部調用自身
遞歸的使用:
要有跳出的條件,結合着return來跳出。
練習:使用遞歸來計算1~任意數字之間全部整數的和。
練習:使用遞歸來計算任意數字的階乘。
!10 = 10*9*8...*1
斐波那契數列
1 1 2 3 5 8 13 21 34 55 89....
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
使用遞歸和普通函數來計算斐波那契數列
(3)預習js中的自定義對象
複習
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.匿名函數
沒有名稱的函數 function(){ }
建立函數——函數聲明 function 函數名稱(){ } |
(1)建立函數——函數表達式
var 函數名稱=function(形參列表){ 函數體 return 返回值; } 調用 函數名稱() |
對比函數聲明和函數表達式的區別
函數聲明存在函數提高,能夠在任意位置建立,也能夠在任意合法位置調用。
函數表達式不存在函數提高,只能先建立再調用。
(2)匿名函數自調用
建立一個獨立的函數做用域,防止污染全局。
(function(形參列表){ 函數體; //封裝的代碼 })(實參列表); |
(3)回調函數
將匿名函數以參數傳遞
function fn(a){ //調用的時候,實參賦給形參a //a就是函數名稱,若是執行匿名函數體,只須要調用a a(); } fn(function(){ .... }); |
2.全局函數
parseInt 將數據轉爲整型
parseFloat 將數據轉爲浮點型
isNaN 判斷一個值是否爲NaN,是->true 不是->false
isFinite 判斷一個值是否爲有限值, 是->true,不是->false
3/0 -> Infinity 無限值
eval 執行字符串中的表達式 eval('1+1') -> 2
練習:使用彈出提示框輸入一組JS表達式,使用eval來執行這組表達式,並打印出來。
06_eval.js 06_eval.html
encodeURI 對URI進行編碼
decodeURI 對已編碼的URI進行解碼
3.對象
對象就是一組屬性和方法(功能)的集合。
一個員工:編號,姓名,性別,生日,工資,部門
哪些是對象?
某我的的手機: 屬性有品牌、顏色、內存、CPU,功能有看視頻,聽音樂,玩遊戲...
某一個飯盒: 屬性有大小、顏色、品牌,方法盛飯、摔...
——萬物皆對象
(1)JS中的對象
內置對象:JS提供的
宿主對象:根據JS不一樣的執行環境來劃分
自定義對象:本身建立的對象
(2)自定義對象
對象字面(直接)量
內置構造函數
自定義構造函數
(3)對象字面量
使用大括號{} 建立空對象
屬性名和屬性值之間用冒號隔開
多組屬性之間用逗號隔開
屬性名引號可加可不加,若是含有特殊字符,必須加
練習:建立一個商品對象,包含的屬性有編號、標題、價格、上架時間、是否在售。
(4)訪問對象的屬性
對象.屬性名
對象['屬性名'] 若是屬性名不加引號,會認爲是變量
練習:建立手機對象,屬性有編號,品牌,尺寸,顏色;修改尺寸和顏色,添加內存屬性。
(5)內置構造函數建立對象
new Object() //建立一個空對象
須要單獨添加每個屬性
練習:建立一個汽車對象,含有屬性型號、品牌、顏色、長度。
(6)檢測是否含有屬性
對象.屬性名 === undefined
true -> 不存在 false->存在
'屬性名' in 對象
true -> 存在 false -> 不存在
對象.hasOwnProperty('屬性名')
true -> 存在 false -> 不存在
(7)遍歷屬性
訪問對象中的每個屬性
for(var key in 對象){ key 對象中每一個屬性名 對象[key] 每一個屬性名對應的屬性值 } |
練習:建立對象,包含5組屬性,每一組屬性是一個價格,使用遍歷屬性,來獲取價格的總和。
(8)對象中的方法
var person={ name:'jerry', say:function(){ //say就是成員方法 this.name // this指代當前的對象 } } person.say();//調用成員方法 |
練習:建立手機對象,屬性有品牌,顏色,尺寸;方法打電話,發短信,看視頻...
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
建立一個圓對象,屬性有半徑、圓周率;方法有計算圓的面積和周長。
建立一個長方形對象
(3)課後預習數組
複習
匿名函數 function(){ }
建立函數 var fn=function(a){ return a; }
自調用 (function(){ var n=1; })();
回調函數
function add(num1){ num1() }
add(function(){ .... })
對象
屬性和方法的集合
內置、宿主、自定義
var person={};
var animal=new Object();
person['name'] person.age
for(var key in 對象){ 對象[key] }
檢測屬性是否存在
對象.屬性名 === undefined
'屬性名' in 對象
對象.hasOwnProperty('屬性名')
方法
{ say:function(){ this.name } }
person.say();
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
數組
數組是由多個元素組成的集合,每一個元素就是一個數據。
1.建立數組
(1)數組字面量
[ 元素1,元素2,元素3... ]
練習:建立數組,保存若干個成績
練習:建立數組,保存若干個大學名稱
(2)訪問數組中的元素
數組[下標]
下標是從0開始,第一個元素下標0,最後一個元素下標是長度減1
練習:建立數組,保存若干個國家名稱,單獨添加2個,修改其中的元素,打印結果。
(3)使用內置構造函數
new Array(元素1,元素2,元素3...)
new Array(3) 初始化元素個數爲3,後期能夠添加更多元素
練習:建立數組,保存若干個編程語言的名稱
練習:建立數組,初始化長度爲5,保存籃球場上五個位置。
2.獲取數組長度
數組.length 能夠獲取到數組中元素個數
在數組的末尾添加元素
數組[ 數組.length ] = 值
3.數組的分類
數組分爲索引數組和關聯數組
索引數組:以數字做爲下標
關聯數組:以字符串做爲下標,只能先建立數組,而後單獨添加元素。
練習:建立數組,添加員工的編號、姓名、性別、工資、生日,下標使用字符串。
4.遍歷數組
(1)for-in
for(var key in 數組){ key 要遍歷的數組元素的下標(數字也能夠是字符串) 數組[key] 獲取下標對應的元素 } |
練習:建立數組,包含多個分數,使用for-in遍歷該數組,獲取總成績。
(2)循環
for(var i=0;i<數組.length;i++){ i表明下標 數組[i] 表明下標對應的元素 } |
循環只能遍歷索引數組,沒法遍歷關聯數組。
練習:建立函數,傳遞一個參數(數組),返回平均工資。
練習:建立數組,包含多個汽車品牌,把數組中品牌名稱爲'寶馬'的元素修改成'BMW'
練習:建立函數getCount,傳遞兩個參數(數組、要查找的值),返回任意一個值在數組中出現的次數。
練習:建立函數getIndex,傳遞兩個參數(數組、要查找的值),返回任意一個值在數組中出現位置的下標,若是找不到返回-1.
練習:建立函數getMax,傳遞一個參數(數組),返回最大值。
5.數組中的方法(API)
API 應用程序編程接口、預約義好的一些方法和函數
toString() 將數組中的元素按照逗號分隔轉化成字符串
join('-') 將數組中的元素按照指定的字符分隔轉換爲字符串,默認是逗號。
concat(arr1,arr2...) 拼接多個數組
slice(start, end) 截取數組中的元素,start開始的下標,end結束的下標,不包含end自己;若是是負數表示倒數。
練習:建立數組,包含a~g,每一個字母是一個元素;截取b~c,e~g;拼接成一個新數組。
splice(start,count,value1,value2..) 刪除數組中的元素,start開始的下標,count刪除的長度,value表示刪除後補充的元素。
練習:建立數組,包含a~h,每一個字母是一個元素;刪除d、e,將f替換m,在下標爲2的位置插入元素z。
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
使用數組遍歷翻轉數組中的元素
a~h h~a
使用冒泡排序將一組數字進行從小到大的排序
數組遍歷
(3)預習字符串對象及相關API
複習
數組
建立數組
數組字面量 [元素1,元素2...]
內置構造函數 new Array(元素1,元素2...)
數組訪問 數組[下標]
數組的長度 數組.length 數組[數組長度]
數組分類 索引數組 關聯數組
遍歷數組 for(var key in 數組){ 數組[key] }
for(var i=0;i<數組.length;i++){ 數組[i] }
數組API toString/join/concat/slice/splice
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.數組API
reverse() 翻轉數組中的元素
sort() 對數組中的元素排序,默認是按照Unicode碼從小到大
對數字排序 sort(function(a,b){ return a-b;//從小到大 //return b-a; //從大到小 }) |
push() 在數組的末尾添加元素,返回添加後的長度,原數組會發生變化
pop() 刪除數組末尾的一個元素,返回刪除後的元素,原數組會發生變化
unshift() 在數組的開頭添加元素
shift() 在數組的開頭刪除一個元素
2.二維數組
數組中的每一個元素也是數組
var arr=[ [], [], []... ] |
訪問二維數組中的元素 arr[下標][下標]
3.字符串操做
包裝對象: 目的是讓原始類型數據能夠向引用類型數據,具備一組屬性和方法。
JS中提供了三種包裝對象: String、Number、Boolean
將任意類型轉爲字符串
new String(數據) 強制轉爲字符串,返回對象
String(數據) 強制轉爲字符串,返回字符串
注意事項: 包裝對象和普通的字符串用法沒有區別。
(1)轉義字符 —— \
轉換字符自己的意義
\n 將普通字符n轉義成換行符
\' 將有特殊意義的引號轉換成普通字符
\t 將普通字符t轉義成製表符(tab鍵效果)
...
練習:打印出現 welcome to chi\na
(2)字符串API
toUpperCase() 將英文字母轉爲大寫
toLowerCase() 將英文字母轉爲小寫
練習:初始化4個英文字母(有大小寫)保存到變量中,循環彈出提示框,輸入4個字符(不區分大小寫),若是輸入正確結束循環。 06_exercise.html 06_exercise.js
length 獲取字符串的長度
charAt() 獲取下標對應的字符 字符串[下標]
charCodeAt() 獲取某個字符的Unicode碼
練習:遍歷字符串'javascript',獲取a字符出現的次數。
indexOf(value,start) 查看某個字符的下標,value要查找的字符串,start開始查找的下標,找不到返回-1
lastIndexOf(value) 查看某個字符最後一次出現的下標
練習:聲明變量保存郵箱,檢測是否爲郵箱格式,若是是打印true,不然打印false。判斷字符串中是否含有@
slice(start, end) 截取字符串,start開始的下標,end結束的下標,不包含end自己;若是end爲空截取到最後。
substr(start, count) 截取字符串,start開始的下標,count截取的長度,若是count爲空截取到最後。
練習:使用變量保存身份證號,截取其中的出生年,月,日,性別。 打印 1997年10月26日 性別男
練習:使用變量保存郵箱,分別截取郵箱的用戶名和域名
練習:將一個英文單詞的首字母轉大寫,其它轉小寫
welCome -> Welcome
split() 按照指定的字符將字符串分隔爲數組
練習:使用split獲取郵箱中的用戶名和域名(jerry@126.com)
4.匹配模式
做用:用於查找、替換字符串
tom tum toom tem 正則表達式
replace(value1,value2) 查找並替換,value1是要查找的字符串,value2是要替換的字符串;value1能夠使用正則表達式的寫法 /china/ig
i -> ignore 忽略大小寫
g->global 全局查找
match(value) 用於查找匹配的字符串,返回數組
search(value) 用於查找匹配的字符串,返回知足條件的第一個的下標,若是找不到返回-1;能夠使用i,不能使用g
5.Math對象
Math對象不須要使用new建立,能夠直接使用
PI 獲取圓周率
abs() 獲取絕對值
floor() 向下取整
ceil() 向上取整
round() 四捨五入取整
max() 獲取一組數字的最大值
min() 獲取一組數字的最小值
pow(x,y) 獲取x的y次冪
random() 獲取隨機數 >=0 <1
複習
push/pop/unshift/shift/reverse/sort
字符串
包裝對象
String Number Boolean
new String()/String()
var a='hello'
var person={}
var arr=[];
轉義字符 \
toUpperCase()/toLowerCase()/charAt()/
indexOf()/lastIndexOf()/slice()/substr()/split()/join()
匹配模式
replace()/match()/search()
Math對象
PI/abs()/floor()/ceil()/round()/max()/min()/
pow()/random()
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1~33 隨機取6個數,不能重複 紅球
1~16 隨機取1個數,和前邊的不要緊 籃球
1.Date對象
用於對日期時間進行存儲和計算
new Date('2019/3/14 9:47:30')
new Date(2019,2,14,9,47,30); //第二個參數月份範圍0~11
new Date() 存儲當前的系統時間
new Date(1000*60*60*24) 存儲的是距離計算機元年的毫秒數所對應的日期時間
(2)獲取Date對象中日期時間
getFullYear/getMonth(範圍0~11)/getDate/getHours
getMinutes/getSeconds/getMilliseconds/
getDay(星期 0~6)/getTime(距離計算機元年毫秒數)
練習:建立對象保存'2019-10-1 10:30:50',打印
2019年10月01日 10點30分50秒 星期二
(3)轉爲本地字符串格式
toLocaleString() // 年-月-日 時:分:秒
toLocaleDateString() //年-月-日
toLocaleTimeString() //時:分:秒
(4)設置日期時間
setFullYear/setMonth/setDate/setHours/setMinutes
setSeconds/setMilliseconds/setTime
setTime設置後,可能會影響到其它的日期時間
(5)複製Date對象
把已經建立的Date對象以參數形式傳遞給構造函數
var d1=new Date();
var d2=new Date(d1); //複製d1對象
練習:建立Date對象,保存員工的入職時間'2019-3-15';3年後合同到期,計算到期時間;合同到期前一個月續簽合同,假如是週末,提早到週五,計算續簽時間;提早一週通知人準備續簽,計算提醒時間;
2.Number對象
new Number(值) 將數據轉爲數值型,返回對象
Number(值) 將數據轉爲數值,返回數值
toFixed(n) 保留小數點後n位
toString(n) 將數值轉爲字符串,n表示進制,默認是10
3.Boolean對象
new Boolean(值) 將數據轉爲布爾型,返回對象
Boolean(值) 將數據轉爲布爾型,返回布爾型
!!值 隱式將數據轉爲布爾型
toString() 將布爾型數據轉爲字符串
4.錯誤處理
SyntaxError: 語法錯誤,錯誤的使用中文,缺乏括號等;出現後全部的代碼都不執行。
ReferenceError: 引用錯誤,使用了未聲明的變量,屬於運行時的錯誤,影響後邊代碼的執行。
TypeError: 類型錯誤,錯誤的使用了數據,例如變量當作函數來用;屬於運行時的錯誤,影響後邊代碼的執行。
RangeError: 範圍錯誤,參數的使用超出了範圍;屬於運行時的錯誤,影響後邊代碼的執行
try{ 嘗試執行的代碼,可能出現錯誤 }catch(err){ err: 捕獲到錯誤 具體處理錯誤的內容 } |
練習:初始化一個變量add,嘗試調用add函數,傳遞兩個數字參數;若是執行錯誤,給add賦值一個匿名函數,而後再調用add。
5.ES6新特性
ECMAScript 6
ECMAScript 2015 2016 2017
《ES6入門》
http://es6.ruanyifeng.com/
(1)塊級做用域
使用let關鍵字聲明變量,只能在塊級做用域下使用,不能被外部訪問,不存在變量提高。
塊級做用域:{ } for、while、do-while、if...
(2)箭頭函數 =>
是回調函數的另外一種寫法,和匿名函數不徹底同樣。
sort( (a,b)=>{ return a-b; } ) |
若是箭頭函數的函數體中只有一行代碼,而且是return形式的,能夠簡化爲 sort( (a,b)=>a-b )
練習:建立函數add,傳遞兩個參數,每一個參數都是回調函數,在回調函數中返回一個數字;在函數add中計算兩個數字相加的和。
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
計算2019-5-1 9:30:00 距離 2019-12-25日相差的天,小時,分鐘,秒鐘。
(3)複習服務器,預習nodejs中的模塊概念
day01
學習一門編程語言的基本步驟
(1)瞭解背景知識:歷史、現狀、特色、應用場景。
(2)搭建開發環境,編寫hello world
(3)常量和變量
(4)數據類型
(5)運算符
(6)邏輯結構
(7)通用小程序
(8)函數和對象
(9)第三方框架、庫
(10)實用的項目
1.ES6
(1)函數參數的默認值
ES6容許爲形參設置默認值,若是沒有傳遞實參,自動使用形參的默認值。
練習:建立函數getSex,傳遞一個參數(0或者1),根據值打印對應的性別;若是參數爲空,默認爲0.
(2)模板字符串
` 在此之間就是模板字符串 ${JS表達式} ` |
練習:建立一個圖書的對象,包含編號,標題,價格,做者,是否在售(1/0);使用模板字符串打印這些內容
2.nodejs概述
(1)對比JS和nodejs
JS運行在瀏覽器端,有不少瀏覽器,代碼存在兼容性;nodejs在服務器端只有一個環境,代碼不存在兼容性。
二者都有內置對象、宿主對象、自定義對象;JS中宿主對象BOM&DOM,nodejs有大量的擴展對象。
JS用於瀏覽器端的交互效果,nodejs用於服務器端的操做,例如數據庫的操做,文件的操做...
(2)nodejs運行模式
腳本模式
node c:/xampp/.../01.js 回車
交互模式
node 回車 進入交互模式
退出: ctrl+c兩次 .exit 回車
3.全局對象
nodejs: global
在交互模式下,聲明的變量和建立的函數都屬因而全局對象下的,能夠使用global來訪問;
例如:var a=1; 能夠global.a訪問
腳本模式下,文件中的變量和函數都不是全局對象下的,不能使用global來訪問
JS: window
在瀏覽器下,文件中的變量和函數都是全局對象的,能夠使用window來訪問; 例如 var a=1; window.a
(1)console對象
global.console.log() 打印日誌
global.console.info() 打印消息
global.console.warn() 打印警告
global.console.error() 打印錯誤
global.console.time('字符串') 開始計時
global.console.timeEnd('字符串') 結束計時
開始和結束的字符串要保持一致
練習:使用計時查看計算for、while、do-while循環100000次的耗時。
(2)process對象
process.arch 查看當前CPU架構
process.platform 查看當前的操做系統
process.env 查看當前計算機的環境變量
process.version 查看當前nodejs的版本號
process.pid 查看當前的進程編號
process.kill() 經過進程編號殺死某一個進程
(3)Buffer對象
緩衝區:在內存中存儲數據的區域
建立buffer
var buf=Buffer.alloc(5, 'abcde')
將buffer數據轉爲字符串
buf.toString()
(4)全局函數
parseInt/parseFloat/isNaN/isFinite/encodeURI/
decodeURI/eval
一次性定時器
var timer=setTimeout( 回調函數, 間隔的時間 ) 當間隔的時間到了,會執行回調函數;單位是毫秒 clearTimeout(timer) 清除一次性定時器 |
週期性定時器
var timer=setInterval( 回調函數, 間隔的時間 ) 每隔一段時間,執行一次回調函數 clearInterval(timer) 清除週期性定時器 |
練習:使用週期性定時器每隔三秒鐘打印'hello',打印三次後,清除定時器。
當即執行
var timer=setImmediate( 回調函數 ) clearImmediate(timer) |
process.nextTick( 回調函數 ) |
3.模塊
模塊就是一個獨立的功能體,每個文件、目錄均可以稱爲一個模塊。
在nodejs下模塊分爲自定義模塊、核心模塊(官方提供)、第三方模塊
nodejs自動會給每個模塊添加構造函數
(function(exports,require,module,__filename,__dirname){ //程序員寫的代碼 }) |
require() 是一個函數,用於引入一個模塊 module 指代當前的模塊 module.exports 是當前模塊導出的對象,是供其它的模塊使用的屬性和方法(公開的內容) exports 等價於 module.exports |
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
建立兩個模塊,主模塊(main.js)和功能模塊(circle.js);在功能模塊中建立兩個函數,分別傳遞1個參數(半徑),計算圓的周長和麪積,導出這兩個函數; 在主模塊中引入功能模塊,並調用兩個函數。
(3)預習querystring,url,fs模塊
day02
全局對象
nodejs: global js: window
function fn(){ }
console.log/info/warn/error/time/timeEnd
process.arch/platform/env/version/pid/kill()
Buffer.alloc(5,'abcde') toString()
setTimeout/clearTimeout
setInterval/clearInterval
setImmediate/clearImmediate
process.nextTick
模塊系統
(function(exports,require,module,__filename,__dirname){
//寫的代碼
module.exports === exports
})
1.模塊中的參數
__filename 當前模塊的完整路徑和模塊名稱
__dirname 當前模塊的完整路徑
2.模塊
|
以路徑開頭 |
不以路徑開頭 |
文件模塊 |
require('./circle.js') 經常使用於用戶自定義模塊,若是後綴名爲js,能夠省略 |
require('querystring') 經常使用於引入官方提供的核心模塊 |
目錄模塊 |
require('./02_2') 到02_2目錄下尋找package.json文件中main屬性對應的模塊,若是找不到引入index.js
|
require('04_2') 會自動到node_modules中尋找目錄模塊04_2,若是當前目錄下沒有,會繼續往上一級目錄尋找,直到頂層目錄;經常使用於第三方模塊 |
練習:建立模塊03_1.js,引入當前目錄下03_2目錄模塊;在03_2下含有文件fun.js,導出一個函數add(計算兩個數字相加),在03_1.js中引入並調用。
練習:在05目錄下建立05_1.js,引入不以路徑開頭的目錄模塊05_2,包含文件focus.js,在文件中導出函數計算三個數字相加,在05_1.js中引入並調用。
3.包和npm
包: package,就是node_modules下的目錄模塊,其中含有package.json文件,是包說明文件。
npm: 用於下載安裝包的工具
下載的網站:www.npmjs.com
切換到安裝的目錄
cd 完整的路徑
進入要安裝的目錄,在空白區域按住shift鍵,單擊鼠標右鍵,在此處打開powershell窗口
使用npm安裝
npm install 包的名稱
4.查詢字符串模塊
查詢字符串:瀏覽器向服務器發請求,傳遞數據的一種方式。
http://www.jd.com/search?ky=電腦&lid=20
parse() 將查詢字符串格式化爲對象
stringify() 將對象轉換成查詢字符串
練習:獲取百度搜索中查詢字符串中的關鍵字 手機
ie=utf-8&tn=baidu&wd=手機
5.URL模塊
操做URL
parse() 將URL格式化爲對象
protocol 協議
hostname 主機名(域名/IP地址)
port 端口
pathname 請求的文件在服務器上的路徑
query 查詢字符串
format() 將對象轉換成URL
練習:獲取URL中查詢字符串中的數據。
http://www.codeboy.com:8080/web/1902.html?sid=10&name=tom
將URL格式化爲對象,獲取查詢字符串
將查詢字符串格式化爲對象,獲取到數據
08_exercise.js
6.文件系統模塊
(1)查看文件的狀態
fs.stat( fd, callback )/fs.statSync( fd )
fd 文件的路徑
callback 回調函數,用來查看結果
err 可能產生的錯誤信息
stats 具體的文件狀態
isDirectory() 是否爲目錄
isFile() 是否爲文件
對比同步和異步操做
同步: 會阻止後邊代碼的執行,只有執行完畢纔會執行後邊代碼;是經過返回值獲取結果。
異步:不會阻止後邊代碼的執行,放在整個線程的最後執行;是經過回調函數獲取結果。
(2)建立目錄
fs.mkdir( fd, callback )/fs.mkdirSync( fd )
(3)移除目錄
fs.rmdir( fd, callback )/fs.rmdirSync( fd )
(4)讀取目錄
fs.readdir(fd, callback)/fs.readdirSync(fd)
callback 回調函數
err 可能產生的錯誤
files 讀取的目錄中的文件
練習:讀取目錄05中的文件有哪些
(5)寫入(建立)文件
fs.writeFile(fd, data, callback)/fs.writeFileSync(fd,data)
fd 文件的路徑
data 要寫入的數據
callback 回調函數
若是文件不存在建立文件,若是文件已經存在,會清空文件中的內容,而後寫入。
(6)追加寫入(建立)
fs.appendFile(fd, data, callback)/
fs.appendFileSync(fd, data)
練習:在文件num1.txt中寫入'hello',運行屢次。
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習:
建立目錄mydir,在該目錄下建立文件data.txt,並寫入如下數據,每一個對象中的數據佔一行。
[{id:1, name:'tom', age:18}, {id:2,name:'kate',age:20} ]
(3)預習http協議,nodejs的http模塊
day03
|
以路徑開頭 |
不以路徑開頭 |
文件模塊 |
require('./circle.js') |
require('fs') |
目錄模塊 |
require('./04_2'); package.json中的main屬性 |
require('mysql') 到node_modules中尋找目錄模塊mysql |
包和npm
npm install 包名稱
querystring parse/stringify
url parse/format
fs stat/statSync/mkdir/rmdir/readdir/writeFile/
appendFile
同步和異步
1.fs模塊
(1)判斷文件是否存在
fs.existsSync(path) 判斷文件是否存在
存在 true 不存在 false
(2)讀取文件
fs.readFile(fd, callback)/fs.readFileSync(fd)
fd 文件的路徑
callback 回調函數
err 可能產生的錯誤
data 讀取的數據,格式爲buffer形式
(3)刪除文件
fs.unlink(fd, callback)/fs.unlinkSync(fd)
練習:完成一個文件計數器。
判斷文件num.txt是否存在,不存在建立,並寫入數據0;
讀取num.txt中的數據,而後讓讀取的值加1,並打印
把加1後的值再次清空寫入到num.txt中
全程使用同步方法 03_num.js
2.http協議
是瀏覽器和web服務器之間的通訊協議
(1)通用頭信息
Request URL: 請求的URL,對應瀏覽器地址欄內容,要向服務器獲取哪些內容
Request Method: 請求的方法, GET/POST...,獲取內容的方式
Status Code: 響應的狀態碼
1**: 正在請求,沒有結束
2**: 成功的響應
3**: 響應的重定向,跳轉到另外一個網址;一般結合着響應頭信息中location一塊兒使用
4**: 客戶端錯誤
5**: 服務器端錯誤
Remote Address: 請求的服務器的IP地址和端口號
(2)響應頭信息
Connection: 鏈接的方式, keep-alive持續鏈接
Content-Type: 響應的文件類型
Content-Length: 響應的文件長度
Location: 當響應重定向的時候,跳轉的URL
(3)請求頭信息
Accept: 客戶端接收的文件類型有哪些
Accept-Encoding: 客戶端接收的文件壓縮形式
User-Agent: 客戶端發送請求使用的瀏覽器
(4)請求主體
無關緊要,客戶端向服務器端傳遞數據
3.http模塊
既能夠模擬瀏覽器向服務器端發請求,也能夠建立web服務器
(1)模擬瀏覽器
http.get( url, callback )
get 請求的方法
callback 回調函數,用來獲取服務器端的響應
res 響應的對象
statusCode 獲取響應的狀態碼
res.on('data', function(buf){ })
經過事件來獲取響應的內容,當有數據傳遞自動觸發
經過回調函數來接收響應的內容
buf就是響應的內容,格式爲buffer
練習:使用http模塊下的get方法向tmooc發請求,並獲取響應的狀態和響應的內容 05_exercise.js
http://www.tmooc.cn/course/100072.shtml
(2)建立web服務器
var server=http.createServer() 建立web服務器
server.listen(8080) 分配8080端口,監聽端口變化
server.on('request', function(req,res){ })
接收瀏覽器的請求,是一個事件,當有請求自動觸發
經過回調函數來接收請求,作出響應
req 請求的對象
url 請求的URL,顯示端口後的部分
method 請求的方法
headers 請求的頭信息
res 響應的對象
writeHead(code, obj) 設置響應的狀態碼和頭信息
code 狀態碼 obj 頭信息對象
write() 設置響應的內容
end() 結束響應,併發送響應內容到瀏覽器
練習:建立web服務器,監聽端口8081,接收瀏覽器的請求
/login 響應內容 this is login page
/member 響應內容 <h2>welcome</h2>
/ 重定向到 /login
以上都沒有 響應內容 404 not found
07_http_server.js
4.express框架
基於nodejs,快速、開放、極簡的web開發框架
www.expressjs.com.cn
安裝 npm install express
(1)路由
瀏覽器向web服務器發請求,web服務器根據請求的方法和請求的URL來作出響應。
三要素:請求的方法、請求的URL、響應(回調函數)
課後任務
(1)複習今天內容,整理思惟導圖
(2)練習
使用http模塊建立web服務器,接收瀏覽器的請求,根據請求的URL來作出不一樣的響應
/index 響應內容 this is homepage
/login 響應內容 <h2>please login</h2>
/ 重定向 /index
其它 響應 404 not found
(3) 預習瀏覽器向服務器發送請求的方式get/post
預習express中間件
day04
http協議
通用頭信息
請求方法、請求URL、響應的狀態碼
響應頭信息
Content-Type: text/html text/plain
Location: http://www.codeboy.com /index
請求頭信息
請求主體
http模塊
向服務器發請求
http.get(url, function(res){ res.statusCode
res.on('data', function(buf){ });
});
建立web服務器
http.createServer()
listen(8080)
express框架
express()
listen(8080)
路由
1.express框架
(1)路由
req對象
method 請求的方法
url 請求的URL
headers 請求的頭信息
query 獲取查詢字符串數據,格式化爲對象
res對象
send() 響應內容併發送,不能屢次使用,若是是數字須要轉成字符串
sendStatus() 響應狀態碼對應的中文 200->ok
sendFile() 響應文件併發送
redirect() 響應的重定向
練習:建立路由並響應
get /index 響應<h1>這是首頁</h1>
get /member 響應文件member.html
get / 響應重定向到 /index
post /register 響應 註冊成功
2.post和get請求
post請求是經過表單提交(現階段)來傳遞數據,服務器端是經過事件來獲取數據,後期能夠使用中間件簡化。
req.on('data', function(buf){ buf就是獲取的數據,格式爲buffer,須要使用查詢字符串模塊格式化爲對象 }) |
get請求經過查詢字符串傳遞數據,服務器端使用req.query獲取數據,結果是對象。
post請求安全性較高,速度較慢,註冊、登陸使用post提交。get請求安全性較低,速度較快,搜索中使用get提交。
練習:建立路由,請求方法get,請求的URL: /reg,響應一個文件 reg.html; 在html建立註冊的頁面(用戶名、密碼、手機),點擊提交,向服務器發送get請求,請求URL: /myreg,響應'註冊成功'。
3.使用路由傳遞數據
設置路由中接收的名稱
server.get('/detail/:lid', function(req,res){ req.params //獲取路由傳遞的數據,格式爲對象 }); |
瀏覽器傳遞數據
http://127.0.0.1:8080/detail/5
5就是傳遞的數據,被lid所接收
練習:建立購物車的路由,請求方法:get,請求URL: /shopping,傳遞商品的價格(price)和名稱(pname),把接收的兩項響應到瀏覽器中。
商品模塊 /list /delete /update
用戶模塊 /list /delete /update
4.路由器
路由在使用過程當中,不一樣模塊下的路由可能出現相同的URL,把同一個模塊下的路由掛載到特定的前綴,例如: 商品模塊下列表路由 /product/list,用戶模塊下的列表路由 /user/list
路由器就是自定義的模塊,存放了全部模塊下的路由
const express=require('express'); var router=express.Router(); //建立空的路由器對象 router.get('/list', function(req,res){ });//往路由器添加路由 module.exports=router; |
web服務器下使用路由器
const userRouter=require('./user.js');//引入路由器模塊 server.use('/user',userRouter);//把路由器掛載到/user下,訪問形式 /user/list |
練習:建立商品模塊路由器(product.js),添加路由商品列表、商品刪除,在web服務器下引入,並掛載到/product。
5.中間件
中間件做用爲主要業務邏輯所服務器
分爲應用級中間件,路由級中間件,內置中間件,第三方中間件,錯誤處理中間件。
(1)應用級中間件
每個中間件都是一個函數,須要配合其它的中間件或者路由使用。
server.use( function(req,res,next){ } ) 攔截全部請求
server.use('/reg', function(req,res,next){ })
攔截特定的請求,當請求的URL爲/reg,纔會執行回調函數。
練習:建立路由(請求方法:get,請求URL:/view)響應當前的瀏覽次數,每次瀏覽,響應次數加1.
在中間件外部建立變量,設置初始值0,中間件中變量加1,在路由中響應瀏覽次數(變量) send(0)
(2)路由級中間件
將路由器掛載到特定前綴,就是使用路由級中間件
server.use('/user', userRouter);
(3)內置中間件
在express中只有一個內置的中間件
課後任務
(1)複習今天內容,複習mysql的SQL語句
(2)練習
建立web服務器,向服務器請求查詢生日文件(birth.html),在html中點擊提交再次向服務器發請求,根據身份證號顯示出生的年月日和性別(中間件);在路由中響應到瀏覽器
day05
1.內置中間件
express中只保留了一個內置的中間件
server.use( express.static( '目錄' ) );
託管靜態資源到某個目錄,若是瀏覽器請求靜態資源,自動到該目錄下尋找,無需使用路由響應文件。
靜態資源:html、css、客戶端js、img...
練習:再次託管靜態資源到files目錄下,若是同時出現兩個相同名稱的文件,顯示哪個目錄下的。
2.第三方中間件body-parser
能夠將post請求的數據直接格式化爲對象
//引入body-parser server.use( bodyParser.urlencoded({ extended:false }) ); urlencoded: 將post請求數據格式爲對象 extended:不使用第三方qs模塊,而使用核心模塊querystring將查詢字符串格式化爲對象 |
在路由中獲取post請求數據
req.body 返回對象
3.mysql模塊
鏈接mysql數據庫服務器
mysql.exe -h127.0.0.1 -P3306 -uroot -p
進入數據庫 use xz;
INSERT INTO emp VALUES(....);
DELETE FROM emp WHERE uid=3;
UPDATE emp SET ename='tom',sex=0 WHERE eid=1;
SELECT eid,ename FROM emp;
(1)普通鏈接
var connection=mysql.createConnection( {} );建立鏈接對象,提供mysql服務器的主機名,端口號,用戶名,密碼,鏈接後要使用的數據庫
connection.connect(); 執行鏈接
connection.query( sql, function(err, result){ } )
sql要執行的SQL語句,result,SQL語句的執行結果
connection.end() 關閉鏈接
(2)使用鏈接池
var pool=mysql.createPool({ }); 建立鏈接池對象,傳遞主機名,端口號,用戶名,密碼,使用的數據庫,鏈接池大小
pool.query( sql,callback )
在SQL語句中能夠使用佔位符 ?
練習:建立web服務器,託管靜態資源到public下,建立add.html(包含部門編號,部門名稱)。06_add.js
點擊表單中的提交按鈕,向服務器發送請求,請求方法:post,請求URL:/add,建立對應的路由獲取提交的數據。
將服務器接收的數據插入到tedu數據庫下dept表中,
課後任務
(1)複習今天內容,整理思惟導圖
(2)建立web服務器,託管靜態資源,點擊提交,將數據插入到tedu數據庫下的emp表中
day06
複習
步驟:
(1) web服務器 (app.js)
託管靜態資源到public
使用body-parser中間件
使用路由器,掛載到指定的位置 例如掛載到 /user
(2)路由器( routes )
引入鏈接池模塊
建立路由器對象
往路由器添加路由
在路由中使用鏈接池
導出路由器
(3)鏈接池模塊(pool.js)
建立鏈接池對象
導出鏈接池對象
SELECT * FROM xz_user LIMIT start,count;
count: 每頁的數據量
start: 開始查詢的值
數據量十、頁碼
start=(頁碼-1)*數據量
1 0
2 10
建立商品模塊路由器 product.js,
建立空的路由器對象
添加路由
導出路由器
把路由器導入到服務器下,掛載到/product下
李然 QQ:1535212067
一.課程安排,(20天)
1.HTML5 Basic(2天)
搭建網頁結構
2.Ajax異步數據交換(3天)
異步完成先後端數據的交互
3.項目1(2天)
4.CSS樣式表(4+2天),讓頁面變得好看
美化HTML
5.Bootstrap框架(4天)
簡化css開發,
支持響應式開發
6.項目(2天)
總結:20天課程遇到問題
1.知識點細碎,沒有條理 2.知識點量極大,單詞量極大 |
二.web基礎知識
HTML5:大前端技術 是html4.01升級版 XHTML1.0的升級版 1999年12月發佈 2000年1月發佈 語法鬆散 語法嚴謹 <input> <input/> |
1.web與internet
internet:全球性計算機互聯網 俗稱:互聯網,因特網 web就是運行在internet上的一種應用程序 internet上的服務
|
2.internet上的應用程序,結構分類
1.C/S C:client 客戶端 S:server 服務器 表明:QQ,LOL...... |
2.B/S B:Browser 瀏覽器 S:server服務器 |
C/S和B/S的區別 1.cs是須要升級 2.bs不須要升級 |
3.web運行原理
web:運行在internet上的一種B/S結構的應用程序 俗稱網站 internet:爲web運行提供了網絡環境 web的工做原理: 基於瀏覽器和服務器以及通訊協議來實現的數據傳輸和展現 通訊協議:規範了數據是如何打包和傳遞 |
服務器 1.功能 存儲數據 接收用戶請求並給出響應 提供了程序的運行環境 具有必定的安全功能 2.服務器產品 Apache/Tomcat/IIS 3.服務器端技術 java/PHP/python/nodejs/C# |
瀏覽器 1.功能 表明用戶發送請求 做爲html.css.js的解析器,以圖形化的界面展現給用戶看 2.瀏覽器的產品 chrome safari Firefox oprea IE 3.瀏覽器技術 HTML5 CSS3 JS |
三.HTML入門
1.HTML是什麼
HyperText Markup Language 超文本標記語言 標記:超文本的組成形式,具備本身獨特的功能 語法:<關鍵字></關鍵字> |
2.HTML的特色
1.以.html或者.htm爲後綴 2.由瀏覽器解析執行 3.使用帶有<>的標記來標識 4.頁面中能夠執行js腳本 |
3.HTML基本語法學習
1.標記
又稱,標籤,元素,節點 語法<關鍵字></關鍵字> 每一個標籤都有本身的功能 咱們要學習關鍵字和對應的功能 |
2.標記的分類
1.雙標記(封閉類型標記) <關鍵字>....</關鍵字> ex:<a></a> <div></div> 2.單標記(非封閉類型標記),空標籤 <關鍵字>或者<關鍵字/> <input>或者<input/> |
練習
新建文檔01_ex.html 在文檔中 寫一對html標籤 寫一對head標籤 寫一對body標籤 |
3.標籤的嵌套
在一對標籤中出現其餘標籤,造成功能嵌套關係 嵌套關係,必須子元素有縮進 注意嵌套層級不要混亂 推薦的寫法
不推薦的的寫法
錯誤的寫法
|
4.屬性
雙標籤 <a href="http://www.tmooc.cn/"></a> <關鍵字 屬性1="值1" 屬性2="值2" ...></關鍵字> 單標籤 <input type="submit" value="登陸"/> <關鍵字 屬性1="值1" 屬性2="值2" .../>
屬性是對該標籤的修飾 |
練習
在01_ex中添加b標籤,內容隨意 b標籤擁有屬性align="center" title="1111" 觀察效果,提示:有一個屬性不生效 |
4.1屬性分類
1.通用屬性,全部元素都有的屬性 id:定義元素在頁面中惟一的標識符 title:鼠標懸停在元素上所提示的文本 style:css中第一內聯樣式的屬性 class:css中,引用類選擇器的屬性 2.專有屬性,某個元素自帶的屬性,其它元素此屬性不生效 |
總結
學習html,究竟怎麼學? 記憶<關鍵字>,記憶超文本標籤的特殊能力 記憶專有屬性,記憶嵌套關係 |
5.html的註釋
不被瀏覽器解析的文字 <!-- 這裏是註釋文字 --> |
四.HTML的文檔結構
<!doctype html> <html> <head></head> <body></body> </html> |
1.文檔類型聲明<!doctype html> 告訴運行解析個人瀏覽器,若是你想正確的運行解析我這篇HTML文檔,請使用h5的規則解析我 |
2.網頁結構 <html> <head></head> <body></body> </html> 語法:<html></html> 標識網頁的開頭和結束 注意,一個.html文件中,有且只有一組html標籤 <head></head>網頁的頭部,定義全局的信息 <body></body>網頁的主體,展現的內容 |
練習
02_ex.html.完成最基本的網頁結構 |
|
<head></head>中的元素
<body></body> 定義網頁主體 body的屬性 text="red"指定網頁的字體顏色 bgcolor="yellow" 指定網頁的背景顏色 15:18上課 |
關於editeplus快捷鍵
ctrl+b 快速在指定的瀏覽器中打開頁面 ctrl+s 保存 定義快捷鍵 ctrl+d 刪除當前行 ctrl+z 回退一步 ctrl+y 前進一步 alt+↑/↓ 移動當前行位置 ctrl+alt+↓ 複製當前行 |
五.文本標記
1.標題元素
<h1></h1>~~~<h6></h6> 在頁面中以醒目的方式顯示文本 特色:1.字體大小有變化 h1最大,h6最小 2.字體加粗 3.獨佔一行,上下有垂直間距 屬性 align 設置標記內容水平對齊方式 取值:left/center/right |
2.段落標記
<p></p> 以突出的形式表現一段文字 特色:1.獨佔一行 2.文本上下有垂直間距 屬性 align |
練習
03_ex.html中,模擬一份我的簡歷 |
3.換行標記
<br>或者<br/> |
4.水平分割線
<hr>或者<hr/> 屬性 size="5px" 分割線粗細 以px爲單位的數字 width="50%" 分割線寬度以px爲單位的數字 % align="left" 分割線水平對齊 left/center/right color="orange" 分割線顏色 合法顏色值 |
5. 預格式化標籤
保存了在編寫代碼時的回車和空格效果 在瀏覽器中解析顯示 <pre></pre> |
6.特殊字符(實體)
html會出現空格摺疊現象 把全部的空格都解析成一個空格 把全部的回車都解析成一個空格 <br> 空格 < < > > © © ® ® × × 人民幣 & |
練習
Copyright © 2000-2019 <北京達內版權全部> |
7.文本樣式標籤
<i></i> <em></em> 斜體 <b> </b> <strong> </strong> 加粗 <s></s> <del></del> 刪除線 語義 <u></u> 下劃線 <sup></sup>上標 <sub></sub>下標 |
8.分區元素,若是不寫樣式,頁面中是看不到的
1.塊分區<div></div> 用於頁面中的佈局效果 特色,單獨成行 |
2.行分區<span></span> 一行文字若是有多種樣式,使用span 特色,與其餘span元素共用一行 span中不容許嵌套塊級元素 |
9.塊級元素和行內元素
1.塊級元素 頁面上,單獨成行的元素,都是塊級元素 ex:h1~h6,p,div 塊級元素默認排列方式,由上到下排列 |
2.行內元素 頁面上,多個元素共用一行 ex:span em i b strong sub sup u s del 行內元素默認排列方式,由左往右排列 |
六.圖像和連接
做業
1.熟練完成nodejs接口11個
2.圖片能夠不寫
3.使用div完善我的簡歷
一.圖像和連接
1.圖像的使用
<img>或<img/> 屬性 src="圖片資源路徑" <img src="圖片資源路徑"> |
2.URL
Uniform Resource Locator 統一資源定位符,俗稱路徑 |
3.url的表現形式
1.絕對路徑---使用網絡資源的時候使用 完整的路徑 通訊協議+主機名稱+文件目錄結構+資源名稱 優勢:不佔用本地存儲空間 缺點:不穩定 使用網絡資源發展出來的行業---圖牀 練習:01_ex中再從tmooc中,盜一張圖,顯示 |
|
2.相對路徑---使用本服務器資源的時候使用
|
4.圖片的屬性
src 設置圖片資源路徑 source的縮寫-數據源 title:鼠標懸停時,顯示的文字 alt:圖片加載錯誤時,顯示的文字 width:設置圖片的寬 height:設置圖片的高 注意:若是設置的寬高比,與原始圖片寬高比不一致,會出現圖片的失真。 解決圖片的失真,寬高屬性,只寫一個,另一個自適應 |
5.連接
1.語法 <a href></a> 屬性 href 連接的路徑 target打開頁面的方式 取值:_self 默認值,在當前頁面中打開新網頁 _blank 在新頁面打開網頁 |
||||
2.a標籤其它表現形式
|
6.a標籤的錨點操做
1.什麼是錨點 錨點,就是頁面中的一個記號 能夠經過超連接的方式連接到記號位置處 2.錨點的使用
練習
|
二.表格
1.表格語法
<table></table> 行 <tr></tr> table row 列 <td></td> table data <table> <tr> <td>數據內容</td> </tr> </table> 編寫4行4列的表格,內容隨意 |
2.屬性
table標籤的屬性 border:設置表格的邊框 width="200px" 設置表格寬 height="200px" 設置表格高 align="center" 設置表格水平對齊方式 bgcolor="pink" 設置表格背景顏色 bordercolor="red" 設置表格邊框顏色 cellpadding="10px" 設置表格內邊距 邊框到內容的距離(以左和上爲準) cellspacing="10px" 設置表格的外邊距 邊框到邊框的距離 |
練習
04_ex.html 設置表格尺寸400px*400px,4*4的表格 表格背景pink 邊框1px,邊框顏色yellow 表格水平居中 表格內邊距5px 外邊距10px |
tr的屬性 align left/center/right 設置當前行內容的水平對齊方式 valign top/middle/bottom 設置當前行內容垂直對齊方式 bgcolor="yellow" 設置當前行的背景顏色 |
td的屬性 width="70px" 設置當前單元格寬度,寬度過大會影響當前列 height="70px" 設置當前單元格的高度,高度過大,會影響當前行 align="right" 設置當前單元格內容的水平對齊方式 valign="top" 設置當前單元格內容的垂直對齊方式 bgcolor="blue" 設置當前單元格的背景顏色 colspan 跨列,列合併 rowspan 跨行,行合併 |
3.不規則的表格
1跨列 colspan="n" 第一步:從指定的單元格的位置處,橫向向右合併N個單元格(n包括本身) 第二步:把被合併的單元格刪除 |
2跨行 rowspan="n" 第一步:從指定的單元格的位置處,縱向向下合併N個單元格(n包括本身) 第二步:把被合併的單元格刪除 |
4.表格可選標記
1.表格的標題 <caption> </caption> 注意,若是設置表格標題,<caption> </caption>必須緊跟<table> |
2.行/列的標題 使用<th></th>替換<td></td> <th></th>:加粗,居中 |
5.複雜表格的應用
1.行分組,默認不可見 能夠將幾個連續行,劃分到一個組中,進行統一管理 表頭<thead></thead> 表主體<tbody></tbody> 表腳<tfoot></tfoot> |
2.表格嵌套 被嵌套的表格,只能放在td中 |
練習
三.列表
1.列表的做用
最原始的做用,有條理的顯示數據 列表是由列表類型和列表項組成 |
2.有序列表
項目中,有序列表就是顯示數據,並且使用概率很小 <ol> order list--ol list item--li <li>打開冰箱門</li> <li>把大象放進冰箱</li> <li>關上冰箱門</li> </ol> 屬性type=" " 標識項的類型 1/a/A/i/I start="" 標識項的起始數字 |
3.無序列表
四.結構標籤
午間練習,把昨天做業中的圖片,添加進去
第二階段練習效果圖示\day01_html_01做業\素材
做業:
1.11個nodejs接口
2.完成課程表
一.列表
1.無序列表
1.什麼是無序列表
2.ul的屬性
|
2.列表的嵌套
1.在li中嵌套其它元素 <ul> <li><img src="../image/06.png"></li> <li><img src="../image/07.png"></li> <li><img src="../image/08.png"></li> </ul> <ol> <li><a href="#">湯圓炒橘子</a></li> <li><a href="#">西紅柿炒月餅</a></li> <li><a href="#">薑絲炒土豆絲</a></li> </ol> |
2.在li中嵌套其它列表 列表的嵌套,必須放在li中,不是語法要求,是語義要求 |
3.定義列表(h5新標籤)
對一個名詞,進行解釋說明的時候,使用定義列表 <dl> 定義列表 <dt> </dt> 要解釋說明的名詞 <dd> </dd> 要解釋說明的內容 </dl> |
二.結構標記
1.用於描述整個網頁結構,取代div作佈局的一套標記
爲何要使用結構標記,而不用div 結構標記的做用根div如出一轍 結構標記是有語義,方便閱讀 使用有語義的標籤,可讓頁面在搜索時更靠前 |
2.經常使用的結構標記
1.<header></header> 定義網頁的頭部,或者某個區域的頂部 2.<footer></footer> 定義網頁的腳部,或者某個區域的底部 3.<nav></nav> 定義網頁導航連接 4.<section></section> 定義網頁主體內容 5.<aside></aside> 定義網頁側邊欄 6.<article></article> 定義與文字相關的內容 好比,論壇,回帖,用戶評論....
|
三.表單(重點&難點***********)
1.做用
1.提供可視化的輸入控件 2.收集用戶輸入的信息,並提交請求給服務器 總結,form自帶提交請求的功能 ajax提交不須要form支持 |
2.表單的組成
1.前端部分 提供表單控件,與用戶交互的可視化控件 2.後端部分 後臺接口對提交的數據進行處理 |
3.表單
<form></form> 屬性:
|
||||||||||
4.表單控件,在form標籤中,可以與用戶進行交互的可視化元素
17:07~17:22休息
|
一.表單
1.其它元素
1.label元素 關聯文本與表單控件 <label for="login_qq">QQ</label> 屬性for,綁定要關聯的表單控件的id值 效果,點擊label文本,被關聯的控件也被點中 |
2.爲控件分組
<fieldset></fieldset>爲控件分組 <legend></legend>分組的標題 |
3.浮動框架
<iframe></iframe> src 要引入的網頁路徑 width 設置iframe的寬度 height設置iframe的高度 須要js和dom的支撐 frameborder 浮動框架的邊框 scrolling 設置滾動條 yes no auto |
4.新表單元素
在html5版本中,新提出來的表單控件
|
二.HTTP協議
1.URL
結構:協議+主機名稱+目錄結構+文件名稱 URL完整的結構 <scheme>://<user>:<pwd>@<host>:<port>/<path>; <params>?<query>#<frag> |
|||
url完整結構詳解
|
2.HTTP協議
HTTP HyperText Transfer Protocol 超文本傳輸協議 規範了數據是如何打包以及傳遞的(專門用於傳輸html文件) |
HTTP協議的歷史
|
3.web請求原理詳解
|
4.消息/報文Message
1.請求消息Request Message(請求起始行,請求頭,請求主體) 2.響應消息Response Message(響應起始行,響應頭,響應主體) |
5. Request Message
請求消息,客戶端發送給服務器的數據塊 由三部分組成:請求起始行,請求頭,請求主體 |
||||
1. 請求起始行
2. 請求頭
3. 請求主體
|
6. Response Message
響應消息,服務器發送給客戶端的數據塊 由三部分組成:響應起始行,響應頭,響應主體 |
|||
1. 響應起始行
2. 響應頭
3. 響應主體,服務器傳給瀏覽器的數據 |
7.緩存
客戶端將服務器響應回來的數據進行自動的保存 當再次訪問的時候,直接使用保存的數據
|
緩存的優勢? 1.減小冗餘的數據傳輸,節省客戶端流量 2.節省服務器帶寬 3.下降了對服務器資源的消耗和運行的要求 4.下降了因爲遠距離傳輸而形成加載延遲 |
緩存的新鮮度和過時
1.請求--無緩存--鏈接服務器--存緩存--客戶端獲得 2.請求--有緩存--夠新鮮--使用緩存--客戶端獲得 3.請求--有緩存--不新鮮--連服務器確認是否過時--沒過時--更新緩存的新鮮度--客戶端獲得 4.請求--有緩存--不新鮮--連服務器確認是否過時--已過時--連服務器--存緩存--客戶端獲得 |
1.與緩存相關的消息頭
Cache-Control:max-age=0 從服務器將文檔傳到客戶端之時起, 此文檔處於新鮮的秒數,這是一個相對時間 語法:Cache-Control:max-age=處於新鮮的秒數 Cache-Control:0 不緩存 |
2.在網頁中添加緩存,須要修改消息頭
<meta http-equiv="消息頭屬性" content="值"> |
8.HTTP性能優化
HTTP的鏈接過程 發起請求-->創建鏈接-->服務器處理請求-->訪問資源-->構建響應-->發送響應-->記錄日誌 |
1.HTTP鏈接性能的優化
1.減小鏈接建立次數(開啓持久鏈接) 2.減小請求次數 3.提升服務器端運行速度 4.儘量減小響應數據的長度 |
2.安全的HTTP協議
HTTPS:安全版本的http協議 SSL:爲數據通訊特供安全支持 1.客戶端發送請求--->SSL層加密--->服務器接收加密文件--->在SSL層解密,獲得請求明文,對請求作處理 2.服務器發送響應--->SSL層加密--->客戶端獲得加密文件--->在SSL層解密,獲得響應明文,解析響應內容
|
一.DOM(簡單dom操做)
ajax提交請求,不須要使用form表單 可是,form表單自帶收集數據的功能 不是用form標籤,就沒有自動收集數據的功能了 咱們須要使用js的dom操做,手寫代碼,收集數據 |
1.使用dom
1.獲取元素對象
2.獲取/修改元素的值/內容
3.innerHTML詳解
4.事件 onclick
|
二.Ajax
1.同步Synchronous
在一個任務進行的過程當中,不能開啓其餘任務 同步訪問:瀏覽器在向服務器發送請求時,瀏覽器只能等待服務器的相應,不能作其餘事 出現場合: 1.地址欄輸入url,訪問頁面(網速很差時,更明顯) 2.a標籤跳轉 3.表單提交 |
2.異步Asynchronous
在一個任務開啓時,能夠開啓其餘任務。 異步的訪問:瀏覽器在向服務器發送請求時,用戶能夠在頁面上作其餘操做 出現場合 1.用戶名重複的驗證 2.聊天室 3.百度搜索建議 4.股票走勢圖 |
1.什麼是Ajax
Asynchronous JavaScript and XML 異步的 js 和 xml 本質:使用js提供的異步對象, 異步的向服務器發送請求, 並接收響應回來的數據 異步對象 XMLHttpRequest |
2.使用ajax
1.建立異步對象 2.建立請求 3.發送請求 4.接收響應數據 |
3.建立異步對象
var xhr=new XMLHttpRequest(); 這種建立方式,不兼容ie8如下的版本 |
4.使用異步對象打開鏈接,建立請求
xhr.open(method,url,isAsyn); method:string類型,請求的方法。好比 "get" ulr:string類型,請求的url.好比 "http://127.0.0.1:8080/login" isAsyn:boolean類型,是否才用異步訪問的方式去訪問服務器 |
5.發送請求
xhr.send(formdata) 注意:只有post請求的使用,纔有請求主體formdata get方法不須要請求主體 因此使用get請求的時候,兩種發送請求的寫法 xhr.send()或者xhr.send(null) |
跨域問題,必定在xz的服務器中,託管靜態資源文件夾中,編寫html文件。否則會發生跨域問題。 運行此html文件,要使用訪問服務器的方式運行,不要使用ctrl+b或者直接雙擊。 //1.建立異步對象 var xhr=new XMLHttpRequest(); //2.打開鏈接,建立請求 xhr.open("get","http://127.0.0.1:8080/demo/ajaxdemo",true); //3.發送請求 xhr.send(null); 15:30~15:45休息 |
6.綁定監聽,接收響應
1.readyState屬性
2. status屬性
3.onreadystatechange 監聽事件
4.常見錯誤
5.使用get提交,發送帶參數的請求(dom)
|
做業:
1.使用get方法完成登陸模塊
2.使用get方法獲取商品列表,把響應數據放到div中顯示
3.提升題,註冊驗證,驗證新用戶名是否可用
模仿學子商城註冊頁,使用獲取焦點和失去焦點事件
一.Ajax
1.post請求
1.post接口 router.post("/login_post",(req,res)=>{ //獲取用戶名和密碼 var $uname=req.body.uname; var $upwd=req.body.upwd; 2.使用post方法提交請求 注意:因爲服務器默認接收普通字符 請求主體有特殊字符 須要在發送以前,設置請求頭信息,改成發送全部字符 設置的位置,是在open以後,在send以前 //1.建立 xhr對象 var xhr=new XMLHttpRequest(); //4.綁定監聽,接收響應 xhr.onreadystatechange=function(){ if(xhr.readyState==4&&xhr.status==200){ var result=xhr.responseText; alert(result); } } //2.打開鏈接,建立請求 xhr.open("post","/demo/login_post",true); //3.發送請求 //設置請求消息頭,修改接收全部字符 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); var formdata="uname="+uname.value+"&upwd="+upwd.value; xhr.send(formdata); |
2.做業,查userlist
任務1.從新完成userlist,要用onload事件(接口,頁面)
任務2.從新完成post登錄(接口,頁面)
3.Json
使用ajax訪問服務器,服務器鏈接數據庫,把結果經過相應傳送給ajax. 前臺ajax內部,xhr.responseText獲得這個相應數據 這個相應數據的類型,string string放的是數組結構,每個元素是什麼? 1.js對象的數據格式
2.JSON數據格式
3.把json字符串轉換成js對象數組
|
常見錯誤
緣由:本機開啓了另一個mysql數據庫 不是你本身xmapp中的mysql 解決方案:須要在任務管理器中把以前的mysql進程清除。而後從新開啓xmapp的mysql 任務管理器,在開始按鈕上點擊右鍵打開 |
設置請求消息頭,的代碼,放在了open以前或者send以後 |
4.XML數據格式
XML:eXtensible Markup Language; 可擴展的 標記 語言 xml是html 的一個變種,專門負責承載數據用的 因此操做xml要使用dom xml的標記,是沒有被預約義過,須要自定義 xml就是作數據傳遞,而不是數據展現 1.xml的語法
2.使用ajax訪問xml數據
3.xml數據解析,使用dom
|
二.AJAX項目
新建mypro.js 在app.js中導入掛載 新建靜態文件夾 mypro 在app.js中託管 全部接口寫在mypro.js中 全部的html寫在mypro文件夾裏 |
1.登錄功能 post方法
做業:
1.完成用戶列表頁
2.完成註冊頁面的失去焦點驗證,及用戶註冊
一.CSS概述
1.CSS是什麼
cascading style sheets 層疊樣式表,級聯樣式表,簡稱樣式表 |
2.做用
美化html頁面 |
3.HTML與CSS的關係
html,負責網頁的搭建,內容的展現 css,負責網頁的修飾,樣式構建 |
4.CSS與HTML的屬性,使用原則
w3c建議,儘可能使用css的方式取代html的屬性 css的優點 1.樣式代碼能夠高度重用 2.樣式代碼可維護性高 |
二.CSS的語法規範
1.使用css的方式
1.行內樣式,內聯樣式 在元素的style屬性中,聲明樣式(全部元素都有style屬性) <any style="樣式聲明"></any>(any是任何元素的意思) 樣式聲明:樣式屬性:樣式值;樣式屬性:樣式值; 樣式屬性和值用:鏈接 多個樣式聲明用;鏈接 內聯樣式在項目中不用,因爲不能重用,默認優先級最高。 只有在學習和測試使用。 |
2.內部樣式 在head標籤中,寫style標籤,在style中定義樣式規則 <style> p{color:red;background:pink;font-size:36px;} </style> 樣式規則: 選擇器,就是規定頁面中哪些元素能夠使用此樣式 {樣式聲明} 內部樣式的重用,只能在當前頁面內重用。 項目中較少使用,在學習和測試中使用較多 |
3.外部樣式 單首創建一個.css文件,在這個文件內寫樣式 在.html的head標籤中,是link引入此樣式 <link rel="stylesheet" href="css的url"> 外部樣式在項目中應用普遍 |
經常使用樣式屬性
color:blue; 字體顏色,取值是合法的顏色 font-size:36px; 字號大小,取值px爲單位的數字 background:yellow 背景顏色,取值合法的顏色 |
練習
css3種使用方式 01_ex.html <h1>lorem</h1>內聯,背景色爲粉色,字體顏色爲黃色 <h2>lorem</h2>內部,背景色爲黃色,字體顏色爲紅 <h3>lorem</h3>外部,背景色爲紅色,字體顏色爲藍色 |
2.CSS的特性
1.繼承性 做用在父元素的樣式,大部分能夠被子元素繼承 |
2.層疊性 能夠爲一個元素定義多個樣式規則 樣式規則中的屬性不衝突時,能夠同時應用這個元素上 |
3.樣式的優先級 若是樣式聲明衝突時,按照樣式規則的優先級去應用 默認的優先級規則,由高到低: 1.最高,內聯樣式 2.內部 外部 就近原則 3.最低,瀏覽器默認樣式 |
4.調整優先級 !important規則 放在屬性值以後,與值之間使用空格隔開 做用:調整樣式優先級,優先級提高 多個樣式都有!important,按照就近原則應用 ex: h2{color:red !important;} |
練習
02_ex.html中 一個p標籤,內容是假文 用內部樣式設置文字顏色爲藍色,字號24px 用外部樣式設置文字顏色爲紅色,字號40px 將外部樣式引入,f12查看頁面效果 而後內部樣式和外部樣式引入的位置,f12觀察效果 嘗試使用!important調整樣式優先級 |
三.基礎選擇器 (重點***)
1.選擇器的做用
規範了頁面中哪些元素可以使用定義好的樣式 選擇器就是爲了匹配元素(選擇器就是一個條件,符合這個條件的元素就能夠使用這個樣式) |
2.基礎選擇器詳解
1.通用選擇器 *{樣式聲明} *{margin:0;padding:0} 全部元素的內外邊距清0 |
2.元素選擇器,標籤選擇器 頁面中全部對應的元素,都應用這個樣式 設置頁面中某種元素的公有默認樣式 ex:p{},div{} 特殊用法:body{margin:0;padding:0} body及內部全部元素的內外邊距清0 |
3.ID選擇器,專屬定製 只對當前頁,一個標籤生效 <any id="id值"></any> #id值{樣式聲明} 通常id選擇器在項目中不多單獨使用,一般會做爲子代選擇器或者後代選擇器的一部分 |
練習:
03_ex.html中有h2標籤,內容是假文。此h2的id爲text1 使用id選擇器設置文本爲紫色purple.背景爲黃色 字體爲斜體 font-style:italic;查看頁面觀察效果 再使用元素選擇器,設置文本爲紅色,背景爲pink 這裏會對就近原則產生疑問 |
||||
4.類選擇器 定義頁面上某些元素的公共樣式(類選擇器,誰想用誰就能夠用) 經過元素的class屬性來引用樣式 <p class="text-danger">Lorem ipsum dolor sit amet.</p> .text-danger{color:red;}
|
||||
練習:04_ex 頁面中添加div和p元素,內容假文 用類選擇器爲全部元素設置字體爲紅色,字號爲24px,用分類選擇器爲p元素設置背景爲黑色 |
||||
5.羣組選擇器 將多個選擇器使用逗號分隔,放在一塊兒,定義一組公共樣式 語法:選擇器1,選擇器2,選擇器3,.....{} ex:div,p,#s1,.d2{color:red;background:yellow;} |
||||
6.後代選擇器 經過元素的後代關係匹配元素 後代,一級或者多級的嵌套關係 語法:選擇器1 選擇器2 選擇器3.....{樣式聲明} 存在的意義:更精準的匹配元素 |
||||
7.子代選擇器 經過元素的子代關係匹配元素 子代,一級嵌套關係 語法:選擇器1>選擇器2>選擇器3.....{} 存在的意義:更精準的匹配元素 |
||||
8.僞類選擇器 匹配元素不一樣狀態下的不一樣樣式
|
||||
9.選擇器的權值 權值:標識當前選擇器的重要程度,權值越大優先級越高 !important >1000 內聯樣式 1000 id選擇器 100 類選擇器 10 元素選擇器 1 *通用選擇器 0 繼承的樣式 無 權值的特色 1.當一個選擇器中含有多個選擇器時,須要將全部的選擇器的權值進行相加,而後比較,權值大的優先顯示 2.權值相同,使用就近原則 3.羣組選擇器的權值單獨計算,不能相加 4.樣式後面加!important,直接獲取最高優先級 內聯樣式不能加!important 5.選擇器權值的計算不會超過本身的最大數量級(100個1加一塊兒也不會大於10) |
四.尺寸和邊框
1.尺寸屬性
做用,改變元素的寬度和高度 width: 寬度 max-width最大寬度 min-width 最小寬度 height:高度 max-height最大高度 min-height最小高度 |
2.頁面中容許設置尺寸的元素
1.全部的塊級元素均可以設置 2.全部行內塊元素均可以設置 input(除了單選多選之外) 3.自己具有尺寸屬性的元素能夠設置 img table 4.大部分行內元素都不能設置寬高 |
3.溢出處理
當內容較大,元素區域較小的時候,就會發生溢出效果 默認都是縱向溢出 overflow:默認值 visible 溢出部分可見 hidden 溢出部分隱藏 scroll 顯示滾動條,溢出時滾動條可用 auto 自動,溢出時有滾動條,不溢出沒有 overflow-x,設置水平軸的滾動條 overflow-y,設置垂直軸的滾動條 |
如何改爲橫向溢出 須要在寬度比較小的容器內部,添加一個寬度較大的元素。 在父容器上,寫overflow。就能夠橫向溢出了 |
附加知識點---單位
尺寸單位 1.px 像素 2.in 英寸 1in=2.54cm 3.pt 磅值,多用於字體大小 1pt=1/72in 4.cm 5.mm 6.% 相對父級的百分比 7.em 相對於父級元素樣式數據乘以的倍數 1.5em 8.rem 相對根元素數據乘以的倍數 boot默認1rem=16px |
做業
1.今天全部css的demo
2.繼續完成ajax註冊功能
驗證用戶名已存在的接口
註冊接口
附加知識點:合法顏色值
1.顏色的英文單詞 2.#rrggbb 6個16進制的數字 ff 爲255 3.#aabbcc簡寫成#abc #f00 #0f0 #00f #ff0 #f0f #0ff 4.rgb(0~255,0~255,0~255); rgb(100,12,23); 5.rgb(0%,10%,50%); 能夠使用,可是項目不用 6.rgba(0~255, 0~255, 0~255,0~1) 1不透明,0全透明 |
一.尺寸和邊框
1.尺寸
2.溢出
3.邊框
邊框的簡寫方式 border:width style color; width邊框的寬度,以px爲單位的數字 style 邊框的樣式 solid 實線 dotted 點點虛線 dashed 短線虛線 double 雙實線 color 邊框的顏色 合法的顏色,transparent透明 邊框的簡寫方式,會同時設置4個方向的邊框 |
邊框的單邊設置 border-top:10px solid #aaa; border-right:10px solid transparent; border-bottom:10px solid transparent; border-left:10px solid transparent; |
邊框的單屬性設置 使用單屬性設置,必須保證邊框有style屬性 border-style:solid; border-width:3px; border-color:#f0f; |
單邊單屬性 border-方向-屬性,一共12個 border-top-width border-top-style border-top-color
border-right-width border-right-style border-right-color
border-bottom-width border-bottom-style border-bottom-color
border-left-width border-left-style border-left-color |
邊框的倒角(圓角) border-radius:圓角的半徑 取值:以px爲單位的數字 % 50%就是一個圓 單角設置,須要兩個方向的邊,才能肯定一個角 先寫上下,再寫左右 border-top-left-radius: border-top-right-radius: border-bottom-left-radius: border-bottom-right-radius: |
邊框的陰影 box-shadow:h-shadow v-shadow blur spread color inset; h-shadow:水平方向偏移量 v-shadow:垂直方向偏移量 blur:陰影的模糊距離,數值越大,越模糊 spread:陰影的尺寸 color:陰影的顏色 inset:把向外的陰影,變成向內的陰影 |
練習
中午,完成最酷的日食或者月食(放射性符號) |
輪廓 邊框的邊框,繪製與邊框周圍的線條 outline:width style color; outline:none/0;去掉輪廓 border:none/0;去掉邊框 |
二.框模型--盒子模型
框模型--元素在頁面上實際佔地空間的計算方式 瀏覽器默認的元素實際佔地寬度 左外邊距+左邊框+左內邊距+內容區域寬度+右內邊距+右邊框+右外邊距 瀏覽器默認的元素實際佔地高度 上外邊距+上邊框+上內邊距+內容區域高度+下內邊距+下邊框+下外邊距 外邊距margin:邊框之外的距離(元素與元素之間的距離) 內邊距padding:邊框與內容之間的距離 |
1.外邊距margin
改變外邊距,元素有位移效果 1.語法
2.簡寫方式
3.外邊距的特殊效果
|
2.內邊距padding
改變內邊距的效果,感受是改變了元素大小 不會影響其餘元素,可是會改變元素本身佔地尺寸,感受上改變了元素自己的大小 |
1.語法:padding padding:v1;設置4個方向的內邊距 padding-top padding-right padding-bottom padding-left 取值:以px爲單位的數字 % |
2.簡寫方式 padding:v1;設置4個方向 padding:v1 v2; v1:上下,v2:左右。padding沒有auto padding:v1 v2 v3; v1:上,v2:左右,v3:下 padding:v1 v2 v3 v4;上右下左 |
3.box-sizing屬性
設置元素佔地尺寸的計算方式 box-sizing
|
項目中,寫樣式的思路
從上往下寫,從外往裏寫,從左往右寫 1.尺寸,大致位置 2.邊框,背景色 3.文本樣式 4.微調 |
一.邊距
1.box-sizing
瀏覽器默認元素框模型 元素的實際佔地寬度:左外邊距+左邊框+左內邊距+內容區域寬度+右內邊距+右邊框+右外邊距 默認box-sizing: content-box; 默認值 content-box 設置的width和height,只是在設置內容區域 border-box 設置的width和height,是邊框內部的部分(包含邊框) 元素實際佔地寬度:左外邊距+設置的width+右外邊距 |
二.背景
1.背景顏色
2.背景圖片
background-image:url(資源路徑) 使用背景圖片,可讓元素內部的子元素,堆疊顯示在背景圖上 而img標籤,默認不能夠堆疊顯示 |
3.背景圖片的平鋪
background-repeat: 取值:repeat,默認值,平鋪 no-repeat,不平鋪,背景圖只顯示一次 repeat-x 在水平方向平鋪 repeat-y 在垂直方向平鋪 |
4.背景圖片的定位
background-position: 取值 1.x y 覺得單位的數字,定義橫向位置和縱向位置 2.x% y% 0% 0% 左上 50% 50% 中間 3.關鍵字 x:left/center/right y:top/center/bottom |
5.背景圖片的尺寸
background-size 取值:1.x y 以px爲單位的數字,設置具體寬高 2.x% y%按父元素寬高%比設置 3.cover,填充,覆蓋。讓背景圖充滿整個容器,哪怕圖片顯示不全,也不要緊 4.contain,包含。讓容器能夠包含整張圖片,圖片是顯示完整的。容器有空白區域,不要緊。 |
6.背景圖片的固定
background-attachment: 取值:scroll,默認值,背景圖會隨窗口滾動條滾動 fixed 背景圖相對於窗口固定,窗口滾動時,背景圖位置不變,可是隻會在原容器內顯示 |
7.簡寫方式
在一個屬性中指定背景的多個屬性值 屬性:background 取值:color url() repeat attachment position; 最精簡的寫法 backgrond:color/image11:01~11:16休息 |
二.漸變 gradient
1.什麼是漸變
漸變是指多種顏色,平緩變化的一種顯示效果 |
2.漸變的主要因素
色標:一種顏色,及其出現的位置 一個漸變,至少有兩個色標 |
3.漸變分類
1.線性漸變,以直線的方式來填充漸變色 2.徑向漸變,以圓形的方式來填充漸變色 3.重複漸變,將線性、徑向漸變重複幾回實現 |
4.線性漸變
background-image:linear-gradient(angle,color-point1, color-point2,.........); angle:表示漸變的方向,角度 取值 1.關鍵字 to top 從下往上 to right 從左往右 to bottom 從上往下 to left 從右往左 2.角度值 0deg to top 從下往上 45deg 90deg to right從左往右 180deg to bottom 從上往下 270deg to left 從右往左 color-point:色標 取值:顏色+以px爲單位的數字 顏色+% |
5.徑向漸變
background-image:radial-gradient(半徑 at 圓心x 圓心y,color-point1,color-point2,.........) 半徑:px爲單位的數字,色標中寫具體值半徑無效,只有色標中使用%,半徑纔有效 圓心x 圓心y:圓心所在的位置 取值1. x y 以px爲單位的數字 2.x% y% 3.關鍵字 x left/center/right y top/center/bottom |
6.重複漸變
重複線性漸變 background-image: repeating-linear-gradient( to bottom, #000 0px,#ff0 25px, #000 50px); |
重複徑向漸變 background-image:repeating-radial-gradient( 50px at center center,#000 0px,#0ff 10px,#000 20px,#ff0 25px,#000 30px,#0ff 40px,#000 50px); |
7.瀏覽器兼容問題(ie8.0如下不考慮)
漸變屬性,支持低版本瀏覽器的編寫方法 chrome/safari -webkit- firefox -moz- IE -ms- opera -o- background:-webkit-linear-gradient(top,color-point1,color-point2,.....); 有前綴的方向,直接使用top/right/bottom/left 從哪裏開始 沒有前綴,要使用to top/to right/to bottom/to left 向哪一個方向 |
三.文本格式化(重點*****)
1.字體屬性
1.指定字號大小
2.設置字體的類型
3.字體加粗
4.字體樣式
5.小型大寫字母
6.字體屬性簡寫方式
|
一.文本格式化(****)
1.字體屬性
2.文本屬性
1.字體顏色
2.文本對齊方式
3.行高
4.文本線條修飾
5.首行縮進
6.文本陰影
練習:
|
二.表格
1.表格的經常使用屬性
1.table的樣式 以前學習的屬性,基本均可以用
2.td/th的樣式
練習
table特殊的表現方式
3.表格的特有屬性
|
三.定位(**********************)
1.什麼是定位
改變元素在頁面中的位置 |
2.分類
1.普通流定位 2.浮動定位 3.相對定位 4.絕對定位 5.固定定位 |
3.普通流定位(默認文檔流)
1.每一個元素在頁面上都有本身的空間 2.每一個元素都是從父元素的左上角開始顯示 3.塊級元素按照從上到下的方式逐個排列,每一個元素單獨成行 4.行內元素是多個元素在一行中顯示,從左往右逐個排列 |
4.浮動定位(重點***********)
讓塊級元素橫向顯示 float: 取值:1.left左浮動,讓元素浮動後停靠父元素的左邊,或者挨着左側已浮動元素 2.right右浮動,讓元素浮動後停靠父元素的右邊,或者挨着右側已浮動元素 3.none 默認值,無任何浮動 |
浮動的特色 1.元素一旦浮動,脫離文檔流(不佔頁面空間,後面未浮動元素上前補位) 2.浮動元素會停靠在父元素的左邊/右邊,或者其它已浮動元素的邊緣 3.父元素橫向顯示不下全部浮動元素時,最後顯示不下的部分會自動換行 4.浮動解決多個塊級元素在同一行顯示的問題 |
5.浮動引起的特殊狀況
1.浮動元素佔位的問題
2.元素一旦浮動,若是元素未定義寬度,那麼元素的寬度將之內容爲準 3.元素一旦浮動,都會變爲塊級元素
4.文本,行內元素,行內塊,是不會被浮動元素壓在下面的 而是,巧妙的避開,環繞着浮動元素顯示 |
6.清除浮動
元素一旦浮動,會對後續元素帶來影響,後續元素會上前補位 若是後續元素不想上前補位,那麼能夠給後續元素設置清除浮動 clear: 取值:left 清除左浮動的影響 right 清除右浮動的影響 none 不清除 both 清除左和右浮動的影響 |
7.高度坍塌
塊級元素的高度,若是不設置,默認高度是靠內容撐起來的 塊級元素內部,全部元素若是都浮動,塊級元素認爲本身內部沒有元素,全部撐不起來。發生了高度坍塌 |
解決方案: 1.爲父元素設置高度,弊端:不是每次都知道高是多少 2.爲父元素設置浮動 |
一.顯示方式
決定元素在網頁中的表現形式 塊級,行內,行內塊,table |
1.語法
display: 取值:1.block 讓元素的表現和塊級元素一致 2.none 不顯示元素,隱藏 3.inline 讓元素的表現和行內一致 4.inline-block 讓元素的表現和行內塊一致 5.table 讓元素的表現和table一致 |
塊級元素:獨佔一行,能夠設置尺寸,上下外邊距生效 行內元素:共用一行,設置尺寸無效,上下外邊距無效 行內塊:共用一行,設置尺寸有效,上下外邊距有效 table:獨佔一行,容許設置尺寸,尺寸之內容爲準 |
二.顯示效果
visibility 取值:1.visible 默認值,可見的 2.hidden 隱藏,不可見 |
Q:display: none和visibility:hidden的區別 display: none,隱藏,元素脫離文檔流,自己不佔據頁面空間,後面元素會上來補位 visibility:hidden,隱藏,元素不脫離文檔流,在頁面不可見,可是佔據位置 |
三.透明度
opacity 取值 0~1 值越小越透明 |
Q: opacity和rgba的區別 rgba只會改變當前的透明度 opacity,元素內部只要跟元素相關的顏色都會跟着改變透明 |
四.垂直對齊方式
vertical-align: 使用場合: 1.表格中 table/td 取值:top/middle/bottom 2.圖片與文字的排版 img 控制圖片與兩邊文字的垂直對齊方式 取值:取值:top/middle/bottom/baseline(基線,默認值) 一般會將全部的圖片垂直對齊方式,更改成非基線之外的方式 |
五.光標的設置
cursor: 取值:1.default 箭頭 2.pointer 小手 3.crosshair + 4.text 5.wait 等待 6.help 幫助 |
六.列表的樣式
1.列表項標識
list-style-type: 取值 1.none 2.disc 3.circle 4.square |
2.列表項圖像
list-style-image:url(路徑); |
3.列表項的位置
設置列表項在li的外部還內部 list-style-position:inside/outside(默認值); |
4.簡寫方式
list-style:type image position; 最經常使用的寫法 list-style:none;去掉列表項 |
練習,ul>li
|
七.定位---相對、絕對、固定定位
position: 取值:static 默認,靜態(默認文檔流定位) relative 相對定位 absolute 絕對定位 fixed 固定定位 當一個元素被position修飾,而且取值爲 relative/absolute/fixed其中一種時, 那麼這個元素被稱爲已定位元素 |
定位要配合偏移屬性使用 當一個元素有position屬性,並取值爲relative/absolute/fixed 那麼這個元素就解鎖4個偏移屬性,元素距離(方向)有多少px top: +往下 -往上 right: +往左 -往右 bottom: +往上 -往下 left:+往右 -往左 |
1.相對定位
相對誰定位,相對本身原來位置偏移某個距離 position:relative;配合4個偏移屬性使用 特色:1.不脫離文檔流 2.相對定位,若是不寫偏移量,效果與沒寫定位是同樣的。不影響任何佈局(爲了絕對定位作準備)
使用場合: 1.自身元素位置的微調 2.做爲絕對定位子元素的已定位祖先級元素 |
2.絕對定位
position:absolute;配合偏移屬性應用 特色:1.絕對定位的元素會相對於,離本身"最近的""已定位的""祖先元素",去實現位置的初始化 若是沒有已定位的祖先元素,相對於body去實現位置的初始化 2.絕對定位,是脫離文檔流的,不佔據頁面空間,後面元素會上前補位。 3.絕對定位的元素,會變成塊級元素 |
3.固定定位
position:fixed;配合偏移量使用 將元素固定在頁面上的某個位置,不會隨着滾動條發生位置變化,一致固定在可視區域 特色:脫離文檔流,位置相對於body初始化 元素不佔頁面空間 後續元素上前補位 元素變爲塊級 |
4.堆疊順序
1.定位的脫離文檔流和浮動的脫離文檔流不是一個體系 2.默認,後定位的元素,堆疊順序高 3.設置堆疊順序 z-index:無單位數字 4.堆疊順序對父子級無效,兒子永遠在父親的上面 5.只有已定位元素,有堆疊順序 |
八.CSS3 CORE
1.複雜選擇器
1.兄弟選擇器 兄弟元素:具有相同父級元素的平級元素之間稱爲兄弟元素 兄弟選擇器,只能日後找,不能往前找
|
2.屬性選擇器
id class name type value style title 容許經過元素所附帶的屬性及其值來匹配頁面元素,很精準 1.[attr] attr表示任意屬性 做用:匹配頁面中全部帶attr屬性的元素 [id]{} [class]{} 2.elem[attr] 做用:匹配頁面中全部帶有attr屬性的elem元素 div[id]{} 3.elem[attr1][attr2]... 做用:匹配頁面中全部帶有attr1和attr2屬性的元素 p[title][id]{} 4.[attr=value] 做用:匹配頁面中全部帶有attr屬性而且值爲value的元素 5.模糊屬性值 [attr^=value] 匹配屬性值以value開頭的元素 [attr$=value] 匹配屬性值以value結尾的元素 [attr*=value] 匹配屬性值中,有value的元素 [attr~=value] 匹配屬性值中,有value這個獨立單詞的元素 |
3.僞類選擇器
已經學過的僞類 :link :visited :hover :active :focus |
|||||
1.目標僞類 讓被激活錨點,應用樣式 選擇器:target{} |
|||||
2.結構僞類
|
一.複雜選擇器
1.:empty
匹配內部沒有任何元素的標籤 注意:內部不準有空格,文字,元素 |
2.:only-child
匹配屬於其父元素的惟一子元素 <p> <a href="">1</a> </p> a:only-child{ background:#ff0; } |
3.否認僞類
:not(selector) 將知足selector條件的元素排除在外 |
4.僞元素選擇器
1. :first-letter或::first-letter 匹配元素的首字符 2. :first-line或: :first-line 匹配元素的首行 首字符和首行發生衝突時,使用首字符樣式 3. ::selection 必須是兩個: 匹配用戶選取內容的樣式 注意:只能修改文本顏色,背景顏色 |
||
4.僞元素選擇器,內容生成 使用 css命令,添加的html元素,稱之爲僞元素 ::before或者:before 匹配到某元素的內容區域以前的部分 添加一個假的元素,元素內容使用content屬性 元素的顯示方式使用display控制 注意:content中只能添加文本或者url(圖片) ::after或者: after 匹配到某元素的內容區域以後的部分
|
二.彈性佈局(重點*************)
1.什麼是彈性佈局
彈性佈局,是一種佈局方式 主要解決某個元素中子元素的佈局方式 爲佈局提供了很大的靈活性 |
2.彈性佈局的相關概念
1.容器 要發生彈性佈局的子元素,的父元素稱爲容器 就是設置display:flex那個元素 2.項目 要作彈性佈局的子元素們,稱之爲項目 就是設置了display:flex那個元素的,子元素們 3.主軸 項目們排列方向的一條軸,稱之爲主軸 若是項目們是按照橫向排列,那x軸就是主軸 若是項目們是按照縱向排列,那麼y軸就是主軸 項目們排列順序,主軸的起點和終點 4.交叉軸 與主軸垂直相交一條軸,叫作交叉軸 項目們在交叉軸上的對齊方式,是交叉軸的起點和終點 |
3.語法
將元素設置成彈性容器以後,他全部的子元素將變爲彈性項目 都容許按照彈性佈局的方式排列 屬性:display: 取值:1.flex 將塊級元素設置爲容器 2.inline-flex 將行內元素變爲容器 |
特色
1.元素設置爲flex容器以後, 項目的float/clear/vertical-align/text-align屬性失效 2.項目能夠修改尺寸 |
4.容器的屬性
|
5.項目的屬性
只能設置在某一個項目上,不影響其餘項目和容器的效果
|
三.CSS hack
因爲不一樣的瀏覽器對css的解析認知不一樣,會致使同一份css在不一樣瀏覽器生成的頁面效果不一樣 這種狀況,咱們開發人員要針對不一樣的瀏覽器寫不一樣的css 讓咱們樣式能夠兼容不一樣的瀏覽器,正確顯示效果 針對不一樣的瀏覽器寫不一樣的css的過程,就叫作css hack
有些公司,還須要使用css hack
tmooc上有拓展視頻 |
四.轉換(重點*************)
1.什麼是轉換
改變元素在頁面中的位置,大小,角度,以及形狀 2D轉換,只在X軸和Y軸上發生轉換效果 3D轉換,增長了Z軸的轉換效果 |
2.轉換屬性
屬性:transform 取值:1.none 默認值,無任何轉換效果 2.transform-function 表示1個或者多個轉換函數。 若是是多個轉換函數,中間用空格分開 |
3.轉換原點
transform-origin: 取值:以px爲單位數字 % 關鍵字x(left/center/right) y(top/center/bottom) 取值的個數 2個值,表示原點在x軸和y軸上的位置 3個值,表示原點在x軸,y軸和z軸上的位置 默認值:原點在元素的中心位置(center center) |
總結:學習轉換,就是學習transform:後面的轉換函數
4.2D轉換
1.位移(改變元素的位置) 轉換函數:translate() 取值:1. translate(x)指定元素在x軸上的位移距離 + 元素往右 - 元素往左 2. translate(x,y)指定元素在x軸和y軸上的位移距離 x:+ 元素往右 - 元素往左 y: + 元素往下 - 元素往上 3. translateX (x); 指定元素在x軸上的位移距離 4. translateY (y);指定元素在y軸上的位移距離 |
一.轉換
1.2D轉換
1.位移 translate(),改變元素的位置 2.縮放,改變元素的大小
3.旋轉,改變元素的角度
4.傾斜
練習:
|
2.3D轉換
3D轉換是模擬的 1.透視距離
2.3d旋轉
|
二.過渡(重點******)過渡是動畫的前身
1.什麼是過渡
讓css的值,在一段時間內平緩變化的效果 |
2.語法
1.指定過渡屬性
2.指定過渡時長
3.過渡的時間曲線函數
4.過渡的延遲時間
5.過渡代碼編寫的位置
6.過渡的簡寫形式
練習
|
三.動畫
1.什麼是動畫
使元素從一種樣式逐漸變爲另外一種樣式 其實就是將多個過渡效果放到一塊兒 |
2.使用關鍵幀,來控制動畫的每個狀態
關鍵幀 1.動畫執行的時間點 2.在這個時間點上的樣式 |
3.動畫的使用步驟
1.使用關鍵幀聲明動畫
2.調用動畫
3.動畫的其餘屬性
|
4.動畫的兼容性
若是要兼容低版本瀏覽,須要在動畫聲明的時候加前綴 @keyframes 動畫名稱{} @-webkit-keyframes 動畫名稱{} @-ms-keyframes 動畫名稱{} @-o-keyframes 動畫名稱{} @-moz-keyframes 動畫名稱{} |
三.CSS優化
css優化目的 1.減小服務器端壓力 2.提高用戶體驗 |
1.CSS優化的原則
儘可能的減小http的請求個數 頁面的頂部,引入css文件 將css和js文件放到外部的獨立文件中 |
2.CSS代碼優化
合併樣式(能寫羣組,就不單寫,能用簡寫方式,就不單獨定義屬性) 縮小樣式文件的大小(能重用就重用) 減小樣式重寫 避免出現空的href和src 選擇更優的樣式屬性值 代碼壓縮 |
四.Bootstrap
1.響應式佈局(css3 2010)
1.什麼是響應式網頁 Responsive web page 響應式/自適應網頁 能夠根據瀏覽設備不一樣(pc,pad,phone) 而自動改變佈局,圖片,文字效果,不會影響用戶瀏覽體驗 |
2.響應式網頁必須作下面幾件事
1.佈局,不能固定元素寬度,必須是流式佈局(默認文檔流+浮動) 2.文字和圖片大小隨着容器的大小改變 3.媒體查詢技術 響應式網頁存在的問題:代碼複雜程度幾何性的增長 複雜網頁,不適合使用響應式 |
3.如何測試響應式網頁
1.使用真實設備 好處:真實可靠 缺點:成本高,測試任務巨大 2.使用第三方模擬軟件測試 好處:不須要太多真實設備,測試方便 壞處:測試效果有限,有待進一步驗證 3.使用chrome等瀏覽器自帶的模擬軟件 好處:簡單方便 壞處:測試效果有限,須要進一步驗證 |
4.編寫響應式佈局(重點********)
1.手機適配,在meta中聲明viewport元標籤 <meta name="viewport" content=" width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0 "> 在content,編寫參數 width=device-width, 設置視口寬度爲設備寬度 initial-scale=1.0, 設置視口的寬度可否縮放 1.0不能縮放 maximum-scale=1.0, 容許縮放的最大倍率 user-scalable=0 是否容許用戶手動縮放 0 不能 |
||
最簡潔的寫法 <meta name="viewport" content="width=device-width, initial-scale=1"> |
||
2.全部的內容/文字/圖片都使用相對尺寸,不使用絕對值 |
||
3.流式佈局+彈性佈局+媒體查詢 完成響應式佈局 |
||
4.媒體查詢,CSS3 Media Query,作響應式必備技術
語法總結
|
做業:
1.使用動畫完成時鐘效果
2.使用媒體查詢完成下面圖示
https://daneden.github.io/animate.css/ 定義好的動畫,在項目中直接使用 |
一.BootStrap
boot給咱們封裝好不少經常使用的樣式,咱們只須要調用類名 可是在項目中,對於不少樣式,咱們仍是須要手寫樣式和媒體查詢 |
BootStrap內容分爲5部分 1.如何使用boot 2.全局css 3.組件 4.js插件 5.定製 sass 6.boot項目 |
1.如何使用boot
<meta name="viewport" content="width=device-width,initial-scale=1"/> |
2.全局CSS樣式
container
container-fluid
1.按鈕相關的class
2.圖片相關
3.文字相關
4.列表相關的class
5.table相關的樣式
|
3.輔助類
1.邊框
2.浮動
3.顯示
4.背景顏色
5.圓角
6.內外邊距
7.尺寸
|
4.柵格佈局(重點********************************)
1.web頁面的佈局方式通常三種
2.柵格使用
3.響應式柵格
|
一.柵格佈局
.container--->row--->col row的直接子元素只能是col 一個row分爲12份,使用col-n來控制子元素佔地幾份 <div class="container"> <div class="row"> <div class="col-lg-3 col-md-6 col-sm-12"></div> <div class="col-lg-3 col-md-6 col-sm-12"></div> <div class="col-lg-3 col-md-6 col-sm-12"></div> <div class="col-lg-3 col-md-6 col-sm-12"></div> </div> </div> |
使用.col類,不添加數字時,自動處理佈局 每個col平均分配空間,col個數能夠超過12個 |
注意:,不一樣屏幕有向上兼容的問題 col-xl-* 只能在xl屏幕有效 col-lg-* 在xl/lg 有效 col-md-*在xl/lg/md 有效 col-sm-*在xl/lg/md/sm 有效 |
列偏移 能夠經過列偏移指定該列及後面的列向右移動 offset-*-n *: xl/lg/md/sm |
柵格嵌套 在col中從新寫一個div.row |
二.彈性佈局
d-block/inline/inline-block/none display全部值 d-*- block/inline/inline-block/none display的響應式 *:xl/lg/md/sm |
||
使用彈性佈局,要在父元素上寫class d-flex d-flex/d-inline-flex建立一個彈性容器 1.主軸方向
2.項目在主軸上的排列方式
boot對彈性佈局,作了響應式封裝 讓開發者很是靈活的作響應式佈局 |
三.表單
1.表單元素的排列方向 form-group 堆疊表單,垂直方向 form-inline 內聯表單,水平方向(彈性佈局) 2.表單元素的樣式class form-control 是input元素的基本類 塊級,w100,字體,背景,邊框,過渡 col-form-label 設置輸入文本與邊框的距離 col-form-label-sm 距離較小 col-form-label-lg 距離較大 對於checkbox的樣式 父級.form-check 相對定位,讓子元素以父級定位 <input checkbox>的class form-check-input 絕對定位,要和. form-check配合使用 .form-text 塊級,有上外邊距 |
四.組件
網頁中一些複雜的特殊效果,以前必須使用js、dom、jq 如今boot爲咱們封裝好了不少組件,咱們能夠直接使用 方便,快捷。可是若是須要個性化的處理,比較繁瑣 boot中,大量使用元素的自定義屬性,來調用方法 |
1.下拉菜單
基本結構 <div class="dropdown"> <button class="dropdown-toggle" data-toggle="dropdown"></button> <ul class="dropdown-menu"></ul> </div> .dropdown-toggle 畫三角 .dropdown-menu 隱藏 data-toggle="dropdown"自定義屬性兩個做用 1.當button被點擊時,激活事件 2.激活的事件,是以dropdown的方式運行 |
2.按鈕組
外層div中class以下幾個值 .btn-group 橫向按鈕組 .btn-group-vertical 縱向按鈕組 能夠添加 btn-group-sm/lg調整按鈕組大小
|
3.信息提示框
外層div的class alert 基本類 alert-danger/warning......提示框顏色 alert-dismissible 爲了修飾內部.close 內層 span,取消信息提示框的小叉叉 .close,與父元素的. alert-dismissible配合使用 自定義屬性 data-dismiss="alert" |
4.導航
1.水平導航
2.選項卡導航
3.膠囊導航
|
5.導航欄
最外層div.navbar . navbar-expand-lg/md/sm/xl 做爲子元素ul.navbar-nav的後代選擇器路徑, 構成響應式導航欄 內層ul.navbar-nav 彈性,默認主軸column 如何改變主軸方向,配合父級navbar-expand-lg/md/sm/xl 在屏幕寬度足夠的時候,橫向顯示項目, 在屏幕寬度不夠的時候,縱向顯示,構成響應式導航欄 li.nav-item a.nav-link |
一.組件
1.導航欄
<div class="navbar navbar-expand-lg bg-dark"> div.navbar-expand-* 配合 ul.navbar-nav 在不一樣屏幕下,讓導航橫向或者縱向顯示 |
2.摺疊效果
<button data-toggle="collapse" data-target="#demo"> 摺疊</button> <div class="collapse" id="demo">內容</div> 總結:a標籤和button標籤均可以綁定,指向元素 a使用的是href="#id" button使用的是data-target="#id" |
3.卡片
<div class="card"> <a class="card-link" href="#">標題</a> |
4.手風琴:卡片+摺疊
<div id="parent"> 注意事項: 1..collapse不能和.card-body在同一個標籤上, 否則會發生隱藏/顯示的卡頓 解決方案div.collapse>div.card-body 2.幾個摺疊部分,能夠同時打開,而不能開啓一個,其它的都關閉 解決方案,在最外層div上寫id="parent" 在全部div.collapse中添加事件的綁定data-parent="#parent" 這樣就能夠保證在最外層div中,只有一個摺疊區域能夠打開了 |
5.摺疊導航欄
<div class="navbar navbar-expand-sm bg-dark navbar-dark"> 緣由:這個div自己有.collapse,做用是隱藏 .navbar-collapse配合父級的navbar-expand-sm 讓當前div的display爲flex,再也不是none, 此div就顯示 2.不隱藏的a標籤,要寫a.navbar-brand 字體變大,上下內邊距,右外邊距 3.按鈕的樣式使用button.navbar-toggler。這是boot專門爲摺疊導航提供的按鈕樣式,此樣式與navbar-expand-sm配合,實現小屏如下按鈕顯示,小屏以上按鈕隱藏 4.最外層div.navbar-dark/light.這個類對當前div沒有任何樣式的操做.他存在的意義,把內部的按鈕和文字,設置成背景的反色。 因爲他自己不對當前div有樣式修改,全部當前div須要添加對應的背景色bg-dark/light |
6.媒體對象
Boot提供了不少類,來處理媒體相關的對象(圖片,影音) <div class="media border p-3">
|
7.焦點輪播圖(輪播時間須要去修改js的代碼)
1.最外層大包裹和輪播圖片 <div class="carousel" data-ride="carousel"> 結構 div.carousel 相對定位 >div.carousel-inner w100 溢出隱藏 >div.carousel-item display:none >img 事件:給最外層div div.carousel添加自定義屬性data-ride="carousel" 而後給某一個 div.carousel-item添加類 .active 這樣輪播圖片就開始運動了 |
2.錄播指示符 <!--3.輪播指示符--> 結構 ul.carousel-indicators>li 對ul的樣式,定位,彈性 .carousel-indicators對後代li的樣式 li的寬高,li背景,li的位置 咱們能夠按照本身的需求,重寫這部分樣式 .carousel-indicators li{ 此外,.carousel-indicators .active 讓當前激活的li變成白色 咱們要重寫此樣式 .carousel-indicators .active{ |
3.左右箭頭 <a data-slide="next" href="#demo" class="carousel-control-next">
結構 兩個a標籤 a.carousel-control-prev/next 這個樣式設置了a的寬度,背景色,位置 咱們須要重寫此樣式 .carousel-control-prev, 自定義屬性 data-silde="next/prev" 注意要寫href="#demo" |
8.模態框
模態框modal是覆蓋在父窗體上的一個子窗體 模態框能夠在不離開父窗體的狀況下與用戶有一些互動 <div id="mymodal" class="modal">
|
二.其餘組件
1.徽章
基本類 badge 顏色 badge-danger/warning/success... 徽章的樣式 badge-pill 膠囊 |
2.巨幕
巨大的內邊距,有背景顏色,和圓角 class="jumbotron" |
3.分頁
ul.pagination>li.page-item>a.page-link li的修飾類 .active 激活 .disabled 禁用 |
4.麪包屑導航
ul.breadcrumb>li.breadcrumb-item 中間的鏈接符號須要本身重寫樣式 .breadcrumb-item + .breadcrumb-item::before{ |
5.進度條
div.progress>div.progress-bar+w-50+bg-danger 子div設置w寬度,就是進度條進度 子div設置背景,就是進度的顏色 子div設置條紋 progress-bar-striped 子div設置動畫 progress-bar-animated 能夠在同一個div.progress中寫多個div.progress-bar |
bootstrap重點:響應式+柵格佈局+SCSS
三.SCSS,動態的樣式語言 (nodejs 8.11以上)
1.css有如下幾個缺點
語法不夠強大,沒有變量和合理的樣式複用機制 致使難以維護 咱們要使用動態樣式語言,賦予css新的特性 提升樣式語言的可維護性 |
常見的動態樣式語言 1.scss/sass (scss兼容sass,scss更接近css語法) 2.stylus 3.Less |
一.scss boot的訂製
SCSS是一款強化css的輔助工具 它和css的語法很像,在CSS的基礎上,添加了變量,嵌套,混合,導入,函數等高級功能。這些拓展命令讓css更增強大與優雅 |
瀏覽器不能直接解析運行scss文件,須要在項目中把scss轉義成css文件。讓瀏覽器解析。 |
scss可讓css開發更高效 |
1.SCSS的使用
scss在服務器端使用 1.安裝nodejs解釋器 v8.11以上 2.在線安裝scss 在cmd控制檯打印命令 npm install -g node-sass 3.無網絡的安裝 node-sass -v 4.測試是否安裝正確 cmd中打印 node-sass -v 顯示版本 |
2.SCSS文件轉換成CSS文件
1.單文件轉換 node-sass scss/01.scss css/01.css scss/01.scss 要轉換的scss文件名和目錄 css/01.css 轉換後的css文件名和目錄 保證執行命令的路徑是scss/01.scss 的父級 能夠在電腦中打開項目的路徑,在路徑文件夾下 按住shift點擊鼠標右鍵,打開powershell窗口 輸入上面命令 10:05~10:20休息 |
2.多文件轉換,文件夾轉換(一個命令把一個文件夾下全部的.scss都轉換) node-sass scss(文件夾名稱) -o css(文件夾名稱) |
3.單文件監聽 node-sass -w scss/01.scss css/01.css 開啓,系統會盯着01.scss文件,當01.scss內容發生改變,保存的時候,自動轉換爲01.css |
4.多文件夾監聽 node-sass -w scss -o css |
3.SCSS基礎語法
1.變量
2.嵌套
3.導入
4.混合器
5.繼承
|
4.運算
1.數字
2.顏色運算
|
三.函數
1.scss定義了不少函數,有些函數甚至能夠直接在css語句中調用
rgba(r,g,b,alpha) hsl(h,s,l) h:hue色調 取值0~360,3個色段,120一個 s:saturation 飽和度 0.0%~100.0% l:lightness 亮度 0.0%~100.0% |
2.數學函數
round($val) 四捨五入 ceil($val) 向上取整 floor($val) 向下取整 min($v1,$v2.....) max($v1,$v2.....) random 隨機數 |
3.字符串函數
unquote($str) 去掉$str的雙引號 quote($str) 給$str添加雙引號 to_upper_case($str); $str變大寫 to_lower_case($str); $str變小寫 |
4.自定義函數
@function get-width($n,$m){ @return $n - $m; } |
練習
定義一個帶參數的函數get_mywidth($n) 函數內定義兩個變量分爲60px和10px 函數返回值爲 $n乘以兩個變量的最大值,再加上$n乘以倆個變量的最小值。將結果賦值給div的width屬性 |
四.指令
@if(){} @else if(){} @else{} 注意:bool值的小括號能夠去掉 |
練習
聲明一個帶參的函數,函數中判斷參數 參數大於1,返回200px 參數等於1,返回100px 參數小於1,返回0 把返回賦值給div的width |
張東
微信: 18301092802
準備:
1. 書: 犀牛書 JavaScript權威指南
2. 微信公衆號: 前端大全
3. 上一屆的筆記: 打印出來
千萬不要記筆記!!!
概述:
JavaScript核心編程: 閉包,面向對象,ES5,ES6,異步編程
DOM: 爲網頁添加交互行爲的一套程序——全部場合使用!
jQuery: DOM的簡化版——PC
Vue: 自動化的框架
React:
正課:
1. 正則表達式
2. String中的正則API:
1. 正則表達式:
2. String中的正則表達式:
查找敏感詞: 4種:
1. 查找一個固定的敏感詞出現的位置
var i=str.indexOf("敏感詞",starti)
在str中,從starti位置開始,找下一個敏感詞出現的位置
返回值: 若是找到,返回敏感詞第一個字的下標
若是沒找到,返回-1
問題: 只能查找一個固定的敏感詞,不支持正則!
2. 模糊查找一個敏感詞的位置:
var i=str.search(/正則/i)
在str中查找符合正則要求的第一個敏感詞出現的位置
返回值: 若是找到,返回敏感詞第一個字的下標
若是沒找到,返回-1
問題: 正則表達式默認區分大小寫
解決: 在正則第二個/後加後綴i, 表示ignore
問題: 只能返回位置,不能返回內容
3. 查找敏感詞內容
2種:
1. 只查找一個敏感詞的內容:
var arr=str.match(/正則/i)
在str中查找第一個敏感詞的[內容和位置]
返回值:
若是找到,返回一個數組:
["0":敏感詞內容, "index": 下標i ]
若是沒找到,返回null
數組:關聯數組和索引數組
js底層一切都是關聯數組,沒有堆和棧
每一個案例三遍:
1. 代碼+註釋抄一遍
2. 保留註釋,刪除代碼,本身試着把代碼填回來
3. 都刪掉,嘗試將註釋和代碼一塊兒寫回來——本身會了
註釋最重要!
正課:
1. String正則API
2. RegExp對象
3. ***Function對象
1. String正則API
查找:4種場景
1. 查找一個固定的關鍵詞出現的位置:
var i=str.indexOf("敏感詞",starti)
2. 用正則表達式模糊查找關鍵詞的位置:
var i=str.search(/正則/i)
3. 查找關鍵詞的內容:
1. 只查找第一個關鍵詞的內容:
var arr=str.match(/正則/i)
arr:["0": 關鍵詞內容, "index": 下標i ]
問題: 只能找一個敏感詞
2. 查找全部敏感詞的內容:
var arr=str.match(/正則/ig) global
arr:[ 敏感詞1, 敏感詞2, ... ... ]
返回全部找到的敏感詞內容的列表
若是找不到返回null
強調: 凡是返回null的函數,都要先判斷不是null,再使用。
4. 既查找全部關鍵詞的內容,又能得到每一個關鍵詞的位置
reg.exec()
替換: 2種:
1. 簡單替換: 將全部敏感詞都替換爲一致的新值
str=str.replace(/正則/ig,"新值")
2. 高級替換: 根據本次找到的敏感詞的不一樣,動態選擇不一樣的新值替換
str=str.replace(
/正則/ig,
//replace每找到一個敏感詞,就自動調用一次回調函數
function(kword){ kword: y c y u
形參kword,自動得到本次找到的敏感詞內容
return 返回的新值
kword.toUpperCase()
}// return Y C Y U
)
回調函數callback:我們負責定義函數,而後將函數交給別的程序去自動執行。
特色: 1. 不必定馬上執行
2. 不止執行一次,可能反覆執行
3. 自動傳入參數
衍生: 刪除敏感詞: ——做業:
其實就是將敏感詞替換爲""
str=str.replace(/正則/ig,"")
切割: 將字符串按指定的分隔符,分割爲多段子字符串
如何:
2種:
1. 簡單切割: 分隔符是固定不變的
var arr=str.split("分隔符")
固定套路: 打散字符串爲字符數組(按""切割)
var arr=str.split("")
2. 複雜切割: 分隔符不固定
var arr=str.split(/正則/)
2. RegExp對象:
什麼是: 專門保存一條正則表達式,並提供用正則表達式執行查找和驗證操做的方法。
什麼時候: 只要在js中使用正則表達式,都要建立正則表達式對象
如何:
建立: 2種:
1. 用/方式:
var reg=/正則/ig;
問題: 不能在程序運行時,動態拼接正則,只能預先寫死正則。
2. 用new:
var reg=new RegExp("正則","ig")
優點: 可在運行時動態拼接正則字符串
功能:
1. 驗證:
var bool=reg.test(str)
驗證str是否符合reg的格式要求
問題: 並非徹底匹配。只要在str中找到部份內容和reg匹配,就返回true!
解決: 要求從頭至尾完整匹配
從此只要作驗證,必須前加^,後加$
2. 查找: 查找全部敏感詞的內容和位置
var arr=reg.exec(str)
在str中找下一個符合reg要求的敏感詞的內容和位置
返回值: 同match不加g時同樣
arr:[ "0": 敏感詞內容, "index": 下標i ]
3. Function對象:
什麼是: 保存一段可重用的代碼段的對象,再起一個名字
爲何: 重用一段代碼
什麼時候: 只要發現一段代碼須要反覆使用時,都要定義爲一個函數。
如何:
1. 聲明方式:
function 函數名(形參列表){
函數體;
return 返回值;
}
var 返回值=函數名(實參列表)
問題: 會被聲明提早:
2. 用賦值方式:
var函數名=function (形參列表){
函數體;
return 返回值;
}
正課:
1. Function對象
2. 面向對象
1. Function對象
建立: 3種:
1. 聲明方式:
function 函數名(形參列表){
函數體;
return 返回值
}
會被聲明提早
2. 賦值方式:
var函數名=function (形參列表){
函數體;
return 返回值
}
不會被聲明提早
揭示: 函數其實也是一個對象
函數名其實只是一個簡單的變量
3. 用new:
var 函數名=new Function("形參1","形參2",...,"函數體")
重載overload:
什麼是: 相同函數名,不一樣形參列表的多個函數,在調用時可根據傳入參數的不一樣,自動選擇匹配的函數執行。
爲何: 減小函數的個數,減輕調用者的負擔
什麼時候: 一件事,可能根據傳入的參數不一樣,選擇執行不一樣的操做時
如何:
問題: js語言默認不支持重載的語法
由於js不容許多個同名函數同時存在
若是同時存在,只有最有一個會覆蓋以前全部
解決: 用arguments對象變通實現
arguments: 每一個函數中自帶的接收全部實參值的類數組對象
每一個函數: 全部函數中都有arguments對象
自帶: 不用本身建立,直接使用
做用: 接收全部實參值
數據結構: 類數組對象——長的像數組的對象
相同: 1. 下標 2. length 3. for循環遍歷
不一樣: 類型不一樣——類數組對象是對象家孩子,無權使用數組家的API
匿名函數:
什麼是: 定義函數時,不起名的函數,稱爲匿名函數
爲何: 節約內存!
什麼時候: 只要一個函數,只使用一次時,都要用匿名函數,而不是有名稱的函數
如何: 2種:
1. 回調函數:
好比: setInterval/setTimeout(function(){...},1000)
arr.sort(function(a,b){return a-b})
str.replace(/正則/ig,function(kw){ ... })
2. 匿名函數自調: 也稱爲當即調用函數IIF
什麼是: 定義一個匿名函數,而後馬上執行
爲何: 臨時建立一個函數做用域,避免使用全局變量
什麼時候: 從此全部的js代碼,都要放在一個巨大的匿名函數自調中。
(function(){
本身的功能代碼
})()
做業:
1. function fun(){
var n=999;
nAdd=function(){ n++ };
return function(){
console.log(n);
}
}
var getN=fun();
getN()//?
nAdd()
getN()//?
2. function fun(){
for(var i=0,arr=[]; i<3;i++){
arr[i]=function(){ console.log(i); }
}
return arr;
}
var funs=fun();
funs[0]();//?
funs[1]();//?
funs[2]();//?
正課:
1. 面向對象:
什麼是成員變量: 在對象中,函數裏面的變量是成員變量
Var lilei={
Sname:lilei,
Sage: 12
Iintr : Function (){
這裏面的是成員變量
}
}
1. 面向對象:
什麼是: 程序中都是用對象結構來描述現實中的事物
爲何: 便於大量數據的維護
什麼時候: 全部程序都是用面向對象的思想管理數據和功能
如何: 面向對象三大特色: 封裝,繼承,多態
1. 封裝:
什麼是: 建立一個對象結構,保存一個事物的屬性和功能
爲何: 便於大量數據的維護
什麼時候: 從此全部數據都是先封裝在對象中,再按需使用
如何: 3種:
1. 用{}建立一個對象:
var 對象名={
屬性: 屬性值,
... : ... ,
功能: function(){
... this.屬性名 ...
}
}
訪問對象的成員: 成員=屬性+方法
訪問屬性: 對象名.屬性
調用方法: 對象名.方法()
問題: 對象本身的方法內,想訪問本身的屬性,也不能直接屬性,報錯: 屬性 未定義
爲何: 對象的屬性沒有直接保存在一個函數的做用域鏈中,而引擎不能擅自進入對象中獲取數據。
解決一: 對象名.屬性/方法
問題: 緊耦合: 對象名發生變化,必須同時改內部的對象名,一旦忘改,就出錯!
解決二: 鬆耦合: 能不能自動得到對象名——this
什麼是this: 正在調用當前函數的.前的對象
每一個函數與生俱來的關鍵詞,可自動得到.前的對象
鄙視時: this只和調用時.前的對象有關,和保存在哪兒毫無關係!
若是一個函數前沒加任何.,默認是window.
總結: 什麼時候: 只要對象本身的方法內,想使用對象本身的屬性和其它方法時,都必須用this.
2. 用new: 2步: 同關聯數組的建立過程
var obj=new Object(); //obj:{}
obj.屬性名=值;
obj.方法名=function(){ ... }
Obj.sname=」li lei」
揭示了: js底層全部對象都是關聯數組
vs 關聯數組相比:
相同:
1. js中的對象,可隨時添加新屬性和新方法,而不會報錯!
2. 訪問對象中不存在的屬性,不會報錯,而是返回undefined
3. 訪問對象中的成員,有兩種方式:
簡寫: 對象名.屬性名/方法名()
// ||等效
什麼時候: 若是要訪問的屬性名是寫死的
完整: 對象名["屬性名"]/["方法名"] ()
什麼時候: 若是要訪問的屬性只能在運行時動態得到
4. 對象也能夠用for in遍歷每一個屬性
缺點: 一次只能建立一個對象,若是反覆建立多個相同結構的對象時,代碼會很繁瑣。
解決: 構造函數
3. 用構造函數反覆建立多個相同結構的對象
什麼是構造函數: 專門描述一類對象統一結構的函數
什麼時候: 只要反覆建立多個相同結構的對象
如何: 2步:
1. 定義構造函數:
function 類型名(形參1, 形參2, ... ){
this.屬性名=形參1;
... = ...;
this.方法名=function(){ ... this.屬性名 ...}
}
2. 用構造函數建立多個對象:
用new調用構造函數,建立出規定格式和功能的對象
var 對象名=new 類型名(屬性值,屬性值,...)
鄙視題: new的原理: 4件事:
1. 建立一片空的存儲空間
2.
3. 用新的空對象做爲主語調用構造函數
new Student(屬性值,...)
=> new.Student(屬性值,...) this->new{}
↓
=> this.屬性名=形參
↓
=>new{}.屬性名=屬性值
在new{}中強行添加該新屬性,並將屬性值保存進對象中——野蠻的強行賦值方式
結果: new{}中就反覆添加了規定的新屬性和方法
4. 返回新對象的結果
凡是不帶前綴的變量,只能在做用域鏈中查找 好比console.log (a)
Day05
正課:
1. OOP
2. ES5
1. OOP
三大特色: 封裝,繼承,多態
封裝:
3. 用構造函數反覆建立多個相同結構的對象:
function Student(sname,sage){
this.sname=sname;
this.sage=sage;
this.intr=function(){
console.log(`I'm ${this.sname},I'm ${this.sage}`);
}
}
//用new建立:
var lilei=new Student("Li Lei",11);
var hmm=new Student("Han Meimei",12);
console.log(lilei);
console.log(hmm);
lilei.intr();
hmm.intr();
問題: 將方法的定義放在構造函數內,會重複建立多個相同函數的副本,浪費內存。且,不便於維護。
解決: 1. 構造函數中不要包含方法定義
2. 將方法定義放在共同的爹中,讓全部孩子共用!
繼承:
什麼是繼承: 父對象中的成員,子對象無需重複建立,就可直接使用。
爲何繼承: 代碼重用,節約內存
什麼時候繼承: 多個孩子對象,都擁有相同的方法定義時,就要用繼承,將方法保存在爹中,全部孩子自動共用。
如何實現繼承: js中的繼承都是自動繼承原型對象
什麼是原型對象: 在一個類型的你們庭中,集中保存全部孩子對象共用的成員的父對象
如何使用原型對象:
建立: 不用本身建立!買一贈一!
當建立構造函數(媽媽)時,自動附贈了一個原型對象(爹)
繼承: 不用本身繼承, new的第二步
讓新建立的子對象,自動繼承構造函數的prototype(爹)
向原型對象中添加共有成員: 須要本身作
Student.prototype.intr=function(){ ... }
媽媽 的 老公
如何使用原型對象中的共有成員:
用子對象調用共有成員:
var lilei=new Student(... ...);
lilei.intr()
//如今lilei裏找,若是找到,就先用本身的
//若是沒找到,才延_ _proto_ _屬性先父對象中查找,只要找到,可直接使用,無需重複建立。
自有屬性和共有屬性:
什麼是自有屬性: 保存在子對象本地,僅當前子對象本身全部的屬性
什麼是共有屬性: 保存在父對象中,全部子對象共有的屬性
讀取屬性值: lilei.sname lilei.className
不管自有屬性仍是共有屬性均可用子對象來讀取
修改屬性時: 若是修改自有屬性,可用子對象修改
lilei.sage++;
若是修改共有屬性: 只能用原型對象,不能用子對象修改共有屬性。
若是強行用子對象修改共有屬性,結果:會爲當前子對象我的添加一個同名的自有屬性。今後,該子對象與其餘子對象分道揚鑣。—— 錯誤的效果!
應該: 只要修改共有屬性,必須用原型對象親自改
Student.prototype.className="初三2班"
lilei.__proto__.intr() I'm undefined, I'm undefined
lilei.intr() I'm Li Lei, I'm 11
原型鏈:
什麼是: 由多級原型對象,逐級繼承,造成的鏈式結構
2個做用:
1. 存儲着一個對象可用的全部屬性和方法
2. 控制着成員的使用順序: 先自有,再共有
vs 做用域鏈:
2個做用:
1. 存儲着全部不用.就可訪問的變量
2. 控制着變量的使用順序,先局部,後全局
js內置類型: 11種:
Number String Boolean
Array Date RegExp Math
Error
Function Object
global(在瀏覽器中被改名爲window)
自定義繼承:
什麼時候: 若是默認的爹不是想要的,可更改
如何: 2種:
1. 僅修改一個對象的父對象:
child.__proto__=father
設置child的爹爲father
Object.setPrototypeOf(child, father)
2. 同時更換多個子對象的爹
更換媽媽的老公
Student.prototype=father
講究時機: 必須在建立子對象以前換!
多態:
什麼是: 一個函數在不一樣狀況下表現出不一樣的狀態
包括2種狀況:
1. 重載
2. 重寫(override):
什麼是: 若是子對象以爲從父對象繼承來的成員很差用,可在子對象本地建立同名成員,覆蓋父對象中的成員。使用時,只要本身有,就先用本身的。
什麼時候: 以爲從父對象繼承來的成員很差用
如何: 只要在對象本地定義與父對象中同名的成員,便可。
2. ES5:
ECMAScript 第5個版本
1. 嚴格模式:
什麼是: 比普通js運行機制,要求更嚴格的模式
爲何: js語言自己具備不少廣受詬病的缺陷
什麼時候: 從此全部的js程序,必須運行在嚴格模式下!
如何:
在當前做用域的頂部寫:"use strict";——啓用嚴格模式
規定:
1. 禁止給未聲明變量賦值:
2. 靜默失敗升級爲錯誤:
什麼是靜默失敗: 執行不成功,但還不報錯。
ES5中規定,全部靜默失敗,都升級爲報錯!
3. 匿名函數自調和普通函數調用中的this,再也不指向window!而是this=undefined。
張東
微信: 18301092802
準備:
1. 書: 犀牛書 JavaScript權威指南
2. 微信公衆號: 前端大全
3. 上一屆的筆記: 打印出來
千萬不要記筆記!!!
概述:
JavaScript核心編程: 閉包,面向對象,ES5,ES6,異步編程
DOM: 爲網頁添加交互行爲的一套程序——全部場合使用!
jQuery: DOM的簡化版——PC
Vue: 自動化的框架
React:
正課:
1. 正則表達式
2. String中的正則API:
1. 正則表達式:
2. String中的正則表達式:
查找敏感詞: 4種:
1. 查找一個固定的敏感詞出現的位置
var i=str.indexOf("敏感詞",starti)
在str中,從starti位置開始,找下一個敏感詞出現的位置
返回值: 若是找到,返回敏感詞第一個字的下標
若是沒找到,返回-1
問題: 只能查找一個固定的敏感詞,不支持正則!
2. 模糊查找一個敏感詞的位置:
var i=str.search(/正則/i)
在str中查找符合正則要求的第一個敏感詞出現的位置
返回值: 若是找到,返回敏感詞第一個字的下標
若是沒找到,返回-1
問題: 正則表達式默認區分大小寫
解決: 在正則第二個/後加後綴i, 表示ignore
問題: 只能返回位置,不能返回內容
3. 查找敏感詞內容
2種:
1. 只查找一個敏感詞的內容:
var arr=str.match(/正則/i)
在str中查找第一個敏感詞的[內容和位置]
返回值:
若是找到,返回一個數組:
["0":敏感詞內容, "index": 下標i ]
若是沒找到,返回null
數組:關聯數組和索引數組
js底層一切都是關聯數組,沒有堆和棧
每一個案例三遍:
1. 代碼+註釋抄一遍
2. 保留註釋,刪除代碼,本身試着把代碼填回來
3. 都刪掉,嘗試將註釋和代碼一塊兒寫回來——本身會了
註釋最重要!
正課:
1. String正則API
2. RegExp對象
3. ***Function對象
1. String正則API
查找:4種場景
1. 查找一個固定的關鍵詞出現的位置:
var i=str.indexOf("敏感詞",starti)
2. 用正則表達式模糊查找關鍵詞的位置:
var i=str.search(/正則/i)
3. 查找關鍵詞的內容:
1. 只查找第一個關鍵詞的內容:
var arr=str.match(/正則/i)
arr:["0": 關鍵詞內容, "index": 下標i ]
問題: 只能找一個敏感詞
2. 查找全部敏感詞的內容:
var arr=str.match(/正則/ig) global
arr:[ 敏感詞1, 敏感詞2, ... ... ]
返回全部找到的敏感詞內容的列表
若是找不到返回null
強調: 凡是返回null的函數,都要先判斷不是null,再使用。
4. 既查找全部關鍵詞的內容,又能得到每一個關鍵詞的位置
reg.exec()
替換: 2種:
1. 簡單替換: 將全部敏感詞都替換爲一致的新值
str=str.replace(/正則/ig,"新值")
2. 高級替換: 根據本次找到的敏感詞的不一樣,動態選擇不一樣的新值替換
str=str.replace(
/正則/ig,
//replace每找到一個敏感詞,就自動調用一次回調函數
function(kword){ kword: y c y u
形參kword,自動得到本次找到的敏感詞內容
return 返回的新值
kword.toUpperCase()
}// return Y C Y U
)
回調函數callback:我們負責定義函數,而後將函數交給別的程序去自動執行。
特色: 1. 不必定馬上執行
2. 不止執行一次,可能反覆執行
3. 自動傳入參數
衍生: 刪除敏感詞: ——做業:
其實就是將敏感詞替換爲""
str=str.replace(/正則/ig,"")
切割: 將字符串按指定的分隔符,分割爲多段子字符串
如何:
2種:
1. 簡單切割: 分隔符是固定不變的
var arr=str.split("分隔符")
固定套路: 打散字符串爲字符數組(按""切割)
var arr=str.split("")
2. 複雜切割: 分隔符不固定
var arr=str.split(/正則/)
2. RegExp對象:
什麼是: 專門保存一條正則表達式,並提供用正則表達式執行查找和驗證操做的方法。
什麼時候: 只要在js中使用正則表達式,都要建立正則表達式對象
如何:
建立: 2種:
1. 用/方式:
var reg=/正則/ig;
問題: 不能在程序運行時,動態拼接正則,只能預先寫死正則。
2. 用new:
var reg=new RegExp("正則","ig")
優點: 可在運行時動態拼接正則字符串
功能:
1. 驗證:
var bool=reg.test(str)
驗證str是否符合reg的格式要求
問題: 並非徹底匹配。只要在str中找到部份內容和reg匹配,就返回true!
解決: 要求從頭至尾完整匹配
從此只要作驗證,必須前加^,後加$
2. 查找: 查找全部敏感詞的內容和位置
var arr=reg.exec(str)
在str中找下一個符合reg要求的敏感詞的內容和位置
返回值: 同match不加g時同樣
arr:[ "0": 敏感詞內容, "index": 下標i ]
3. Function對象:
什麼是: 保存一段可重用的代碼段的對象,再起一個名字
爲何: 重用一段代碼
什麼時候: 只要發現一段代碼須要反覆使用時,都要定義爲一個函數。
如何:
1. 聲明方式:
function 函數名(形參列表){
函數體;
return 返回值;
}
var 返回值=函數名(實參列表)
問題: 會被聲明提早:
2. 用賦值方式:
var函數名=function (形參列表){
函數體;
return 返回值;
}
正課:
1. Function對象
2. 面向對象
1. Function對象
建立: 3種:
1. 聲明方式:
function 函數名(形參列表){
函數體;
return 返回值
}
會被聲明提早
2. 賦值方式:
var函數名=function (形參列表){
函數體;
return 返回值
}
不會被聲明提早
揭示: 函數其實也是一個對象
函數名其實只是一個簡單的變量
3. 用new:
var 函數名=new Function("形參1","形參2",...,"函數體")
重載overload:
什麼是: 相同函數名,不一樣形參列表的多個函數,在調用時可根據傳入參數的不一樣,自動選擇匹配的函數執行。
爲何: 減小函數的個數,減輕調用者的負擔
什麼時候: 一件事,可能根據傳入的參數不一樣,選擇執行不一樣的操做時
如何:
問題: js語言默認不支持重載的語法
由於js不容許多個同名函數同時存在
若是同時存在,只有最有一個會覆蓋以前全部
解決: 用arguments對象變通實現
arguments: 每一個函數中自帶的接收全部實參值的類數組對象
每一個函數: 全部函數中都有arguments對象
自帶: 不用本身建立,直接使用
做用: 接收全部實參值
數據結構: 類數組對象——長的像數組的對象
相同: 1. 下標 2. length 3. for循環遍歷
不一樣: 類型不一樣——類數組對象是對象家孩子,無權使用數組家的API
匿名函數:
什麼是: 定義函數時,不起名的函數,稱爲匿名函數
爲何: 節約內存!
什麼時候: 只要一個函數,只使用一次時,都要用匿名函數,而不是有名稱的函數
如何: 2種:
1. 回調函數:
好比: setInterval/setTimeout(function(){...},1000)
arr.sort(function(a,b){return a-b})
str.replace(/正則/ig,function(kw){ ... })
2. 匿名函數自調: 也稱爲當即調用函數IIF
什麼是: 定義一個匿名函數,而後馬上執行
爲何: 臨時建立一個函數做用域,避免使用全局變量
什麼時候: 從此全部的js代碼,都要放在一個巨大的匿名函數自調中。
(function(){
本身的功能代碼
})()
做業:
1. function fun(){
var n=999;
nAdd=function(){ n++ };
return function(){
console.log(n);
}
}
var getN=fun();
getN()//?
nAdd()
getN()//?
2. function fun(){
for(var i=0,arr=[]; i<3;i++){
arr[i]=function(){ console.log(i); }
}
return arr;
}
var funs=fun();
funs[0]();//?
funs[1]();//?
funs[2]();//?
正課:
1. 面向對象:
什麼是成員變量: 在對象中,函數裏面的變量是成員變量
Var lilei={
Sname:lilei,
Sage: 12
Iintr : Function (){
這裏面的是成員變量
}
}
1. 面向對象:
什麼是: 程序中都是用對象結構來描述現實中的事物
爲何: 便於大量數據的維護
什麼時候: 全部程序都是用面向對象的思想管理數據和功能
如何: 面向對象三大特色: 封裝,繼承,多態
1. 封裝:
什麼是: 建立一個對象結構,保存一個事物的屬性和功能
爲何: 便於大量數據的維護
什麼時候: 從此全部數據都是先封裝在對象中,再按需使用
如何: 3種:
1. 用{}建立一個對象:
var 對象名={
屬性: 屬性值,
... : ... ,
功能: function(){
... this.屬性名 ...
}
}
訪問對象的成員: 成員=屬性+方法
訪問屬性: 對象名.屬性
調用方法: 對象名.方法()
問題: 對象本身的方法內,想訪問本身的屬性,也不能直接屬性,報錯: 屬性 未定義
爲何: 對象的屬性沒有直接保存在一個函數的做用域鏈中,而引擎不能擅自進入對象中獲取數據。
解決一: 對象名.屬性/方法
問題: 緊耦合: 對象名發生變化,必須同時改內部的對象名,一旦忘改,就出錯!
解決二: 鬆耦合: 能不能自動得到對象名——this
什麼是this: 正在調用當前函數的.前的對象
每一個函數與生俱來的關鍵詞,可自動得到.前的對象
鄙視時: this只和調用時.前的對象有關,和保存在哪兒毫無關係!
若是一個函數前沒加任何.,默認是window.
總結: 什麼時候: 只要對象本身的方法內,想使用對象本身的屬性和其它方法時,都必須用this.
2. 用new: 2步: 同關聯數組的建立過程
var obj=new Object(); //obj:{}
obj.屬性名=值;
obj.方法名=function(){ ... }
Obj.sname=」li lei」
揭示了: js底層全部對象都是關聯數組
vs 關聯數組相比:
相同:
1. js中的對象,可隨時添加新屬性和新方法,而不會報錯!
2. 訪問對象中不存在的屬性,不會報錯,而是返回undefined
3. 訪問對象中的成員,有兩種方式:
簡寫: 對象名.屬性名/方法名()
// ||等效
什麼時候: 若是要訪問的屬性名是寫死的
完整: 對象名["屬性名"]/["方法名"] ()
什麼時候: 若是要訪問的屬性只能在運行時動態得到
4. 對象也能夠用for in遍歷每一個屬性
缺點: 一次只能建立一個對象,若是反覆建立多個相同結構的對象時,代碼會很繁瑣。
解決: 構造函數
3. 用構造函數反覆建立多個相同結構的對象
什麼是構造函數: 專門描述一類對象統一結構的函數
什麼時候: 只要反覆建立多個相同結構的對象
如何: 2步:
1. 定義構造函數:
function 類型名(形參1, 形參2, ... ){
this.屬性名=形參1;
... = ...;
this.方法名=function(){ ... this.屬性名 ...}
}
2. 用構造函數建立多個對象:
用new調用構造函數,建立出規定格式和功能的對象
var 對象名=new 類型名(屬性值,屬性值,...)
鄙視題: new的原理: 4件事:
1. 建立一片空的存儲空間
2.
3. 用新的空對象做爲主語調用構造函數
new Student(屬性值,...)
=> new.Student(屬性值,...) this->new{}
↓
=> this.屬性名=形參
↓
=>new{}.屬性名=屬性值
在new{}中強行添加該新屬性,並將屬性值保存進對象中——野蠻的強行賦值方式
結果: new{}中就反覆添加了規定的新屬性和方法
4. 返回新對象的結果
凡是不帶前綴的變量,只能在做用域鏈中查找 好比console.log (a)
Day05
正課:
1. OOP
2. ES5
1. OOP
三大特色: 封裝,繼承,多態
封裝:
3. 用構造函數反覆建立多個相同結構的對象:
function Student(sname,sage){
this.sname=sname;
this.sage=sage;
this.intr=function(){
console.log(`I'm ${this.sname},I'm ${this.sage}`);
}
}
//用new建立:
var lilei=new Student("Li Lei",11);
var hmm=new Student("Han Meimei",12);
console.log(lilei);
console.log(hmm);
lilei.intr();
hmm.intr();
問題: 將方法的定義放在構造函數內,會重複建立多個相同函數的副本,浪費內存。且,不便於維護。
解決: 1. 構造函數中不要包含方法定義
2. 將方法定義放在共同的爹中,讓全部孩子共用!
繼承:
什麼是繼承: 父對象中的成員,子對象無需重複建立,就可直接使用。
爲何繼承: 代碼重用,節約內存
什麼時候繼承: 多個孩子對象,都擁有相同的方法定義時,就要用繼承,將方法保存在爹中,全部孩子自動共用。
如何實現繼承: js中的繼承都是自動繼承原型對象
什麼是原型對象: 在一個類型的你們庭中,集中保存全部孩子對象共用的成員的父對象
如何使用原型對象:
建立: 不用本身建立!買一贈一!
當建立構造函數(媽媽)時,自動附贈了一個原型對象(爹)
繼承: 不用本身繼承, new的第二步
讓新建立的子對象,自動繼承構造函數的prototype(爹)
向原型對象中添加共有成員: 須要本身作
Student.prototype.intr=function(){ ... }
媽媽 的 老公
如何使用原型對象中的共有成員:
用子對象調用共有成員:
var lilei=new Student(... ...);
lilei.intr()
//如今lilei裏找,若是找到,就先用本身的
//若是沒找到,才延_ _proto_ _屬性先父對象中查找,只要找到,可直接使用,無需重複建立。
自有屬性和共有屬性:
什麼是自有屬性: 保存在子對象本地,僅當前子對象本身全部的屬性
什麼是共有屬性: 保存在父對象中,全部子對象共有的屬性
讀取屬性值: lilei.sname lilei.className
不管自有屬性仍是共有屬性均可用子對象來讀取
修改屬性時: 若是修改自有屬性,可用子對象修改
lilei.sage++;
若是修改共有屬性: 只能用原型對象,不能用子對象修改共有屬性。
若是強行用子對象修改共有屬性,結果:會爲當前子對象我的添加一個同名的自有屬性。今後,該子對象與其餘子對象分道揚鑣。—— 錯誤的效果!
應該: 只要修改共有屬性,必須用原型對象親自改
Student.prototype.className="初三2班"
lilei.__proto__.intr() I'm undefined, I'm undefined
lilei.intr() I'm Li Lei, I'm 11
原型鏈:
什麼是: 由多級原型對象,逐級繼承,造成的鏈式結構
2個做用:
1. 存儲着一個對象可用的全部屬性和方法
2. 控制着成員的使用順序: 先自有,再共有
vs 做用域鏈:
2個做用:
1. 存儲着全部不用.就可訪問的變量
2. 控制着變量的使用順序,先局部,後全局
js內置類型: 11種:
Number String Boolean
Array Date RegExp Math
Error
Function Object
global(在瀏覽器中被改名爲window)
自定義繼承:
什麼時候: 若是默認的爹不是想要的,可更改
如何: 2種:
1. 僅修改一個對象的父對象:
child.__proto__=father
設置child的爹爲father
Object.setPrototypeOf(child, father)
2. 同時更換多個子對象的爹
更換媽媽的老公
Student.prototype=father
講究時機: 必須在建立子對象以前換!
多態:
什麼是: 一個函數在不一樣狀況下表現出不一樣的狀態
包括2種狀況:
1. 重載
2. 重寫(override):
什麼是: 若是子對象以爲從父對象繼承來的成員很差用,可在子對象本地建立同名成員,覆蓋父對象中的成員。使用時,只要本身有,就先用本身的。
什麼時候: 以爲從父對象繼承來的成員很差用
如何: 只要在對象本地定義與父對象中同名的成員,便可。
2. ES5:
ECMAScript 第5個版本
1. 嚴格模式:
什麼是: 比普通js運行機制,要求更嚴格的模式
爲何: js語言自己具備不少廣受詬病的缺陷
什麼時候: 從此全部的js程序,必須運行在嚴格模式下!
如何:
在當前做用域的頂部寫:"use strict";——啓用嚴格模式
規定:
1. 禁止給未聲明變量賦值:
2. 靜默失敗升級爲錯誤:
什麼是靜默失敗: 執行不成功,但還不報錯。
ES5中規定,全部靜默失敗,都升級爲報錯!
3. 匿名函數自調和普通函數調用中的this,再也不指向window!而是this=undefined。
Day06 ES5 ES6
正課:
1. ES5
2. ES6
1. ES5:
Object.create() 沒有構造函數,僅依靠父對象,就能建立子對象。
如何: var child=Object.create(father,{
//爲child添加自有屬性
//用defineProperties的語法
屬性名:{
value:屬性值,
writable:true,
enumerable:true,
configurable:false
}
})
1. 建立子對象child
2. 自動設置子對象繼承父對象father
3. 爲子對象child添加自有屬性
// Object.create作的事情
// 01自動建立新的空對象hmm
// 02自動設置hmm繼承father
// 03爲hmm添加自由屬性
var father={
money:100000,
car:"benchi"
};
var hmm=Object.create(father,{
phone:{
value:"iphone",
Writable:true,
enumerable:true,
configurable:false
},
bao:{
value:"lv",
writable:true,
enumerable:true,
configurable:false
}
});
console.log(hmm)
console.log(hmm.money)
console.log(hmm.car)
call apply bind 換函數中的this
1. call apply 在本次調用時,臨時替換函數中的this爲指定的對象
calc.call(lilei,10000,1000,2000)
用lilei調用calc,並傳入參數10000,1000,2000
//默認this->window
//call將this->lilei
apply只比call多一個功能: 打散數組類型的參數爲單個值
2. bind: 永久綁定this和部分參數值:
什麼時候: 只要但願永久綁定this,反覆使用
從此,只要回調函數中的this,要更換,都用bind
由於回調函數被調用幾回,不肯定
如何:
1. 綁定:
var lcalc=calc.bind(lilei,10000);
基於原函數calc,建立一個如出一轍的新函數,並永久替換函數中的this爲lilei,永久替換函數的第一個參數base爲10000,最後將新函數保存到變量lcalc中
2. 調用lcalc: 不用重複傳入對象和已經綁定的參數值
lcalc(1000,2000) // Li Lei的總工資是 13000
數組API:
1. 查找元素的位置:
回顧: var i=str.indexOf("關鍵詞",starti)
數組中: var i=arr.indexOf(元素值, starti)
在arr數組中,查找starti位置後的下一個"元素"出現的位置
返回值: 若是找到,返回元素的下標i
若是沒找到,返回-1
2. 判斷數組是否由規定的內容組成:
1. 判斷是否全部元素都符合要求
var bool=arr.every(function(elem, i, arr){
//elem:當前元素值
//i : 當前位置
//arr : 當前數組對象
return 根據elem,i,和arr判斷當前元素是否符合要求
})
2. 判斷是否包含符合要求的元素
var bool=arr.some(function(elem, i, arr){
return 判斷條件
}
只要包含符合條件的元素,就返回true
3. 遍歷API: 依次取出數組中的每一個元素值,執行相同的操做
1. forEach: 對原數組中每一個元素執行相同的操做
arr.forEach(function(elem,i,arr){
//對當前元素執行相同操做
})
2. map: 依次取出原數組中每一個元素值,執行相同操做後,放入新數組中返回
var evens=arr.map(
//newArr=[]
for( ... ... ){
function(elem,i,arr){
↓
return 新值
} ↓
//newArr[ 2 4 6 ]
}
//return newArr;
)
結果: evens=newArr=[2 , 4, 6]
遍歷索引數組:for forEach
遍歷類數組對象:for
遍歷對象和關聯數組: for in
保護原數組,並生成新數組: map——只有索引數組
4. 過濾和彙總:
過濾: 複製出原數組中符合條件的元素,組成新的子數組返回。原數組保持不變。
var subArr=arr.filter(funtion(elem,i,arr){
return 判斷條件
})
結果: filter會拿着回調函數去每一個元素上執行一次,只有符合判斷條件的元素,纔會被複製出來,放入新數組返回
彙總: 對數組中的全部元素進行統計和分析,得出最終結論
var result=arr.reduce(
function(prev, elem, i, arr){
//prev: 是截止目前的臨時彙總值
return 截止目前元素的臨時彙總值
},
起始值
)
補: 按值傳遞: 兩個變量間賦值時,其實都是將原變量中的值複製一個副本給對方
1. 若是傳遞的是原始類型的值: number string bool null undefined
將原始值複製一個副本給對方,修改新變量的值,不影響原變量
2. 若是傳遞的是引用類型的值: 數組,日期,自定義對象
只是將地址值複製給新變量。造成兩個變量用相同的地址指向同一個對象。任何一方修改對象,另外一方都會受影響
2. ES6:
let 代替var,用於聲明變量:
var的兩個問題:
1. 聲明提早
2. 沒有塊級做用域
let的優勢:
1. 阻止聲明提早
2. 添加塊級做用域,讓if else if else while for ...都變成了做用域
let的原理:
let a=100;
至關於:
(function(){
var _a=100;
...
})()
參數加強:
1. 默認值default:
什麼時候: 只要一個形參,未來不傳值,也但願有一個默認值做爲備胎時
1. 定義函數時:
function calc(bonus1,bonus2,base=10000){
}
坑: 有默認值的形參必須放在參數列表末尾!
通常狀況下只能有一個
2. 調用時:
calc(5000,6000,4000) base=4000
calc(5000,6000) base=10000
2. 剩餘參數rest: 代替arguments
什麼時候: 只要不肯定參數的個數時,都用rest
arguments的問題:
1. 不是純正的數組,沒法使用數組家的API
2. 只能接收全部參數,沒法有選擇的接收參數
rest的優勢:
1. 是純正的數組,可以使用數組家全部API
2. 可有選擇的接收部分參數
如何:
1. 定義時:
function calc(ename, ...salary){
salary會接住除ename以外的全部剩餘參數
且salary是純正的數組
}
2. 調用時:
除ename外,再傳多少個參數都會被salary數組接收
3. 打散spread: 將數組類型的參數,打散爲多個值傳入函數
什麼時候: 函數但願多個值分別傳入,但給定的多個值卻放在數組中
如何:
var arr=[2,6,7,1];
Math.max(...arr) //7
在調用函數時...可將數組打散爲多個參數值,分別傳入
箭頭函數: 對一切函數的簡化!
如何:
1. 去掉function,變爲=>
2. 若是形參列表只有一個形參,可省略()
3. 若是函數體只有一句話,可省略{}
但若是僅有的一句話仍是return,則必須省略return
箭頭函數的特色: 內外this通用!
若是但願內外this相同時,可改成箭頭函數
若是不但願內外this相同時,就不能改箭頭函數
好比: 對象的方法,事件處理函數
正課:
1. ES5
2. ES6
1. ES5
call/apply/bind
什麼是: 替換函數中不想要的this爲指定的對象
什麼時候: 若是函數執行時,其中的this不是想要的,都要替換this爲想要的對象
如何:
1. call/apply
在本次調用函數時,臨時替換函數中的this爲指定對象
本次調用後,替換失效。
call: 任意函數.call(任意對象, 實參值列表...)
讓任何一個對象,可臨時調用任何一個不相干的函數,並傳入實參值列表。
好比: calc.call(lilei,10000,2000,3000);
用lilei調用calc函數,並傳入10000,2000,3000三個參數值。
apply: 若是實參值列表是以數組形式給的,則必須將call
換成apply
如何: var arr=[10000,2000,3000] //實參值列表
calc.apply(lilei, arr)
用lilei調用calc,可是會打散數組參數爲單個值
好比: arr=[10000,2000,3000]
calc.apply(lilei, arr )
打散數組 ↓ ↓ ↓
等效於: calc.call(lilei, 10000,2000,3000)
結果: this base bonus1 bonus2
2. bind:
什麼是: 基於原函數,建立一個新函數,並永久綁定this
什麼時候: 若是函數中的this,須要反覆被替換,就用bind建立一個新的專屬的函數。永久綁定this。
如何: var 新函數=原函數.bind(對象, 要綁死的實參值,...)
好比: var calc_l=calc.bind(lilei, 10000)
建立一個和calc如出一轍的新函數calc_l,並永久替換calc_l中的this爲lilei對象,並永久替換第一個參數base爲10000。
好處: 從此反覆使用calc_l不用再反覆傳入lilei和10000.
強調: bind僅建立新函數,不執行函數
要執行函數: calc_l(1000,2000)
//bonus1, bonus2
強調: 用bind建立的新函數中的this,不可能再被別人用call替換。由於bind後的函數中的this已經被替換成固定的對象了。因此再用call/apply已無this可換
總結:
當函數中的this不是想要的,想換成想要的
就用call/apply/bind
1. 當僅臨時替換本次調用函數中的this時——call
當實參值列表是數組形式時,必須將call換成apply,自動打散數組爲單個值
2. 若是一個函數須要反覆替換this爲一個指定的對象時,就用bind建立一個專屬的新函數,永久綁定this爲指定的對象,同時可綁定部分固定的參數值。
數組API:
ES5中爲數組擴展了不少新的API
1. 數組中也有indexOf方法,查找一個指定元素的位置
用法同字符串.indexOf徹底同樣:
var i=arr.indexOf(要找的元素, [開始位置])
// 3 , 5
//從5位置開始找下一個3
在arr數組中,從starti位置開始,查找下一個指定元素的位置i
其中: starti可省略,默認從0位置開始找
若是找到匹配的,返回元素的下標位置
若是沒找到,返回-1
好比:
var str="1234321";
// 0123456
console.log(
//在arr中找第一個3的位置
str.indexOf(3/*,0*/),//2
//在arr中從3位置開始找下一個3的位置
str.indexOf(3,3),//4
//在arr中從5位置開始找下一個3的位置
str.indexOf(3,5),//-1 //找不到了
//在arr中找第一個5的位置
str.indexOf(5) //-1 //找不到
);
var arr=[1,2,3,4,3,2,1]
// 0 1 2 3 4 5 6
console.log(
//在arr中找第一個3的位置
arr.indexOf(3/*,0*/),//2
//在arr中從3位置開始找下一個3的位置
arr.indexOf(3,3),//4
//在arr中從5位置開始找下一個3的位置
arr.indexOf(3,5),//-1 //找不到了
//在arr中找第一個5的位置
arr.indexOf(5) //-1 //找不到
);
2. 判斷: 判斷數組中的元素是否符合要求
arr.every(條件) 判斷數組中是否全部元素都符合條件
每一個
arr.some(條件) 判斷數組中是否包含符合條件的元素
一些
如何: 僅以every爲例
var bool=arr.every(function(elem, i, arr){//規定
//elem: 自動得到當前位置上的元素值
//i: 自動得到當前位置下標i
//arr: 自動得到.前的數組對象
return 判斷條件
//若是當前元素值elem,符合判斷條件要求,返回true
//若是當前元素值elem,不符合判斷條件,返回false
})
執行原理: every會自動遍歷arr中每一個元素,每遍歷一個元素,就用回調函數在當前元素上執行一次。每次調用是都會自動給回調函數傳入當前元素值、當前位置和當前數組對象。中途every會記錄每一個元素判斷後獲得的結果。最後,只有全部元素判斷的結果都爲true,總體才返回true。只要有一個元素的判斷結果返回false,總體就返回false
好比:
var arr1=[1,2,3,4,5];
var arr2=[2,4,6,4,2];
//判斷哪一個數組全是偶數
console.log(
arr1.every(function(elem){
return elem%2==0
}),//false
arr2.every(function(elem){
return elem%2==0
})//true
);
正課:
1. ES6
1.ES6:
ECMAScript的第6個版本: 在不改變原理的基礎上,儘可能簡化了代碼。
let:
什麼是: 專門代替var,用於聲明變量用的關鍵詞
什麼時候: 從此全部的var,都用let代替
爲何:
var的兩個缺點:
1. 聲明提早: 打亂了程序正常執行的順序
2. 沒有塊級做用域: 塊內的變量頗有可能提早到塊外部,影響本來正確的外部的程序。
塊: if(){ ... }else if(){ ... }else{ ... }
for(){ ... }
while(){ ... } do{ ... }while();
都是塊,但都不是做用域
其內部的變量,都會被提早到塊外對外部形成不可預期的影響。
好比:
var t=0;
function fun(){
t+=10;//本來就是想對全局t+10
}
fun();
console.log(t); //10
過了一段時間/其它人給函數中添加了一段不會執行的代碼:
var t=0;
function fun(){
var t//undefined;
t+=10;//本來就是想對全局t+10
//由於有了局部變量t,就沒法修改全局了
var err=false;
if(err){ //if根本沒執行
//if不是做用域,攔不住內部的t被提早到外部函數的頂部
var t=new Date();
... ...
}
}
fun();
console.log(t); //0
結論: 從此全部的var都用let代替
let的兩個做用:
1. 阻止聲明提早: 在let a以前,不容許使用變量a
在程序中,相同範圍內,不容許重複聲明兩個let a;
2. 讓if while for do while塊都變成做用域,塊內部的變量沒法提早到外部,也就不會影響外部。
let的原理: 其實let底層就是一個匿名函數自調
let至關於作了兩件事:
1. 用匿名函數自調包裹當前範圍內的剩餘代碼
2. 將let後的變量a,改名爲_a
好比:
再好比:
for+let: 會造成閉包
for(let i=0;i<3;i++){
arr[i]=function(){console.log(i)}
//(function(_i){
//arr[_i]=function(){console.log(_i)}
//})(i)
}
箭頭函數: 對全部函數定義的簡寫:
function 函數名(形參列表){ 函數體; return 返回值 }
var 函數名= function (形參列表){ 函數體; return 返回值 }
3句話:
1. 去function,在()和{}之間加=>
(形參列表)=>{ 函數體; return 返回值 }
2. 若是形參列表中只有一個形參,可省略()
形參1=>{ 函數體; return 返回值 }
3. 若是函數體只有一句話,可省略{}
形參1=>一句話
若是僅剩的一句話,仍是return,必須去return
省略{}後,結尾的分號,必須省略
箭頭函數的雙刃劍: 箭頭函數中的this,是內外通用的
好比:
var lilei={
sname:"Li Lei",
friends:["tom","jerry","jack","rose"],
intr:function(){
//this->lilei
this.friends.forEach(
function(name){//回調函數
//不加bind,回調函數中的this->window
console.log(`${this.sname} 認識 ${name}`);
}.bind(this) //加上bind才能將函數內部錯誤的this換成外部正確的this
)
}
}
若是以爲bind不直觀,可改成箭頭函數:
var lilei={//對象的{不是做用域!}
sname:"Li Lei",
friends:["tom","jerry","jack","rose"],
intr:function(){//這裏的function不能改箭頭,一旦改成箭頭,this->window
//this->lilei
this.friends.forEach(
//內部的function可改成箭頭函數,由於但願和外部的this通用!this->lilei
name=>console.log(`${this.sname} 認識 ${name}`)
)
}
}
總結: 若是但願內外this一致時,就可改成箭頭函數,代替bind
若是不但願內外this相同時,就不可改成箭頭函數。好比: 對象中的方法不能改箭頭;事件處理函數不能改箭頭
for of: 快速遍歷一個數組的內容的最簡化寫法
總結: 遍歷一個數組:
1. for循環
for(var i=0;i<arr.length;i++){
arr[i] //得到當前數組元素
}
最靈活的遍歷,便可控制遍歷的順序,又可控制遍歷的步調
2. forEach簡化:
arr.forEach((elem,i)=>{
elem //當前數組元素
})
問題: 只能從頭至尾依次遍歷每一個元素,不能控制順序(從後向前或從前向後)和步調(2,4,6,... 5,10,15,... )
什麼時候: 若是既關係內容,又關心位置,但不會改變遍歷的順序或步調時
3. for of更簡化:
for(var elem of arr){
//of會依次取出索引數組中的每一個元素值
elem //當前數組元素
}
問題:只能得到元素內容,沒法得到元素位置
因此: 僅關心元素內容時,才用for of
vs for in
1. 使用場合: for of專門遍歷索引數組
for in專門遍歷關聯數組
2. of vs in:
of只取元素值
in 只取屬性
好比: var names=["亮亮","然然","東東"]
for(var name of names){
//of依次取出names數組中每一個人名保存到前邊的變量name中
console.log(name + " - 到!");
}
參數加強:
1. 默認值:
ES6中能夠對形參列表中的最後一個形參設置默認值
什麼時候: 若是隻有最後一個形參不肯定時
如何:
//定義函數find,在arr中查找指定元素出現的位置
//若是不給第三個參數,則默認從0位置開始找
//若是給第三個參數,則從給定的位置向後找
function find(arr,elem,starti){
/*方法一: if判斷
if(starti===undefined){
starti=0;
}*/
//方法二: 短路
//starti=starti||0;//0是starti的備胎
//||會自動將先後轉爲boolean
//若是starti轉換後不是false,就首選starti使用。若是starti轉換後爲false,就用0代替starti;
console.log(`在arr中,從${starti}位置開始,找下一個${elem}出現的位置...`);
}
//方法三: ES6的默認值
function find(arr,elem,starti=0){
//若是沒有給starti傳參,則自動用0代替!
console.log(`在arr中,從${starti}位置開始,找下一個${elem}出現的位置...`);
}
var arr=[];
find(arr,3);//從0位置開始
find(arr,3,5);//從5位置開始找
2. 剩餘參數: 代替arguments
什麼是: 讓函數能夠自動收集結尾多個不肯定的參數值
什麼時候: 若是在函數形參的結尾,有不肯定個數的參數值傳入,則可用剩餘參數方式收集
爲何:
arguments: 2大缺點:
1. 不是純正的數組類型對象,數組家的API一個都不能用
2. 只能收集全部參數值,沒法有選擇的收集部分參數值
如何: 2步:
1. 在定義函數時,在能夠肯定的形參後添加"...數組名"
2. 在函數內,"數組名"數組中,就自動收集了除已經肯定的形參以外的剩餘實參值。
好比:
定義函數時:
function calc(ename,...arr){
調用時:
calc("Li lei",10000,2000,3000);
//...arr[10000,2000,3000]
calc("Han Meimei",5000,1000,2000,3000);
//...arr[5000,1000,2000,3000]
優勢: 1. 可有選擇的得到部分實參值
2. arr是純正的數組,數組家的API能夠隨便用!
3. 打散數組: 代替apply,專門用於打散數組類型的參數
什麼時候: 只要函數須要多個零散的參數值,但給定的參數值倒是放在一個數組中傳入的,發生不一致,就要打散數組
apply必定有問題:
apply的主要目的是替換this,順便打散數組
若是隻但願打散數組參數,和this無關時,用apply就會很彆扭.
好比: Math.max(arr)不支持數組中查找最大的元素
傳統: 可用: apply打散數組類型參數爲單個值
console.log(Math.max.apply(null,nums));
console.log(Math.max.apply(Math,nums));
console.log(Math.max.apply(nums,nums));
apply的第一個參數即沒用,又必須寫
解決: 不用apply,用...
如何: console.log(Math.max(...nums))
// 拆
...先將nums數組打散爲單個值,再陸續傳給max
總結:
1. 若是在定義函數時,形參列表中...arr,是收集剩餘參數保存到數組的意思
2. 若是在調用函數時,在實參列表中...arr,做用是相反的,是打散數組爲單個值,再傳入。
解構:
什麼是: 僅提取出一個大對象中的部分紅員單獨使用
什麼時候: 若是隻使用一個大對象中的一小部分紅員時
如何: 3種狀況:
1. 數組解構: 下標對下標:
var date=[2019,5,5];
/*var y=data[0]
var m=data[1]
var d=data[2]*/
var [y,m,d]=date;
y m d
2. 對象解構: 屬性對屬性:
好比:
var user={
uid:1001,
uname:"dingding",
set:1,
signin:function(){
console.log("登陸...");
},
signout:function(){
console.log("註銷...");
},
signup:function(){
console.log("註冊...");
}
}
//var {uid:uid,signup:signup}=user;
var {uid,signup}=user;
console.log(uid);
signup();
原理:
3. 參數解構:
什麼是: 在向函數中傳參時,將一個大的對象,打散後,傳遞給對應的形參變量.
什麼時候: 多個形參不肯定時,又要求按順序傳入時、
爲何:
1. 默認值: 只能應對結尾一個參數不肯定時
2. 剩餘參數: 雖然可應對多個參數不肯定的狀況
但沒法規定傳入參數的順序
好比:
function calc(ename, base,飯補, 高溫,房補)
calc(lilei, 10000, , 200, 600)
calc(hmm, 10000, , , 200)
calc(jack, 10000, , 300, 500)
總結: 當多個形參都不肯定時,且每一個實參值必須對位傳給指定的形參變量時,單靠調整形參的個數和順序,沒法知足全部調用的狀況
解決: 參數解構:
如何: 2步:
1. 定義形參時,全部的形參變量都要定義在一個對象結構中
好比:
//1. 定義形參列表時,就用對象結構定義
function ajax({
//與順序無關
url:url,
type:type,
data:data,//不肯定
dataType:dataType//不肯定
}){
console.log(`向${url}發送${type}請求`);
if(data!=undefined&&type=="get"){
console.log(`在url結尾拼接參數?${data}`)
}
if(data!=undefined&&type=="post"){
console.log(`xhr.send(${data})`);
}
if(dataType=="json"){
console.log(`JSON.parse(返回結果)`);
}
}
2. 調用函數傳參時,全部實參值,都要放在一個對象結構中總體傳入。
好比:
ajax({
url:"http://localhost:3000/products/getProductsByKwords",
type:"get",
data:"kw=macbook i5",
dataType:"json"
});
總結: 參數解構,其實就是對象解構在傳參時的應用而已
正課:
1. ES6
1. ES6
OOP:
1. 對對象直接量的簡寫: 2處:
1. 若是對象的成員值來自於外部的變量,且屬性名和變量名相同時,可只寫一個:
好比: user.js
var signin=function(){ 登陸... }
var signup=function(){ 註冊... }
var signout=function(){ 註銷... }
var obj={ signin:signin, signup:signup, signout:signout };
{ signin, signup, signout };
//將三個函數放在一個對象中導出export
module.exports=obj
2. 對象直接量中方法的定義不須要加":function"
爲何: 對象中的方法,不能用箭頭函數簡寫。一旦簡寫,方法中的this再也不指向當前對象,極可能指向全局的window。
好比:
var lilei={
sname:"Li Lei",
intr:function(){//不能改爲箭頭函數
... this.sname ...
}
}
解決:
var lilei={
sname:"Li Lei",
intr (){//不要加箭頭
//等效於intr:function(),可保持this不變!
... this.sname ...
}
}
2. class
什麼是class:
用途: 描述一類事物統一屬性結構和功能的程序結構
本質: 其實就是之前的構造函數+原型對象的總體
爲何: 由於構造函數和原型對象分開的寫法不符合封裝的含義。
如何: 3句口訣
//1. 用class{}包裹構造函數和原型對象方法
class Student{
//2. 構造函數名提高成類型名,全部構造函數改名爲constructor
constructor(sname,sage){
this.sname=sname;
this.sage=sage;
}
//3. 全部方法再也不須要prototype前綴,再也不須要=function
intr(){
console.log(`I'm ${this.sname}, I'm ${this.sage}`);
}
}
class的用法和存儲結構跟ES5中構造函數建立的對象用法和存儲結構是徹底相同的
3. class之間的繼承:
問題: 兩種類型之間存在部分相同的屬性結構和方法定義,代碼可能出現重複編寫。
解決: 定義抽象父類型: 2步:
1. 定義抽象父類型集中定義多個子類型共有的屬性和方法
1.1 在父類型的構造函數中僅定義相同部分的屬性
1.2 在父類型原型對象中僅定義相同部分的方法
2. 讓子類型繼承父類型:
2.1 子類型使用extends繼承父類型
2.2 子類型構造函數中先用super調用父類型構造函數
好比:
//定義敵機類型
//全部敵機都有名稱,速度和分值三個屬性
//全部敵機均可以飛行,擊落敵機能夠得分
//定義蜜蜂類型
//全部蜜蜂都有名稱,速度和分值三個屬性
//全部蜜蜂均可以飛行,擊落蜜蜂能夠的獎勵
//可是,由於敵機和蜜蜂兩種類型擁有部分相同的屬性和方法,致使代碼重複,不便於往後維護
//因此,應該先定義抽象父類型"敵人類型",集中保存兩種子類型部分相同的屬性和方法。
class Enemy{
//抽象父類型構造函數中集中保存全部子類型共有的屬性部分
constructor(fname,speed){
this.fname=fname;
this.speed=speed;
}
//抽象父類型原型對象中集中保存全部子類型共有的方法
fly(){
console.log(`${this.fname}以時速${this.speed}飛行`);
}
}
//子類型必須繼承(extends)父類型,才能得到父類型中的方法
class Plane extends Enemy{
//子類型構造函數中:
constructor(fname,speed,score){
//先借用父類型構造函數(super)幫忙添加共有的屬性部分
super(fname,speed);//Enemy中的constructor()
//再本身添加本類型自有的獨特的屬性
this.score=score;
}
//Prototype中:只定義本身類型特有的方法便可,沒必要定義相同部分的方法。
getScore(){
console.log(`擊落${this.fname}得${this.score}分`);
}
}
class Bee{
constructor(fname,speed,award){
this.award=award;
}
getAward(){
console.log(`擊落${this.fname}得到${this.award}獎勵`);
}
}
var f22=new Plane("F22",1000,5);
//表面上f22是Plane一個媽媽建立的,可是其實f22中三個屬性:fname和speed是奶奶給的,只有score纔是媽媽給的。是兩我的合做建立的f22對象。
console.log(f22);
f22.fly();
f22.getScore();
var bee=new Bee("小蜜蜂",50,"1 life");
console.log(bee);
bee.fly();
bee.getAward();
Promise:
什麼是: 專門實現異步函數,順序執行的一種機制
爲何: 避免回調地獄
什麼時候: 多個異步函數,必須順序執行時
如何:
2步:
1. 定義異步函數內:
function liang(){
return new Promise(function(open){
亮要執行的全部代碼(包含異步代碼)
//當亮的任務執行完,自動打開open()
//當open(),自動執行下一個then中的函數
})
}
2. 多個支持promise的異步函數,用.then串聯起來
liang().then(ran).then(dong).then(function(){結束})
用class對構造函數和原型對象的封
正課:
1. 什麼是DOM:
2. DOM Tree:
3. 查找元素:
1. 什麼是DOM: document object model
什麼是: 專門操做網頁內容的一套對象和函數的集合
DOM實際上是一個標準: W3C制定的,規定了全部瀏覽器操做網頁內容的API統一標準。
爲何: 1. DOM是操做網頁內容的惟一辦法!
2. DOM標準幾乎全部瀏覽器100%兼容.
什麼時候: 從此只要操做網頁的內容,只能用DOM
包括:
查找元素,修改元素,添加元素,刪除元素,事件綁定
2. DOM Tree:
什麼是: 內存中保存網頁中全部內容的樹形結構
網頁中的一切內容,在內存中,都是保存在一棵DOM樹中
爲何: 網頁中的內容是父子級嵌套的包含關係
樹形結構是最直觀的描述上下級包含關係。
如何:
1. 當瀏覽器讀取到一個html內容時
先在內存中創建一個樹根節點: document
document就表明整個網頁
document.write("xxx") 向網頁中寫入一句話
2. 瀏覽器一邊掃描HTML內容,一邊在DOM樹上建立節點對象
網頁中每項內容都是DOM樹上的一個節點對象
3. 查找元素: 4種:
1. 不須要查找,就可直接訪問的元素:
document
document.documentElement -> <html>
document.head -> <head>
document.body -> <body>
提示: 在控制檯中輸出元素節點,僅輸出DOM樹結構,而不是輸出節點對象
若是確實須要查看一個元素對象的屬性: console.dir(元素)
2. 按節點間關係查找:
節點樹: 包含全部網頁內容的完整樹結構
2大類關係:
1. 父子: 4種:
元素.parnetNode 得到元素的父節點
父元素.childNodes 得到父元素下的全部直接子節點的集合
返回: 多個平級子元素組成的類數組對象
父元素.firstChild 得到父元素下的直接子節點中第一個節點
父元素.lastChild 得到父元素下的直接子節點中的最後一個節點
2. 兄弟: 2種:
元素.previousSibling 得到元素的前一個平級的兄弟節點
前一個 兄弟
元素.nextSibling 得到元素的下一個平級的兄弟節點
下一個兄弟
問題: 網頁中一切內容都是節點,包括看不見的空格,換行都是節點對象,極大的干擾查找!
解決: DOM出了一種新的樹:
元素樹: 僅包含元素節點的樹結構
優勢: 不會受看不見的空字符干擾查找!
2大類關係:
1. 父子: 4種:
元素.parentElement 得到元素的父元素
和parentNode幾乎通用
由於能當爹的必定是元素
父元素.children 得到父元素下的全部直接子元素的集合
返回: 多個直接子元素組成的類數組對象
父元素.firstElementChild 得到父元素下的直接子元素中第一個元素
父元素.lastElementChild 得到父元素下的直接子元素中的最後一個元素
2. 兄弟: 2種:
元素.previousElementSibling 得到元素的前一個平級的兄弟元素
元素.nextElementSibling 得到元素的下一個平級的兄弟元素
什麼時候使用按節點間關係查找:若是已經站在DOM樹的某個節點上了,想找周圍附近的節點時,首選按節點間關係查找,且必須用元素樹。不要用節點樹。
day 02
正課:
1. 查找
2. 修改
1. 查找: 4種:
1. 不須要查找就可直接得到的元素: 4個
document 根節點對象
document.documentElement 根元素對象<html>
document.head <head>元素對象
document.body <body>元素對象
2. 按節點間關係查找: 2大類關係,6個屬性
什麼時候: 已經站在樹上的一個節點上了。
1. 父子關係:
元素.parentElement 得到元素的父元素
.parentNode
元素.children 得到元素的全部直接子元素
返回: 全部直接子元素對象組成的類數組對象
元素.firstElementChild 得到元素的第一個直接子元素
元素.lastElementChild 得到元素的最後一個直接子元素
2. 兄弟關係:
元素.previousElementSibling 得到元素的前一個相鄰的平級兄弟元素
元素.nextElementSibling 得到元素的後一個相鄰的平級兄弟元素
問題: 不可能全部的查找都從body爲起點,一旦元素藏的很深,代碼會很繁瑣
3. 按HTML特徵查找:
什麼時候: 首次查找元素時
包括: 4個函數:
1. 按id查找:
var elem=document.getElementById("id")
得到 元素 按 id
強調: 1. .前的主語必須是document
2. 僅返回一個匹配的元素對象
若是找不到: 返回null
2. 按HTML標籤名查找:
var elems=任意父元素.getElementsByTagName("標籤名")
得到 元素們 按標籤 名
<標籤>
強調: 1. .前的主語能夠是任意父元素
好比: table.getElementsByTagName("tr")
只查找當前table下的全部tr元素對象
ul.getElementsByTagName("li")
只查找當前ul下的全部li元素對象
2. 返回當前父元素下全部符合條件的元素的類數組對象。若是找不到,返回空的類數組對象([].length=0)
3. 不只查找直接子元素,且在全部後代中查找
好比:
<ul> ul.getElementsByTagName("li") 8個
<li>
<ul> ul.getElementsByTagName("li") 3個
<li>
<li>
<li>
</ul>
</li>
<li>
<ul>
<li>
<li>
<li>
</ul>
</li>
3. 按name屬性查找:
只有表單中要將值回發給服務器端的元素,纔有name屬性。name屬性會成爲回發服務端時的變量名
好比: <form>
<input type="text" name="uname"/>
<input type="password" name="upwd"/>
<input type="submit">
提交時: http://xxxx/接口?uname=xxx&upwd=xxx
什麼時候: 幾乎專門用於查找表單中的表單元素
如何:
var elems=document.getElementsByName("name");
強調: 1. .前的主語必須是document
2. 返回多個元素組成的類數組對象
若是找不到,返回[].length=0
好比:
<input type="radio" name="sex" value="1"/>男
<input type="radio" name="sex" value="0"/>女
var elems=document.getElementsByName("sex");
elems:[ <input> , <input> ]
坑:
<input type="text" name="uname"/>
<input type="password" name="upwd"/>
<input type="submit">
var txtName=document.getElementsByName("uname")
但願只得到<input>姓名文本框對象
但不管在任何狀況getElementsByName都返回一個類數組對象,即便只找到一個元素對象,也必須放在類數組對象中返回。
var elems=document.getElementsByName("uname");
elems: 類數組對象 [ <input> ] != <input>對象
[0]
若是想得到input姓名文本框對象,須要再多寫一步下標
var txtName=elems[0];
4. 按class屬性查找:
var elems=任意父元素.getElementsByClassName("class名")
強調: 1. .前能夠是任意父元素
2. 返回全部符合條件的後代元素的集合
若是找不到返回空集合:[].length=0
3. 不只查找直接子元素,且在全部後代中查找符合條件的。
好比:
<ul> ul.getElementsByClassName("child") 6個
<li class="parent">
<ul> ul.getElementsByClassName("child") 3個
<li class="child">
<li class="child">
<li class="child">
</ul>
</li>
<li class="parent">
<ul>
<li class="child">
<li class="child">
<li class="child">
</ul>
</li>
4. 若是一個元素被多個class修飾,只使用其中一個class就能夠找到元素
<div class="alert alert-danger">
var elems=父元素.getElementsByClassName("alert")
父元素.getElementsByClassName("alert-danger")
都返回: 類數組對象: [ <div>對象 ].length=1
[0]
若是隻想得到惟一的div元素對象:
必須再多寫一步下標:
var div=elems[0]
總結: 4種查找方式:
1. 按id查找:
var elem=document.getElementById("id")
2. 按標籤名查找:
var elems=父元素.getElementsByTagName("標籤名")
3. 按name屬性查找:
var elems=document.getElementsByName("name")
4. 按class屬性查找:
var elems=父元素.getElementsByClassName("class")
4. 其實js中也能夠使用選擇器查找元素: 2個函數:
1. 若是肯定只找一個元素:
var elem=任意父元素.querySelector("任意複雜選擇器")
2. 若是查找多個元素:
var elems=任意父元素.querySelectorAll("任意複雜選擇器")
按選擇器查找,效率不如按HTML特徵查找
總結:
1. 若是僅靠一個條件就可查找到想要的元素:
首選按HTML查找——快
2. 若是查找條件複雜
首選按選擇器查找——簡單
2. 修改
內容:
1. 獲取或修改元素開始標籤到結束標籤之間的原始HTML片斷: 元素.innerHTML
2. 獲取或修改元素開始標籤到結束標籤之間的純文本內容: 元素.textContent
vs 元素.innerHTML 多幹兩件事:
1. 去掉全部內嵌標籤
2. 將特殊符號翻譯爲正文
3. 全部表單元素的值,都必須用.value才能得到
樣式:
1. 若是修改內聯樣式:
元素.style.css屬性="屬性值"
好比: div.style.display="none"; 隱藏
至關於: <div style="display:none">
div.style.display="block"; 顯示
至關於:<div style="display:block">
div.style.width="400px" 必須加單位
至關於: <div style="width:400px">
特例: 若是css屬性名包含-,則必須去橫線,變駝峯
首字母小寫,以後每一個單詞首字母大寫
修改元素的背景圖片:
div.style.backgroundImage="url(...)"
至關於: <div style="background-image:url(...)">
屬性: 3種:
1. HTML標準屬性: HTML標準中規定的,全部HTML元素都具備的屬性: 好比: title, class, id, value, name ... ...
2種方式修改:
1. 最先的一批覈心DOM函數: 4個
1. 獲取一個元素指定屬性的值:
元素.getAttribute("屬性名")
好比: <a href="http://tmooc.cn" target="_blank">
a.getAttribute("href")
-> "http://tmooc.cn"
2. 修改一個元素指定屬性的值:
元素.setAttribute("屬性名","新值")
好比: a.setAttribute("target","_self")
結果: <a href="http://tmooc.cn" target="_self">
3. 判斷是否包含指定屬性:
var bool=元素.hasAttribute("屬性名")
好比: a.hasAttribute("target") => true
a.hasAttribute("title") => false
4. 移除屬性:
元素.removeAttribute("屬性名")
好比: a.removeAttribute("target")
結果: <a href="http://tmooc.cn">
問題: 太長!
2. 使用HTML DOM提供的屬性:
HTML DOM在覈心DOM基礎上,對經常使用的屬性和元素對象提供了部分簡寫的代碼
福利: HTML DOM已經將全部標準屬性提早定義在了內存中的元素對象上!可直接用元素.屬性名獲取或修改。
好比: <a href="http://tmooc.cn" target="_blank">
其實: a在內存中:
a:{
id:"",
href:" http://tmooc.cn ",
target:" _blank ",
title:"",
name:""
}
因此: 獲取a的href: a.href
修改a的target: a.target="_self"
判斷a是否包含title: a.title!=""
移除a的target: a.target="";
特例: class屬性
ECMAScript中規定: 全部js對象內部都有一個隱藏的class屬性,記錄當前對象的類型名: "[object Object]"
class
若是ECMAScript標準中已經提早規定過了class屬性另有用途。則DOM標準中不能重複定義class屬性
因此DOM標準規定class屬性一概改名爲className
訪問元素的className屬性,其實就是在訪問<標籤 class="">
/全部DOM效果的固定套路:
//1. 查找觸發事件的元素
var d2=document.getElementById("d2");
//2. 爲元素綁定事件處理函數
d2.onclick=function(){
//3. 查找要修改的元素
var d1=document.getElementById("d1");
var d2=this;
//4. 修改元素
//若是d2的內容是<<,就關閉
if(d2.innerHTML=="<<"){
//d1.style.display="none";
d1.style.width="0px";
d2.innerHTML=">>";
}else{//不然, 就打開
//d1.style.display="block";
d1.style.width="64px";
d2.innerHTML="<<";
}
}
2. 四大狀態屬性:
3. 自定義擴展屬性:
day 03
正課:
1. 修改:
2. 添加/刪除元素:
3. HTML DOM經常使用對象:
1. 修改:
內容: .innerHTML .textContent .value
屬性:
1. 標準屬性: 2種:
1. 核心DOM: 4個函數:
.getAttribute() .setAttribute() .hasAttribute()
.removeAttribute();
坑: 核心DOM 僅對字符串類型的屬性起做用
2. HTML DOM: 元素.屬性名
2. 三大狀態屬性: disabled selected checked
值都是bool類型,不能用核心DOM函數
只能用.操做:
好比: //想啓用按鈕
btn.setAttribute("disabled",false) 無效
應該: btn.disabled=false;
再好比: //想判斷一個checkbox複選框是否選中:
應該: if(chb.checked==true) 可簡寫爲 if(chb.checked)
補充: CSS中有三大狀態僞類:
:checked :selected :disabled
專門選擇處於某種狀態的元素
3. 自定義擴展屬性:
什麼是: 開發人員自行添加在元素開始標籤中的,HTML標準中沒有的屬性。
什麼時候: 2個典型的場景
1. 代替id, class和元素選擇器,用於選擇觸發事件的元素
2. 在網頁中臨時緩存業務數據
如何使用自定義擴展屬性:
1. 在html開始標籤中手動添加定義擴展屬性:
<ANY data-屬性名="屬性值"
好比: <a href="#" data-trigger="tab"
2. 用js爲元素添加自定義擴展屬性:
不能用.添加: 由於自定義擴展屬性不是標準屬性,內存中的元素對象上沒有!
只能用核心DOM函數添加
a.setAttribute("data-trigger","tab")
等效於: <a href="#" data-trigger="tab"
3. 讀取自定義擴展屬性的值:
不能用.來讀取自定義擴展屬性
由於自定義擴展屬性不是標準屬性,沒有提早定義在內存中的元素對象上
只能用核心DOM的函數來獲取自定義屬性的值
a.getAttribute("data-自定義屬性")
樣式:
1. 修改內聯樣式: 元素.style.css屬性名="屬性值"
強調: 1. css屬性名中若是包含-,必須去橫線變駝峯
修改div的z-index爲11
div.style.z-index=11;
應該: div.style.zIndex=11;
2. 若是css屬性值包含單位,必須添加單位
修改: ul的高:
ul.style.height="106px"
問題: 若是同時修改一個元素的多個css樣式屬性,代碼會很繁瑣
解決: 若是批量修改一個元素的多個css樣式時,都是先將樣式定義在一個css的class中,再在js中只修改class屬性便可.
總結:
內容: .innerHTML .textContent .value
屬性:
1. 標準屬性: 核心DOM四個函數 或 . 都行
2. 狀態屬性: disabled selected checked
只能用.改
3. 自定義擴展屬性:
只能用.getAttribute("data-屬性名")
.setAttribute("data-屬性名",值)
樣式:
1. 修改內聯樣式: 元素.style.css屬性名="值"
2. 若是批量修改樣式,最好用 .className="xxx"
2. 添加/刪除
1. 添加新元素: 3步
1. 建立新的空元素:
var a=document.createElement("a")
結果: <a></a>
2. 爲新元素添加必要的屬性
a.innerHTML="go to tmooc";
a.href="http://tmooc.cn"
結果: <a href="http://tmooc.cn"> go to tmooc </a>
3. 將新元素掛載到DOM樹的指定父元素下:
爲何: 瀏覽器顯示網頁內容是根據DOM樹上的節點對象畫出來的。若是DOM樹上的節點不變化,則瀏覽器不回重繪頁面。
要想讓瀏覽器將新元素畫出來,只能新元素添加到DOM樹的指定位置,改變DOM樹,纔會觸發瀏覽器的重繪操做。
如何: 3個函數:
1. 追加到指定父元素下的末尾
父元素.appendChild(a)
2. 插入到指定元素以前
父元素.insertBefore(a,child)
將a插入到父元素下的child元素以前
3. 替換現有元素
父元素.replaceChild(a, child)
用a替換父元素下的child元素
優化: 儘可能減小操做DOM樹的次數,避免重繪
爲何: 每修改一次DOM樹,頁面會重繪一次
解決: 2種狀況:
1. 若是同時添加父元素和子元素到DOM樹
應該先在內存中將子元素所有添加到父元素中
最後將整個父元素一次性添加到DOM樹上
只會觸發一次重繪!
打開新鏈接的方式
網頁跳轉
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>打開新連接方式總結</title>
<script>
/*打開新連接方式總結:
1. 在當前窗口打開,可後退
2. 在當前窗口打開,不可後退
3. 在新窗口打開,可打開多個
4. 在新窗口打開,只能打開一個
*/
function fn(){
open("http://www.baidu.com" ,"_self");
}
</script>
</head>
<body>
<a href="javascript:fn()">在當前窗口打開,可後退</a>
</body>
</html>
網頁的跳轉
Day 04
正課:
1. 添加/刪除
2. HTML DOM經常使用對象
3. BOM
4. ***事件
1. 添加/刪除:
優化: 儘可能減小操做DOM樹的次數
1. 若是同時添加父元素和子元素時
應先將子元素都添加到父元素中
最後,再一次性將整個父元素加入DOM樹
結果: 瀏覽器只重繪一次
2. 若是父元素已經在頁面上了,要添加多個平級子元素
應先將平級子元素添加到文檔片斷對象中
最後,再一次性將文檔片斷對象添加到DOM樹
結果: 瀏覽器也只重繪一次
什麼是文檔片斷: 內存中臨時保存多個子元素的虛擬父元素對象
什麼時候使用: 只要向頁面中添加多個平級子元素時
如何: 3步:
1. 建立文檔片斷:
var frag=document.createDocumentFragment();
建立 文檔 片斷
2. 將子元素添加到文檔片斷中
frag.appendChild(child)
3. 將整個文檔片斷添加到DOM樹
父元素.appendChild(frag)
刪除元素: 父元素.removeChild(child)
2. HTML DOM經常使用對象
Image Select/Option Table/... Form/表單元素
Image對象: 就表明頁面上一個<img>元素
惟一的簡化:
建立一個<img>元素: var img=new Image();
等效於: var img=document.createElement("img")
結果: <img>
Select對象: 表明頁面上一個<select>元素
屬性:
select.selectedIndex : 得到當前選中項的下標
select.value: 得到select中當前選中項的內容/值
若是選中的option有value,則優先返回value,若是選中的option沒有value,則返回innerHTML內容代替
select.options: 得到select下全部的option元素對象組成的集合。
select.options.length 得到select下全部option元素對象的個數
select.length: 等效於select.options.length
好比: 強行select.length=0; 會清空select
Option:表明select元素下的每一個option元素對象
簡化: 建立:
var opt=new Option(innerHTML, value)
Table對象: 表明頁面上一個table元素
Table是個你們族,採用逐級管理的方式:
Table管着行分組:
Table可添加行分組: var thead=table.createTHead();
等效於: var thead=document.createElement("thead")
table.appendChild(thead);
var tbody=table.createTBody()
var tfoot=table.createTFoot();
刪除行分組: table.deleteTHead();
table.deleteTFoot();
獲取行分組: table.tHead
table.tFoot
table.tBodies[i]
行分組管着行:
行分組可添加行: var tr=行分組.insertRow(i)
在行分組內i位置,添加並插入一個新行
原位置的行不是替換,而是向後順移一位
固定套路:
1. 末尾追加一個新行
var tr=行分組.insertRow()
2. 在開頭插入一個新行:
var tr=行分組.insertRow(0)
行分組可刪除行: 行分組.deleteRow(i)
坑: i要求是行在行分組內的相對下標位置
問題: 行在行分組內的相對下標位置沒法自動得到
解決: 從此刪除行不要用行分組
應該直接用table對象.deleteRow(i)
由於i要求是行在整個表中的下標位置
又由於行在整個表中的下標位置可用tr.rowIndex自動得到,因此,從此刪除行的標準寫法:
table.deleteRow(tr.rowIndex);
行分組可獲取行: 行分組.rows[i]
行管着格:
行能夠添加格: var td=tr.insertCell(i)
固定套路: 在行末尾追加新格:
var td=tr.insertCell()
問題: insertCell只能建立td,不能建立th
行能夠刪除格: tr.deleteCell(i)
行能夠獲取格: tr.cells[i]
補充: DOM中三大對話框:
alert confirm prompt
警告 確認 輸入
Form對象: 表明頁面上一個<form>元素
獲取: 也不須要查找,就可直接得到:
瀏覽器已經將網頁中全部form元素保存在了document對象的forms集合中: var form=document.forms[i]
若是網頁中只有一個表單,則document.forms[0]
屬性: form.elements 得到表單中全部表單元素的集合
form.elements.length 得到表單中表單元素的個數
form.length 等效於 form.elements.length
得到表單中倒數第二個表單元素——提交按鈕:
var btnSubmit=form.elements[form.length-2]
表單元素對象: <input> <button> <select> <textarea>
獲取: 若是要獲取的表單元素有name屬性
可用: form.name名
3. BOM: Browser Object Model
什麼是: 專門操做瀏覽器窗口或軟件的一套對象和函數
什麼時候: 若是想操做瀏覽器窗口,或訪問瀏覽器軟件相關的配置信息
如何:
包括:
window: 2個角色:
1. 代替ES標準中的global充當全局做用域對象
2. 保存全部除ES外的DOM和BOM的對象和函數庫
包括:
全局的BOM函數和屬性:
alert() confirm() prompt() window.open() window.close() ... ...
掌控特定功能的對象:
location對象 專門掌控地址欄
history對象 掌控着前進/後退/刷新
navigator對象 掌控着瀏覽器的配置信息
document對象 掌控着網頁的全部內容
screen 對象 掌控着和顯示屏有關的信息
event對象 掌控着瀏覽器中發生的全部事件
window中經常使用的全局函數或屬性:
1. 對話框: alert() confirm() prompt()
2. 窗口大小:
2組:
1. 完整窗口大小: window.outerWidth/outerHeight
2. 文檔顯示區: window.innerWidth/innerHeight
文檔顯示區: 瀏覽器窗口內專門用於顯示網頁內容有限的白色區域。
3. 打開和關閉窗口:
打開窗口: window.open() 和<a>的用法幾乎徹底同樣
總結: 用程序打開新連接有幾種效果:
1. 在當前窗口打開,可後退:
html: <a href="url" target="_self">
js: open("url" , "_self")
2. 在當前窗口打開,禁止後退:
js: location.replace("新url")
用新url代替history中當前舊的url,保持history中只有一條記錄。從而禁止後退。
3. 在新窗口打開,可同時打開多個:
html: <a href="url" target="_blank">
js: open("url" , "_blank")
4. 在新窗口打開,只能打開一個:
html: <a href="url" target="自定義窗口名">
js: open("url" , "自定義窗口名")
在瀏覽器中,每一個窗口都有內置的name屬性來惟一標識一個窗口
瀏覽器規定,相同name名的窗口只能打開一個。
其實target屬性,是在給新窗口起名
若是target的名字是自定義的名稱,則新打開的窗口,只能開一個。不能重複開。
可是,target有兩個內置的名稱:
_self: 用當前窗口本身的名字,給新窗口,致使新窗口覆蓋現有窗口
_blank: 不給新窗口指定任何名稱,瀏覽器會自動隨機分配新窗口的名稱。致使新窗口的名稱不會重複
關閉窗口: window.close()
history: 保存當前窗口打開後,成功訪問過的url的歷史記錄的集合。
什麼時候: 用程序執行前進,後退,刷新
如何: history.go(1) 前進一步
history.go(0) 刷新
history.go(-1) 後退一步
location:
什麼是location: 專門保存當前正在打開的url的信息的對象
什麼時候: 1. 得到url地址欄中各個部分的參數時
2. 經過操做地址欄中的地址實現跳轉和刷新時
如何:
1. 得到url中的各個部分:
http://localhost:3000/public/products.html#top?kwords=macbook
協議 主機 端口 相對路徑 錨點 查詢字符串
location.href 完整url
location.protocol 協議部分
location.host 主機名+端口號: localhost:3000
location.hostname 主機名 localhost
location.port 端口號 3000
location.pathname 相對路徑 public/products.html
location.hash 錨點地址 #top
location.search 查詢字符串 ?kwords=macbook
想進一步得到變量值: location.search.split("=")[1]
2. 經過操做地址欄實現跳轉和刷新:
1. 在當前窗口打開新連接,可後退:
location.href="新url" <==> open("新url","_self")
2. 在當前窗口打開新連接,禁止後退:
location.replace("新url")
3. 刷新當前頁面:
location.reload(); <==> history.go(0)
navigator:
什麼是: 保存瀏覽器配置信息的對象
什麼時候: 判斷瀏覽器的名稱和版本號
如何:
1. navigator的userAgent屬性包含了瀏覽器的名稱和版本號——字符串——沒有標準
測試: window 10的 Edge瀏覽器
Day 05
事件對象e:當事件發生時,瀏覽器自動建立的,封裝事件信息和操做事件的API 的對象;
事件對象—— 01能夠封裝事件的信息 02操做事件的API的
正課:
1. 事件:
1. 事件:
什麼是: 瀏覽器自動觸發的或用戶手動觸發的,頁面中元素狀態的改變。
事件發生時如何執行一項任務: 綁定事件處理函數
什麼是: 當事件發生時自動調用的一個函數
本質: 是元素對象上一個事件名屬性
好比: btn.onclick sel.onchange txt.onfocus
什麼時候: 只要但願發生事件時自動執行一項任務
如何:
在事件發生前就提早綁定事件處理函數到元素的事件屬性上。
如何綁定: 3種:
1. 在html中綁定:
html中: <ANY onclick="fun()">
js中: function fun(){ ... }
問題: 不符合內容與行爲分離的原則,不便於維護
2. 在js中用賦值方式綁定:
js中: 元素對象.onclick=function(){
this->當前觸發事件的元素對象自己
}
問題: 一個事件屬性,只能綁定一個處理函數
3. 在js中經過添加事件監聽對象的方式: ——最靈活
元素對象.addEventListener("事件名",處理函數)
添加 事件 監聽對象
強調: 事件名原本是沒有on: click, change, focus
只不過在用.時,爲了和其它普通屬性區分,才加了on前綴。
原理:
什麼是事件監聽對象: 一個保存元素+事件名+處理函數一套組合的對象:
好比: btnShoot.addEventListener("click",fun1);
先建立一個事件監聽對象:
{
元素: btnShoot,
事件: click,
處理函數: fun1
}
而後,addEventListener會將監聽對象添加到瀏覽器中一個隱藏的事件隊列中。
當事件發生時,瀏覽器會遍歷事件隊列中的每一個監聽對象,選擇匹配的監聽對象中的處理函數執行。
如何從元素上移除一個處理函數:
元素對象.removeEventListener("click",處理函數)
處理函數決不能用匿名函數
強調: 若是一個處理函數有可能被移除,則綁定時,就不能用匿名函數。必須用有名稱的函數。移除時,必須使用函數名,找到原函數對象,才能移除。
事件模型: 從點擊元素觸發事件開始,到事件處理函數執行完,期間所發生的一切事情。
DOM標準規定: 從點擊元素觸發事件開始,到事件處理函數執行完,期間共經歷三個階段:
1. 捕獲階段: 由外向內,記錄各級父元素上的處理函數
2. 目標觸發: 先觸發最初發生事件的元素上的處理函數
目標元素(target): 最初發生事件的實際想點擊的元素
3. 冒泡階段: 由內向外,依次執行捕獲階段記錄的父元素上的時間處理函數。
事件對象:
什麼是: 當事件發生時,瀏覽器自動建立的,封裝事件信息和操做事件的API 的對象
什麼時候: 1. 想改變事件默認的執行行爲時
2. 得到事件信息時
如何:
建立: 不用本身建立,直接使用
在事件發生時,自動獲取事件對象:
事件對象老是做爲處理函數的第一個參數傳入處理函數中。——信任
如何獲取事件對象:
btn.onclick=function(e){ //event的縮寫
//當事件發生時,會自動調用處理函數,並自動傳入事件對象給形參e
}
事件對象能幹什麼?
1. 中止冒泡(Propagation): e.stopPropagation()
2. 利用冒泡(事件委託/事件代理)
優化: 儘可能減小事件監聽對象的個數
由於瀏覽器觸發事件,是在監聽隊列中遍歷查找符合條件的監聽對象來觸發。
因此,監聽對象越多,事件響應就越慢
如何: 當多個平級子元素都須要綁定相同的事件時,只要在父元素上綁定一次事件處理函數。全部孩子就可冒泡共用。
2個難題:
1. this已經不指子元素了,而是指父元素:
由於處理函數是定義在父元素上,且是等到事件冒泡到父元素時才觸發。
如何得到實際單擊的子元素:
用e.target代替this
目標
e.target可自動得到實際點擊的目標子元素
且不隨冒泡而改變
總結: this->不求天長地久,只願曾經擁有
e.target->一旦擁有別無所求
2. 有可能點在正確的子元素上,也有可能點偏,點在不想要的元素上。
解決: 在正式執行操做前,必須先驗證e.target是否是想要的。
好比: 驗證標籤名, 驗證class, ... ...
補: 如何獲取元素的標籤名: 元素.nodeName
但nodeName返回全大寫的標籤名:
BUTTON A IMG LI ... ...
v
阻止默認行爲:
問題: 有些瀏覽器的某些元素擁有默認的行爲,而默認行爲不是咱們想要的。
好比: <a href="#"> 默認行爲會在url地址欄結尾添加#,擅自篡改地址欄。
如何: e.preventDefault();
阻止 默認
預告: HTML5拖拽API中,幾乎全部函數:
一上來先是兩句話:
e.stopPropagation()
e.preventDefault();
得到鼠標的座標:
事件對象中包含3組座標:
1. 相對於整個屏幕左上角的座標:
e.screenX e.screenY
2. 相對於文檔顯示區左上角的座標:
e.clientX e.clientY
3. 相對於當前所在元素左上角的座標:
e.offsetX e.offsetY
Day 01
正課:
1. 什麼是jQuery
2. 如何使用jQuery
3. 查找元素
4. 修改元素
1. 什麼是jQuery:
第三方開發的 執行DOM操做的 極簡化的 函數庫
第三方: 先下載,才能使用
執行DOM操做: 學jQuery仍是在學DOM的增刪改查+事件綁定。
極簡化: jQuery是DOM操做的終極簡化
函數庫: jQuery中都是用函數解決一切問題,沒有屬性。
爲何: 2個緣由:
1. 是DOM操做的終極簡化: 4個方面
增刪改查
事件綁定
動畫
ajax
2. 解決了絕大部分兼容性問題:
凡是jQuery讓用的,都沒有兼容性問題
好比: IE8: 不支持:nth-child(i) 選擇器
document.querySelector("xxxx:nth-child(i)")錯誤
若是使用jQuery: $("xxxx:nth-child(i)") 正確!
原理: jQuery先檢查兼容性問題。
若是發現當前瀏覽器不兼容,會用js模擬出選擇器的效果。
CSS選擇器:nth-child(i) -> js中的children[i-1]
jQuery的問題:
1. 僅限於PC端
2. 僅僅是對DOM操做的每一步進行的簡化。並無完全簡化開發的步驟。
2. 如何使用jQuery:
下載: jquery.com
1.x: 兼容舊瀏覽器 1.11.3
未壓縮版: 擁有完備的註釋,代碼格式和見名知義的變量名。——可讀性好。問題: 體積大不便於下載和傳輸。
壓縮版: 去掉註釋,全部空格/換行等格式,最簡化了變量名。——體積極小。問題: 可讀性差。——上線後/生產環境中
Webpack工具: 將HTML,CSS,JS代碼壓縮打包爲極簡化的代碼。
2.x: 再也不兼容舊瀏覽器
3.x: 不兼容舊瀏覽器,增長了部分新特性
引入: 在須要使用jQuery的頁面中先引入jquery.js文件
<script src="js/jquery-1.11.3.js"></script>
而後再編寫自定義js程序
<script>自定義的js程序</script>
原理:
引入jquery-1.11.3.js後:
在內存中添加了一種新的類型jQuery,包括兩大部分:
1. 構造函數: 建立該類型的子對象,並填充對象的內容
function jQuery(選擇器){
//...
}
2. 原型對象: 保存該類型全部的孩子共用的函數
jQuery.prototype:{
//全部jQuery子對象可以使用的公共的函數
}
只要想使用jQuery家的簡化版API,必須先建立jQuery類型的子對象。又由於jQuery家的函數都是爲了操做DOM元素的,因此建立jQuery對象時,都要找到DOM樹上的原生DOM元素,保存到jQuery對象中。
好比: var btn1=new jQuery("#btn1")
先在原生DOM樹上找到id爲btn1的原生DOM按鈕。
而後建立jQuery對象,保存找到的這個按鈕對象。
可是new jQuery太麻煩,因此jQuery構造函數中,提早包含了return new jQuery,調用jQuery(),就等效於調用new jQuery了,以此省略new:
function jQuery(選擇器){
return new jQuery(選擇器)
}
因此: var btn1=jQuery("#btn1")
可是jQuery的名字仍是長,因而做者: $=jQuery
因此,用$=用jQuery=new jQuery
因此: var btn1=$("#btn1");
由於jQuery對象是jQuery家的孩子,不是DOM家的孩子,因此jQuery對象不能使用原生DOM的API,同理原生DOM的按鈕也不能使用jQuery的簡化版API,因此變量名必須有所區分,因此習慣上全部jQuery對象的變量都以$開頭,好比: var $btn1=$("#btn1")
對jQuery對象,調用簡化版函數,jQuery對象會自動翻譯爲對應的原生函數,自動做用於內部保存的原生DOM對象上,好比: $btn1.click(function(){ ... })
就等效於: btn1.addEventListener("click",function(){ ... })
再好比: 調用$btn1.html(),會被自動翻譯爲btn1.innerHTML
本質: jQuery對象實際上是一個保存多個找到的DOM元素的類數組對象
3. 查找: 2種:
1. 按選擇器查找元素:
var $elems=$("任意選擇器")
jQuery支持全部CSS3的選擇器
同時還擴展了一批新的選擇器:
回顧: 子元素過濾: 同CSS
在多個父元素內,選擇處在指定位置的子元素
:first-child :last-child :nth-child(i) :only-child
新: 基本過濾/位置過濾: jQuery新增的
先將符合條件的全部元素取出來,放在一個大的集合中,再按元素在集合中的順位編號選擇指定的元素
:first :last :even :odd :eq(i) :gt(i) :lt(i)
偶數 奇數 等於 大於 小於
新: 內容過濾: 用元素的內容中的文本關鍵詞做爲查詢條件:
1. :contains(關鍵詞): 只要元素的內容中包含"關鍵詞",就選中該元素
2. :has(選擇器): 只要當前元素的內容中包含符合"選擇器"條件的子元素,就選中
新: 可見性過濾: 選擇那些可見的或不可見的元素
:hidden 匹配看不見的隱藏元素
只能匹配兩種: display:none 和 input type="hidden"
不能匹配兩種: visibility:false 和 opacity:0
:visible 匹配看的見的元素
新: 表單過濾: 專門查詢表單中的表單元素的選擇器
:input 選擇全部表單元素: input select textarea button
vs input 僅選擇input元素
每種type都對應一種選擇器:
:text :password :checkbox :radio :file ... ...
2. 按節點間關係查找元素:
好比: $elem.next() 得到當前元素的下一個兄弟元素
$elem.nextAll() 得到當前元素以後全部的兄弟元素
4. 修改:
內容: 3種:
1. 原始的HTML片斷: .innerHTML => .html()
2. 若是想去內嵌的標籤或特殊符號: .textContent => .text()
3. 表單元素的值: .value => .val()
屬性:
1. HTML標準屬性:
2. 三大狀態屬性: checked selected disabled
$elem.prop("狀態",bool)
3. 自定義擴展屬性:
樣式: .style.css屬性=值 => $elem.css("css屬性名","值")
福利: 不用寫單位——僅jq有
問題: 一次只能改一個css屬性:
解決: 同時修改多個css屬性:
$elem.css({
"css屬性1": 值1,
... : ... ,
})
jQuery函數的特色: 3個:
1. 自帶遍歷效果: 對jQuery對象總體調用函數,等效於自動對內部保存的多個原生DOM對象,分別調用函數。
好比: 頁面上三個button,每一個按鈕都要綁定單擊事件:
//用DOM作
var btns=document.getElementsByTagName("button");
for(var btn of btns){//只能遍歷
btn.onclick=function(){ ... }
}
//用jQuery作,不用遍歷,只要對總體調用一次click()
var $btns=$("button");
$btns.click(function(){ ... })
等效於自動: btns[0].onclick=function(){ ... }
btns[1].onclick=function(){ ... }
btns[2].onclick=function(){ ... }
2. 一個函數兩用: 調用一個函數時,若是不給新值,自動執行獲取值的操做。若是給了新值,自動切換爲更新的操做。
好比: DOM獲取或修改一個按鈕的內容:
獲取: btn.innerHTML
修改: btn.innerHTML=新值
jQuery中:
獲取: btn.html()
修改: btn.html(新值)
3. 幾乎全部函數都返回正在遍歷的jQuery對象,便於重複使用
好比: $("ul>li:first").css(...) //return $("ul>li:first")
可繼續對$("ul>li:first")繼續執行操做
好比: 可直接跟.html(),繼續訪問第一個li的內容
鏈式操做: 將多個操做經過.鏈接起來連續調用,稱爲鏈式操做。
前提: 必須對每一步函數調用的返回值瞭如指掌
優勢: 減小變量的使用,減小查找的次數,優化程序
補: var bool=$elem.is("選擇器")
判斷當前元素是否知足選擇器的條件要求
返回bool值: 若是elem元素的特徵知足選擇器的要求,就返回true,不然返回false。
Day 02
正課:
1. 修改
2. 按節點間關係查找
3. 添加/刪除/替換/克隆
4. 事件綁定
1. 修改:
內容:
1. 原始HTML片斷內容:
.innerHTML -> .html([新內容]) 兩用
2. 純文本內容(去內嵌標籤):
.textContent -> .text([新內容]) 兩用
3. 表單元素的值:
.value -> .val([新值]) 兩用
屬性:
1. HTML標準屬性: 2種:
1. 核心DOM:
元素.getAttribute()
元素.setAttribute()
↓
$元素.attr("屬性名"[,新值]) 兩用
2. HTML DOM:
元素.屬性名=值
property
↓
$元素.prop("屬性名"[,新值]) 兩用
不管attr仍是prop均可同時修改多個屬性:
$元素.attr|prop({
屬性名:值,
... : ... ,
})
2. 狀態屬性: disabled checked selected
不能用核心DOM的getAttribute()或setAttribute()訪問
天然也就不能用$元素.attr()訪問
只能用.訪問: chb.checked=true;
而在jquery中只能用: $元素.prop()
3. 自定義擴展屬性:
只能用核心DOM的getAttribute()和setAttribute()訪問
天然也能用jQuery的$元素.attr()
可是,不能用.訪問: ANY.data-trigger=值
天然也不能用jQuery的$元素.prop()訪問
樣式:
elem.style.css屬性 -> $元素.css()
問題: 只能一個一個的修改css屬性,沒法快速簡介的批量修改。
解決: 只要批量修改樣式,都用class屬性
jQuery: $元素.addClass("類名") 添加class
$元素.removeClass("類名") 移除class
$元素.hasClass("類名") 判斷是否包含class
比DOM的 className="類名"是覆蓋,沒法只精確修改某一個class。
而addClass和removeClass(),可精確修改某一個class,而不影響其它class。
另外: $元素.toggleClass("類名")
自動判斷是否包含指定"類名",自動在有和沒有這個類名之間來回切換
好比一個按鈕在有class down和沒有class down之間來回切換:
//若是當前按鈕沒有class down,就添加down
if(!$(this).hasClass("down")){
$(this).addClass("down");
}else{//不然,就移除down
$(this).removeClass("down");
}
其實最簡單的寫法: $(this).toggleClass("down");
2. 查找:
1. 按選擇器查找:
2. 按節點間關係查找:
兩大類關係
1. 父子關係
元素.parentNode|parentElement 父元素
jq -> $元素.parent();
元素.children 全部直接子元素
jq -> $元素.children(["選擇器"]);
若是沒有選擇器,就得到全部直接子元素
若是提供了選擇器,就僅得到符合選擇器要求的部分直接子元素
jq -> $元素.find("選擇器")
在元素的全部後代中查找符合選擇器要求的
強調: 必須寫選擇器
元素.firstElementChild 第一個直接子元素
jq-> $元素.children().first()
元素.lastElementChild 最後一個直接子元素
jq-> $元素.children().last()
2. 兄弟關係
元素.previousElementSibling 前一個兄弟
jq->$元素.prev()
擴展: jq -> $元素.prevAll(["選擇器"])
選擇當前元素以前全部兄弟元素(符合條件的)
元素.nextElementSibling 後一個兄弟
jq->$元素.next()
擴展: jq -> $元素.nextAll(["選擇器"])
選擇當前元素之後全部兄弟元素(符合條件的)
擴展:
jq->$元素.siblings(["選擇器"])
選擇除當前元素之外不管先後的全部兄弟元素(符合條件的)
3. 添加/刪除/替換/克隆:
1. 添加元素:
jq: 2步:
1. 用html片斷建立新元素:
var $elem=$(`html片斷`)
2. 將新元素添加到DOM樹
末尾追加: 父元素.appendChild(新元素)
jq -> $父元素.append($新元素)
擴展: 開頭追加: $父元素.prepend($新元素)
中間插入: 父元素.insertBefore(新元素, child)
jq -> $child.before($新元素)
擴展: 在當前元素後插入新元素: $child.after($新元素)
問題: 要麼返回父元素,要麼返回舊的子元素,沒法在調用後繼續利用鏈式操做,對新元素作後續連續操做。
解決: 其實以上API都有一對兒:
好比: $父元素.append($新元素)
$新元素.appendTo($父元素)//return $新元素
.對新元素繼續操做
再好比: $父元素.prepend($新元素)//return $父元素
$新元素.prependTo($父元素)//return $新元素
.對新元素繼續操做
2. 刪除: $元素.remove();
3. 替換:
父元素.replaceChild(新元素, 舊元素)
jq-> $舊元素.replaceWith($新元素)//return $舊元素
$新元素.replaceAll($舊元素)//return $新元素
.對新元素繼續操做
4. 克隆: var $新元素=$元素.clone();
4. 事件綁定:
標準事件綁定:
DOM: 元素.addEventListener("事件名",處理函數)
元素.removeEventListener("事件名",處理函數)
jq: addEventListener->on
removeEventListener -> off
$元素.on("事件名",處理函數)
$元素.off("事件名",處理函數)
簡寫的事件綁定: 僅限於最經常使用的21種事件
$元素.事件名(function(e){
e.stopPropagation();
e.preventDefault();
var $this=$(this);
var $tar=$(e.target)
... ...
})
事件代理:
DOM:父元素.addEventListener("click",function(e){
var tar=e.target;
if(tar是xxxx){
正式的邏輯
}
})
jq: 2處簡寫:
1. this又回來了!
2. 不用寫if了!
$父元素.on("click","選擇器條件",function(e){
//自動if($tar.is("選擇器條件"))
//自動保證全部進入function的元素都是符合選擇器條件的。
var $tar=$(this);
... ...
})
什麼是DOM對象:就是js對象,使用js的方式獲取到的元素就是js對象,也就是dom對象;
Jq與js的聯繫:jq對象就是js對象的一個集合,僞數組,裏面存放了一大堆的js對象
Day 03
正課:
1. 事件
2. 動畫
3. 類數組對象操做
4. 添加自定義函數
5. 封裝自定義插件
1. 事件:
頁面加載後執行:
問題: 瀏覽器加載HTML和js是順序加載
必須保證js在HTML加載後執行,才能保證全部的查找都能找到想要的元素。
可是<script>可能被放在開頭,也可能被放在結尾
如何保證不管<script>放在網頁開頭和放在結尾,都能正常執行呢?
解決: 不要將js代碼直接放在<script>內
window有一個事件: load,會在整個網頁加載完成後,自動執行。全部js代碼都應該放在window.onload=function(){}中,在頁面加載後自動執行。
強調: window.onload=functio(){}不管寫在哪兒,都只能在整個窗口內容加載完才自動執行
問題: window.onload有兩個缺點:
1. =是賦值覆蓋的意思,若是同時出現多個window.onload=function(){ ... },結果只有最後一個會覆蓋以前全部。
解決: $(window).load(function(){ ... })
//addEventListener() 可反覆加多個
2. window.onload須要等待全部頁面內容(html,css,js,圖片)加載完成才執行。——慢, 晚
其實大多數狀況下,用戶急於使用功能,而無所謂圖片內容和網頁美觀。
解決: 其實在window.onload以前還有一個事件會提早觸發: DOMContentLoad——只等待HTML和JS加載完,無需等待CSS和圖片。——快,早!
可是DOMContentLoad事件有兼容性問題,只能用jQuery方式綁定: $(document).ready(function(){ ... })
當 網頁 就緒 自動執行
因此,放在$(document).ready(function(){...})中的代碼會在DOM內容加載後就提早觸發。無需等待CSS和圖片。
總結: jQuery中全部代碼都要放在$(document).ready()中
簡化: $(document).ready(function(){...})
||
$().ready(function(){ ... })
||
$(function(){ ... })
總結: jQuery中全部代碼都要放在$(function(){ ... })中
除非必須依賴css和圖片的jq代碼才必須在window.load中執行。可是不多。
鼠標事件:
mouseover mouseout —— 即便父子元素也當作獨立的元素看待,從父元素進入子元素,一樣會觸發父元素的mouseout事件,與現實不符。
解決: jQuery 用 mouseenter mouseleave 代替
優勢: 認爲進入子元素,並無離開父元素
簡寫: 若是同時綁定mouseenter和mouseleave時
其實只要綁定一個hover函數便可:
$元素.mouseenter(function(){ ... })
.mouseleave(function(){ ... })
||
$元素.hover(
function(){ ... }, //-> mouseenter
function(){ ... } //-> mouseleave
)
模擬觸發: 即便沒有點擊按鈕,也可執行按鈕的單擊事件處理函數
如何: $元素.事件名() //手動調用指定元素上的事件處理函數
2. 動畫:
1. 簡單動畫: 固定的三種動畫效果
1. 顯示隱藏: $元素.show() $元素.hide() $元素.toggle()
問題/優勢: 本質實際上是用display:block和display:none來實現的瞬間顯示隱藏。
解決: 加參數: 動畫持續時間
$元素.show(2000) $元素.hide(2000)
2. 上滑下滑: $元素.slideUp()
$元素.slideDown()
$元素.slideToggle() 切換
3. 淡入淡出: $元素.fadeIn()
$元素.fadeOut()
$元素.fadeToggle();
問題:
1. 效果固定的,沒法修改
2. 都是用js程序和定時器模擬的動畫效果——效率低
總結: 未來能用css作的動畫,首選css——效率高,可維護
特別推薦: $元素.show() $元素.hide() $元素.toggle()
不包含動畫效果,僅簡化display操做
好比: $元素.css("display","block")
.show()
$元素.css("display","none")
.hide()
$元素.toggle() 自動在顯示和隱藏之間來回切換
2. 萬能動畫: 對任意css屬性應用動畫效果
$元素.animate({
//目標樣式
css屬性:值,
... : ... ,
}, 動畫持續時間ms)
讓{}裏的css屬性,在規定的時間ms內,從當前值緩慢過渡到目標值
問題: 1. 也是用js和定時器模擬的,效率低
2. 功效相似於css的transition,還不如transition
相同: 凡是單個數值的屬性: 都支持
width, height, left, top, padding, margin ...
不一樣: CSS中的transition支持顏色動畫
也支持CSS3變換
jq中的animate不支持顏色動畫
也不支持CSS3變換
排隊和併發:
排隊變化: 多個css屬性,前後按順序變化
如何: 對同一個元素反覆調用屢次動畫函數,多個動畫函數的效果是排隊順序執行的。
好比: $s2.animate({left:400},2000)
.animate({top:300},2000)
本質:
全部的元素都有一個動畫隊列:
調用動畫函數,並非馬上執行動畫的意思,僅僅是將動畫效果加入隊列中等待順序執行。
併發變化: 多個css屬性,同時變化
如何: 放在一個animate中的多個css屬性默認併發同時變化
動畫結束後自動執行:
jQuery中全部動畫函數都是定時器模擬的,因此都是異步的。主程序中其它函數是不會等動畫執行完才執行的。
解決: 若是但願在動畫接收後才自動執行一項任務,可用動畫函數提供的回調函數參數
如何: 每一個動畫函數,都有最後一個參數,是一個回調函數。放在回調函數中的代碼,必定會在動畫結束後才自動執行
中止動畫: $元素.stop()
坑: .stop()默認只中止隊列中當前正在播放的動畫,後續動畫依然繼續播放。
解決: .stop(true) 中止當前動畫,並清空隊列
選擇器: :animated 匹配正在播放動畫的元素
3. 類數組對象操做:
jQuery的$()查詢後的結果就是一個類數組對象
可是在js中類數組對象很受歧視,數組家的函數,都用不了。
jQuery中爲類數組對象提供了兩個最經常使用的函數:
$(...).each() 相似於 js中的數組的forEach
遍歷集合中的每一個元素,執行相同的操做
如何: 遍歷一個ul下的全部li
$("ul>li")//返回類數組對象
//.forEach(function(elem, i , arr){ ... })
.each(function(i, elem){
elem->每一個li ...
$(elem)->jq的$li
})
$(...).index() 相似於js中的數組的indexOf
查找集合中是否包含指定的元素,以及在什麼位置
如何: 在一批元素中查找一個指定元素的位置
好比: 查找一個$li在ul下全部li中是第幾個
var i=$("ul>li").index($li)
可簡寫: 若是是在同一個父元素下找li的位置
var i=$li.index(); //自動就在當前裏的父元素內查找
4. 添加自定義函數:
什麼時候: 當jQuery中提供的函數不夠用時
如何: 向jQuery的原型對象中添加新函數,全部jQuery對象均可以使用。
好比: 爲全部jQuery對象添加一個函數: sum() 能對找到的全部元素的內容自動求和。
1. 先在jQuery原型對象中添加自定義的共有函數
//jQuery.prototype.sum=function(){
||
jQuery.fn.sum=function(){
//遍歷未來調用sum()的點前的jQuery查找結果集合中的每一個元素,並計算內容的和
var $elems=this; //直接拿到$("ul>li") jq對象,不須要$()
var total=0;
$elems.each(function(i, elem){//elem取出的是$elems中保存的一個一個的DOM對象
var $el=$(elem);
total+=parseInt($el.html())
})
//返回計算結果
return total;
}
2. 在任意jQuery對象上調用
var 內容的和=$("ul>li").sum()
5. 封裝jQuery自定義組件:
官方組件庫: jQuery UI
如何:
1. 引入jQuery UI的css
2. 按組件的要求編寫HTML內容
3. 引入jQuery.js和jQuery UI.js
4. 編寫自定義代碼,找到組件的父元素,對父元素調用一次組件函數。
jQueryUI的原理: 侵入性: 在程序員不知情的狀況下,自動添加樣式和行爲。
若是本身封裝了插件,本身用,jQueryUI方式必定是簡單
若是考慮可維護性和靈活性,jQueryUI封裝的太死了,不便於維護。
jQuery組件是一套可重用的CSS樣式和js功能的集合
爲何: 重用!
什麼時候: 當發現不少網頁中都須要一個小功能時,就要將這個功能的樣式和行爲封裝爲一個組件,未來反覆使用
如何:
定義組件:
0. 前提: 已經用原始的CSS,DOM,jq實現了。只不過暫時沒有分離出來。因此定義jQuery組件其實僅是一個提取的過程
1. 向jQuery的原型對象中添加自定義的組件函數
1.1 爲組件的HTML元素添加樣式
自動在各個元素上侵入class
1.2 爲組件的HTML元素添加行爲
2. 將原來寫好的CSS代碼提取到專門的css文件中獨立存儲
使用組件: 和使用jQuery UI組件的用法徹底同樣
Day 04
jQuery中的$()共能夠作幾件事?
$("選擇器") 查找DOM元素,保存進jQuery對象中
$(this|e.target) 將DOM元素,封裝爲jQuery對象
$(`html片斷`) 建立新元素
$(function(){ ... }) 綁定事件,DOM內容加載後就提早觸發
鄙視: 如何避免組件間樣式衝突
很差的作法: 更名
由於項目中要求描述一個事物或一種功能,必須用統一的名稱。
好的作法: 在全部的樣式類前加上統一的前綴
正課:
1. ajax
2. *****跨域
1. ajax
$.ajax({
url:"服務端接口地址", //http://localhost:3000/users/login
type:"get|post",
data: { uname: "dingding", upwd: "123456" },
//"uname=dingding&upwd=123456",
//若是返回json,須要自動JSON.parse()轉爲js對象
dataType:"json", //若是不寫須要本身手動調用JSON.parse()
//onreadystatechange =function(res){ ... }//在響應回來後,處理響應結果
success: function(res){
//res是JSON.parse()已經翻譯過的可直接使用的js對象/數組
}
})
2. *****跨域:
瀏覽器同源(origin)策略: 也稱禁止跨不一樣源頭訪問資源
強調: 僅限於ajax
瀏覽器規定發送ajax請求時,只有相同域名的客戶端和相同域名的服務端之間才能發送請求:
好比: 學子商城項目:
客戶端:
http://localhost:3000/index.html
index.js
$.ajax()
請求↓ ↑響應 成功
服務端:
http://localhost:3000/index
跨域: 從一個域名下的網頁,向另外一個域名下的服務端發送ajax請求——受瀏覽器的同源策略控制,禁止發送的
好比:
1. 域名不一樣:
http://www.a.com/index.html -> http://www.b.com
2. 子級域名不一樣:
http://oa.tedu.cn/index.html -> http://hr.tedu.cn
3. 端口號:
http://localhost:5500/index.html -> http://localhost:3000
4. 協議不同:
http://localhost/index.html -> https://localhost
:80 :443
5. 即便同一臺機器,域名和IP之間互相訪問
http://localhost/index.html -> http://127.0.0.1
域名 IP
以上5種狀況,都會報ajax請求錯誤:
CORS...Access-Control-Allow-Origin
可是,現實中,隨處可見跨域請求:
手機都能看天氣和股票
淘寶可跟蹤全部快遞公司的物流信息
必定能夠跨域請求: 如何跨域
1. CORS方式: 僅服務端改代碼,就可跨域
同源策略的本質: 其實能夠發送ajax請求
也能夠正常執行服務端的程序
也能夠順利返回正確的結果
可是,瀏覽器通過檢查數據的來源,發現和當前網頁的來源不一致,因此,到手的數據不讓用!
如何: 其實就是在服務器端返回響應的響應頭中假裝成指定的源頭
//res.send(result); //不要用res.send了
res.send實際上是一種簡寫:
等效於:
res.writeHead()+res.write(JSON.stringify(result))+res.end()
想跨域,就不要用簡寫的res.send()
本身在服務端寫三步:
res.writeHead(200,{
"Access-Control-Allow-Origin":"http://127.0.0.1:5500"
});
res.write(JSON.stringify(result));
res.end();
這樣返回的數據,就被假裝成來自127.0.0.1:5500的,就能夠經過瀏覽器的同源策略檢查,可正常使用
2. JSONP方式: JSON with padding
填充式JSON
方案一: 用<script src="服務端接口地址"代替$.ajax發送請求。
服務端: 將要發送的數據填充在一條js語句中
res.write(`document.write("${weather}")`)
客戶端: <script src="服務端接口地址"
<script 發送請求到服務端
並可以收到服務端返回的js語句字符串:
document.write("${weather}")
<script只要收到js語句,就馬上自動執行
問題: 要在客戶端執行的js語句,在服務端寫死了,衆口難調。
方案二: 提早在客戶端定義一個函數,用於處理服務端返回的請求,服務端僅使用函數名拼接一條函數調用的js語句
客戶端: function show(weather){
任意js語句
}
服務端: res.write(`show("${weather}")`)
問題: 本該定義在客戶端的函數名,在服務端是寫死的,衆口難調
方案三: 用請求參數,將函數名傳遞給服務器
客戶端: <script src="http://localhost:3000?callback=show"
服務端: 接收客戶端傳來的名爲callback的參數中保存的函數名
將callback函數名動態拼接到要返回的函數調用語句中
問題: <script是在頁面中寫死的,只能在頁面加載過程當中執行一次。沒法按需反覆執行,好比每次單擊按鈕時,隨時發送請求。
方案四: 每次單擊按鈕時動態建立<script元素
客戶端:
$("button").click(function(){
//不要用$("<script>")動態建立<script>元素
//瀏覽器會強行將<script>解析爲標籤
//退一步,用核心DOM
var script=document.createElement("script");
script.src=`http://localhost:3000?callback=doit`;
document.body.appendChild(script);
})
問題: 每次單擊時都會建立<script,反覆單擊會致使<script堆積
解決: 在回調函數結尾:
刪除body最後一個<script>
function doit(weather){
alert(weather);
//回調函數結尾: 刪除用過的<script>
$("body>script:last").remove();
}
jQuery對jsonp方式跨域進行了終極的簡化:
$.ajax({
url:
type:
data:
dataType:"jsonp"
success:function(){
... ...
}
})
VUE
安裝服務器腳手架
npm i express-generator -g 安裝服務器腳手架
express --no-view server 不帶模板引擎
npm install 安裝依賴
Day 01
正課:
1. 什麼是Vue
2. 如何使用Vue
3. MVVM
4. 綁定語法
5. 指令
1. 什麼是Vue:
漸進式的 基於MVVM的 執行數據操做的 純前端js框架
漸進式: 能夠逐步在項目中使用Vue框架
能夠和現有傳統技術很好的結合
全家桶: 若是要使用一種框架,就只能使用框架的全部技術。不能和其它技術混搭。
基於MVVM?
執行數據操做的: 終極簡化對網頁執行的數據操做: 增刪改
純前端js框架: 不要nodejs,僅靠瀏覽器就可運行項目
2. 如何使用:
官網: cn.vuejs.org
下載: 版本: 2.6
2種:
1. 下載vue.js文件,引入網頁中——前三天
開發版: 體積大,可讀性好,帶錯誤提示
生產版: 體積小,可讀性差,去掉了全部錯誤提示
2. 腳手架代碼——最後一天作項目
如何引入:
<script src="js/vue.js">
<script>自定義代碼</script>
如何使用:
3大步:
1. 定義頁面的HTML內容:
要求: 必須包含在一個<div id="app"></div>內
必須用{{變量}}標記處,要使用數據的位置
若有事件處理函數,就用@click綁定事件處理函數
好比: <div id="app">
<button @click="add">click me({{n}})</button>
2. 在自定義程序中先定義頁面所需的全部數據。
要求: 必須包含在一個data:{}對象中
好比: 頁面上有一個{{n}},表示一處n須要發生變化,因此
var data={ n:0; }
3. 建立new Vue()對象示例,將數據和頁面元素綁定起來
var vm=new Vue({
el:"#app",
data: data,
//結果: data中的變量是什麼值,頁面中就顯示什麼值
//data中的變量被改爲什麼值,頁面中就自動變成什麼值
//若是須要事件處理函數,都要定義在methods:{}中
methods:{
add:function(){//當單擊按鈕時,自動觸發add函數
this.n++; //修改data中的n+1,頁面上的n自動跟着變化
}
}
})
事件: 2步:
1. 在頁面的html元素上用@click="add" 綁定事件處理函數
2. 事件處理函數,不要定義在new Vue的外邊
應該定義在new Vue中專門的methods屬性內:
new Vue({
el:"#app",
data: data,
methods:{
add:function(){
this.變量++
}
}
})
總結: 頁面須要什麼,Vue就定義什麼
好比: <button @click="add">click me(0)</button>
new Vue({ ↑ ↑
add:function(){} {{n}}
<button @click="sub">- <span>1 <button @click="add">+
new Vue({ ↑ ↑ ↑
sub:function(){} {{n}} add:function(){}
3. MVVM模式:
傳統的DOM:
HTML: 只負責靜態內容,不會自動變化
CSS: 只負責靜態樣式,不會自動變化
JS: 即要負責內容的變化,又要負責樣式的變化
問題: 1. 步驟繁瑣且重複: 查找,綁定,遍歷,替換,拼接字符串
2. 不便於維護:jQuery中,若是頁面結構或內容發生變化,則js中選擇器和HTML片斷都要跟着修改
現代框架: MVVM模式
1. 界面/視圖View: 包括靜態的HTML+CSS
2. 數據模型Model: 頁面中所需的全部數據的總體
3. 控制器/視圖模型ViewModel: 自動將數據模型Model中的變量,填充到界面中所需的位置
總結: 什麼是M V VM模式: 頁面須要什麼,模型就定義什麼。
視圖模型會自動將模型中的數據填充到頁面中。且模型數據發生變化時,視圖模型會自動更新頁面。
優勢: 1. 沒有任何重複的代碼
2. 界面和模型鬆耦合,界面變化,不須要修改模型,甚至不須要修改ViewModel控制器。——及其便於維護
ViewMode的原理:
當new Vue將模型對象和頁面元素綁定在一塊兒時,內部自動構建兩大子系統:
1. 響應系統:
自動將data中的每一個變量變成訪問器屬性
從此,全部對變量的讀寫,自動都被訪問器接管,由訪問器屬性代爲執行。
好比:修改變量的值時,自動調用變量的set方法,修改實際的變量值。
而每一個變量的set方法,當變量發生改變時,都會自動發送通知:xxx變量的值變成xxx了
通知是交給另外一子系統,虛擬DOM樹的
2. 虛擬DOM樹:
當new Vue()建立對象時,會掃描el:"#app"指向的父元素div,及其子元素。而後,僅找到可能發生變化的元素,保存在一個簡化版的虛擬DOM樹結構中:
好比:
var virtualDOM={
element: div, //<div id="#app"
id:"#app",
children:[
{
element: button, //<button>click me({{n}})
innerHTML: "click me {{n}}",
@click:"add"
},
//其它可能變化的元素
]
}
什麼是虛擬DOM樹: 僅保存可能變化的元素的簡化版樹結構對象,同時預先封裝了要對元素執行的DOM操做。
當響應系統發來某變量被修改的通知後,虛擬DOM樹先遍歷本身內部的元素,找到受這個被修改變量影響的元素。而後自動調用預先定義好的DOM操做,更新實際DOM樹上的元素。其他未受變量影響的元素,保持不變。
虛擬DOM樹的優勢:
1. 僅包含可能變化的元素,內容精簡,便於快速遍歷,查找變化的內容。
2. 封裝了DOM操做,自動執行DOM操做,無需開發人員重複編碼。
this: 凡是進入new Vue中的,不管是data中的變量,仍是methods中的方法,都被打散,直接隸屬於new Vue,變爲相鄰的平級成員。因此,在方法中想訪問data中的數據,必須加this.
4. 綁定語法:
{{ }} 學名: 插值(Interpolation)語法
什麼是: 專門用於將一個變量的值自動插入到頁面的指定位置
什麼時候: 凡是頁面上可能發生變化的地方,都用{{}}
如何:
基本用法: {{變量名}}
結果: 運行時: 會被自動替換爲變量的值
擴展: {{一切合法的有返回值的js表達式}}
好比: 算術計算、方法調用、對象屬性、三目運算...
可是,不能寫沒有返回值的:
if else for while 程序結構
好比: <h1>空氣質量: {{pm25<100?"好":
pm25<200?"中":
pm25<300?"差":
"活不了了!"}}
執行時,vue會拿着data中的數據變量pm25,到{{}}中執行js表達式,比較每一個判斷條件,選擇一個符合條件的值返回,做爲替換{{}}位置的值。
5. 指令:directive
什麼是: 爲HTML增長新功能的專門的屬性
爲何: HTML自己不具有程序該有的功能
一個程序基本的功能:
變量:
判斷:
循環:
什麼時候: 只要想在html中使用相似變量,判斷,循環等程序的功能時,就用指令:
Vue中共定義了13種指令:
1. v-bind:
什麼是: 專門用於綁定屬性值的指令
什麼時候: 只要一個屬性值可能根據變量的值自動變化時
爲何: {{}}只能用於綁定元素內容(innerHTML)中的值
不能用於動態綁定屬性值
如何:
<ANY v-bind:屬性="任意合法的js表達式"
可省略v-bind
好比: <img :src="pm25<100?'img/1.png':
pm25<200?'img/2.png':
'img/3.png' "
執行時: Vue會拿着data中的pm25變量,到有:的屬性中執行三目運算,選擇其中一個符合條件的字符串,做爲替換src屬性值的路徑。
2. v-if v-else-if v-else
多個元素,根據條件不一樣,選其一顯示
只有符合條件的元素才顯示
不符合條件的同組其餘元素默認隱藏
如何:
//若是pm25<100
<img v-if="pm25<100" src="img/1.png"
<span></span>之間絕對不能插入其它無關元素
//不然 若是pm25<200
<img v-else-if="pm25<200" src="img/2.png"
//不然
<img v-else src="img/3.png"
原理: 其實全部帶v-if v-else-if v-else的元素都沒有在頁面上。而是根據條件,動態決定臨時添加哪一個元素到頁面
——靠添加刪除DOM元素的方式控制元素的顯示
強調: 之間不能插入其它無關的元素
3. v-show
根據條件決定當前一個元素是顯示仍是隱藏
如何: <ANY v-show="條件">
當條件知足時,當前元素就顯示
當條件不知足時,當前元素就不顯示
好比: <button v-show="i<count" @click="next">下一頁</button>
問題: 若是用在多個元素控制顯示隱藏,則必須把條件反覆寫在每一個元素上
vs v-if:
v-show採用display:none/block方式控制顯示隱藏,不修改DOM樹上的節點——效率高
v-if 採用動態添加刪除元素的方式控制顯示隱藏——效率低
4. v-for:
遍歷數組中每一個元素
每遍歷一個數組元素就自動建立一個HTML元素
而且在HTML元素中還可綁定遍歷出的數組元素內容
什麼時候: 根據數組反覆生成多個相同結構的元素時
如何:
1. 只須要寫一個要生成的元素做爲模板
2. 在要重複生成的元素上加v-for
好比:
data中: tasks:["吃飯","睡覺","打亮亮","再吃飯"]
<ul>
<!--遍歷tasks數組中的每一個元素,將每一個元素的值臨時保存在變量task中,每遍歷一個tasks數組中的元素,就建立一個相同結構的li,並動態綁定循環變量的值到元素內容中-->
<li v-for="(task,i) of tasks">{{i+1}} - {{task}}</li>
<!--結果-->
</ul>
5. 事件綁定:
v-on:click="處理函數"
@click="處理函數"
強調: 1. 處理函數必須寫在new Vue中的methods中
2. 處理函數中的this再也不指向當前按鈕對象,而是指整個vue對象
3. 處理函數中要操做data中的變量必須加this.
6. v-html v-text:
代替{{}}綁定元素的內容
{{}}的問題: 2個
1. 始終保持變量中的字符串原始樣子輸出
即便綁定HTML片斷,也只能原樣顯示
解決: 用v-html代替{{}}
2. 若是new Vue加載慢時,客戶會短暫看到{{}}
解決: 用v-text代替{{}}
由於v-text是屬性,即便慢,暫時綁定不出來,頁面上也不會出現綁定語法。
缺點: 對字符串拼接和過濾器支持很差
7. v-cloak:
專門用於在new Vue加載慢時,暫時隱藏元素
如何: 2步:
1. 在要隱藏的元素上添加v-cloak屬性,不用給值
2. 手動在網頁頂部提早定義[v-cloak]{display:none}
原理: 當new Vue加載完以後,自動查找全部v-cloak屬性,並移除。
8. v-once:
僅在頁面加載時綁定一次變量值。以後,即便變量發生變化,也不更新頁面
如何: <ANY v-once>
原理: 全部要更新的元素都保存在虛擬DOM樹中
標有v-once的元素,在首次綁定後,就從虛擬DOM樹中移除。下次即便變量再變化,掃描虛擬DOM樹,找不到標有v-once的元素了。
9. v-pre:
萬一內容中包含{{}},但不想被vue編譯時,可用v-pre阻止編譯內容:
如何: <ANY v-pre>
<body>
<div id="app">
<!-- <input type="button" value="toggle" @click="toggle"> -->
<input type="button" value="toggle" @click="flag=!flag">
<!-- v-if 的特色:每次都會從新刪除或建立元素 -->
<!-- v-show 的特色: 每次不會從新進行DOM的刪除和建立操做,只是切換了元素的 display:none 樣式 -->
<!-- v-if 有較高的切換性能消耗 -->
<!-- v-show 有較高的初始渲染消耗 -->
<!-- 若是元素涉及到頻繁的切換,最好不要使用 v-if, 而是推薦使用 v-show -->
<!-- 若是元素可能永遠也不會被顯示出來被用戶看到,則推薦使用 v-if -->
<h3 v-if="flag">這是用v-if控制的元素</h3>
<h3 v-show="flag">這是用v-show控制的元素</h3>
</div>
<script>
// 建立 Vue 實例,獲得 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {
/* toggle() {
this.flag = !this.flag
} */
}
});
</script>
</body>
<body>
<div id="app">
<!-- <input type="button" value="toggle" @click="toggle"> -->
<input type="button" value="toggle" @click="flag=!flag">
<!-- v-if 的特色:每次都會從新刪除或建立元素 -->
<!-- v-show 的特色: 每次不會從新進行DOM的刪除和建立操做,只是切換了元素的 display:none 樣式 -->
<!-- v-if 有較高的切換性能消耗 -->
<!-- v-show 有較高的初始渲染消耗 -->
<!-- 若是元素涉及到頻繁的切換,最好不要使用 v-if, 而是推薦使用 v-show -->
<!-- 若是元素可能永遠也不會被顯示出來被用戶看到,則推薦使用 v-if -->
<h3 v-if="flag">這是用v-if控制的元素</h3>
<h3 v-show="flag">這是用v-show控制的元素</h3>
</div>
<script>
// 建立 Vue 實例,獲得 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {
/* toggle() {
this.flag = !this.flag
} */
}
});
</script>
</body>
總結:
1. 元素內容隨變量自動變化: {{}}
2. 元素的屬性值隨變量自動變化: :屬性="變量/js表達式"
3. 多個元素,多選一顯示時: v-if v-else-if v-else
4. 只有一個元素控制顯示隱藏時: v-show
5. 反覆生成多個相同結構的元素時: v-for
6. 只要綁定事件: @事件名="處理函數"
7. 只要綁定的內容是HTML片斷時: v-html
8. 代替{{}}綁定普通元素內容時: v-text ——避免短暫看到{{}}
9. 但願全部{{}}的元素,在new Vue加載完以前暫時隱藏: v-cloak
10. 但願僅在首次加載時,綁定一次變量值,以後頁面不隨變量改變而改變: v-once
Day 02
正課:
1. ***雙向綁定
2. 綁定樣式
3. 計算屬性
4. 自定義指令
5. 過濾器
1. 雙向綁定:
問題: 用: 只能進行單向綁定(Model(data)->View(html))
若是用:綁定表單元素的值,則用戶修改表單元素的內容,沒法自動修改data中的模型變量。意味着vue中永遠拿不到用戶在界面中修改的新值。
解決: 從此凡是綁定(可輸入,可選擇的)表單元素,必須用雙向綁定,才能在界面修改時,自動更新data中的數據
雙向綁定: 既能Model(data)->View(html)
data中變化,頁面自動跟隨變化
又能View(html) -> Model(data)
頁面中變化,data中的變量自動跟隨變化
如何: v-model:value="變量"
簡寫: 由於幾乎全部表單元素都用value屬性控制元素的內容或值,因此,幾乎全部v-model都綁定value屬性,因此可簡寫爲: v-model="變量"
其它表單元素的雙向綁定:
1. radio:
特殊在: value任何狀況下是固定的
變的是checked屬性,也就是選中與不選中狀態
好比: 性別:
<input type="radio" name="sex" v-model="sex" value="1" checked >男
<input type="radio" name="sex" v-model="sex" value="0" checked >女
data:{
sex:1 0
}
是v-model="sex"將data中的sex和頁面中的radio元素綁定
綁定時: 用data中sex的值和每一個radio的提早寫死的value作比較。若是那個radio的value值恰好等於data中sex的值就選中
其他不選中
修改時: 用當前選中的radio的寫死的value,反向賦值回data中的sex上
2. select:
特殊: 每一個option的value都是提早寫死的
變得只是option的selected屬性,變的只是選中的option是哪一個。
好比:
<select v-model="city">
<option value="bj.png">北京</option>
<option value="hz.png">杭州</option>
<option value="sh.png">上海</option>
</select>
data:{
city:"bj.png"
}
其實: v-model="city" 其實僅僅起到一個綁定鏈接的做用
不具體綁定某一個屬性
綁定時: 用data中city變量的值和每一個option中的寫死的value作比較。若是data中city變量的值等於option中寫死的value的值,則當前option就選中。其他option就不選中
修改時: 用當前選中項的寫死的value,反向更新會data中的city變量
原理: v-model="city"其實,不具體綁定修改元素某個屬性的值。而是爲元素添加修改事件,好比onchange, oninput等。在事件處理函數中修改new Vue對象中的模型變量的值。進一步觸發模型變量的set方法,觸發通知,引發其餘使用該變量的元素的狀態的改變。
3. checkbox:
單選時,變化的只是checked屬性
什麼時候: 若是但願用checkbox控制一個bool類型的變量值時
如何: <input type="checkbox" v-model="isAgree">贊成
data: { isAgree:false }
綁定時: 根據isAgree的值,決定checkbox的checked狀態
修改時: onchange=function(){ vm.isAgree=this.checked}
用當前checkbox的checked狀態,更新data中的isAgree
雙向綁定中可用watch機制,實時得到修改的新變量值:
什麼時候: 只要但願邊修改邊實時執行操做時
如何:
data: { kwords:"" }
watch:{
kwords:function(){
//執行操做
}
}
只要經過任何手段修改一次kwords變量的值,都會馬上觸發一次kwords()函數,執行一次操做。
2. 綁定樣式:
綁定style內聯樣式: 2種:
1. 將整個style屬性值當作一個大的字符串去綁定
問題: 若是使用style綁定樣式,說明常常會單獨修改一個樣css屬性值。而若是style是一個字符串,很是不便於程序僅修改其中一個css屬性。
解決: style支持對象形式綁定
2. 以對象形式綁定style
2步:
1. 在data中定義一個內嵌對象結構,保存style中每一個css屬性
好比: 但願div#pop的位置上下左右變化,可定義對象:
data:{
popStyle:{
left:"100px",//必須帶單位
top:"50px"
}
}
2. 在HTML元素的style上,用冒號綁定data中的樣式對象,好比:
<div id="pop" :style="popStyle"></div>
運行時: new Vue()會自動將
popStyle:{
left:"100px",//必須帶單位
top:"50px"
}
轉化爲字符串: "left:100px; top:50px"
結果仍是: style="left:100px; top:50px"
說明: 若是div中還有部分固定的內聯樣式,可將普通style和:style同時使用。好比:
<div id="pop" style="width:100px; height:100px;" :style="popStyle"></div>
運行時: 先將:style中的對象編譯爲字符串,再和固定不變的普通style內容合併到一個style中。
結果: <div id="pop" style="width: 100px; height: 100px; left: 100px; top: 50px;"></div>
綁定class: 2種方式:
1. 以字符串綁定class——很差
2. 以對象方式綁定class
2步:
1. data中定義個對象,包含全部要顯示的class做爲屬性名。用true/false控制哪一個class應用,哪一個class不用。
好比: data:{
phoneClass:{
vali_info:true,//默認啓用
vali_success:false,//驗證經過啓用
vali_fail:false//驗證失敗才啓用
}
},
2. html中用:class,綁定data中的對象
好比: <span :class="phoneClass">1[3-9]\d{9}</span>
結果: new Vue()自動將phoneClass中,全部標記爲true的class名,拼接爲字符串,替換元素中class的內容,應用指定的class。好比
phoneClass:{
vali_info:true,
vali_success:true,
vali_fail:false
}
會被翻譯爲"vali_info vali_success"
最終: <span class="vali_info vali_success"
其實: :class="對象"中變化的類名,也能夠和其餘固定不變的類名同時存在:
好比: <span class="vali" :class="phoneClass">
結果: 先翻譯: phoneClass爲:
"vali_info vali_success"
再和class="vali"組合造成一個class
最終: <span class="vali vali_info vali_success"
3. 計算屬性:
什麼是: 屬性的值不是實際存在的,每次加載時都須要動態計算出來
什麼時候: 只要想使用的值,不是現成的,須要動態計算才能得到
如何: 2步:
1. 在new Vue中定義計算屬性的邏輯
new Vue({
el:"#app",
data:{ 變量1, 變量2, ... },
computed:{
彙總的屬性名(){
return 彙總結果
}
}
})
好比: 定義計算屬性,動態計算購物車中商品的總價:
data:{
cart:[
{pname:"iphonex",price:5566,count:2},
{pname:"iphonexs",price:8888,count:3},
{pname:"iphonexs max",price:9999,count:1}
]
},
computed:{
total(){
console.log("計算了一次總價");
//先定義變量
var sum=0;
//遍歷cart中每一個商品
for(var p of this.cart){
//每遍歷一個商品,就就計算小計,並彙總到結果中
sum+=p.price*p.count;
}
return sum;
}
}
2. 在頁面元素中,使用綁定語法,直接綁定計算屬性的函數名:
<ANY>{{彙總的屬性名}}</ANY>
不要加()
好比: <td>總價:¥{{total.toFixed(2)}}</td>
原理: 當在綁定語法中發現模型變量時,先在data中找。若是data中沒有,就會進入computed中查找。若是找到computed中的計算屬性,就調用計算函數,而後將返回的結果,替換回頁面中須要綁定的位置。
vs 普通函數:
1. 用法: 綁定函數的返回值: {{函數名()}}
綁定計算屬性: {{屬性名}} //不用加()
2. 重複計算:
若是屢次綁定函數的返回值,綁定幾回,就重複調用函數執行幾回。效率低。
若是屢次綁定計算屬性,不管綁定多少次,只在第一次綁定時執行一次計算,而後,將計算結果馬上緩存在vue中。當下次再綁定時,直接取出緩存的值使用。避免重複計算——效率高。
3. 使用場景:
若是更關心函數的返回值用於顯示時,首選計算屬性
若是不關係返回值,而是更關係執行過程時,首選普通函數
4. 自定義指令:
若是但願給HTML元素添加13種指令以外的新功能,就可自定義指令。
如何:
1. 建立: 一個名爲v-focus的指令
Vue.directive("focus",{//強調: 不要加v-前綴
inserted(dom_elem){
dom_elem.DOM函數()
}
})
2. 使用:<ANY v-focus></ANY>
原理:
當new Vue()時,Vue框架會掃描原始DOM中的元素
只要發現帶自定義指令的元素,就觸發自定義的inserted()函數,對當前DOM元素,執行預先定義好的DOM操做。
5. 過濾器:
什麼是: 對data中原始值進行再加工,而後再顯示的一種特殊的函數。
什麼時候: 只要data中的值不能直接顯示給人看時
好比: 性別:0,1 時間/日期的毫秒數
如何:
1. 建立過濾器函數:好比,建立將性別0和1轉爲女和男的過濾器
Vue.filter(
"sexFilter", //過濾器函數名
function(oldValue){//過濾器函數自己
//至少有一個形參接收來自data中變量的原始值
//對原始值加工後返回新值
return oldValue==1?"男":"女";
//必須有返回值
}
)
2. 在綁定語法中使用過濾器
<h1>性別:{{sex|sexFilter}}</h1>
其中: 使用|將過濾器函數鏈接到sex原始變量的後邊。
執行時,sex的值,自動傳給過濾器sexFilter的函數的形參oldValue,通過過濾加工,將返回的新值顯示到綁定位置。
其實,過濾器能夠帶參數,來選擇不一樣的返回值樣式:
好比:定義可根據語言選擇返回不一樣語言性別的過濾器
Vue.filter(
"sexFilter",
function(oldValue,lang="cn"){//en cn
if(lang=="cn"){//若是傳入cn或不傳入,則默認都返回中文的男女
return oldValue==1?"男":"女"
}else{//不然,返回英文的男女。
return oldValue==1?"Male":"Female"
}
}
)
使用帶參數的過濾器:
<h1>性別:{{sex|sexFilter("en")}}</h1>
<h1>性別:{{sex|sexFilter("cn")}}</h1>
<h1>性別:{{sex|sexFilter}}</h1>
強調: 雖然定義形參lang時,lang處於第二個形參,可是使用過濾器時,由於原始值自動佔了第一個形參oldValue,因此,自定義傳入的實參值cn或en,就可直接做爲第一個實參傳入。實際給的確實第二個形參lang。
總結:
var vm=new Vue({
el:"#app",//引入html元素,造成虛擬DOM樹
data:{ //保存頁面須要的全部模型變量
//頁面中有幾處變化,data中就要有幾個變量支持
uname:,
sex:,
popStyle:{
css屬性: 屬性值,
... : ...
}
phoneClass:{
樣式類: true,
... : ...
}
},
methods:{ //全部函數
處理函數(){
this->new Vue()
this.變量
},
自定義函數(){ ... }
},
watch:{ //全部對data中變量的監聽函數
變量名(){ //變量名要和data中的某個變量同名
}
},
computed:{//計算屬性
total(){
return
}
}
})
Day 03
正課:
1. Axios
2. 組件
3. 組件化開發
4. SPA
1. Axios:
什麼是: 基於promise的專門發送ajax請求的函數庫
爲何: 在vue中發送ajax請求
1. 本身寫ajax四步/五步: 代碼重複嚴重
2. jQuery中$.ajax(): 大材小用,得不償失。
jQuery不是專門執行ajax請求的。而是執行全部DOM操做的函數庫。包含大量的DOM操做的函數。而在vue中其實只須要$.ajax(),其他函數根本用不上。
3. Vue框架自帶ajax請求的模塊: vue-resource: 只能在vue中使用。
4. Vue官方推薦: axios
可在任何位置發送ajax請求
index.html ->
new Vue() ->
node.js index.js ->
什麼時候: 從此,只要在vue中發送ajax請求,都用axios
如何:
1. 引入axios.js
2. 發送請求:
get方式:
axios.get("url",{
params:{
請求參數: 參數值
}
}).then(function(返回結果result){
result.data 纔是服務器返回的結果
})
好比: 用id查詢一個商品
axios.get("/products/getById",{
params:{
lid:5
}
})
//http://localhost:3000/products/getById?lid=5 ->
// { lid:5, title: macbook, subtitle: 優惠酬賓, ... } <-
.then(function(result){
var product=result.data;
})
2. 組件:Component
什麼是: 擁有專屬的HTML,CSS,JS和數據的可重用的頁面獨立區域。
爲何: 可重用
什麼時候: 只要發現頁面中一個獨立的功能/區域反覆被使用,都要封裝爲組件。
如何:
1. 封裝組件:
Vue.component("組件名",{
template:`HTML片斷`, //代替了之前的el
//<button>-</button><span>{{n}}</span><button>+<bu
data:function(){
return {//至關於之前的data
n:1
}
},
其他成員和new Vue中徹底同樣
methods:{
事件處理函數
},
watch:{
對變量實時監控
},
computed:{
計算屬性
}
})
好比: //建立一個名爲my-counter的組件
//未來反覆在主頁面中使用
Vue.component("my-counter",{
template:`<div>
<button @click="sub">-</button>
<span>{{n}}</span>
<button @click="add">+</button>
</div>`,
data:function(){
return { n:1 }
},
methods:{
sub(){ this.n--; },
add(){ this.n++; }
}
})
2. 反覆使用組件: 組件其實就是一個可重用的自定義HTML標籤而已。
<組件名></組件名>
好比: <my-counter></my-counter>
原理:
Vue.component()將組件模板添加到Vue你們庭中備用。
new Vue()掃描DOM樹時,發現自定義標籤,就在Vue家裏找到同名組件,用template替換頁面的自定義標籤。
同時調用組件的data()函數,爲此處的一個組件示例下一個專屬的蛋(數據data對象{n:1})
未來,每替換一個自定義標籤,說明組件被使用了一次,就會自動調用一次data()函數,返回一個專屬的數據對象給當前組件專門使用。
3. 組件化開發:
什麼是: 未來全部的網頁都是由組件組成的。拿到網頁後先劃分組件。再分別編寫每一個組件的HTML,CSS和Vue代碼。最後再拼接到一塊兒
爲何: 可多人團隊協做開發
調試方便,組件之間互不影響
什麼時候: 從此全部網頁必須都用組件化開發。
如何:
1. 拿到頁面後,先劃分組件
2. 建立組件: Vue.component() 同上
3. 在主頁面中引入組件: <todo>同上
4. new Vue()
問題: 用Vue.component()建立的組件能夠出如今頁面的任何位置,不受限制
解決: 限制子組件必須出如今規定的父組件內纔有意義
如何: 3種組件:
1. new Vue({ el:"#app" }) —— 根組件
一般只有在項目惟一的首頁上才只有一個new Vue()
2. Vue.component() —— 全局組件
可出如今頁面的任何位置
3. 子組件: 被限制在一個固定父組件內使用的組件
什麼時候: 從此只要一個組件,有明確的使用範圍,不能亂放時,都要定義成子組件
如何: 2步:
1. 建立子組件: 與建立全局組件內容相同,但降級爲普通對象定義格式:
好比: todo-item必須屬於todo-list下才有意義:
var todoItem={
template:`<li>
1 - 吃飯 <button>x</button>
</li>`
};
強調: 子組件名必須用駝峯命名!由於以後會被自動翻譯爲-分隔,好比: todoItem -> Vue -> todo-item
2. 在父組件中添加components屬性,包含子組件對象
好比: var todoList={
template:`<ul>
<todo-item></todo-item>
<todo-item></todo-item>
<todo-item></todo-item>
</ul>`,
components:{ todoItem } //強調,這裏必須和上一步定義子組件時的變量名保持一致。
}
結果: <todo-item>就只能在<todo-list>下使用
組件間傳遞數據:
父->子:
1. 子: 爲組件定義自定義屬性,未來用於從父對象中綁定得到父對象中的變量。
var 子={
template:`... `,
data(){
//僅限於子組件本身使用的內部變量
},
//定義 自定義屬性
props:[ "tasks" ]
}
2. 父: 經過綁定子組件的自定義屬性,將本身的變量交給子組件
<子 :tasks="tasks"></子>
孩子的兜 <-- 爹的變量
4. SPA: Single Page Application
單 頁面 應用
什麼是: 一個應用程序雖然有不少界面,可是隻有一個完整的物理頁面.html文件。
咱們看到的「界面」,其實都是一些較大的組件
經過對地址欄中的相對路徑判斷,動態決定替換成哪一種組件。
爲何:
多頁面 |
單頁面 |
一個應用中包含多個.html |
一個應用中只有一個.html |
每切換一次頁面,都會從新發送請求——請求次數多 |
全部組件都是在首頁第一次加載時,已經所有加載過來了。每切換一次頁面,不須要向服務器從新發起頁面請求。只是在客戶端本地挑選匹配的組件替換頁面內容而已。——請求次數少 |
每次切換頁面時,都要重建整棵DOM樹——效率低 |
每次切換界面時,不須要整棵重建DOM樹,只要替換局部的節點對象便可。——效率高 |
對於共用的資源,每次切換頁面,都要重複請求。 |
每次切換界面時,由於<head>中的引用沒變,因此不會重複請求共享的資源。 |
如何實現單頁面應用:
1. 劃分"頁面"組件: —— 組件結構圖
2. 建立組件: 同建立普通組件
3. 定義惟一的完整的.html頁面
引入公共的資源:
<link rel="stylesheet" href="css/bootstrap.css">
...
引入vue.js和vue-router.js
引入全部組件對象的所在的js文件備用
<body>中
<div id="app">
<my-header/>頁頭組件,全部頁面共用
<router-view/>臨時佔位,未來會根據路由地址不一樣,動態選擇不一樣的組件template替換<router-view>所在位置。
4. 定義路由字典:
路由字典是保存全部相對地址和對應組件配對兒信息的數組。
var routes=[
{path:"/",component:index},
{path:"/details/:lid",component:details,props:true},
{path:"/products",component:products},
{path:"*",component:{
template:`<div><h2 style="color:red">404:Not found——東哥寫的,不是報錯</h2></div>`
}},
];
5. 將路由字典加入路由器中
var router=new VueRouter({routes})
6. 將路由器放入new Vue()中
var vm=new Vue({
el:"#app",
data:{},
router
})
運行時:
http://127.0.0.1:5500#/
http://127.0.0.1:5500#/details
http://127.0.0.1:5500#/products
強調: vue路由才用錨點地址#/xxx來識別不一樣路徑。必須加#
跳轉:
2種:
1. 寫死的連接: 全部a都換成<router-link
<router-link :to="/details"></router-link>
最終會被翻譯回: <a href="#/details"></a>
2. 用程序跳轉: 登陸成功後跳轉回首頁
this.$router.push("/地址")
url地址傳參:
1. 路由字典中:
var routes=[
{path:"/details/:lid", component: details, props:true}
] //讓lid自動傳給props中同名的變量
強調:
1. 凡是帶參數的地址,訪問時必須帶參數才能進入。若是不帶參數,會跳轉到404
2. 在目標組件對象中定義同名props屬性
var details={
...
props:[ "lid" ]
}
3. 在跳轉時傳參:
/details/5 //沒有: ,沒有?, 沒有變量名=
Day 04
正課:
1. 腳手架
2. ***VUE/組件的生命週期
1. 腳手架:
什麼是: 已經具備核心功能的半成品項目代碼
咱們只要在規定位置填入個性化定製的功能便可
爲何: 簡化開發
如何:
1. 安裝腳手架的工具命令:
npm i -g @vue/cli 電腦安裝完命令後 : 直接建立 vue create 文件夾名字
2. 用命令反覆建立腳手架:
cd 要保存項目的文件夾完整路徑
好比: cd C:\xampp\htdocs\dd\6_VUE\day04
用vue命令工具,建立一個項目的腳手架代碼
1. Your connection to the default npm registry seems to be slow.
Use https://registry.npm.taobao.org for faster installatio
n? (Y/n) n
2. ? Please pick a preset: (Use arrow keys)
default (babel, eslint)
> Manually select features
3. ? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Babel 將腳手架中瀏覽器不認識的一切東西翻譯爲瀏覽器認識的。 必選 至關於 翻譯官
( ) TypeScript 更嚴格的javascript,ng框架使用
( ) Progressive Web App (PWA) Support
(*) Router 必選
(* ) Vuex 爲下一階段作登陸/購物車作準備
( ) CSS Pre-processors
( ) Linter / Formatter 代碼格式檢查工具,要求過於變態
( ) Unit Testing
( ) E2E Testing
4. Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) n
history模式可去掉地址欄中的#
但須要服務端同步配置重定向,才能讓客戶端支持
因此,學習時,不用啓用history
5. Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys)
In dedicated config files
> In package.json //在package.json一個文件中,保存全部配置信息
6. Save this as a preset for future projects? (y/N) N
是否保存以上配置步驟的選項爲從此全部項目的默認配置。不保存。由於不一樣項目須要的組件可能不同。
3. 運行腳手架項目: npm run serve
臨時啓動一個簡易版的調試服務器來宿主html,css,js
將腳手架中瀏覽器不認識的代碼編譯爲瀏覽器認識的代碼
在默認: http://localhost:8080/
打開瀏覽器在地址欄中: http://localhost:8080/
問題: npm run serve僅臨時編譯代碼,並運行,不產生最終編譯結果。就不能部署上線。
解決: npm run build
將腳手架中瀏覽器不認識的代碼編譯爲瀏覽器認識的代碼
將編譯後的代碼壓縮爲統一的文件。
未來: 往新浪雲上拷貝時,只拷貝dist/中的內容便可。
4. 服務端項目配置:
1. cors:
origin: 之前是http://127.0.0.1:5500
如今要改成http://localhost:8080
credentials:true 容許接收客戶端帶來的身份信息
5. 客戶端vue項目配置:
1. axios:
問題: 默認不帶axios
解決: 安裝: 在xz_vue/內,運行npm i -s axios 或者 npm install axios -S
問題: 未來咱們但願在全部Vue組件內,使用axios
this.axios.get("url",{params:{參數:值}})
解決: 在main.js中,將axios對象添加到Vue的原型對象中。
在mian.js中配置axios
//mian.js是根組件 new Vue,全部所需的模塊和對象都要在new Vue以前配置好
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
//手動引入-------這個是須要親自手動添加的,其餘代碼,腳手架自帶
import axios from 'axios' //引入axios文件
Vue.prototype.axios=axios //全部組件都是Vue.prototype的孩子
axios.defaults.withCredentials=true //讓axios的請求攜帶驗證信息到服務端(鑰匙)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
正課:
1. 腳手架
2. 組件的生命週期
1. 腳手架:
什麼是: 前人總結的包含優秀開發經驗的半成品項目
爲何: 避免重複勞動
什麼時候: 從此只要使用框架開發,都用腳手架代碼
如何: 2步:
1. 安裝命令行工具——用於生成腳手架代碼的工具
npm i -g @vue/cli
2. 用命令行工具生成腳手架代碼——建立項目
vue create 項目名
babel: js代碼翻譯工具
將瀏覽器不認識的新標準的js代碼,翻譯爲瀏覽器認識的ES5的等效代碼,好比
ES6中也定義了模塊:
拋出模塊: export default { ... }
等效於node中的module.exports={ ... }
引入模塊: import from "模塊名"
等效於node中的require("模塊名")
瀏覽器不認識,只能請babel翻譯爲ES5的等效代碼。
結果: 在當前運行命令的目錄建立了一個項目文件夾,其中包含了腳手架代碼
測試: cd 項目名 進入項目文件夾
npm run serve
1. 啓動臨時開發服務器(development Server),宿主編譯後的靜態頁面
2. 編譯(compile / build)腳手架代碼中瀏覽器不認識的內容爲認識的內容
3. 在腳手架代碼中填寫個性化的內容
問題: 腳手架代碼不包含axios
解決: 安裝和配置axios
1. 在項目本地安裝axios: npm i -save axios
2. 將axios對象放入vue的原型對象中:
main.js是整個vue項目的惟一根組件new Vue
全部須要的模塊或對象,都要在new Vue以前配置好
坑: axios默認不帶鑰匙到服務器,也就沒法打開本身的櫃子,訪問本身的信息。
解決: 在main.js中要求axios必須攜帶鑰匙
axios.defaults.withCredentials=true;
2. 組件的生命週期:
什麼是: 一個組件的加載過程
包括: 4個階段:
1. 建立: create 建立組件對象和模型數據對象data:
至關於: Vue.component("",{
data(){ return { ... } }
})
2. 掛載: mount 掃描頁面構建虛擬DOM樹,並首次綁定數據到頁面指定位置。
至關於: Vue.component("",{
data(){ return { ... } },
template:"#tplXXX" //虛擬dom樹
})
3. 更新: update 當模型變量被更改時,自動觸發
4. 銷燬: destroy 當主動調用銷燬方法銷燬組件時自動觸發
若是但願在生命週期的不一樣階段自動執行一項任務,就要綁定生命週期鉤子函數:
包括: 4個階段,包括8個鉤子函數
1. create:前 beforeCreate(){ ... }
後 created(){ //有data,沒有虛擬DOM樹
//ajax請求爲了初始化data,此時已經有data對象了,因此已經能夠發送ajax請求
this.axios.get("url",{
params:{ 參數 }
}).then(res=>{
this.模型變量=res.data.屬性名
this.products=res.data;
})
//暫時不能執行DOM操做,好比讓元素得到焦點
}
2. mount: 前 beforeMount(){ ... }
後 mounted(){//即有data,又有DOM樹
//也能夠寫ajax請求
//能夠執行DOM操做
}
瞭解:
3. update: 前 beforeUpdate(){ ... }
後 updated(){ ... }
4. destroy: 前 beforeDestroy(){ ... }
後 destroyed(){ ... }
<template><template>標籤,html5中專門用於爲框架/組件保存一段影藏的模板片斷,至關於<div style=」display:none」></div>
第四階段
Day 01
今天學習的內容
程濤 taonetwork2018
1:第四階段課程簡介
vue移動端組件庫和項目 6day
html5新特性(視頻/繪圖) 7day
微信公衆平臺 --小程序 6day
混編 1day
2:vue UI 組件庫
vue 當前很火前端框架,用戶數衆多
vue 開始針對pc端用戶而不是針對移動設備開發
國內團隊:餓了麼[MintUI/ElementUI],滴滴打車,MUI...
MintUI 針對移動端開發組件庫
ElementUI 針對PC端用戶開發組件庫
2.1:補充知識點:PC端項目和移動端項目
-區別:屏幕寬度
PC端: w > 992px
移動端: w < 992px
-區別:操做方式
PC端: 鼠標和鍵盤
移動端: 手指
-區別:事件
PC端: keyup/keydown/click/blur/..
移動端: touchstart/touchmove/touchend/tap/longtap
2.2:vue ui mint-ui組件使用
下載安裝提供二種方式
(1)方式一:(學習)
mint-ui官方網站下載 css/js/fonts 加載當前html文件中
(2)方式二:
vue cli 腳手架工具當下載配置使用[錄像]
下載指令 npm i mint-ui -S
2.3:vue cli 腳手架
-vue cli 如何生成
1:vue cli 建立項目 (?)
2:vue cli 開發自動化工具生成 webpack (?)
-vue cli 目錄結構
package.json 配置信息
-vue cli 啓動項目
npm run serve
#注意啓動目錄
..vue_app_00/npm run serve
2.4:將mint-ui引入腳手架 main.js
(1)按需引入
(2)完成引入
import Vue from 'vue'
import MintUI from 'mint-ui' #完整引入mint-ui庫組件
import 'mint-ui/lib/style.css' #單獨引入樣式文件
import App from './App.vue'
Vue.use(MintUI) #將mint-ui庫全部組件註冊
#vue實例對象中
new Vue({
el: '#app',
components: { App }
})
2.5:第一個mint-ui組件 Toast
簡短消息提供框
示例:1:建立組件 src/components/Exam01.vue 空
2:指定路徑 src/router.js /Exam01
3:執行組件在瀏覽器地址欄輸入
http://127.0.0.1:8080/#/Exam01
-基本用法
this.$toast({})
參數:
message:提示消息文本的內容
position:位置 top;bottom;middle
duration:持續時間(單位毫秒) 3000 ; -1不關閉
className:類名爲其添加樣式
.mytip{ background:#fff !important; color:red !important; font-size:12px !important; } |
iconClass:圖標類名
示例:Exam01.vue
2.6:提示框中能夠顯示圖標
https://www.iconfont.cn/ 阿里媽媽專業圖標網站
(1)下載圖標
-將圖標加入購物車
-點擊購物車,下載代碼
(2)將圖標應用當前項目
-在src建立目錄font 上目錄用於保存字體圖標文件
-main.js 引入字體圖標文件css文件
import "./font/iconfont.css"
-應用方法
<i class="iconfont icon-gao"></i>
-iconClass:"iconfont icon-gao"
#注意:字體圖標能夠修改大小
#修改 src/font/iconfont.css
# .iconfont {
font-family: "iconfont" !important;
font-size: 16px;
}
2.6:彈出式交互提示框
標準語法: this.$messagebox({})
title 提示框的標題 String
message 提示框的內容 String
showConfirmButton 是否顯示確認按鈕 boolean
showCancelButton 是否顯示取消按鈕 boolean
示例:建立
組件: src/components/ExamMessageBox02.vue
路徑: /ExamMessageBox02
2.7:表單輸入域:表單編輯器
<mt-field label="用戶名" placehodler="請輸入用戶"
v-model="uname"></mt-field>
type 輸入框類型 text/number/url/date/password...
label 標籤
placeholder 佔位符
readonly 只讀
attr: 設置原生屬性
state 校驗狀態 error;success;warning
示例:建立
組件: src/components/ExamField03.vue
路徑: /ExamField03
2.8:使用mint-ui 完成淘寶登陸
練習:分析功能
1:第一個輸入域
[請輸入手機號碼]
[手機號/郵箱/會員名]
2:[賬戶密登陸]
-建立組件 Login.vue /Login
做業1:完成Login04.vue 登陸組件
-用戶名和短信切換
-密碼框顯示與隱藏
-按鈕提示文字切換
Day 02
今天學習內容
1:複習昨天重點知識
2:做業 仿淘寶登陸
3:今天的目標
mint-ui組件庫官方網站:
http://mint-ui.github.io/#!/zh-cn
3.1:mint-ui 組件庫-表單
-開關組件
<mt-switch v-model="val1">開關</mt-switch>
val1:true
-單選框列表
<mt-radio
title="單選框列表"
v-model="val2"
:options="['選項a','選項b','選項c']">
</mt-radio>
-複選框列表
<mt-checklist
title="複選框表"
v-model="val3"
:options="['選項A','選項B','選項C']">
</mt-checklist>
3.2:mint-ui 組件庫-面板--(重點)
面板,可切換顯示子頁面
<mt-tab-container v-model="active"> 父元素(面板)
<mt-tab-container-item id="tab1"> 子面板1
<mt-cell v-for=""></mt-cell> 單元格
</mt-tab-container-item>
<mt-tab-container-item id="tab2"> 子面板2
<mt-cell v-for=""></mt-cell> 單元格
</mt-tab-container-item>
<mt-tab-container-item id="tab3"> 子面板3
<mt-cell v-for=""></mt-cell> 單元格
</mt-tab-container-item>
</mt-tab-container>
注意:改變active值與子面板id一致即顯示對應子面板
練習: 在data中保存數組件,
(1)list["美食","購物","休閒"]
(2)依據數組值建立三個mt-button
(3)點擊按鈕完成子面板切換
(4)當前被點擊文字高亮
3.4:mint-ui 組件庫-面板--(重點)
底部選項卡,點擊tab會切換顯示頁面,
<mt-tabbar v-model="selected" fixed>
<mt-tab-item id="外賣">
<img slot="icon" src="../asserts/100*100.png" />
外賣
</mt-tab-item>
<mt-tab-item id="訂單">
<img slot="icon" src="../asserts/100*100.png" />
外賣
</mt-tab-item>
</mt-tabbar>
- fixed 固定在頁面底部
-value 返回當前選中tab-item的id
3.5:微信
(1)建立components/weixin/Home.vue 全局組件
(2)從上到下設計每個組件
(3)最上面子組件 components/weixin/common/TitleBar.vue
(4)簡潔示例 F.vue父 S.vue子元素
Day 03
今天學習的內容
1:複習上週重點
2:今天的目標
2.1:mint-ui組件庫;綜合應用 微信
2.2:網頁結構分析
2.3:建立項目目錄
weixin 項目目錄
common 子組件
json 數據文件
Home.vue 入口組件
2.4:頂部標題欄
-將標題欄建立成一個子組件做爲Home.vue一部分
-分析分爲二個部分左側文字右側兩張圖片
-使用彈佈局因爲標題欄固定,定位方式 fixed
-common/TitileBar.vue
注意:左側文字 右側圖片 兩張點擊事件由父元素
2.5:消息面板建立
-Message.vue 消息子組件
負責消息外觀設計:
左側:圖片
左側:標題和子標題
右側:時間
-MessageList.vue 消息列表子組件
負責加載數據 weixin/json/messagelist.json
建立循環
而且在循環調用Message.vue 子組
-Home.vue 調用MessaeList.vue 子組件
2.6:底部導航欄 tabbar
-圖片 ic_weixin_normal.png/ic_weixin_selected.png
-tabbar中圖片建立單獨組件
-子件組TabBarIcon.vue 圖片顯示與切換樣式
-在Home.vue 建立 tabbar中間圖片TabBarIcon.vue
3:項目階段:學子商城
-用戶登陸(**)
-商品列表
-商品詳情
-購物車(*****)
做業:
(1)複習weixin 項目(重點)
(2)用戶登陸組件 Login.vue
(3)session 百度搜索
(4)mysql 查詢SQL SELECT
Day 04
今天學習的內容
1:複習昨天的重點
2:今天的目標
2.1:weixin完成--(重點)
2.2:學子商城--登陸
用戶輸入用戶名和密碼點擊提交按鈕,
若是格式出錯 提示:用戶名格式不正確 密碼格式不正確
用戶不存在 提示:用戶名或密碼不正確
正確 跳轉商品主頁
2.3:學子商城--數據庫-加密
t_login[id/uname/upass]
id INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(255)
upass VARCHAR(32)
2.3:學子商城--數據庫
因爲用戶登陸密碼要求安全度比較高,習慣加密保存
示例:
tom/123
t_login
id uname upwd
1 tom 123 #錯誤保存方式
解決思路:
將密碼:123 原先密碼 -> 加密技術 ->x93k3s82820sk202jd98i
id uname upwd
1 tom 202cb962ac59075b964b07152d234b70 #正確
解決辦法: md5(); 加密函數 32位
md5(123) => 202cb962ac59075b964b07152d234b70
常規安全思路:
(1)用戶密碼8位以上:數字/小寫字母/大寫字母/特殊字符
(2)屢次加密
如何登錄:
(1)用戶輸入用戶名和密碼 tom/123
(2)node.js 接收用戶 tom/123
(3)將用戶輸入123加密 #判斷方式密碼比較密碼 52
md5(123) =>202cb962ac59075b964b07152d234b70
(4)sql語句完成登陸驗證
SELECT id FROM t_login WHERE uname = ? AND upwd = md5(?)
(5)數據庫表
id uname upwd
1 tom 202cb962ac59075b964b07152d234b70 #正確
2.4:項目目錄結構
2.5:學子商城--cors 跨域
vue-cli 腳手架 8080 Login.vue
vue-server-app node.js服務器 3000
#以上程序在執行因爲8080訪問另外一個程序3000
#跨域訪問
解決方案:
(1)jsonp
(2)cors 第三方模塊安裝配置node.js便可
-下載cors
-在node.js 服務器配置:哪一個程序能夠跨域訪問當前node.js
const cors = require("cors");
server.use(cors({
origin:[容許跨域請求程序地址],
credentials:true # 是否驗證
}));
示例:容許腳手架8080跨域訪問 node.js
const cors = require("cors");
server.use(cors({
origin:["http://127.0.0.1:8080","http://localhost:8080"],
credentials:true # 是否驗證
}));
2.6:學子商城--session-cookie
session對象:原理
在服務端保存用戶專有數據對象.[uid]
因爲session對象保存服務器端安全性高
-session對象:當用戶訪問網站第一個網頁,就建立session
對象(session開始)中間用戶能夠打開多個網頁(會話中),
當用戶關閉瀏覽器(會話結束)一旦會話結束,會話對象中保存
數據也就丟失.
session對象做用:用於保存用戶登陸憑證,一般憑證用戶編號
-在項目添加 session 功能
(1)將數據保存session對象中
req.session.uid = 1;
(2)從session對象中獲取數據
var uid = req.session.uid;
2.7:在項目如何添加session功能
(1)引入模塊
const session = require("express-session");
(2)配置模塊
server.use(session({
secret:"128位字符串", #128位字符串
resave:true, #每次請求是否更新數據
saveUninitialized:true #保存初始化數據
}));
(3)當用戶登陸成功,將用戶uid 保存session對象
req.session.uid = 1;
(4)其它模塊讀取session中uid [購物車/訂單]
var uid = req.session.uid;
常見概念上錯誤
哪一個是服務器/哪一個是腳手架/node_modeuls在哪裏
每一個程序有本身獨立node_modeuls 相互不要緊
2.8:學子商城--用戶登陸
src/components/xz/Login.vue 登陸組件[參考淘寶登陸]
1:用戶名輸入框/密碼輸入框/登陸按鈕
2:佔位符
3:外觀樣式參考淘寶登陸
4:用戶名和密碼必須經過正則表達式驗證 messagebox
5:發送ajax請求 axios 驗證
src/components/xz/Home.vue 商城首頁
2.9:ajax 庫axios
#兼容性不錯
(1)設置請求服務器原始路徑(基礎路徑)
http://127.0.0.1:3000/login
http://127.0.0.1:3000/cartlist
http://127.0.0.1:3000/cartRemove
...
axios.defaults.baseURL = "http://127.0.0.1:3000/";
.get("login");
.get("carlist");
.get("cartRemove");
(2)設置跨域請求保存session值
axios.defaults.withCredentials=true
做業:學子商城 用戶登陸組件Login.vue
404 錯誤 發送的請求地址 服務器沒有 地址錯誤
{path:'/',redirect:"/XZHome"}, //redirect 重定向
Day 05
今天學習的內容
1:複習昨天的內容
2:今天的目標
2.1:session
2.2:session:會話
會話指操做過程:
-會話開始:當用戶打開網站一個網頁
-會話中:中間用戶能夠打開此網站多個網頁
-會話結束:當用戶關閉瀏覽器
2.3:session對象 [會話對象]
session對象是在當前會話保存數據專用對象
在當前會話中全部網頁中共享此數據
當會話結束結束:session 對象保存數據也丟失
2.4:session對象工做原理
-當會話開始在服務器端建立session對象
-爲了保存數據安全性,服務器會將session對象中數據加密保存
-將session id值發送客戶端瀏覽器cookie保存
-cookie保存session id 作爲用戶憑證
-若是會話結束 session對象失效/對應cookie失效
2.5:node.js在程序如何啓session
-引入模塊
const session = require("express-session")
-配置模塊
server.use(session({
secret:"128位字符串", #自定義字符串
resave:true, #每次請求更新數據
saveUninitialized:true #保存初始化數據
}));
-在項目登陸時將用戶id 保存session
req.session.uid = 2; #正確
req.session.id = 2; #錯誤
-其它的功能直接讀取id 便可做爲用戶登陸成功憑證
示例:顯示購物車,誰購物車 var uid = req.session.uid;
#注意:將數據保存至session坑名稱
保存數據名稱不要叫id緣由 session對象有一個屬性id
2.6:腳手架配置
axios 默認狀況下發送ajax跨域請求丟失session
axios.defaults.withCredentials=true
發送ajax請求基礎路徑
axios.defaults.baseURL="http://127.0.0.1:3000/"
示例:登陸
this.axios.get("login");
2.7:出錯調試
1:F12->查看控制臺->若是有錯讀錯誤理解問題緣由
2:F12->NETWORK->
Header
Response
3:一行一行調試
handler for "click": "ReferenceError: n is not defined"
緣由:n沒有定義
net::ERR_CONNECTION_RESET
緣由: node.js 服務器出錯中止工做
解決:查看node.js 控制檯窗口讀取出錯信息
Error: connect ECONNREFUSED 127.0.0.1:3306
緣由:mysql中止工做沒有啓動或者出錯
2.8:完成學子商城--用戶登陸-組件跳轉
this.$router.push("組件路徑")
示例:
登陸成功/Home
this.$router.push("/Home");
2.9:完成學子商城--商品列表-分頁
-數據庫
xz_laptop[lid/title/price]
-app.js
/product
參數: pno頁碼=1 ;pageSize頁大小=4
sql: SELECT lid,title,price FROM xz_laptop LIMIT ?,?
第一問號:查詢起始行數 (pno-1)*pageSize; 頁碼減一乘以頁大小
第二問題:一次查詢幾行 pageSize
json: {code:1,msg:"查詢成功",data:result}
-xz/product.vue
2.10:完成學子商城--商品列表-分頁
-當組件建立成功後加載第一頁數據
created()
(1)發送ajax請求服務器 /product?pno=1
(2)服務器返回第一頁數據{code:1,msg:"成功",data:[]}
(3)獲取數據而且建立循環顯示內容
-當用戶點擊"加載更多" 加載下一頁數據
click
(1)加載更多:數據追加
0
2.11:建立xz/Home.vue 組件
-子標題組件
-分隔塊
-面板
-tabbar
做業:學子商城tabbar完成
今天學習的內容
1:複習昨天的重點
2:今天的目標
2.1:完成weixin--面板
<mt-tab-container v-model="active">
<mt-tab-container-item id="message">
<messagelist></messagelist>
</mt-tab-container-item>
</mt-tab-container>
2.2:完成weixin--底部導航條
<mt-tabbar v-model="active" fixed>
<mt-tab-item id="message">
圖片:子組件
文字
</mt-tab-item>
</mt-tabbar>
2.3:完成weixin--底部導航條--按鈕上顯示圖片子組件
TabBarIcon.vue
-focused:false 當前按鈕是不是焦點
-selectedImage: 選中顯示圖片
-normalImage: 默認顯示圖片
2.4:修改tabbar默認樣式
/*修改tabbar 默認文字顏色*/ .mint-tabbar>.mint-tab-item{ color:#999999; } /*修改tabbar 選中文字顏色*/ .mint-tabbar>.mint-tab-item.is-selected{
color:#45c018; }
|
#注意:vue事件有一些修飾符 native:原生事件
若是自定義屬性直使用事件綁定便可,若是調用組件庫中組件
直接綁定失敗狀況,清加修飾符 native 啓動原生事件綁定
父元素給子元素綁定事件 native
#注意:去除默認邊框
-App.vue 根組件它的內補丁影響咱們組件
-normalize.css->n.css 通用樣式文件
public/index.html
2.4:學子商城--登陸--分析
用戶打開登陸網頁輸入用戶名和密碼點擊提交按鈕
-格式出錯 提示:用戶名格式不正確
-用戶不存在 提示:用戶名或密碼不正確
-正確 跳轉商品主頁
2.5:學子商城--登陸--[後端程序]服務器-數據庫
-進入xz庫 USE xz;
-建立表用戶登陸表
xz_login [id 編號/uname 用戶名/upwd 密碼]
id INT PRIMARY KEY AUTO_INCRMENET
uname VARCHAR(50),
upwd VARCHAR(32),
通用功能:密碼內容須要加密後保存不是原文件保存
1 tom 123 原文
1 tom sd09234ksd90239epsd093kds0923 密文
爲何密碼須要加密保存防止工做人員泄密
解決思路:將密碼加密處理
解決方法:md5() 單向加密算法 加密結果32位密碼
"123" => 202cb962ac59075b964b07152d234b70
常規問題:
-md5單向加密沒有解密算法
-md5屢次加密 md5(md5('123'))
-更有效方法強化用戶密碼難:
8位以上/數字/大寫/小寫/特殊符號
如何登陸流程
(1)用戶輸入用戶名和密碼 tom/123將數據發app.js
(2)app.js 接收用戶輸入 tom/123
(3)app.js 將用戶輸入123加密與數據密碼比較
SELECT id FROM xz_login WHERE name = ?
AND upwd = md5(?);
數據庫 xz_login
1 tom 202cb962ac59075b964b07152d234b70
(4)pool.query(sql,[uname,upwd],(err,result)=>{
if(err)throw err;
if(result.length==0){
res.send({code:-1,msg:"用戶名或密碼錯誤"});
}else{
res.send({code:1,msg:"登陸成功"});
}
})
-添加測試數據
2.6:學子商城--登陸--[後端程序]服務器-app.js
(1)加載第三方模式
express web服務器
mysql mysql驅動模塊
cors 跨域 腳手架8080 app.js 3000
express-session session
#下載 npm i mysql express express-session cors
#必須聯網完成以上操做
(2)配置第三方模式
-mysql 建立鏈接池 [必須條件]
-配置跨域 cors 指定哪一個程序能夠跨域訪問服務器
origin:["http://127.0.0.1:8080","http://localhost:8080"]
-配置session
secret:"安全字符串", #加密字符串
resave:true, #每次請求保存session數據
saveUninitialized:true #保存初始化數據
(3)處理用戶登陸任務
server.get("/login",(req,res)=>{
-參數 uname/upwd
-sql SELECT id FROM xz_login WHERE uname = ?
AND upwd = md5(?)
-json {code:1,msg:"登陸成功"}
});
測試:
(1)啓動node app.js
(2)打開瀏覽器在地址欄輸入
http://127.0.0.1:3000/login?uname=tom&upwd=123
按回車
http://127.0.0.1:3000/login?uname=tom&upwd=122
按回車
2.7:學子商城--登陸--[前端程序]腳手架
-src/components/xz/Login.vue
-建立輸入框 用戶名 密碼 提交按鈕 (mint-ui)
-爲提交按鈕綁定點擊事件
(1)獲取用戶名和密碼
(2)正則表達式驗證是否有誤 顯示短消息
(3)發送ajax請求
2.8:session-會話-(前端後端程序)
(1)session一個用戶操做過程
-會話開始:當用戶打開某個網站第一個網頁
-會話中:中間用戶能夠打開此網站多個網頁
-會話結束:當用戶關閉瀏覽器
(2)session對象(在服務器爲了保存這次會話專有數據對象)
session對象是保存當前會話中使用數據,在當前會話
中全部網頁能夠共享此數據,可是當會話結束session數據
失效
爲何使用session 對象,項目中有一些數據必須保存
session對象好比:當前登陸用戶編號 uid
解決問題:
做業1:完成學子商城用戶登陸組件
HTML5
Day01
今天學習的內容
1:複習上週重點
2:今天的目標
2.1:html5新特性--視頻音頻
-常見屬性
controls 是否顯示播放控件 <video controls >
autoplay 是否自動播放 <video autoplay> 兼容性太差
loop 是否循環播放
muted 是否靜態播放
poster 在播放視頻以前是否顯示廣告圖片
preload 預加載方式(策略)
none:不預加載任何數據
metadata:僅預加載元數據
(視頻時長;視頻第一個畫面;視頻高度寬度)
auto:預加載元數據,還加載必定時長視頻
2.3:html5新特性--視頻高級特性--事件
-canplaythrough 當前視頻加載結束能夠播放事件
duration 獲取視頻時長
-ended 視頻播放結束觸發事件
-timeupdate 視頻正在播放
currentTime 當前播放時間點
2.4:html5新特性--視頻高級特性--樣式
video 樣式 object-fit
fill: 默認 "填充" 將視頻拉伸操做填滿父元素(變形)
contain: "包含" 保持原有視頻尺寸,父元素留有空白區域
conver: "覆蓋" 保持原有視頻尺寸, 寬度或高度至少有一
個與父元素一致(裁切)
2.5:html5新特性--音頻
基礎知識: x.mp3 x.wav ...
<audio src="x.mp3" id="a3"></audio>
特性1:默認audio不可見,若是添加controls屬性可見
特性2:屬性方法事件大多數與視頻相同
練習:建立複選框實現控制背景音樂播放練習
當選中複選框播放背景音樂 a3.play()
當清空複選框暫停播放 a3.pause()
cb.change = function(){this.checked==true}
2.6:html5新特性--在網頁上繪圖--(重點)
-網頁繪製三種技術
(1)svg: 2D矢量圖 用線段組成圖形
特色:能夠無限放大或縮小不會失真,顏色不夠豐富
(2)canvas:2D位圖 用像素點組成圖形
特色:不能夠放大或縮小,顏色細膩
(3)webgl:3D位圖
還沒有歸入 H5標準
2.7:html5新特性--在網頁上繪圖--canvas
(重點-工做流程-座標系-單詞多)
-座標系
-工做流程
(1)經過標籤建立畫布
<canvas id="c3" width="500" height="400"></canvas>
注意事項:畫布寬度和高度只能經過js 或者標籤屬性來賦值
可是不能使用css賦值(出現變形)
(2)經過js程序獲取畫布
var c3 = document.getElementById("c3");
(3)經過畫布元素獲取畫布中指定畫筆對象[上下文對象]
var ctx = c3.getContext("2d");
#2d平面圖形
-繪製矩形
ctx.strokeRect(x,y,w,h); 繪製空心矩形
x,y 矩形左上角位置
w,h 短形寬度和高度
ctx.strokeStyle = "#fff"; 設置空心邊框樣式
ctx.lineWidth = 1; 設置空心邊框寬度
ctx.fillRect(x,y,w,h); 繪製實心矩形
ctx.fillStyle = "#fff"; 設置實心填充樣式
*ctx.clearRect(x,y,w,h); 清除一個矩形範圍內全部元素
練習1:繪製左右移動空心矩形
06_rect_exam.html
練習2:繪製柱狀銷售統計圖
07_rect_exam.html
-繪製文字(字符串)
var str = "石家莊"
ctx.font = "19px SimHei"; 字體與大小
ctx.fillText(str,x,y); 繪製文本
ctx.textBaseline = ""; 指定文本基線
["alphabetic","top","bottom"]
str:繪製文本
x,y:文本左上角位置
做業1:薪水統計圖[柱狀統計圖]
var sales = [
{m:"一月",s:3000},
{m:"二月",s:3200},
{m:"三月",s:3400},
...
{m:"十二月",s:5400}
];
|| &&