四天學會JavaScript(Day1~Day4)
Day1
前言
一年一度的國慶長假終于來了,但是對于一名菜鳥來說,是絕對不能放過這么好的一個學習機會的,所以我打算花七天的時間把JavaScript的大體內容簡單的過一遍,前端這一塊呢,我幾乎是一個小白,過去也只是寫寫Ajax,或者整幾個XX事件,接收接收資料而已,所以這個國慶我是計劃用七天的時間把JavaScript語言從頭到尾,簡單的過一遍,畢竟本人是后端開發的程式員,前端也不需要太過深入,換句話說是暫時不用太過深入,于是,前天下班的時候我就找領導借了本七百多頁【JavaScript高級程式設計】的書,那么這四天的博客就是我四天的筆記,我會盡量把書中的精華總結出來,
一般情況下呢,一個后端程式員在他入職之前肯定是經歷了一個學習階段,而學習階段肯定是學過Servlet,JSP的,不然后面的SSM什么的都沒法學,而學JSP的前提也是要首先會一點HTML,CSS,JavaScript或者Jquery,所以說像這種速成的學法比較適合有一定基礎的人而不是零基礎,零基礎如果要專門學前端的話不建議速成,
第一天的學習內容
JavaScript基本語法
垃圾收集機制
參考資料型別
Array型別
順序堆疊資料結構
順序佇列資料結構
RegExp
JavaScript簡介
JavaScript是誕生于1995年,很多沒接觸過JavaScript的人可能會認為這個語言一定和Java有關系,然而事實并不是這樣,
JavaScript剛誕生的時候,主要目的還是為了處理以前由服務器端語言比如說Perl負責的一些輸入驗證操作,再此之前,必須把表單資料發送到服務器端才能確定用戶是否沒有填寫某個必填域,學過JavaWeb的人一定是很容易理解這個概念的,如果說表單的每次請求都要發給后端才能驗證判斷是否遺漏哪些必填項的話,回應的速度肯定是會慢很多的,所以現在JavaScript也逐漸成為市面上常見瀏覽器的必備功能,
現如今呢,JavaScript已經變成了一個功能非常全面的編程語言,它從一個簡單的輸入驗證器發展到現在確實非常出乎人的意料,你可以說它是一個非常簡單的編程語言,也可以說它是一個非常難學的編程語言,說它簡單,是因為它可以很快學會使用,但是如果要深入掌握,那就需要很多年的時間了,而我呢,是打算七天學完,所以說,我這七天也僅僅只是學會它的使用而已,如果要再深入研究底層的話應該是需要很長時間,
JavaScript基本語法
JavaScript的語法很多都借鑒了C語言或者類C語言,在JavaScript中是區分大小寫的,第一個字符必須是一個字母、下劃線(_)或者美元符號($)符號,注視這一塊也是C語言風格的注釋,可以是//也可以是/**/,
typeof 運算子可以讓用戶知道變數是什么資料型別,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>網頁標題</title>
<script type="text/javascript">
var flag = true;
alert(typeof flag);
//回傳結果是 boolean
</script>
</head>
<body>
</body>
</html>
NAN
NAN是英文Not a Number的縮寫,從英文意思就知道是非數值,這個數值主要表示本來要回傳一個數值的運算元未回傳數值的情況,(這樣就不會拋錯誤了),就舉個例子,當 9 / "hello" 的時候,回傳的則是NAN,因為9是數值但是"hello"不是數值而是字串,isNAN()函式就是用來判斷一個值到底是不是數值
alert(isNaN(NaN)); //true
alert(isNaN(666)); //false
數值轉換
在JavaScript里面有三個函式可以把非數值轉換成數值: Number()、parseInt()、parseFloat(),第一個函式Number可以用于任何資料型別、另外兩個函式就是專門給字串用的,在Java語言里面也見過這樣的方法,
使用Number轉化成數值的時候,字串必須完全是數字,否則回傳NAN,使用parseInt的時候,如果第一個字符是數值那么它會判斷第二個字符是不是數值,直到遇見非數值的時候,后面的就不會再判斷直接回傳前面的內容了,就比如num3只回傳了15一個道理,
var num1 = Number("helloworld"); //NAN
var num2 = parseInt("hello"); //NAN
var num3 = parseInt("15asf96"); //15
var num4 = parseInt("4546465"); //4546465
var num5 = Number("asf45448f4sa86"); //NAN
var num6 = Number("15464"); //15464
var num7 = Number("15asfasf"); //NAN
alert(num1 + " " + num2 + " " + num3 + " " + num4 + " " + num5 + " " + num6 + " " + num7);
字串面量
| \n | 換行 |
| \t | 制表 tab |
| \b | 退格 |
| \r | 回車 |
| \\ | 斜杠 |
| \' | 單引號 |
| \"" | 雙引號 |
| \xnn | 以十六進制代碼 nn 表示一個字符 |
| \unnn | 以十六進制代碼表示一個uniCode字符 |
for-in 陳述句
有點像for each
for(var propName in window){
document.write(propName);
}
with陳述句
with陳述句的作用是把代碼的作用域全都設定到一個特定的物件中,下面兩段代碼的作用是相同的,
var str = "today is great day";
var a = str.substring(2);
var b = str.charAt(3);
alert("a = " + a + " b = " + b);
var str = "today is great day";
with(str){
var a = substring(2);
var b = charAt(3);
alert("a = " + a + " b = " + b);
}
函式
在JavaScript中函式都是統一使用function來宣告,如果需要回傳直接return就好了,
function my(num1,num2){
return num1 + num2;
}
var result = my(9,9);
alert("result = " + result);
沒有多載
在JavaScript中,函式沒有多載,假如程式員定義了兩個名字相同的函式,呼叫的時候則會呼叫下面的那個,
= = 和 = = = 有什么區別?
“= = =”首先計算其運算元的值,然后比較這兩個值,比較程序沒有任何型別轉換,相等運算子“= =”如果兩個運算元不是同一型別,那么相等運算子會嘗試一些型別轉換,然后進行比較
var a = 1;
var b = '1';
alert(a == b); //true
alert(a === b); //false
垃圾收集
JavaScript具有自動垃圾收集機制,也就是說執行環境會負責管理代碼執行程序中使用的記憶體,而在C和C++之類的語言中,開發人員的基本任務就是手工跟蹤記憶體的使用情況,這樣很容易造成許多問題,這個垃圾收集器的作業原理也很簡單,其實就是找到那些不用的變數,然后釋放掉它的記憶體,不需要像C++一樣還要去delete,
當我們在一個函式中定義了一個區域變數,那么這個區域變數會在該函式執行的程序中存在,而這個程序中會為該區域變數在堆疊(或者堆)的記憶體上分配相應的空間以便存盤他們的值,直到函式要執行結束了,這個時候區域變數就沒有存在的必要,然后就會釋放他們供記憶體使用,
標記清除
JavaScript中最常見的垃圾清理方式是標記清除,當變數進入環境的時候會將這個變數標記為進入環境,當變數要離開的時候會被標記成離開環境,垃圾收集器會在運行的時候給存盤在記憶體中的所有變數都加上標記,然后它會去掉環境中的變數以及被環境中的變數參考的變數標記,而在此之后再被加上標記的變數就會被視為準備洗掉的變數,原因是環境中的變數已經無法訪問這些變數了,最后垃圾收集器完成記憶體清除的作業,銷毀那些帶標記的值并識訓他們所占用的記憶體空間,
管理記憶體
雖然JavaScript已經具有了垃圾收集機制,但是在記憶體管理和垃圾收集面臨的問題還是有點與眾不同,最常見的問題就是分配給Web瀏覽器的可用記憶體數量通常要比分給桌面的要少,這樣做的目的主要是為了防止運行JavaScript的網頁耗盡全部系統記憶體而導致系統崩潰,記憶體限制問題不僅會影響給變數分配記憶體,同時還會影響呼叫堆疊以及在一個執行緒中能夠同時執行的陳述句數量,所以說我們要確保占用最少的記憶體給瀏覽器最好的性能,
如果說一個資料已經不再有用了,則可以把他置為Null來釋放這個參考,通常稱之為解除參考,
function fun(name){
var obj = new Object();
obj.name = name;
return obj;
}
var local = fun("hello world");
alert(local);
//手工解除參考
local = null;
不過,這種做法并不意味著自動回收該值所占用的記憶體,解除參考的真正作用是讓值脫離執行環境,方便垃圾收集器下次執行的時候將其回收,
參考資料型別
Object型別
JavaScript中物件其實就是一組資料和功能的集合,物件可以通過執行new運算子跟要創建的物件型別的名稱來創建,而創建Object型別的實體并為其添加屬性或者方法就可以創建自定義物件,下面三段代碼作為操作的案例,
使用建構式的方法創建
function fun(){
var obj = new Object();
obj.name = "alvin";
obj.age = 12;
obj.score = 98;
alert("姓名: " + obj.name + " 年齡: " + obj.age + " 成績: " + obj.score);
}
使用物件字面量的方法創建
var person = {
name : "bob",
age : 18,
score : 98
};
alert("姓名: " + person.name + " 年齡: " + person.age + " 成績: " + person.score);
還可以直接 = {},此類操作和 new Object() 是相同的
var person = {};
person.name = "alvin";
person.age = 18;
person.score = 78;
alert("姓名: " + person.name + " 年齡: " + person.age + " 成績: " + person.score);
Array型別
作為一名后端程式員來說,一看名字就知道這是陣列,但是JavaScript的陣列和Java或者C語言的陣列不太一樣,JavaScript的陣列使用起來更加有點像是Python語言里面的串列,在C語言里面,陣列的大小和型別都是固定的,也就是說,一旦定義了陣列的大小和型別就不再可以改變,而JavaScript的陣列大小可以動態調整,并且存盤的型別可以是任何型別,下面一段代碼舉個例子,
var arr = new Array();
arr[0] = "hello";
arr[1] = 123;
arr[2] = 9.9;
arr[3] = true;
alert(arr);
陣列的創建方法還有一種,就是前面說過的字面量表示法
var arr = [1,2,3,4,5,6,7];
alert(arr);
檢測陣列
在JavaScript里,如果要確定一個物件是不是陣列就可以使用 instanceof 運算子得到滿意的結果,
var arr = [1,2,3,4,5];
if(arr instanceof Array){
alert("是陣列");
}else{
alert("不是陣列");
}
但是這么做的話又會有一個問題,那就是它假定只有一個全域執行環境,如果網頁中包含多個框架,那實際上就存在兩個完全不同的全域執行環境,從而存在兩個以上不同版本的Array建構式,如果說我要從一個框架向另一個框架傳入陣列,那么傳入的陣列和第二個框架中原生創建的陣列分別具有各自不同的建構式,于是乎后面就出現了Array.isArray()方法,
var arr = [1,2,3,4,5];
if(Array.isArray(arr)){
alert("是陣列");
}else{
alert("不是陣列");
}
轉換方法
在JavaScript中所有物件都具有toLocaleString()、toString()和valueOf()方法,其中呢,valueOf 回傳的還是陣列本身,而呼叫toString就會回傳陣列的字串,而每個元素之間都會有一個逗號,學過Java語言的話一定深有體會,
toLocaleString() 和 toString咋一看顯示的內容好像差不多啊,但實際上還是有一定區別的,toLocaleString()是為了取得每一項的值,呼叫的是每一項的toLocaleString()方法,而不是toString()方法,
堆疊和佇列
堆疊和佇列都是屬于資料結構一類,本人過去曾寫過這類的博客,
堆疊和佇列的基本概念
順序堆疊和鏈堆疊
順序堆疊和鏈堆疊的應用
順序隊和鏈隊
使用自定義的堆疊來優化二叉樹的遍歷
在JavaScript中也提供了一種讓陣列的行為類似于其他資料結構的方法,就比如說,陣列可以表現得像堆疊,堆疊是一種可以限制插入和洗掉的資料結構,其本質更像是一種受限制的線性表,堆疊既可以用陣串列示也可以用鏈表表示,而在這里自然是陣串列示的順序堆疊,
push()方法可以接收任意數量的引數,把它們逐個添加到陣列末尾,并且回傳修改陣列的長度,而pop()方法則是從陣列末尾移除最后一項,減少length值,然后回傳移除的項,
//創建一個陣列
var arr = new Array();
//推入兩項
var count = arr.push("alvin","bob");
alert(count); //2
//再推入一個
count = arr.push("finally");
alert(count);
//取得最后一項
var item = arr.pop();
alert(item); //這里回傳的是 finally, 也就是最后一項
//結果
alert(arr);
接著我們說說佇列,佇列和堆疊一樣都是受限制的線性表,然后佇列和堆疊是相反的資料結構,可以參考博客堆疊和佇列的基本概念,堆疊是先進后出,而佇列則是先進先出,由于push()是向陣列末尾添加項的方法,所以模擬佇列就需要一個從陣列前端取的項的方法,而實作這個操作的方法則是shift(),它能夠移除陣列的第一項并且回傳該項,然后陣列長度-1,shift和push結合可以讓陣列用起來像是佇列,
//創建一個陣列
var arr = new Array();
//推入兩項
var count = arr.push("alvin","bob");
alert(count); //2
//再推入一個
count = arr.push("finally");
alert(count);
//取得最后一項
var item = arr.shift();
alert(item); //這里回傳的是 finally, 也就是最后一項
//結果
alert(arr);
我們發現代碼其實沒什么改變,只是把pop換成了shift而已~
排序方法
在陣列中提供了兩個用來排序的方法,它們分別是sort和reverse,sort是順序,reverse是逆序,也就是翻轉,
迭代方法
在JavaScript中為陣列定義了五個迭代方法,每個方法接收兩個引數,要在每一項上運行的函式作為該函式作用域物件,影響this本身,傳入這些方法中的函式會接收三個引數:陣列項的值、該項在陣列中的位置和陣列物件本身,根據使用的方法不同,這個函式執行后的回傳值可能會也可能不會影響方法的回傳值,這里分別介紹一下
| every() | 對陣列中的每一項給定運行函式,如果該函式對每一項都回傳true,那么就回傳true |
| filter() | 對陣列中的每一項給定運行函式,回傳該函式會回傳true的項組成陣列, |
| forEach() | 對陣列中的每一項給定運行函式,這個方法沒有回傳值/ |
| map() | 對陣列中的每一項給定運行函式,回傳每次呼叫的結果組成的陣列 |
| some() | 對陣列中的每一項給定運行函式,如果該函式對任一項回傳true那么就回傳true, |
語法示例
var numbers = [1,2,3,4,5,6,7];
var result = numbers.some(function(item,index,array){
return (item > 2);
});
alert(result);
歸并方法
在JavaScript中還為陣列提供了兩個歸并陣列的方法,他們都會迭代陣列的所有項然后構建一個最侄訓傳的值,reduce()是從第一個開始,而reduceRight()則是從最后一個開始,
//求陣列中所有值之和
var arr = [1,2,3,4,5];
var sum = arr.reduce(function(prev,cur,index,array){
return prev + cur;
});
alert(sum);
Date型別
JavaScript中的Data型別是在早期Java語言中util包中的Date基礎上構建的,方法比較多,使用的時候可以看手冊或者API,
//獲得當前的時間
var now = new Date();
alert(now);
//設定時間
now = new Date("2018-9-12");
alert(now);
| toDateString() | 以特定的格式顯示年,月,日,周 |
| toTimeString() | 以特定的格式顯示時,分,秒,地區 |
| toLocaleDateString() | 以特定地區的格式顯示年,月,日,周 |
| toLocaleTimeString() | 以特定地區的格式顯示年,月,日,周 |
| toUTCString() | 以特定的格式完整的UTC日期 |
RegExp
JavaScript通過RegEXp型別來支持正則運算式
var patt=/pattern/modifiers;
pattern(模式) 描述了運算式的模式
modifiers(修飾符) 用于指定全域匹配、區分大小寫的匹配和多行匹配
當使用建構式創造正則物件時,需要常規的字符轉義規則(在前面加反斜杠 \),比如,以下是等價的:
var re = new RegExp("\\w+");
var re = /\w+/;
每個正則運算式都可帶有一或多個標志(flags),用來表明正則運算式的行為,正則運算式的匹配模式支持三種標志,
g : 表示全域模式,這個模式將被應用于所有字串,而不是在發現第一個匹配項的時候就立即停止,
i : 表示不區分大小寫模式,也就是確定匹配項時忽略模式和字串的大小寫,
m :表示多行模式,就是在到達一行文本末尾時還會繼續查找下一行中是否與模式匹配的項,
所以說一個正則運算式就是一個模式和三個標志的組合體,不同的組合產生不同的效果,
//匹配字串中所有good 實體
var pattern = /good/g;
//匹配第一個bat或cat 不區分大小寫
var pattern2 = /[bc]at/i;
//匹配所有以at結尾的三個字符的組合,不區分大小寫
var pattern3 = / .at/gi;
| 字面量模式 | 等價的字串 |
| /\[bc\]at/ | "\ \[bc\\]at" |
| /\.at/ | "\\.at" |
| /name\/age/ | "name\\/age" |
| /\d. \d{1,2}/ | "\\d. \\d{1,2}" |
| /\w\\hello\\123/ | "\\w\\\\hello\\\\123" |
使用正則運算式字面量和使用RegExp建構式創建的正則運算式不太一樣,在JavaScript中正則運算式字面量始侄訓共享同一個RegExp實體,而使用建構式創建的每一個RegExp實體都是一個新的實體,
RegExp實體屬性
| global | 布林值,表示是否設定了g的標志 |
| ignoreCase | 布林值,表示是否設定了i的標志 |
| lastIndex | 整數,表示開始搜索下一個匹配項的字符位置,從0算起, |
| multiline | 布林值,表示是否設定了m的標志 |
| source | 正則運算式的字串表示,按照字面量形式而非傳入建構式中的字串模式回傳, |
通過這些屬性可以獲知一個正則運算式的各方面資訊
var pattern = /\[bc\]at/i;
//false
alert(pattern.global);
//true
alert(pattern.ignoreCase);
//false
alert(pattern.multiline);
//0
alert(pattern.lastIndex);
//\[bc\]at
alert(pattern.source);
Day2
前言
今天是國慶假期的第三天,也是我學JavaScript的第二天,我們知道,對于一個已經在職的程式員來說,學習一門新的編程語言,其實也就是學習它的語法,因為編程語言的概念大部分都是互通的,只要語法理解了就好上手,JavaScript我是用速成的方法學習,主要目的還是想把里面的東西都過一遍知道這些到底是怎么一回事,以后寫代碼看API的時候也容易看得懂,但是由于時間過短,語法和特性有可能會忘記一些,這種情況是很糟糕的,為了確保這七天下來,我能把語法和一些特性給記住,所以我決定每天學習完當天的內容之后,再使用JavaScript實作一種資料結構,這樣七天下來我才能夠記住語法并且看API也可以寫的來,
第二天學習的內容
面向物件程式設計
鏈表資料結構(面向物件語法練習)
BOM
DOM
事件
RegExp后續
RegExp建構式屬性
RegExp建構式包含了一些屬性,這些屬性適用于作用域中的所有正則運算式,并且基于所執行的最近一次正則運算式操作而變化,關于這些屬性的另一個獨特之處,就是可以通過兩種方式訪問他們,換句話說這些屬性分別有一個長屬性名和一個短屬性名,
| 長屬性名 | 短屬性名 | 說明 |
| input | $_ | 最近一次要匹配的字串,Opera未實作此屬性 |
| lastMatch | $& | 最近的一次匹配項,Opera未實作此屬性 |
| lastParen | $+ | 最近一次匹配的捕獲組,Opera未實作此屬性 |
| leftContext | $' | input字串中lastMatch之前的文本 |
| multiline | $* | 布林值,表示是否所有運算式都是多行模式,IE和Opera未實作此屬性 |
| rightContext | $' | input字串中lastMatch之后的文本 |
面向物件程式設計
關于面向物件的概念呢,這里就不多說了,直接學習語法就可以了,面向物件編程思想
昨天學習了參考資料型別Object,所以現在也就大概知道物件是怎么創建的了,今天寫兩段代碼回顧一下
物件的創建
建構式法
var person = new Object();
person.name = "alvin";
person.age = 18;
//物件的方法
person.sum = function(){
alert(person.name);
}
//呼叫
person.sum();
字面量法
var person = {
name : "alvin",
age : 19,
fun : function(){
alert("hello world");
}
};
person.fun();
除了這兩種方法以外我們還有其他創建方式
工廠模式(寄生建構式模式)
工廠模式是軟體工程領域的一種廣為人知的設計模式,這種模式抽象了創建具體物件的程序,
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.hello = function(){
alert("hello");
}
return o;
}
var person = createPerson("alvin",19,"work");
person.hello();
alert(person.name);
建構式模式
建構式和普通的函式本質上沒什么區別,只是建構式在呼叫的時候是用new罷了,按照寫代碼的規范,建構式一般就使用大寫字母開頭,
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.hello = function(){
alert("hello");
};
}
var per = new Person("alvin",19,"work");
per.hello();
alert(per.name);
原型模式
我們創建的所有函式都包含了prototype屬性,這個屬性是一個指標,指向一個物件,而這個物件的用途是包含可以由特定型別的所有實體共享的屬性和方法,
function Person(){}
Person.prototype.name = "alvin";
Person.prototype.age = 29;
var per1 = new Person();
var per2 = new Person();
alert(per1.name == per2.name); //true
in運算子除了可以在for回圈的時候使用,也可以用來判斷一個屬性是否存在一個物件里面,如果有就回傳true,否則回傳false,如果想要洗掉物件的屬性的值則可以使用delete
function Person(){
}
Person.prototype.name = "alvin";
alert("name" in Person); //true
alert(Person.prototype.name); //alvin
delete Person.name;
alert(Person.name); //什么也沒有
更簡單的原型語法
function Person(){}
Person.prototype={
name : "alvin",
age : 29,
job : "java",
hello : function(){
alert("hello");
}
}
var per = new Person();
per.hello();
alert(per.name);
組合使用建構式模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor : Person,
hello : function(){
alert("hello");
}
}
var per = new Person("alvin",19,"java");
alert(per.name);
per.constructor.age = 7;
alert(per.constructor.age);
繼承
在JavaScript里面描述了原型鏈的概念,并且將原型鏈作為繼承的主要方法,基本思想是利用原型讓一個參考型別繼承另一個參考型別的屬性和方法,實作原型鏈的一個基本模式代碼如下
function SuperType(){
this.prototype = true;
}
SuperType.prototype.getSuperValue = function(){
return this.prototy;
}
function SubType(){
this.subproperty = false;
}
//繼承SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSuperValue = function(){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());
面向物件這塊,內容比較多,下次有時間我單獨學這一塊,因為對于后端的我來說可能用的也不太多,今天還是主要把精力放在BOM和DOM上,接下來就再實作一個單鏈表資料結構來鞏固下語法,
面向物件練習(實作單鏈表資料結構)
關于單鏈表資料結構,我過去也寫過一些這樣的博客,那么今天為了鞏固JavaScript在面向物件這一塊兒的語法,就用JavaScript來實作一遍單鏈表的增刪查改吧~不過我說實話...資料結構這種東西和編程語言也沒有太大關系,它只是一種思想,所以等下我的代碼風格可能還是和以前寫C語言的風格差不多,
線性表的基本概念
單鏈表的操作
這里就再用JavaScript寫一遍鏈表,
//單向鏈表類
function SingleLinkList(){
//內部類
function Node(data){
this.data = data;
this.next = null;
}
//頭節點
var head = new Node(null);
//新增
this.add = function(data){
var temp = new Node(data);
temp.next = head.next;
head.next = temp;
};
//遍歷
this.print = function(){
var temp = head.next;
while(temp!= null){
if(temp.next != null){
console.log(temp.data + "->");
}else{
console.log(temp.data);
}
temp = temp.next;
}
};
//修改
this.replace = function(index,newData){
var temp = head.next;
var i = 0;
//先找到它,找到之后直接改就是
while(temp != null){
if(i == (index - 1)){
break;
}
i++;
temp = temp.next;
}
var f = new Node(newData);
temp.next.data = f.data;
};
//洗掉
this.del = function(index){
//找到之后直接刪就是,,,
var temp = head.next;
var i = 0;
//先找到它,找到之后直接改就是
while(temp != null){
if(i == (index - 1)){
break;
}
i++;
temp = temp.next;
}
temp.next = temp.next.next;
}
}
//main函式
function main(){
var list = new SingleLinkList();
for(var i = 0; i < 10; i++){
list.add(i);
}
list.replace(3,666);
list.del(6);
list.print();
}
main();
BOM
window物件
BOM的核心物件是window,它表示一個瀏覽器的實體,在瀏覽器中,window物件有雙重角色,它既是通過JavaScript訪問瀏覽器視窗的一個介面,又是ECMAScript規定的Global物件,這意味著網頁中定義的任何一個物件、變數和函式,都以window作為其Global物件,因此也有權限訪問parseInt()等方法,
window常用的屬性
| closed | 回傳視窗是否已被關閉 |
| document | 檔案物件 |
| history | 客戶訪問過的URL的資訊 |
| location | 當前 URL 的資訊 |
| navigator | 管理瀏覽器基本資訊 |
| opener | 回傳對創建此視窗的視窗的參考 |
| screen | 客戶端的螢屏和顯示性能的資訊 |
| self | 回傳對當前視窗的參考,等價于 Window 屬性 |
| status | 設定視窗狀態欄的文本 |
| top | 回傳最頂層的先輩視窗 |
window常用的函式
| alert() | 顯示帶有一段訊息和一個確認按鈕的警告框, |
| confirm() | 顯示帶有一段訊息以及確認按鈕和取消按鈕的對話框, |
| prompt() | 顯示可提示用戶輸入的對話框 |
| open() | 打開一個新的瀏覽器視窗或查找一個已命名的視窗, |
| close() | 關閉瀏覽器視窗 |
| setInterval() | 按照指定周期(以毫秒計)來呼叫函式或計算運算式, |
| setTimeout() | 在指定的毫秒數后呼叫函式或計算運算式, |
| clearInterval() | 取消由 setInterval() 設定的 timeout, |
| clearTimeout() | 取消由 setTimeout() 方法設定的 timeout, |
location物件
location物件是最有用的BOM物件之一,它提供了與當前視窗中加載的檔案資訊,還提供了一些導航功能,事實上,localtion還是一個很特別的一個物件,因為它即是window物件的屬性,也是document的屬性,換句話說,window和document參考的都是同一個location,
至于屬性和方法會用就行,不用去記,需要的時候可以翻API,
document.write("<h3>location物件:代表當前打開視窗的URL</h3>")
document.write("<br>主機名:"+location.hostname);//主機名 127.0.0.1
document.write("<br>埠名:"+location.port); // 埠 8020
document.write("<br>主機名+埠名:"+location.host);//127.0.0.1:8020
document.write("<br>當前檔案URL:"+location.href);//!!!!!! 完整的URL
document.write("<br>"+new Date().toLocaleString());
history物件
history物件保護著用戶上網的記錄,從視窗被打開的那一刻算起,因為history是window物件的屬性,所以每個瀏覽器視窗,每個標簽頁乃至每個框架都有自己的history物件與特定的window物件關聯,因為安全方面的考慮,開發人員無法得知用戶瀏覽過的URL,不過借由用戶訪問過的頁面串列,同樣可以在不知實際URL的情況下實作后退和前進,
//后退一頁
history.go(-1);
//前進一頁
history.go(1);
//跳轉最近的某個頁面
history.go("wrox.com");
navigator物件
這個物件的主要作用就是管理瀏覽器基本資訊
document.write("<h3>history物件:有關客戶訪問過的URL的資訊</h3>")
document.write("<h3>navigator物件:管理瀏覽器基本資訊</h3>")
document.write("<br>瀏覽器名稱:"+navigator.appName);
document.write("<br>瀏覽器版本:"+navigator.appVersion);
document.write("<br>瀏覽器型別:"+navigator.userAgent);//!!!!!
document.write("<br>作業系統:"+navigator.platform);
document.write("<br>是否啟用java:"+navigator.javaEnabled());
var browserType = navigator.userAgent.toLowerCase();
//輸出瀏覽器名稱
if(browserType.indexOf("msie")>=0){
document.write("IE");
}else if(browserType.indexOf("chrome")>=0){
document.write("chrome");
}else if(browserType.indexOf("firefox")>0){
//document.write(" 火狐");
alert("火狐");
}else{
document.write("other");
}
DOM
DOM是針對HTML和XML檔案的一個API,DOM描繪了一個層次化的結點樹,允許開發人員添加、移除、修改某個頁面的部分,
Node型別
DOM1級定義了一個Node介面,該介面將由DOM中的所有結點型別實作,這個Node介面在JavaScript中作為Node型別實作的,除了IE以外,在其他所有瀏覽器中都可以訪問這個型別,JavaScript中的所有型別都繼承自Node型別,因此所有結點都共享相同的結點屬性和方法,
document型別
JavaScript中通過Document型別表示檔案,在瀏覽器中document物件是HTMLDocument的一個實體(繼承自Document型別),表示整個HTML頁面,而且document物件是window物件的一個屬性,因此可以將其作為全域物件來訪問,
Element型別
除了Docuemnt以外,Element算是最常用的型別了,Element型別用于表現XML或HTML元素,提供了對元素標簽名、子節點及特性的訪問,
document的基本使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
function testGetElementById(){
//獲得名字的id
var elem = document.getElementById("username");
//直接列印那條id所在的Input陳述句
console.info(elem);
//
console.info(elem.type+" "+elem.id+" "+elem.name+" "+elem.value);
elem.value="修改后的value";
}
function testGetElementsByName(){
//獲得所有name是hobby的陣列
var arr = document.getElementsByName("hobby");
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
function testGetElementsByTagName(){
//獲得所有的標簽名稱,可以是option,也可以是span,
var arr = document.getElementsByTagName("option");
for(var i=0;i<arr.length;i++){
console.log(arr[i]);
}
}
function testParentNode(){
var elem = document.getElementById("username");
console.info(elem);
var formElem = elem.parentNode.parentNode.parentNode.parentNode.parentNode;
console.info(formElem);
}
function testChildNodes(){
var elem = document.getElementById("professional");
var arr = elem.childNodes;
console.info(arr.length);
for(var i=0;i<arr.length;i++){
if(arr[i].nodeType==1){
console.log(arr[i]+ " "+arr[i].value+" "+arr[i].nodeType);
}
}
}
function testSiblings(){
var elem = document.getElementById("p2");
var elem2 = elem.previousElementSibling;
console.info(elem2)
}
window.onload = testParentNode;
</script>
</head>
<body>
<form action="" id="form1">
用戶名:<input type="text" name="username" id="username" value="請輸入姓名" ><br />
密碼:<input type="password" name="pwd" id="pwd" /><br />
愛好<input type="checkbox" name="hobby" value="music" checked/>音樂
<input type="checkbox" name="hobby" value="sports" />體育
<input type="checkbox" name="hobby" value="art" />美術<br />
職業:<select name="professional" id="professional">
<option value="1">工人</option>
<option value="2" id="p2">農民</option>
<option value="3" selected="selected">解放軍</option>
<option value="4">知識分子</option>
</select><br />
<input type="button" value="提交" onclick="testGetElementsByTagName()"/>
</form>
</body>
</html>
事件
事件這個東西比較簡單,主要作用就是讓客戶點擊HTML按鈕的時候觸發某個JavaScript的函式...而且剛剛操作DOM的時候也用到了onclick單擊事件,當然還有好多其他的事件,也不用去記,要的時候看API或者看手冊就可以了~
可能今天學的東西都不太深入,其實我是打算最后兩天的時候再做個總結,
Day3
前言
今天是國慶假期的第四天,也是我學習JavaScript的第三天,為了能夠熟練語法,今天就打算用JavaScript實作一遍二叉樹資料結構,然后今天還打算把Ajax和Json復習一下,再把Jquery的一些常用操作復習一下,明天就開始寫前端專案,還有bootstrap和Vue框架,
今天學習的內容
二叉樹資料結構(面向物件語法復習)
Ajax和Json
jQuery的使用
表單驗證案例
增刪查改的購物車
錯誤處理和除錯
二叉樹資料結構
二叉樹資料結構如果僅僅只是說我要遍歷的話,那還是比較簡單的,二叉樹的遍歷方法呢,我們可以使用遞回來遍歷,但是遞回的話如果真正實踐的時候還是不建議使用的,因為一旦資料量大了,采用遞回容易堆疊溢位,當然我們還有其他遍歷的方式,比如說我用堆疊輔助回圈來遍歷,比如說我可以將二叉樹線索化來遍歷都可以,那么今天呢,為了更好的鞏固JavaScript面向物件的語法,我就想先序遍歷和后序遍歷使用堆疊輔助回圈,然后中序遍歷我就使用遞回,兩種遍歷的方式都用上,更好鞏固語法,
在過去呢,我也曾寫過一些資料結構的博客,這里可以列出來分享,
樹與二叉樹
二叉樹遍歷的四個應用案例
二叉樹層次遍歷
堆疊輔助回圈遍歷二叉樹
資料結構的實作
//二叉樹類
function BinaryTree(){
//懶得寫get set 就直接把結點放這了
this.root = null;
this.left = null;
this.right = null;
//構造葉子結點
this.getTree = function(root){
var tree = new BinaryTree();
tree.left = null;
tree.right = null;
tree.root = root;
return tree;
}
/**
* 先序遍歷
* 這里采用堆疊輔助回圈
* @param {Object} tree
*/
this.preOrder = function(tree){
//定義一個堆疊
var stack = new Array();
//初始化堆疊
var top = -1;
var p = new BinaryTree();
//根節點入堆疊
stack[++top] = tree;
//堆疊慷訓圈退出,遍歷結束
while(top != -1){
//出堆疊并輸出堆疊頂結點
p = stack[top--];
//使用document輸出
document.write(p.root + " ");
//堆疊是先進后出的,所以先讓右孩子進去,再進左孩子
//等下出來的時候.就是左孩子先出來,右孩子后出來
//堆疊頂結點的右孩子存在,則右孩子入堆疊
if(p.right != null){
stack[++top] = p.right;
}
//堆疊頂結點左孩子存在就讓左孩子入堆疊
if(p.left != null){
stack[++top] = p.left;
}
}
}
/**
* 中序遍歷
* 這里就采用遞回了
* @param {Object} tree
*/
function minOrder(tree) {
if(tree){
if(tree.left){
minOrder(tree.left);
}
document.write(tree.root + " ");
if(tree.right){
minOrder(tree.right);
}
}
}
this.inOrderTraversal = function(tree){
minOrder(tree);
}
/**
* 后序遍歷
* 這里則又是采用堆疊輔助循環
* 具體的原理在(使用自定義的堆疊優化二叉樹的遍歷那篇文章有說過)
* @param {Object} tree
*/
this.postOrder = function(tree){
if(tree != null){
//定義兩個堆疊
var stack1 = new Array();
var stack2 = new Array();
var top1 = -1, top2 = -1;
var p = new BinaryTree();
stack1[++top1] = tree;
while(top1 != -1){
p = stack1[top1--];
stack2[++top2] = p;
if(p.left != null){
stack1[++top1] = p.left;
}
if(p.right != null){
stack1[++top1] = p.right;
}
}
while(top2 != -1){
p = stack2[top2--];
document.write(p.root + " ");
}
}
}
}
//main 函式
function main(){
var binary = new BinaryTree();
//規劃二叉樹
var tree = binary.getTree('A');
tree.left = binary.getTree('B');
tree.right = binary.getTree('C');
tree.left.left = binary.getTree('D');
tree.left.right = binary.getTree('E');
//先序遍歷
binary.preOrder(tree);
//換行
document.writeln("<br/>");
//中序遍歷
binary.inOrderTraversal(tree);
//換行
document.writeln("<br/>");
//后序遍歷
binary.postOrder(tree);
}
main();
Ajax和Json
在今年六月份時候,我曾寫過一篇【大話Ajax】的文章,那篇文章主要就是使用Servlet和JSP發送和接收Json格式字串,當然SpringMVC的Responsebody注解發給后臺的也是JSON格式字串,那今天呢,就再學一遍吧~
XMLHttpRequest物件
XMLHttpRequest 是瀏覽器介面物件,該物件的 API 可被JavaScript、VBScript 以及其它web 瀏覽器內嵌的腳本語言呼叫,通過 HTTP 協議在瀏覽器和 web 服務器之間收發 XML 或其它資料,XMLHttpRequest 可以與服務器實作異步互動,而無需讓整個頁面重繪,因此成為Ajax編程的核心物件,
Ajax的使用步驟
創建 XMLHttpRequest 物件
var xhr = new XMLHttpRequest();
給定請求方式以及請求地址
xhr.open("get","http://www.baidu.com");
發送請求
xhr.send();
獲取服務器端給客戶端的回應資料
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200){
document.getElementById("span").innerHTML = xhr.readyState;
alert(xhr.readyState);
}
}
JSON
語法
Json的語法可以表示三種型別的值
簡單值 : 使用JavaScript相同的語法,可以在Json中表示字串、數值、布林值和Null,
物件: 物件作為一種復雜資料型別,表示的是一組無序的鍵值對,而每個鍵值對的值可以是簡單值,也可以是復雜資料型別的值,
陣列: 陣列也是一種復雜資料型別,表示一組有序的值的串列,可以通過數值索引來訪問其中的值,數值的值也可以是任意型別——簡單值,物件或者陣列
在 JSON 未出現之前在 Ajax 中對于資料傳遞方式,會使用 XML 作為主要資料格式來傳輸資料,直到 JSON 出現后逐漸放棄使用 XML 作為資料傳輸格式,JSON 比 XML 更小、更快,更易決議,
Josn六種資料型別
string:字串,必須要用雙引號引起來,
number:數值,與JavaScript的number 一致,
object:JavaScript的物件形式,{key:value}表示方式,可嵌套,
array:陣列,JavaScript的Array表示方式[value],可嵌套,
true/false:布爾型別,JavaScript 的boolean 型別,
null:空值,JavaScript的null,
使用JSON接收資料的案例
@GetMapping("/test")
@ResponseBody
public User testController(){
return new User("alvin","123456");
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
//請求方式和地址
xhr.open("get","test");
//發送
xhr.send();
xhr.onreadystatechange = function () {
var parse = JSON.parse(xhr.responseText);
alert(parse.username + " " + parse.password);
document.getElementById("data").innerHTML
= parse.username + "<br/>" + parse.password;
}
</script>
</head>
<body>
<span id="data"></span>
</body>
</html>
jQuery
jQuery是JavaScript的一個函式庫,對JavaScript進行了一個封裝,jQuery將常用的、復雜的操作進行函式化封裝,直接呼叫,大大降低了使用JavaScript的難度,改變了使用JavaScript的習慣, jQuery能做的JavaScript也能做,但使用jQuery能大幅提高開發效率,
JavaScript中獲取元素內容的方式
getElementById( ) :回傳一個節點物件,
getElementsByName( ):回傳多個(節點陣列),
getElementsByTagName( ) :回傳多個(節點陣列)
jQuery選擇器
基本選擇器
標簽選擇器 $("a")
ID選擇器 $("#id") $("p#id")
類選擇器 $(".class") $("h2.class")
通配選擇器 $("*")
并集選擇器$("elem1,elem2,elem3")
后代選擇器$(ul li)
父子選擇器 $(ul>li)
屬性選擇器
[attribute] 匹配包含給定屬性的元素
[attribute1][attribute2] 復合屬性選擇器,需要同時滿足多個屬性
[attribute=value] 匹配給定的屬性是某個特定值的元素
[attribute!=value] 匹配所有屬性不等于特定值的元素
[attribute^=value] 匹配給定的屬性是以某些值開始的元素
[attribute$=value] 匹配給定的屬性是以某些值結尾的元素
[attribute*=value] 匹配給定的屬性是以包含某些值的元素
位置選擇器
針對整個頁面而言的位置選擇器
first 獲取第一個元素
:last 獲取最后一個元素
odd 匹配所有索引值為奇數的元素,從 0 開始計數
even匹配所有索引值為偶數的元素,從 0 開始計數
eq(n) 匹配一個給定索引值的元素
gt(n) 匹配所有大于給定索引值的元素
lt(n) 匹配所有小于給定索引值的元素
針對上級標簽而言的位置選擇器
first-child 匹配第一個子元素
last-child匹配最后一個子元素
only-child如果某個元素是父元素中唯一的子元素,將會被匹配
nth-child(n) :nth-child(odd|even) :nth-child(xn+y) 匹配其父元素下的第N個子或奇偶元素
表單選擇器
關于表單項的選擇器
text :password :radio :checkbox :hidden :file :submit
input 匹配所有 input, textarea, select 和 button 元素
關于表單項狀態的選擇器
selected :checked :enabled :disabled
hidden :visible :not
注意$("input")和$(":input")的區別
$("input"):標簽選擇器,只匹配input標簽
$(":input"): 匹配所有 input, textarea, select 和 button 元素
jQuery操作Json案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
type:"get",
url:"/test",
//傳遞引數
data:"username=alvin&password=12345",
success:function (result) {
$("#username").html(result.username);
$("#password").html(result.password);
}
});
})
</script>
</head>
<body>
<span id="username"></span>
<span id="password"></span>
</body>
</html>
表單驗證案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
function checkForm(){
//判斷用戶名是否符合驗證規則
var flag1 = checkUser();
//判斷郵箱是否符合驗證規則
var flag2 = checkEmail();
//如果均符合驗證規則,驗證成功,否則驗證出錯
if(flag1 && flag2){
return true;
}else{
return false;
}
}
function checkUser(){
//清空上次檢查的提示資訊
//$("#usererror").html("");
$("#usererror").empty();
// 用戶名不能為空
var user = $("#user").val();
if(user == ""){
//alert("用戶名不能為空");
$("#usererror").html("用戶名不能為空");
return false;
}
// 用戶名長度大于6
if(user.length <=6){
//alert("用戶名長度需要大于6");
$("#usererror").html("用戶名長度需要大于6");
return false;
}
// 用戶名中不能有數字 ad34adf
for(var i=0;i<user.length;i++){
var ch = user.charAt(i);
if(ch>='0' && ch<='9' ){
//alert("用戶名中不能有數字");
$("#usererror").html("用戶名中不能有數字");
return false;
}
}
return true;
//return undefined
}
function checkEmail(){
//清空上次驗證郵箱的提示資訊
$("#emailerror").empty();
var email = $("#email").val();
if(email.indexOf('@')<0){
//alert("郵箱中必須有@");
$("#emailerror").html("郵箱中必須有@");
return false;
}
if(email.indexOf('.')<0){
//alert("郵箱中必須有.");
$("#emailerror").html("郵箱中必須有.");
return false;
}
return true;
}
function operUser(){
$("#user").select();
//$("#user").val("");
}
</script>
</head>
<body>
<table id="center" border="0" cellspacing="0" cellpadding="0">
<form action="doRegister.jsp" method="post" name="myform" onsubmit="return checkForm()" >
<tr>
<td >您的姓名:</td>
<td>
<input id="user" type="text" onfocus="operUser()" onblur="checkUser()"/>
<div id="usererror" style="display: inline;"></div>
</td>
</tr>
<tr>
<td >輸入密碼:</td>
<td><input id="pwd" name="pwd" type="password"/></td>
</tr>
<tr>
<td >再輸入一遍密碼:</td>
<td><input id="repwd" type="password"/></td>
</tr>
<tr>
<td >您的Email:</td>
<td>
<input id="email" type="text" onblur="checkEmail()"/>
<span id="emailerror"></span>
</td>
</tr>
<tr>
<td> </td>
<td ><input name="btn" type="submit" value="注冊" class="rb1" /></td>
</tr>
</form>
</table>
</body>
</html>
購物車案例
需求:使用jQuery實作對購物車的增刪查改全選反選功能,單個選擇復選框的時候如果滿了,全選框也必須自動勾上,修改數量的時候數量變成文本格式,修改數量按鈕自身變成確定按鈕,修改的時候要檢查數量是否正確,
做這個的目的就和我寫資料結構一樣,主要是為了順順手,因為這些選擇器也好還是事件也好都太多了,我不可能一個一個去背,只能說下次要用的時候看看檔案可以上手,待會兒也會用到各種選擇器

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script type="text/javascript">
//全選操作
$(function(){
//全選操作
$("#chks").click(function(){
//獲取全選框的值,this就相當于是chks,
//prop會根據是否選中回傳true和false,也可以在后面修改true和false
var flag = $(this).prop("checked");
//這句話的意思是將所有input name = chk 的值都根據flag改變
//觸發chks單機事件勾選了的時候flag是true,沒勾選的時候就是false
//所以當全選框是true的時候,下面全改成true,全選是false下面就全改成false就好了
$("input[name=chk]").prop("checked",flag);
});
//為了防止復選框被一個一個點滿的時候全選框沒有被改變.所以這里要處理一下
//使用了該選擇器后,用戶每次點擊復選框,都會在這里進行判斷一下
$("input[name=chk]").click(judgeAll());
//反選操作
$("#fx").click(function(){
//獲取所有復選框
$("input[name=chk]").each(function(){
//獲取原來的值
var flag = $(this).prop("checked");
//修改相反的值
$(this).prop("checked",!flag);
})
//直接呼叫就可以了
judgeAll();
});
/**
* 新增
*/
$("#addRow").click(function(){
//創建一個
var newRow = $('<tr>'+
'<td><input type="checkbox" name="chk" id="" value="2"/></td>'+
'<td>《c primer plus》</td>'+
'<td>Stephen Prata</td>'+
'<td>10</td>'+
'<td>'+
'<input type="button" name="aa" id="" value="修改數量" οnclick="updateAmount(this)"/>'+
'<input type="button" name="" id="" value="洗掉" οnclick="delRow(this)"/>'+
'</td>'+
'</tr>');
//======================================
//這里用到了位置選擇器,last是最后一個,如果要放在第一個就用first
$("tr:last").after(newRow);
});
/**
* 多行洗掉
*/
//這個對應的是橫著那一排的洗掉id,不是單獨洗掉的那個單擊事件
$("#delRow").click(function(){
//獲取所有被選中的復選框
var toDelArr = $("input[name=chk]:checked");
//先判斷是否選擇,如果沒選就提示
if(toDelArr.length == 0){
alert("至少選中一行");
}else{
//toDelArr.remove();是反面教材,因為剛剛只是獲得復選框,直接刪自然也只會刪掉復選框
//toDelArr.parent().remove();也不行,因為它只會刪掉當前的td,要想刪掉tr需要兩個parent
//toDelArr.parent().parent().remove(); 這種寫法雖然可以但是也太麻煩了
//最好的寫法還是這種,parents里面一定要寫東西,不然整個頁面都刪掉了,,,
toDelArr.parents("tr").remove();
}
});
/**
* 復制多行
*/
$("#copyRow").click(function(){
//獲取所有被選中的復選框
var toCopyArr = $("input[name=chk]:checked");
//先判斷是否選擇,如果沒選就提示
if(toCopyArr.length == 0){
alert("至少選中一行");
}else{
//each是在回圈,所以回圈里面一個一個加就相當于多行增加
toCopyArr.each(function(){
//復制一份
var cloneRow = $(this).parents("tr").clone();
//粘貼一份
$("#ta").append(cloneRow);
});
}
});
})
/**
* 為了讓反選和普通選擇都進行判斷并且代碼不用重復寫
* 所以這里就封裝成一個函式讓它們呼叫
*/
function judgeAll(){
//獲取所有的復選框
var arr = $("input[name=chk]");
//先默認全部選中
var flag = true;
//arr.each就相當于是在回圈遍歷
arr.each(function(){
//判斷所有復選框是否被選中
var flagplus = $(this).prop("checked");
//假如有一個沒被選中,那么全選框就是false
if(flagplus == false){
flag = false;
return;
}
});
//決定全選框的值
$("input[name=chks]").prop("checked",flag);
}
/**
* 修改當前數量
*/
function updateAmount(obj){
//數量變成文本框的值,文本框變成數量的值
//獲取原來的數量 prev是指修改數量的前面一個表格,不然就會把自己變成下面input的格式
//如果要把input格式換成作者那個位置,可以用兩個prev()試試
var amountCell = $(obj).parent().prev();
var amount = amountCell.html();
//將指定位置的td改成input文本格式
amountCell.html('<input type="text" value = "'+ amount +'" οnblur="checkAmount(this)"/>');
//把修改按鈕變成確定按鈕
//獲得當前按鈕單元格
var buttonCell = $(obj).parent();
//準備新按鈕
var newButton = $('<input type="button" name="" id="" value="確定" οnclick="confirmAmount(this)"/>'+
'<input type="button" name="" id="" value="洗掉" οnclick="delRow(this)" />');
//添加新按鈕
buttonCell.html(newButton);
}
/**
* 確定數量
* @param {Object} obj
*/
function confirmAmount(obj){
//文本框變成數量
//獲取原來的數量
var amountInput = $(obj).parent().prev().find("input");
var amount = amountInput.val();
//修改文本框的數量
$(obj).parent().prev().html(amount);
//確定按鈕變成修改按鈕
//獲得當前按鈕單元格
var buttonCell = $(obj).parent();
//準備新按鈕
var newButton = $('<input type="button" name="" id="" value="修改數量" οnclick="updateAmount(this)"/>'+
'<input type="button" name="" id="" value="洗掉" οnclick="delRow(this)" />');
//添加新按鈕
buttonCell.html(newButton);
}
//判斷數量是否正確
function checkAmount(obj){
//獲取值
var amount = $(obj).val();
//判斷是否正確
if(isNaN(amount) || amount < 1 || parseInt(amount) != amount){
alert("必須是大于0的整數!");
}
}
/**
* 洗掉當前行
*/
function delRow(obj){
//這里就是一句話解決了,,,
$(obj).parents("tr").remove();
}
</script>
</head>
<body>
<h3>購物車</h3>
<hr />
<input type="button" id="fx" value="反選" />
<input type="button" id="addRow" value="新增一行" />
<input type="button" id="delRow" value="洗掉行"/>
<input type="button" id="copyRow" value="復制行" />
<table border="1px" cellpadding="10px" cellspacing="0" id="ta">
<tr>
<td width="50px"><input type="checkbox" name="chks" id="chks" value="1" /></td>
<td width="200px">書名</td>
<td width="200px">作者</td>
<td width="200px">數量</td>
<td width="200px">操作</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="2"/></td>
<td>《計算機組成原理》</td>
<td>Alan Clements</td>
<td>10</td>
<td>
<input type="button" name="aa" id="" value="修改數量" onclick="updateAmount(this)"/>
<input type="button" name="" id="" value="洗掉" onclick="delRow(this)"/>
</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="3" /></td>
<td>《深入理解計算機系統》</td>
<td>布賴恩特</td>
<td>10</td>
<td>
<input type="button" name="" id="" value="修改數量" onclick="updateAmount(this)"/>
<input type="button" name="" id="" value="洗掉" onclick="delRow(this)" />
</td>
</tr>
<tr>
<td><input type="checkbox" name="chk" id="" value="4" /></td>
<td>《編譯原理》</td>
<td>Alfred V.Aho</td>
<td>30</td>
<td>
<input type="button" name="" id="" value="修改數量"οnclick="updateAmount(this)"/>
<input type="button" name="" id="" value="洗掉" onclick="delRow(this)"/>
</td>
</tr>
</table>
</body>
</html>
錯誤處理和除錯
由于JavaScript本身是動態語言,而且這么多年來也沒有一個固定的開發工具,事實上,你就是新建一個記事本,也可以寫JavaScript代碼然后放瀏覽器上運行,不同的瀏覽器自然對JavaScript的編譯支持等都不太相同,今天就來學習一下前端的除錯問題,至于try catch的話,明天寫代碼的時候再用兩遍就熟了吧~
現在我就隨便打開一個SpringBoot的專案去運行,然后按F12打開瀏覽器的控制臺,這里是用谷歌瀏覽器,其實學Web開發是比較建議用谷歌或者火狐的,按F12之后進入除錯頁面就會看到很多選項

