七天學會JavaScript~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,好好加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/157649.html
標籤:其他
