復習呢有一個很直觀的感受,就是以前學的東西,萌懂半懂的,這一來全部都清楚了,你以前以為你學的并不好但是復習一次把以前的案例一做,居然能夠自己獨立完成,知識點看著掌握的還不錯,
1.
兩天時間就把整個ajax復習完了,一天目前還暫時做不到哈哈,確實還是有很多案例都要思考一會,直接從案例下手吧,一個圖書管理的案例,在這個案例里面吧就是用三個介面來獲取圖書,增加圖書,洗掉圖書,在js方面沒多大問題,在html方面,還讓我多熟悉了下vscode快速編程bootstrap,直接bs3,form-inline類名可以讓每個表單項為行內塊元素,table-hover可以增加表格的每一行懸停效果,
獲取圖書串列:封裝為一個函式,通過ajax發起get請求,然后把拿到的資料通過foreach回圈出來,
增加圖書串列:也是發起一起請求,然后要重新獲取一下串列

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./lib/bootstrap.css"> <style> .panel-body { text-align: center; } .input-group { width: 30%; margin: 0 10px; } .panel { width: 90%; margin: 0 auto; } .table { width: 90%; margin: 15px auto 0; } </style> </head> <body> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">添加新圖書</h3> </div> <!-- 1.添加了一個類名form-inline 可使里面的表單元素變成行內塊元素 --> <div class="panel-body form-inline"> <div class="input-group "> <div class="input-group-addon">書名</div> <input type="text" class="form-control bookname" id="exampleInputAmount" placeholder="請輸入書名"> </div> <div class="input-group"> <div class="input-group-addon">作者</div> <input type="text" class="form-control author" id="exampleInputAmount" placeholder="請輸入作者"> </div> <div class="input-group"> <div class="input-group-addon">出版社</div> <input type="text" class="form-control publisher" id="exampleInputAmount" placeholder="請輸入出版社"> </div> <button type="button" class="btn btn-primary">添加</button> </div> </div> <!-- 2.table-borderred可以為每一個表單元素增加邊框 table-hover 添加滑鼠滑過表單的懸停狀態 --> <table class="table table-bordered table-hover"> <thead> <tr> <th>id</th> <th>書名</th> <th>作者</th> <th>出版社</th> <th>操作</th> </tr> </thead> <tbody> </tbody> </table> <script src="./lib/jquery.js"></script> <script> /* $.get('http://www.liulongbin.top:3006/api/getbooks', res => { // console.log(res); if (res.status !== 200) return console.log(獲取資料失敗); let htmlStr = '' let str = '' res.data.forEach(item => { htmlStr = `<tr> <td>${item.id}</td> <td>${item.bookname}</td> <td>${item.author}</td> <td>${item.publisher}</td> <td><a href="javascript:;">洗掉</a></td> </tr>` str += htmlStr }) document.querySelector('tbody').innerHTML = str }) */ // 3.上面我自己的做的方法固然可以但是這里既然是用的jq那就用jq的方法來實作 function getBook() { $.ajax({ method : 'get', url : 'http://www.liulongbin.top:3006/api/getbooks', success : res => { if (res.status !== 200) return alert('獲取資料失敗') // jq的回圈方法 // 注意這里的i不能省略 let arr = [] $.each(res.data, (i, item) => { arr.push(`<tr> <td>${item.id}</td> <td>${item.bookname}</td> <td>${item.author}</td> <td>${item.publisher}</td> <td><a href="javascript:;" data-id="${item.id}" class="del">洗掉</a></td> </tr>`) }) $('tbody').empty().append(arr.join('')) }}) } getBook() // 洗掉圖書模塊 function delBook() { // 4.洗掉圖書也要用到一個介面 // 4.1注意這里的jq的事件委托,在后代選擇器這里,不管是寫id還是class還是標簽都不再需要$符號直接引號寫上來即可 $('tbody').on('click', '.del' , function() { // 這里點誰就會觸發誰,用到了事件委托,說明現在每個a標簽上也有點擊事件了他們就是事件的呼叫者 // attr這個方法可以設定可以獲取屬性的值,洗掉用removeAttr let id = $(this).attr('data-id') console.log(id); $.get('http://www.liulongbin.top:3006/api/delbook', {id : id}, res => { if (res.status !== 200) return alert('洗掉失敗') // 洗掉成功重繪一下表格 getBook() }) }) } delBook() // 添加圖書模塊 function addBook() { $('.btn').on('click', function() { $.post('http://www.liulongbin.top:3006/api/addbook',{ bookname : $('.bookname').val(), author : $('.author').val(), publisher : $('.publisher').val() }, res => { console.log(res); if (res.status !== 201) return alert(res.msg) getBook() return alert(res.msg) }) }) } addBook() </script> </body> </html>
2.
第二個是一個聊天機器人的案例,以前也說過這些案例,只是這次來做感想又深入了一步,這個案例分為了三步,先是把自己發的訊息能夠渲染到聊天界面,然后添加一個resetui重置右側滾動條的函式,可以讓聊天界面跟著我們的剛發的訊息走,然后把獲取機器人回復訊息封裝為一個函式,具體里面是通過我們發的訊息為一個引數然后去獲取請求,會給你傳回來一個引數,同時可以把這個引數以機器人回復的姿態渲染到聊天界面,最后就是語音播放功能,把機器人的訊息作為一個引數封裝一個函式,html增加一個audio標簽,src就為我們這次請求的src,要加上網頁的一個根路徑哦

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <link rel="stylesheet" href="css/reset.css" /> <link rel="stylesheet" href="css/main.css" /> <script type="text/javascript" src="js/jquery-1.12.4.min.js"></script> <script type="text/javascript" src="js/jquery-ui.min.js"></script> <script type="text/javascript" src="js/jquery.mousewheel.js"></script> <title>聊天機器人</title> </head> <body> <div class="wrap"> <!-- 頭部 Header 區域 --> <div class="header"> <h3>小思同學</h3> <img src="img/person01.png" alt="icon" /> </div> <!-- 中間 聊天內容區域 --> <div class="main"> <ul class="talk_list" style="top: 0px;"> </ul> <div class="drag_bar" style="display: none;"> <div class="drager ui-draggable ui-draggable-handle" style="display: none; height: 412.628px;" ></div> </div> </div> <!-- 底部 訊息編輯區域 --> <div class="footer"> <img src="img/person02.png" alt="icon" /> <input type="text" placeholder="說的什么吧..." class="input_txt" /> <input type="button" value="發 送" class="input_sub" /> </div> </div> <audio src="" autoplay></audio> <!-- <script type="text/javascript" src="https://www.cnblogs.com/heymar/archive/2022/04/23/js/scroll.js"></script> --> <!-- <script> $(function(){ // 初始化右側滾動條 // 這個方法定義在scroll.js中 resetui() }) </script> --> <!-- 1.下面兩個jq的js都是為了配合最后一個可以用resetui函式來初始化右側滾動條讓滾動條跟著螢屏內容走 --> <script src="./js/jquery-1.12.4.min.js"></script> <script src="./js/jquery-ui.min.js"></script> <script src="./js/jquery.mousewheel.js"></script> <script src="./js/scroll.js"></script> <script> // 先完成點擊發送添加訊息功能 let content = '' $('.input_sub').on('click', function() { content = $('.input_txt').val() if (content.trim() == '') return $('.talk_list').append(`<li class="right_word"> <img src="img/person02.png" /> <span>${content}</span> </li>` ) $('.input_txt').val('') resetui() getBoot(content) }) // 機器人回復 // 2.注意這里機器人的回復是怎么做到的 是再點擊后呼叫的這個函式 function getBoot(text) { $.get('http://www.liulongbin.top:3006/api/robot',{spoken : text},res => { console.log(res); if (res.message == 'success') { $('.talk_list').append(`<li class="left_word"> <img src="img/person01.png" /> <span>${res.data.info.text}</span> </li>` ) } resetui() getSpeaker(res.data.info.text) }) } // 語音回復 // 3.注意這里也是需要被別人呼叫函式 function getSpeaker(text) { $.ajax({ method : 'get', url : 'http://www.liulongbin.top:3006/api/synthesize', data : {text : text}, success : res => { if (res.status !== 200) return alert('獲取語音失敗') $('audio').attr('src', res.voiceUrl) } }) } // 最后回車發送訊息 $('.input_txt').on('keyup', (e) => { // console.log(e.keyCode); if (e.keyCode == 13) { $('.input_sub').trigger('click') } }) </script> </body> </html>
3.
制作簡易版模板引擎,關于模板引擎這方面,只要牢牢記住他的一個規則,先匯入,然后定義資料,定義模板,再去呼叫,最后渲染,基本沒啥問題,然后定義模板那里的一些標準語法等等
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div></div> <!-- 2.模板 --> <script type="text/html" id="model"> <div>我的名字:{{name}}</div> <div>我的年齡:{{age}}</div> <div>我的性別:{{sex}}</div> <div>我的家庭住址:{{address}}</div> </script> <script> // 3.封裝函式 function template(id, data) { let str = document.getElementById(id).innerHTML // console.log(str); let reg = /{{([a-zA-Z]+)}}/ let result = reg.exec(str) while (result !== null) { str = str.replace(result[0], data[result[1]]) result = reg.exec(str) } return str } </script> <script> // 1.定義資料 let data = { name : '王五', age : 18, sex : '男', address : '重慶市江北區' } // 4.呼叫 let htmlStr = template('model', data) // 5.渲染 document.querySelector('div').innerHTML = htmlStr </script> </body> </html>
以下就是一個完整的模板引擎使用案例,在這個案例中我的幾個錯誤點:一個是如果你標準語法使用了回圈后,在你的每一個回圈的項里面有一個字串你想給轉換成陣列,還記得你下面要獲取資料嗎,那么就在這里做一個回圈,對每一條data資料里面的字串,push進陣列,錯誤點二就是標準語法里面關于圖片這一點,首先要知道凡事用到了標準語法那就必須{{}}包起來,因為你圖片還有一個根路徑嘛,所以也要一起包著進去,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <link rel="stylesheet" href="./assets/news.css" /> <script src="./lib/jquery.js"></script> <script src="./lib/template-web.js"></script> </head> <body> <div id="news-list"> </div> </body> <script type="text/html" id="model"> {{each data}} <div class="news-item"> <!-- <img class="thumb" src="http://www.liulongbin.top:3006'+${{$value.img}}+'" alt="" /> --> <!-- 2.錯誤點二,凡是用到變數的地方都需要標準語法 這里需要把整個都包起來 --> <img class="thumb" src={{'http://www.liulongbin.top:3006' + $value.img}} alt="" /> <div class="right-box"> <h1 class="title">{{$value.title}}</h1> <div class="tags"> <!-- {{each {{tags}} | arrFormat}} <span>{{$value}}</span> {{/each}} --> <!-- 1.錯誤點一 這里我想的太復雜了,不用過濾器來做,但是我認為這樣做應該可以只是不知道哪一步搞錯了,這里有個更簡便的方法 在獲取資料的時候就可以將每一個tags有字串改為陣列 --> <span>{{$value.tags[0]}}</span> <span>{{$value.tags[1]}}</span> <span>{{$value.tags[2]}}</span> </div> <div class="footer"> <div> <span>{{$value.source}}</span> <span>{{$value.time | timeFormat}}</span> </div> <span>評論數:{{$value.cmtcount}}</span> </div> </div> </div> {{/each}} </script> <script> $.ajax({ type : 'GET', url : 'http://www.liulongbin.top:3006/api/news', success : res => { if (res.status !== 200) return alert('獲取新聞串列失敗') console.log(res); for (let i = 0; i < res.data.length; i++) { // 1.1注意 這一換成陣列后需要將當前整個賦值給她 res.data[i].tags = res.data[i].tags.split(',') } let htmlStr = template('model', res) $('#news-list').append(htmlStr) } }) template.defaults.imports.timeFormat = function(value) { let date = new Date(value) let y = date.getFullYear() let m = addZero(date.getMonth() + 1) let d = addZero(date.getDate()) let hh = addZero(date.getHours()) let mm = addZero(date.getMinutes()) let ss = addZero(date.getSeconds()) return `${y}-${m}-${d} ${hh}:${mm}:${ss}` } // 補零函式 function addZero(n) { return n < 10? '0' + n : n } </script> </html>
4.
然后封裝自己的ajax函式,用到原生js的xhr方法,在封裝里面去判斷你是get還是post請求通過toUpperCase,包括xhr level2的一些新功能,設定HTTP時限,xhr.timout對應還有一個事件ontimeout,formdata表單管理可以拿來模擬表單資料,同樣也可以拿來獲取表單資料,第三個是可以上傳檔案了,關鍵步驟在于獲取到上傳檔案的表單元素后面跟一個.files就會得到一個上傳的檔案的陣列,跟第四個新特性組合起來就是有進度顯示,通過一個事件xhr.upload.onprogress里面有三個e的屬性但是要注意這個時間必須寫到open和send函式之前,然后就是jq里面的ajaxstart和ajaxend兩個事件,
然后就是jsonp,其原理就是通過script標簽不受同源策略限制而通過src發起的服務器請求,把回到函式、引數都加進去,在jq里面jsonp通過ajax方法來做,datatype改為jsonp,
一個案例來綜合展示jsonp、防抖和全域快取,首先我們的關鍵字需要作為一個引數去獲取建議串列,然后再定義模板這里回圈res,里面就寫一個標簽,因為里面的value使我們陣列里面的每一項,直接取第一個,然后會根據陣列的長度自動給你多少個標簽,渲染到頁面上
防抖就是會定義一個函式里面是一個定時器去執行我們獲取建議串列的函式,當你一觸發這個事件,首先會清除這個定時器然后在執行定時器函式,你想想我如果設定個時間50ms,那么我們打字的速度,肯定是比這個還快的,所以你一直在輸入他也一直在清楚定時器,定時器就一直沒有執行,當你停下來了,這個時候正常執行定時器,獲取到我們的建議串列,下面會有兩個圖來詳細展示一下區別,有防抖和沒有防抖的,
然后就是全域快取,就是我們的輸入一個apple再來一個mac,這個時候是兩個單詞吧,那我把mac一刪,難道又要去請求一次apple,那不就請求三次了嗎,我只請求兩次完成這個操作可以嗎,那就要用到全域快取,定義一個全域空物件,在我們渲染html那里,空物件的屬性名為搜索的關鍵字=為我們的res,然后當我們搜索的時候先去判斷搜索的關鍵字通過一個for in回圈看看物件里面有沒有這個關鍵字,如果有先執行快取里面的res,就不再去請求服務器了,


最后是一個節流策略,就是我們限制我們的觸發次數,跟防抖還是有本質區別的,通過一個節流閥,定義一個timer為null,進入這個事件給她定義為多少ms的定時器,進入這個事件先去檢測,timer是不是為空,如果不為空就return只有當為null才會去執行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> img { position: absolute; left: 0; top: 0; } html, body { width: 100%; height: 100%; } </style> </head> <body> <img src="./angel.gif" alt=""> <script> let timer = null document.body.addEventListener('mousemove', (e) => { if (timer) return timer = setTimeout(() => { document.querySelector('img').style.left = e.pageX + 'px' document.querySelector('img').style.top = e.pageY+ 'px' console.log(11); timer = null // console.log(e.pageX); }, 15); }) </script> </body> </html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/462938.html
標籤:其他