Elements(元素)
這個頁面顯示的都是后臺html代碼,如果想要定位到某個位置可以右鍵檢查,就自然跳過來了,

Console(控制臺)
這個界面會顯示控制臺的資訊,比如代碼報錯了...或者console.log()等可以把內容輸出到這里,就跟平時寫Java代碼IDEA或者eclipse下面的控制臺差不多,
Sources(資料來源)
點擊它可以看到后臺代碼的檔案資訊
Network
Network可以查看當前url的請求內容,請求狀態等資訊,還可以分析網路狀態
工具打開之后,點擊network,就可以查看當前網路錄制情況,默認是開啟網路錄制的,查看圖中圈中的部分,判斷是否開啟了網路錄制,紅色代表正在錄制,點擊之后關閉,變為灰色,那就是停止錄制

選擇XHR更是可以直接找到后臺介面甚至查看Json,Preview就可以看到Json

好了,今天差不多先學到這,明天是計劃先用HTML+CSS+JavaScript做個純底層的案例,接著再學習bootstrap和vue,好好加油!
Day4
前言
今天是國慶假期的第五天了,同時也是我學習JavaScript的第四天,經過了前面三天的學習,基本的概念也都過了一遍,是時候該做專案了,其實我之所以會選擇國慶期間學前端,是因為我打算國慶之后開始來做一個電商專案,這個電商專案會很大,我應該是會采用分布式,主要目的不是為了上線也不是為了賺錢,而是單單純純的想全堆疊的做一次,提高技術水平,所以我必須先把前端學好,今天的學習打算呢,我是計劃先用最原始的HTML,CSS,JavaScript來做一個頁面好看點的專案,當然實際功能可能還是和昨天的購物車差不多,接著呢,我今天還要學習bootstrap和vue兩大前端框架,不過我更多的還是會學習bootstrap,因為我是計劃在我的專案中去使用它,
第四天的學習內容
單鏈表的翻轉(面向物件語法復習)
CSS樣式
購物車(圖形版)
bootstrap框架
Vue框架
登錄框(bootstrap實作)
單鏈表的翻轉
前天呢,學習第二天的時候我說過為了鞏固面向物件的語法,所以是決定每天寫一遍資料結構的,不過從明天開始就正式進入專案階段了也就沒必要寫了,今天就寫個單鏈表的翻轉,然后寫下購物車,當然這次的購物車要比昨天的購物車多了一些圖片素材,主要目的還是為了鞏固,
我們都知道堆疊資料結構是先進后出的,所以其實你要翻轉單鏈表特別簡單,只需要把資料放到堆疊里面再吐出來就可以了~沒什么難度,但是呢,我前天寫單鏈表的那種寫法遍歷出來和添加的順序都是反的,所以應對這種情況使用堆疊反而無法翻轉,因為翻轉后的資料再經歷一次翻轉就又相當于是還原了,所以這種情況下如果我要達到翻轉效果,可以使用佇列,佇列是先進先出的,把本來就已經翻轉的資料重新插入再遍歷可以達到效果,
在這里我要宣告一下,正常情況下都是使用堆疊來達到翻轉效果,但是我這種情況使用佇列會更好一些,
關于堆疊和鏈表的資料結構理論的話我過去也寫過博客,這里就列出來分享一下,
堆疊和佇列的基本概念
順序堆疊和鏈表堆疊
順序佇列和鏈表佇列
代碼實作
/**
* 鏈表類
*/
function LinkList(){
//結點類
function Node(data){
this.data = data;
this.next = null;
}
//頭節點
var head = new Node(null);
//插入元素
this.add = function(data){
var temp = new Node(data);
temp.next = head.next;
head.next = temp;
};
//遍歷元素
this.print = function(){
var temp = head.next;
while(temp != null){
document.write(temp.data + " ");
temp = temp.next;
}
};
//翻轉
this.rev = function(){
var temp = head.next;
//定義一個佇列
var queue = new Array();
//把鏈表元素存入佇列內
while(temp != null){
queue.push(temp.data);
temp = temp.next;
}
//將 head 置空 然后重新添加
head = new Node(null);
//把佇列的結點吐出來
while(queue.length > 0){
//剛剛push是從后往前添加,所以現在shift是
//從前往后吐出來,因此達到先進先出的效果
this.add(queue.shift());
}
};
}
//main 函式
function main(){
var list = new LinkList();
//添加元素
for(var i = 0; i < 10; i++){
list.add(i);
}
//列印原鏈表
list.print();
document.write("<br/>");
//翻轉鏈表
list.rev();
//列印翻轉后的
list.print();
}
main();
翻轉

購物車
剛才把鏈表翻轉了一下,主要目的不是鍛煉資料結構,而是鞏固JavaScript編程語法,如果要學習資料結構,個人是建議使用C語言或者C++語言來實作會更好一些,因為C/C++語言比較接近底層,特別是C語言,
購物車呢,昨天使用jQuery已經實作過一遍了,那么今天我就打算使用JavaScript來實作一遍,當然,這一次我會盡量把網頁做的好看一點,當然實際的功能和昨天還是差不多,更多的還是為了鞏固,做完購物車之后就要開始學習bootstrap和vue了,
購物車的頁面
這個購物車的頁面我是對京東購物車的一個模仿,當然我也只是拿來學習用的,并不是拿去商業用途,還望別介意哈,

這個頁面呢是使用純HTML+CSS畫的,然后JavaScript是用來干什么的呢?需求如下:
功能需求:
1: 全選功能:而且點擊復選框也會自動勾選全選框,不能有BUG
2: 計算功能:通過商品數量的增加旁邊的價格也跟著增加
3: 洗掉功能:洗掉購物車中的商品
4: 結算功能:算出最后應該付款的價格
這個專案在JavaScript上的需求比昨天的都要簡單,主要練習的方向是HTML和CSS,因為等下學框架的時候,比如說bootstrap框架它都是把這些底層封裝好的,所以在學習框架之前先趕緊用一遍底層,
如果想到了一個需求的解決方法,但是又不知道用什么標簽或者屬性,那么《菜鳥教程》或者《w3school》這兩個網站可以幫助自己,也可以在額外創建一個專門做實驗的html檔案,可以臨時試試它的效果如何,
還有一件事就是,不管是HTML、CSS還是JavaScript,又或者其他語言,比如說Java,Python等,永遠都不要花心思去記那些工具,方法什么的,只要知道有這個東西,然后它底層是怎么一回事就好了,知道原理寫代碼的時候看API能夠看得懂就好了,因為人不可能全都記得住,有這個時間,還不如多去鉆研一些邏輯思維,或者資料結構與演算法,RBAC,設計模式什么的,當然學習底層個人覺得比較好的方法可以先學點C/C++語言,因為C語言是底層,就比如說垃圾回識訓制,如果學過C語言的人他就能很快聽得懂,學過C++就知道解構式這種東西,個人觀點,不喜勿噴,當然如果有大神的話,請求指點,因為本人是個菜鳥,哈哈^ ^,
在這里呢,使用兩個檔案來寫,一個檔案專門寫CSS,另一個則是HTML+JavaScript,檔案名字我也懶得取了,直接new_file省事,
代碼實作
CSS全域設定
這些都是比較常用的格式,主要是為了美觀,我自己也是在網上搜索的,甚至說接下來的頁面,我也會邊看手冊邊寫,就像看字典一樣,因為我實話實說我真的沒法記住它們,但是看手冊的話,還是可以拼出來的,
/*清除所有格式*/
body,div,h1,h2,h3,h4,h5,h6,li,ol,ul{margin: 0px; padding: 0px;}
/*整個文本默認居中*/
body{text-align: center;font-size:14px;}
/*所有a標簽去掉下劃線*/
a{text-decoration: none;}
/*li的點去掉*/
li{list-style: none;}
如何使用CSS定位HTML標簽的位置來設定格式?
<!-- 這里先寫好class,等下到了CSS檔案里,就可以根據這個class
找到該標簽的位置,然后設定格式
-->
<div class="nav">
</div>
/*這里面的navigation,是根據前臺html標簽里面的class找到的*/
.nav{
height: 30px;
/*#f1f1f1是顏色,具體的對應可以查百度*/
background-color: #f1f1f1;
}
基本的事項剛剛也說完了,現在直接放代碼了,由于HTML和CSS代碼比較多,而且也都是拼出來的沒什么邏輯性,所以CSS就不放筆記里來了,HTML我也刪減一部分,只保留系結了事件的標簽,筆記盡量記一些有邏輯性的東西,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>購物車</title>
<link rel="stylesheet" type="text/css" href="css/shop.css"/>
<script type="text/javascript">
//獲得所有多選框的物件
var all = document.getElementsByName("select");
/**
* 全選操作,點擊這個按鈕其他的都會自動全選
* 但是這里不能使單選來決定是否全選
* 我們還需要另一個函式
* @param {Object} obj
*/
function isSelectAll(obj){
var flag = obj.checked;
for(i in all){
all[i].checked = flag;
}
}
/**
* 單選框決定全選框
* @param {Object} obj
*/
function isSelectAllPlus(obj){
//默認全選
var flag = true;
/**
* 之所以這樣回圈,是因為第一個和最后一個按鈕都不是商品的按鈕
* 而是全選的按鈕,所以這里就避過了第一個和最后一個兩個按鈕
*/
for(var i = 1; i < all.length - 1; i++){
//如果有一個沒選那就不是全選
if(!all[i].checked){
flag = false;
//也沒必要繼續回圈判斷了
break;
}
}
//改變第一個和最后一個框
all[0].checked = flag;
all[all.length - 1].checked = flag;
}
/**
* 控制增加減少
* @param {Object} obj
* @param {Object} sigle
*/
function checkAdd(obj,sigle){
var pre;
if(sigle == "1"){
//獲得下一個結點
pre = obj.nextElementSibling;
//如果數量大于0
if(Number(pre.value) > 0){
//獲得節點的value值
pre.value=Number(pre.value)-1;
}
}else{
//獲得上一個結點物件
pre = obj.previousElementSibling;
//獲得結點value的值
pre.value = Number(pre.value) + 1;
}
//計算每一個商品的價格
//獲得每一個商品的單價
var val=pre.parentNode.previousElementSibling.innerHTML;
//計算總的價格
var num =Number(val)*Number(pre.value);
//把總的價格賦值給指定的物件
pre.parentNode.nextElementSibling.innerHTML="¥"+num;
}
/**
* 洗掉結點
*/
function deleteByThis(obj){
//獲得父節點的div 這么多parent的原因昨天體驗過
var divNode = obj.parentNode.parentNode.parentNode;
divNode.remove();
}
/**
* 結算最后的價格
*/
function countMoney(){
//統計商品的總價格
var count = 0;
//統計是否有勾選的物件
var checkedNum = 0;
//統計商品的數量
var number = 0;
//回圈遍歷
for(var i = 0; i <all.length; i++){
//如果選中才會進入計算
if(all[i].checked){
//商品的數量
checkedNum++;
//獲得ul父結點
var par = all[i].parentNode.parentNode;
//獲得指定ul下面的所有的li
var li= par.getElementsByTagName("li");
//單個商品的總價格
var money=li[6].innerText.split("¥")[1];
//獲得所有商品的總價格
count += Number(money);
document.getElementById("countMoney").innerText=count;
//獲得商品的數量
var shopCount=li[5].getElementsByTagName("input");
var num=shopCount[0].value;
number+=Number(num);
//獲得商品數量統計的物件
document.getElementById("snum").innerText=number;
}
}
//如果沒有勾選自然就都是0
if(checkedNum==0){
document.getElementById("countMoney").innerText=0;
document.getElementById("snum").innerText=0;
}
}
</script>
</head>
<body>
<!--顯示選單的結束-->
<!--商品詳情展示開始-->
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀鋒之影</a></li>
<li class="info_4"><a>經典皮膚</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">洗掉</a><br />
<a>已到我的關注</a>
</li>
</ul>
</div>
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀鋒之影</a></li>
<li class="info_4"><a>經典皮膚</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">洗掉</a><br />
<a>已到我的關注</a>
</li>
</ul>
</div>
<div class="info warp">
<ul>
<li class="info_1"><input type="checkbox" name="select" onclick="isSelectAllPlus(),countMoney()"/> </li>
<li class="info_2"> <img src="img/img1.jpg" width="80px"/> </li>
<li class="info_3"><a>刀鋒之影</a></li>
<li class="info_4"><a>經典皮膚</a> </li>
<li class="info_5">6300</li>
<li class="info_6">
<button onclick="checkAdd(this,1),isSelectAllPlus(),countMoney()">-</button>
<input type="text" name="" id="" value="1" />
<button class="bot" onclick="checkAdd(this,2),isSelectAllPlus(),countMoney()">+</button>
</li>
<li class="info_7">¥6300</li>
<li>
<a href="javascript:viod(0)" onclick="deleteByThis(this),countMoney()">洗掉</a><br />
<a>已到我的關注</a>
</li>
</ul>
</div>
<!--商品詳情展示結束-->
<!--結算開始-->
<div class="balance warp">
<ul class="balance_ul1">
<li>
<input type="checkbox" name="select" id="" value="" onclick="isSelectAll(this),isSelectAllPlus(this),countMoney()"/>
全選
</li>
<li><a>洗掉選中商品</a></li>
<li><a>移到我的關注</a></li>
<li><a>清除下柜商品</a></li>
</ul>
<ul class="balance_ul2">
<li>已經選擇<span id="snum">0</span>件商品</li>
<li>總價 <span id="countMoney">¥0</span></li>
<li>
<button class="butt">去結算</button>
</li>
</ul>
</div>
<!--結算結束-->
</body>
</html>
Vue框架
Vue這個框架一般多用于前后端分離的專案,就像我上班的時候前端很多都是用Vue框架,前后端分離的好處就是可以讓我們后端程式員只關心后端的代碼,不用去管前端,還有就是開發的時候前端和后端各顧各的,不用誰先等誰寫完,后端程式員用Responsebody發個Json給前端就沒啥事了,其他的頁面效果都讓他們寫,,,我也是因為長期這樣,所以前端學的特別差,不過呢,前面我也說了我是打算自己全堆疊的來做一次分布式電商專案,我自己的電商專案可能還是會使用bootstrap框架,個人也更喜歡那個,
學習
學習框架這一塊呢,有時間可以買本書系統的學,也可以去vue官網看教程和API,真正系統的學習Vue內容還是很豐富的,我這里之所以一天學兩個框架,是因為一方面我從事的是后端開發,并不是靠前端吃飯,我也想國慶以后再慢慢深入,二方面是這個東西我個人認為,還是多在專案中實踐才不容易忘,不然長期不用也還是會忘記的,就像我們用慣了鍵盤打字以后,就很容易提筆忘字一個道理,
實作前后端分離的常用前端框架,
Vue框架用的很多,但并不是唯一,其他的前后端分離框架也有,最常用的有三款,
Vue.js 小巧,靈活,功能卻很強大,在市場上占有率更高,屬于成熟穩定的框架,
React相比Vue.js更新一些,近幾年有追趕Vue.js的架勢,更適合做移動專案,
AngularJS相比Vue更加大量一些,只有在一些大型專案中才可能被使用,
安裝
安裝直接運行安裝軟體就可以了,然后輸入CMD進入命令列,輸入node-v和npm-v看見版本號就知道是否安裝成功,然后下面的命令也都是在CMD命令列里面使用
安裝淘寶鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝webpack
cnpm install -g webpack webpack-cli
安裝 Vue Cli
cnpm install -g @vue/cli
安裝Vue.js插件(我這里是用IDEA),創建專案的時候名字最好不要大寫

template和script互動
<template>
<div id="app">
<div>
我是{{name}},我的上司是{{king}}
我是{{person.name}} 今年 {{person.age}} 歲
</div>
</div>
</template>
<script>
// export是一個資料物件,我們可以寫多個屬性或者函式
export default {
data(){
return{
name:"諸葛亮",
king:"劉禪",
person:{
name:"小明",
age : 16
}
}
}
}
</script>
條件判斷加單機事件
<!-- template -->
<div>
我是{{person.name}} 今年 {{person.age}} 歲
<!-- 單擊事件,直接寫動作,然后用 v-on: 系結 -->
<input type="button" v-on:click="person.age = person.age + 1" value="年齡 + 1"/>
<!-- 也可以在下面定義一個函式(也可以叫方法)拿來呼叫,系結的話也可以用@來作為v-on的簡寫 -->
<input type="button" @click="AddAge" value="年齡-1"/>
<!-- if判斷 -->
<span v-if="person.age<18">未成年</span>
<span v-else-if="person.age >= 18 && person.age < 35">青年</span>
<span v-else-if="person.age >= 35 && person.age < 50">壯年</span>
<span v-else-if="person.age >= 50 && person.age < 60">中年</span>
<span v-else>老年</span>
</div>
<!-- script : export default -->
methods:{
//定義當前組件中可以使用的所有函式
AddAge:function () {
this.person.age = this.person.age - 1;
}
}
回圈陳述句
<!-- template -->
<div>
<!--
v-bind:key 系結一個變數,相當于定義一個臨時變數
v-for="變數 in 集合" 變數是使用某已有變數,不能定義新變數,
-->
學校學院分別有
<ul>
<li v-for="My in MyClass" v-bind:key="My">
學院{{My.name}} 班級數 {{My.number}}
</li>
</ul>
</div>
<!-- script : export default -->
//在return回傳下面再定義一個陣列,我們等下用回圈來遍歷
MyClass:[
{"name":"資訊工程系","number":8},
{"name":"機電工程系","number":6},
{"name":"經濟管理系","number":7}
]
Html支持
如果希望能夠決議HTML,必須使用v-html指令,v-html是任意HTML標簽的屬性,v-html的取值可以是Model中定義的欄位,
<!-- template -->
<span v-html="MyJava"></span>
<!-- script data() return~ -->
MyJava:"我愛<b>Java</b>編程"
組件
組件:如果專案中多次用到類似效果,就可以把這個效果進行自定義組件,新建專案后默認存在HelloWorld.vue就是一個組件,組件檔案必須匯入才能使用,其中Helloworld為自定義名稱,通過這個名稱就可以呼叫對應組件,如果import時直接寫組件名(大小寫相同)IDEA會提升生成組件的路徑,所以一般習慣上都是把名稱定義為組件檔案名,components: 組件檔案只import是不能被使用的,必須在components中注冊組件,注冊后在中就可以通過組件名直接參考組件了,在中組件以標簽形式存在,標簽名為組件名,其中msg是在Helloworld中定義的props引數,表示需要傳遞給組件的資料,
在src下面的components目錄新建一個檔案,名字隨便取
<template>
<div>
<div>這是一個組件</div>
<!-- 獲取組件傳遞的引數名稱和型別 -->
<div>{{MyLove}}</div>
</div>
</template>
<script>
export default {
//我的組件名
name: "MyComponents",
//props:定義組件傳遞的引數名稱和型別
props:{
MyLove:String
}
}
</script>
<style scoped>
</style>
現在回到剛剛那個地方
<template>
<div id="app">
<div>
<MyComponents MyLove="Java"/>
</div>
</div>
</template>
<script>
//匯入,不匯入會報錯
import MyComponents from "@/components/MyComponents";
// export是一個資料物件,我們可以寫多個屬性或者函式
export default {
components:{
MyComponents
},
</script>
bootstrap框架
bootstrap官網
菜鳥教程
bootstrap框架也是我比較喜歡的一個框架,經過了四天的學習,明天第五天是要開始做專案了,雖然今天和昨天也做了專案,但那都是基于底層的,如果是要做比較大的專案會很費勁,就像我剛剛的那個購物車,僅僅只是一個頁面,我光CSS代碼就寫了三百多行,這樣一來效率是很低的,后天就差不多可以開始為電商做準備了,
bootstrap的官網也好還是菜鳥教程都有檔案和API,官方博客等都可以看一看,如果沒有能力盲寫代碼的話,其實看著API寫代碼也并沒有什么不好,事實上我每次寫前端代碼都是看著API寫的,就像JavaScript那么多事件和方法,HTML那么多標簽,我也很難做到全都記住,就把它們當成字典就好了,邏輯思維其實才是更重要的,這也是為什么很多地方都喜歡面試問演算法的原因,
柵格系統
Bootstrap包含了一個回應式的、移動設備優先的、不固定的網格系統,可以隨著設備或視口大小的增加而適當地擴展到12列,它包含了用于簡單的布局選項的預定義類,也包含了用于生成更多語意布局的功能強大的混合類,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
<link rel="stylesheet" href="../css/bootstrap.css"/>
<script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../js/bootstrap.js"></script>
</head>
<body>
<div class="container">
<div class="row" >
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;
box-shadow: inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>我熱愛資料結構與演算法分析</p>
</div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;box-shadow:
inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
bootstrap是一個非常流行的框架
</p>
<p>
C語言是一門面向程序的編程語言
</p>
</div>
<div class="clearfix visible-xs"></div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;
box-shadow:inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
C++是一個面向物件的編程語言
</p>
</div>
<div class="col-xs-6 col-sm-3"
style="background-color: #dedef8;box-shadow:
inset 1px -1px 1px #444, inset -1px 1px 1px #444;">
<p>
分布式
</p>
</div>
</div>
</div>
</body>
</html>

查看原始碼
平時呢,寫Java代碼的時候總會遇到各種各樣的類,各種各樣的框架,所以,要了解一個沒見過的框架最快速的方法就是看原始碼,看原始碼,不僅方便學習框架,也方便學習里面的演算法,同樣的道理放到JavaScript里面,也是行得通的,
在剛剛寫購物車的時候,臨時學了下CSS,其實我過去很少接觸這玩意兒...因為后端學習HTML和JavaScript里面的Ajax和Json就已經足夠了,jstl和thymeleaf等技術都有它們自己獨特的語法,不過,現在我知道CSS檔案對應著HTML頁面的class,所以更換樣式的話也可以根據CSS檔案里面的樣式,把class的名字改成框架里面CSS的名字就可以了~
比如我可以把剛才的柵格系統換一個樣式,其實也很簡單,直接打開bootstrap的原始碼就可以了,搜索我剛剛使用的col-lg-6,找到它,我可以換成一個和它同類的樣式,看看變化,

當我把所有的col-lg-6換成10以后,樣式就變成了這個樣式,其實只要肯看原始碼,學習起來還是特別迅速的,雖然我不怎么學前端,但是把學習Java的這個概念移植過來,道理也還是那個道理,
BootStrap組件
在bootstrap官網里面有很多很多的組件原始碼參考,要用的時候可以直接拿過來,或者拿過來再修改一點點

Bootstrap按鈕
<button type="button" class="btn btn-primary">主要</button>
<button type="button" class="btn btn-secondary">副手</button>
<button type="button" class="btn btn-success">成功</button>
<button type="button" class="btn btn-danger">危險</button>
<button type="button" class="btn btn-warning">警告</button>
<button type="button" class="btn btn-info">資訊</button>
<button type="button" class="btn btn-light">明亮</button>
<button type="button" class="btn btn-dark">黑暗</button>
<button type="button" class="btn btn-link">鏈接</button>

按鈕組
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-secondary">左邊</button>
<button type="button" class="btn btn-secondary">中間</button>
<button type="button" class="btn btn-secondary">右邊</button>
</div>
小彈窗(英文翻譯是卡片...我感覺不太對勁所以就理解成小彈窗)

<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">一些快速的示例文本可在卡標題上構建,并構成卡內容的大部分,</p>
<a href="#" class="btn btn-primary">跳轉</a>
</div>
</div>
輪播
<div id="carouselExampleSlidesOnly" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="../img/tree.png" class="d-block w-100" alt="..." height="200">
</div>
<div class="carousel-item">
<img src="../img/wather.png" class="d-block w-100" alt="..." height="200">
</div>
<div class="carousel-item">
<img src="../img/montain.png" class="d-block w-100" alt="..." height="200">
</div>
</div>
</div>
其實還有好多好多東西,我就不一 一再CSDN上面試了,其實這個框架最主要還是要學會前后端互動,不過前后端互動可能就要等到寫專案的時候了,因為平時上班我也只是發個Json給前端就不管不問了,這次全堆疊的來寫一個大專案,還是要多多學習的,今天就用Bootstrap隨便寫一個登陸頁面和后臺管理就結束了吧,
使用BootStrap實作一個登錄框
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Document</title>
<link rel="stylesheet" href="../css/bootstrap.css"/>
<script type="text/javascript" src="../js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../js/bootstrap.js"></script>
</head>
<body background="../img/tree.png"; style=" background-repeat:no-repeat ;background-size:100% 100%; background-attachment: fixed;">
<div class="modal-dialog" style="margin-top: 10%;">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title text-center" id="myModalLabel">登錄</h4>
</div>
<div class="modal-body" id = "model-body">
<div class="form-group">
<input type="text" class="form-control"placeholder="用戶名" autocomplete="off">
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="密碼" autocomplete="off">
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<button type="button" class="btn btn-primary form-control">登錄</button>
</div>
<div class="form-group">
<button type="button" class="btn btn-default form-control">注冊</button>
</div>
</div>
</div>
</div>
</body>
</html>

剛剛在網上隨便找了張圖片做背景,今天先學到這里,明天還是老規矩,先用JavaScript實作一個資料結構,鞏固語法的記憶,然后就來一個SpringBoot和Bootstrap聯合的小專案,國慶七天!絕不頹廢!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/163337.html
標籤:AI
