<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          js垃圾回收和內存泄露、js異步之宏任務和微任務

          前端達人

          js垃圾回收

          標記清除 

                 當變量進入環境時,在函數中聲明一個變量,就將這個變量標記為“進入環境”。從邏輯上講,永遠不能釋放進入環境的變量所占用的內存,因為只要執行流進入相應的環境,就可能會用到它們。而當變量離開環境時,則將其標記為“離開環境”

          引用計數 

                  就是跟蹤記錄每個值被引用的次數。當聲明了一個變量并將一個引用值賦給該變量時,則這個值的引用次數為1。如果同一個值又被賦值給另一個變量,則該值的引用次數加1。相反,如果這個值引用的變量又取得了另外一個值,則這個值的引用次數減 1。當這個值的引用次數變成 0 時,則說明沒有辦法再訪問這個值了,因此就可以將其占用的內存空間回收、當下次再運行時,它就會釋放引用次數為 0 的值所占用的內存

          內存泄漏:

                  不用的內存,沒有及時釋放,就叫做內存泄漏

          js中的內存泄漏:

          1. 循環引用

                  一個DOM對象被一個Javascript對象引用,同時又引用其它的Javascript對象,這個DOM對象可能會引發內存泄露。這個DOM對象的引用不會在腳本停止的時候被垃圾回收。要想破壞循環引用,就將引用DOM元素的對象賦值為null

          2. 閉包

                  在閉包中引入閉包外部的變量時,當閉包結束此對象無法被垃圾回收

          3. DOM泄露

                  當原有dom被移除時,子節點引用沒有被移除則無法回收

          4. Timers 計(定)時器泄露

          js異步之宏任務(marcroTask)和微任務(microTask)

                  宏任務包括:setTimeout、 setInterval、 Ajax 和 DOM事件
                  微任務:Promise、 async/await
                  微任務宏任務的執行時間要

          異步和單線程

                  異步單線程相輔相成的,js是一門單線程腳本語言,所以需要異步來輔助

          事件循環

                  同步進入主線程,異步進入任務隊列,主線程內的任務執行完畢為空,就去任務隊列讀取對應的函數,進入主線程執行

          執行順序:
                  一:先執行所有的同步任務(log)
                  二:執行完畢再去執行第一個宏任務
                  三:執行第一個宏任務時,先看有沒有需要執行的‘微任務,如果有就執行,沒有就執行‘宏任務’        








          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          用Express搭建服務器

          前端達人

          用Express搭建服務器

          之前一直是用axios請求rap2模擬的接口,想試著用express自己寫一個簡單的,然后連下MySQL數據庫。

          0、準備工作

          • 安裝node
          • 初始化項目:新建一個文件夾,在里面
            npm init -y 
                    
            • 1
          • 安裝express
            npm install express 
                    
            • 1

          1、第一個小栗子(發布服務)Express 中文網

          • 新建www.js文件,把這段代碼寫進去,然后直接node www.js啟動服務,然后在瀏覽器訪問http://localhost:3000就可以看到后端返回的Hello World!啦。
             const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { //這里面可以先從數據庫獲取數據,然后返回給前端 res.send('Hello World!') }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) }) 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13

          2、前端axios.get請求

          • 發布服務之后就可以用axios請求啦,請求的代碼如下:(但是會有問題,解決方法見 第3節
             axios.get('http://localhost:3000').then((res) => { console.log(res); }); 
                    
            • 1
            • 2
            • 3
            • 4

          3、前端axios.get請求的跨域問題

          • 第2節介紹了如何用axios請求后臺服務,但是在本地訪問上面的http://localhost:3000,如果不是同一端口的話會出現跨域不能請求的問題。解決方法是在www.js文件中加上下面這段:
           //加了這句之后就可以跨域請求了??? app.use(function (req, res, next) { res.header('Access-Control-Allow-Origin', '*'); //允許所有來源訪問 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS'); //允許訪問的方式 next(); }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 這樣你就可以在本地其他端口的項目上訪問3000端口啦

          4、后端post接口

          app.post('/post', (req, res) => { console.log(JSON.stringify(req.body));//前端發送給后端的數據 res.send('ok');//返回給前端的數據 }); 
          
          • 1
          • 2
          • 3
          • 4

          5、前端axios.post請求

           axios.post(`http://localhost:3000/post`, "向后端發送的數據").then(res => { console.log("后端返回的數據res=>", res); }); 
          
          • 1
          • 2
          • 3
          • 這樣你在前端就可以向后端發送請求信息,后端接收并驗證之后再把數據返回給前端就好了。
          • 但是,這樣還是會有點問題,第6節解決。

          6、 在express中獲取post請求數據(本節原文鏈接)

          1. express沒有內置的POST請求API,但是有聽說將body-parser(詳情) 內置到express中了。但是我試了直接使用不了。所以還是直接安裝第三方包

          2. 使用第三方包body-parser

            npm i body-parser 
                    
            • 1
          3. app.js

            //1引包 const bodyParser=require('body-parser') //2配置 // 配置模板引擎和 body-parser 一定要在 app.use(router) 掛載路由之前 // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) // parse application/json app.use(bodyParser.json()) 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
          • 至此使用express搭建的簡易服務器就好了,后續可以再連接數據庫進行增刪查改。

          轉載整合自(文中鏈接) 參考鏈接:
          Express 中文網
          在express中獲取post請求數據(原文鏈接)
          body-parser(詳情)






          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務


          Web各大地圖開發

          前端達人

          Web各大地圖開發

          介紹

          想必大家對地圖都不陌生,都使用過地圖吧,有了地圖我們也就不用在把回家的路徑牢牢地記住了,只需要在地圖上搜索下就能進行導航了,

          而且在打車的時候也都使用的是地圖,…地圖作用范圍很廣很廣這里就不在多介紹了直接進入主題.

          目前市面上主流的地圖有:

          1. 高德地圖

            https://lbs.amap.com/ 開發者平臺

          2. 百度地圖

            https://lbsyun.baidu.com/ 開發者平臺

          3. 騰訊地圖

            https://lbs.qq.com/ 開發者平臺

          4. 天地圖

            https://www.tianditu.gov.cn/ 開發者平臺

          以上就是我們常用的地圖,也是可以免費調用的地圖不收費,但是有次數限制都夠用,基本所有的地圖開發都要先申請為開發者后才能進行地圖的開發

          雖然高德很火很厲害,但是我公司讓我用天地圖開發,所以下面的案例大致演示天地圖的開發的流程,其他平臺的地圖開發流程基本都類似.

          只要掌握一個地圖的開發那么其他地圖開發就是小兒科了…

          開發地圖需要的準備

          1. 進入天地圖頁面

          2. 注冊賬號

          3. 申請成為開發者

            開發者分為: 個人開發者和企業開發者 根據情況自行選擇

          4. 然后根據需求創建應用-生成應用key

          5. 入門Dome

            實例代碼:

            http://lbs.tianditu.gov.cn/api/js4.0/guide.html 以下代碼的內容介紹

            <!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>HELLO WORLD</title> <script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=9e70e9aa0be51fe8ad220e1c4b5d5aa5"></script> <script> var map; var zoom = 12; function onLoad() { map = new T.Map('mapDiv'); map.centerAndZoom(new T.LngLat(116.40769, 39.89945), zoom); //39.897019,116.323003 } </script> </head> <body onLoad="onLoad()"> <div id="mapDiv" style="position:absolute;width:100%; height:900px"></div> </body> </html> 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20

            地圖級別 也就是地圖加載后顯示的縮放級別

            縮放級別1~2 那么就是洲級別 (亞洲 ,美洲…)

            縮放級別3~4 那么就是國家級別

            縮放級別5~6 那么就是省級別

            縮放級別7~8 那么就是市級別

            縮放級別9~10 那么就是區級別

            縮放級別11~12 那么就是縣級別

            …以此類推 最多縮放18級別(街道級別)

            上案例效果圖:

          各種需求進行開發

          頁面

          http://lbs.tianditu.gov.cn/api/js4.0/examples.html 基本日常所需的實例,稍微改動就能使用了

          上面實例無法滿足你的要求或者需要添加特殊操作,那么能在下面AOI文檔中能找到具體實例代碼里的每一個方法使用詳細,然后在根據業務需求進行修改就行了

          http://lbs.tianditu.gov.cn/api/js4.0/class.html

          接口服務

          在天地圖中提供了幾個服務接口用來獲取一些數據的地方 ,但是注意有每日調用配額限制的(控制臺可以查看次數限制)

          http://lbs.tianditu.gov.cn/server/search.html

          比如:客戶想查詢或者快速定位某一個區域或者街道的位置,但是自己通過地圖一點一點的找太麻煩了那么就可以通過接口的方式直接獲取到想要的數據,

          查詢: 北京市延慶區延慶鎮蓮花池村前街50夕陽紅養老院的坐標

          http://api.tianditu.gov.cn/geocoder?ds={"keyWord":"北京市延慶區延慶鎮蓮花池村前街50夕陽紅養老院"}&tk=9e70e9aa0be51fe8ad220e1c4b5d5aa5

          接口返回的數據:

          {“msg”:“ok”,“location”:{“score”:40,“level”:“地名地址”,“lon”:116.002677524,“lat”:40.4509903540001,“keyWord”:“北京市延慶區延慶鎮蓮花池村前街50夕陽紅養老院”},“searchVersion”:“6.0.0”,“status”:“0”}

          響應接口

          參數值 參數說明 參數類型 備注(值域)
          status 返回狀態 string 0:正常返回,101:結果為空,404:出錯。
          msg 返回信息 string OK:正常,其他異常。
          location 地址信息 json 地址信息

          location

          參數值 參數說明 參數類型 備注(值域)
          lon 坐標點顯示經度 Double 必須返回。
          lat 坐標點顯示緯度 Double 必須返回。
          level 類別名稱 string 非必須返回。
          typeRound 附近相似點 Array 開啟周邊查詢必需返回。

          然后在代碼里通過

           map.centerAndZoom(new T.LngLat(116.41593, 39.92313), 16); 
          
          • 1

          從新設置下地圖顯示的位置,以及縮放比例就行了.

          標注案例

          在很多項目都要求把客戶提供的公司…在地圖上標注出來并且顯示對應的描述,

          在天地圖提供的實例中是默認鼠標點擊顯示,然后點擊消失,實際中這樣太麻煩了我們稍作修改,改變為鼠標懸浮顯示,鼠標離開消失

          修改后的代碼

          <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>天地圖-地圖API-范例-多個點的信息窗口</title> <script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=9e70e9aa0be51fe8ad220e1c4b5d5aa5"></script> <style type="text/css"> body, html{width: 100%;height: 100%;margin:0;font-family:"微軟雅黑";} #mapDiv{height:900px;width:100%;} input,p { margin-top: 10px; margin-left: 5px; font-size: 14px; } </style> <script> var map var zoom = 15; function onLoad() { var data_info = [[116.417854,39.921988,"地址:北京市東城區王府井大街88號樂天銀泰百貨八層"], [116.406605,39.921585,"地址:北京市東城區東華門大街"], [116.412222,39.912345,"地址:北京市東城區正義路甲5號"] ]; //初始化地圖對象 map = new T.Map("mapDiv"); //設置顯示地圖的中心點和級別 map.centerAndZoom(new T.LngLat(116.41593, 39.92313), zoom); for(var i=0;i<data_info.length;i++){ var marker = new T.Marker(new T.LngLat(data_info[i][0],data_info[i][1])); // 創建標注 var content = data_info[i][2]; map.addOverLay(marker); // 將標注添加到地圖中 addClickHandler(content,marker); } function addClickHandler(content,marker){ // 改為鼠標懸浮顯示 marker.addEventListener("mouseover",function(e){ openInfo(content,e)} ); //添加鼠標離開后關閉提示框 marker.addEventListener("mouseout",function(e){ map.closeInfoWindow() } ); } function openInfo(content,e){ var point = e.lnglat; marker = new T.Marker(point);// 創建標注 var markerInfoWin = new T.InfoWindow(content,{offset:new T.Point(0,-30)}); // 創建信息窗口對象 map.openInfoWindow(markerInfoWin,point); //開啟信息窗口 } } </script> </head> <body onLoad="onLoad()"> <div id="mapDiv"></div> <p>為多個點添加多個點的信息窗口</p> </body> </html> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58

          如果客戶不知道自己公司…的坐標,我們可以通過-客戶給的名稱,進行自動搜索地理位置然后進行標注實現

          <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <meta name="keywords" content="天地圖"/> <title>天地圖-地圖API-范例-地理編碼</title> <style type="text/css">body,html{width:100%;height:100%;margin:0;font-family:"Microsoft YaHei"}#mapDiv{width:100%;height:400px}input,b,p{margin-left:5px;font-size:14px}</style> <script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=9e70e9aa0be51fe8ad220e1c4b5d5aa5"></script> <script> var map; var zoom = 3; var geocoder; function onLoad() { //初始化地圖對象 map=new T.Map("mapDiv"); //設置顯示地圖的中心點和級別 map.centerAndZoom(new T.LngLat(116.40969,39.89945),zoom) //創建對象 geocoder = new T.Geocoder(); //根據國家名稱自動搜索,對應的坐標,然后插入標注 var list=["美國","中國","阿拉伯聯合酋長國"]; for (let string of list) { geocoder.getPoint(string,searchResult); } } function searchResult(result){ console.log("經緯度: "+result.location.lat + ',' + result.location.lon) if(result.getStatus() == 0){ //創建標注對象 var marker = new T.Marker(result.getLocationPoint()); //向地圖上添加標注 map.addOverLay(marker); var markerInfoWin = new T.InfoWindow("信息窗口"); marker.addEventListener("click", function () { marker.openInfoWindow(markerInfoWin); });// 將標注添加到地圖中 }else{ alert(result.getMsg()); } } </script> </head> <body onLoad="onLoad()"> <div id="mapDiv"></div> <p>本示例演示如何使用地理編碼接口獲得坐標信息。</p> </body> </html> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56

          vue 引入天地圖

          • index.html 中引入天地圖在線 API
          <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>vue-tdt-demo</title> <!-- 引入天地圖在線 API --> <script src="http://api.tianditu.gov.cn/api?v=4.0&tk=您的密鑰" type="text/javascript"></script> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • components 文件夾中新建 TdtMap.vue 組件

          mounted() 中初始化天地圖

          <template> <div :id="tdtMapDivID" class="divTdtMap"></div> </template> <script> export default { name: 'TdtMap', data() { return { tdtMapDivID: "tdtMapDivID_"+this._uid, tdtMap: {} } }, created() { }, mounted(){ // 初始化天地圖 this.initTdtMap() }, watch: { }, methods: { // 初始化天地圖 initTdtMap(){ this.tdtMap = new T.Map(this.tdtMapDivID) this.tdtMap.centerAndZoom(new T.LngLat(116.40769, 39.89945), 12) }, } } </script> <style scoped> .divTdtMap { margin: 0px; padding: 0px; width: 100%; height: 80vh; z-index: 0; } </style> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 測試組件,新建 test.vue

          導入 組件、注冊 組件和 使用 組件

          <template> <!-- 使用組件 --> <TdtMap></TdtMap> </template> <script> /* 導入組件 */ import TdtMap from './components/TdtMap' export default { name: 'TdtMap', components: { /* 注冊組件 */ TdtMap, }, data() { return { } }, created() { }, mounted(){ }, watch: { }, methods: { }, } </script> <style scoped> </style> 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34

          隱藏天地圖LOGO

           document.getElementsByClassName("tdt-control-copyright tdt-control")[0].style.display = 'none' 
          
          • 1











































          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          函數作用域和立即執行函數

          前端達人

          變量作用域

          • JavaScript是函數級作用域編程語言:變量只在其定義時所在的function內部有意義。

          全局變量

          • 如果不將變量定義在任何函數的內部,此時這個變量就是全局變量,它在任何函數內都可以被訪問和更改。

          遮蔽效應

          • 如果函數中也定義了和全局同名的變量,則函數內的變量會將全局的變量“遮蔽”。

          注意考慮變量聲明提升的情況

          • 這個程序的運行結果是什么呢?

          形參也是局部變量

          • 這個程序的運行結果是什么呢?

          局部函數

          • 先來認識函數的嵌套:一個函數內部也可以定義一個函數。和局部變量類似,定義在一個函數內部的函數是局部函數。

          作用域鏈

          • 在函數嵌套中,變量會從內到外逐層尋找它的定義。

          不加var將定義全局變量

          • 在初次給變量賦值時,如果沒有加var,則將定義全局變量。

          什么是閉包

          • JavaScript中函數會產生閉包(closure)。閉包是函數本身和該函數聲明時所處的環境狀態的組合。

          •  函數能夠“記憶住”其定義時所處的環境,即使函數不在其定義的環境中被調用,也能訪問定義時所處環境的變量。

          觀察閉包現象

          • 在JavaScript中,每次創建函數時都會創建閉包。
          • 但是,閉包特性往往需要將函數“換一個地方”執行,才能被觀察出來。

          閉包非常實用

          • 閉包很有用,因為它允許我們將數據與操作該數據的函數關聯起來。這與“面向對象編程”有少許相似之處。
          • 閉包的功能:記憶性、模擬私有變量。

          閉包用途1 - 記憶性 

          • 當閉包產生時,函數所處環境的狀態會始終保持在內存中,不會在外層函數調用后被自動清除。這就是閉包的記憶性。

          閉包的記憶性舉例

          • 創建體溫檢測函數checkTemp(n),可以檢查體溫n是否正常,函數會返回布爾值。
          • 但是,不同的小區有不同的體溫檢測標準,比如A小區體溫合格線是37.1℃,而B小區體溫合格線是37.3℃,應該怎么編程呢?
          
          
          1. <!DOCTYPE html>
          2. <html lang="en">
          3. <head>
          4. <meta charset="UTF-8">
          5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
          6. <title>Document</title>
          7. </head>
          8. <body>
          9. <script>
          10. function createCheckTemp(standardTemp) {
          11. function checkTemp(n) {
          12. if (n <= standardTemp) {
          13. console.log('你的體溫正常');
          14. } else {
          15. console.log('你的體溫偏高');
          16. }
          17. }
          18. return checkTemp;
          19. }
          20. // 創建一個checkTemp函數,它以37.1度為標準線
          21. var checkTemp_A = createCheckTemp(37.1);
          22. // 再創建一個checkTemp函數,它以37.3度為標準線
          23. var checkTemp_B = createCheckTemp(37.3);
          24. checkTemp_A(37.2);
          25. checkTemp_B(37.2);
          26. </script>
          27. </body>
          28. </html>

          閉包用途2 - 模擬私有變量

          • 在Java、C++等語言中,有私有屬性的概念,但是JavaScript中只能用閉包來模擬。

          • 題目:請定義一個變量a,要求是能保證這個a只能被進行指定操作(如加1、乘2),而不能進行其他操作,應該怎么編程呢?
          
          
          1. <!DOCTYPE html>
          2. <html lang="en">
          3. <head>
          4. <meta charset="UTF-8">
          5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
          6. <title>Document</title>
          7. </head>
          8. <body>
          9. <script>
          10. // 封裝一個函數,這個函數的功能就是私有化變量
          11. function fun() {
          12. // 定義一個局部變量a
          13. var a = 0;
          14. return {
          15. getA: function () {
          16. return a;
          17. },
          18. add: function () {
          19. a++;
          20. },
          21. pow: function () {
          22. a *= 2;
          23. }
          24. };
          25. }
          26. var obj = fun();
          27. // 如果想在fun函數外面使用變量a,唯一的方法就是調用getA()方法
          28. console.log(obj.getA());
          29. // 想讓變量a進行加1操作
          30. obj.add();
          31. obj.add();
          32. obj.add();
          33. console.log(obj.getA());
          34. obj.pow();
          35. console.log(obj.getA());
          36. </script>
          37. </body>
          38. </html>

          使用閉包的注意點

          • 不能濫用閉包,否則會造成網頁的性能問題,嚴重時可能導致內存泄露。
          • 所謂內存泄漏是指程序中己動態分配的內存由于某種原因未釋放或無法釋放。

          立即執行函數IIFE

          • IIFE(Immediately Invoked Function Expression,立即調用函數表達式)是一種特殊的JavaScript函數寫法,一旦被定義,就立即被調用。

          形成IIFE的方法

          • 函數不能直接加圓括號被調用。

          • 函數必須轉為“函數表達式”才能被調用。

          IIFE的作用1 - 為變量賦值

          • 為變量賦值:當給變量賦值需要一些較為復雜的計算時(如if語句),使用IIFE顯得語法更緊湊。

          IIFE的作用2-將全局變量變為局部變量

          • IIFE可以在一些場合(如for循環中)將全局變量變為局部變量,語法顯得緊湊。








          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          Web API介紹及DOM對象(一)

          前端達人

          目錄

          一、API 和 Web API

          1.API 

          2.Web API  

          3.API 和 Web API總結 

          二、DOM 介紹 

          1. DOM樹 

          三、獲取元素方法 

          1.getElementById()

          2.getElementsByTagName

            2.1element.getElementsByTagName() 

          3.HTML5 新增的方法獲取

          3.1 document.getElementsByClassName('類名')

          3.2 document.querySelector('選擇器')

          3.3 document.querySelectorAll('選擇器')

          4.獲取 body 、html 元素 

          四、事件和樣式操作 

          1.事件概述

          2.執行事件的步驟 

          2.1 常見的鼠標事件 

          3. 操作元素 

          3.1 改變元素內容

          3.2 修改元素屬性

          3.3 修改表單元素的屬性

          3.4 修改樣式屬性


          一、API 和 Web API

          1.API 

           API( Application Programming Interface,應用程序編程接口)
          是一些預先定義的函數,目的是提供應用程序
          與開發人員基于某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內部工作機制的細節。
          簡單理解: API是給程序員提供的一種工具,以便能更輕松的實現想要完成的功能

          2.Web API  

          Web API是瀏覽器提供的一套操作瀏覽器功能和頁面元素的API( BOM和DOM)。

          比如我們想要瀏覽器彈出一個警示框,直接使用alert( '彈出');

          3.API 和 Web API總結 

          1. API是為我們程序員提供的一個接口,幫助我們實現某種功能,我們會使用就可以,不必糾結內部如何實現
          2. Web API主要是針對于瀏覽器提供的接口,主要針對于瀏覽器做交互效果
          3. Web API 一般都有輸入和輸出(函數的傳參和返回值) ,Web API很多都是方法(函數)
          4.學習Web API可以結合學習內置對象方法的思路學習

          二、DOM 介紹 

          文檔對象模型( Document Object
          Model ,簡稱DOM) ,是W3C組織推薦的處理可擴展標記語言( HTML或者XML )的標準編程接口
          W3C已經定義了一系列的DOM接口,通過這些DOM接口可以改變網頁的內容、結構和樣式 

          1. DOM樹 

          •  文檔:一個頁面就是一個文檔,DOM中使用 document表示
          • 元素:頁面中的所有標簽都是元素,DOM中使用 element表示
          • 節點:網頁中的所有內容都是節點(標簽、屬性、文本、注釋等),DOM中使用 node表示

          DOM把以上內容都看作是對象 

          三、獲取元素方法 

          1.getElementById()

           使用 getElementById( ) 方法可以獲取帶有ID的元素對象

          
          
          1. <div id="time" >2019-9-9 </div>
          2. <script>
          3. var timer = document.getElementById('time');
          4. console.dir(timer);
          5. </script>
          6. //返回結果為<div id= "time">2019-9-9</div>這一整個標簽

           注意:
          1.因為我們文檔頁面從上往下加載,先得有標簽所以我們script 寫到標簽的下面
          2. get 獲得element 元素 by 通過駝峰命名法
          3.參數 id 是大小寫敏感的字符串
          4.返回的是一個元素的對象
          5. console.dir 打印我們返回的元素對象更好的查看里面的屬性和方法

          2.getElementsByTagName

           使用getElementsByTagName()方法可以返回帶有指定標簽名的對象的集合
           document.getElementsByTagName('標簽名');

          
          
          1. <ul>
          2. <li>1</li>
          3. <li>2</li>
          4. <li>3</li>
          5. <li>4</li>
          6. <li>5</li>
          7. </ul>
          8. <script>
          9. var lis = document.getElementsByTagName('li');
          10. console.log(lis);
          11. </script>

           1. 返回的是 獲取過來元素對象的集合  以偽數組的形式存儲的

           2. 我們想要依次打印里面的元素對象我們可以采取遍歷的方式  
             for(var i = 0; i < lis.length; i++) {
                 console.log(lis[i]);
              }

           3. 得到元素對象是動態的,標簽里面的內容變了,得到的內容就變了.

            2.1element.getElementsByTagName() 

          element.getElementsByTagName()  可以得到這個元素里面的某些標簽 

          
          
          1. <ul id = "nav">
          2. <li>1</li>
          3. <li>2</li>
          4. <li>3</li>
          5. <li>4</li>
          6. <li>5</li>
          7. </ul>
          8. <script>
          9. var nav = document.getElementById('nav');
          10. var navLis = nav.getElementsByTagName('li');
          11. </script>

          3.HTML5 新增的方法獲取

          3.1 document.getElementsByClassName('類名')

          根據類名返回元素對象集合  

          
          
          1. <div class="box" >123</div>
          2. <script>
          3. var boxs = document.getElementsByClassName('box');
          4. </script>

          3.2 document.querySelector('選擇器')

           根據指定選擇器返回第一個元素對象
           注意:里面的選擇器需要加符號 類選擇器:.box   id選擇器: #box

          
          
          1. var firstBox = document.querySelector('.box');
          2. var nav = document.querySelector('#nav');
          3. var firstBox = document.querySelector('li');

          3.3 document.querySelectorAll('選擇器')

          返回指定選擇器的所有元素對象集合 

          
          
          1. var allBox = document.querySelectorAll('.box');
          2. //返回所有 class 名為 box 的標簽

          4.獲取 body 、html 元素 

          
          
          1. var body = document.body ;
          2. // 返回 body 元素對象
          3. var htmlEle = document.documentElement;
          4. // 返回 html 元素對象

          四、事件和樣式操作 

          1.事件概述

          JavaScript 使我們有能力創建動態頁面,而事件是可以被JavaScript偵測到的行為

          簡單理解:觸發---響應機制

          網頁中的每個元素都可以產生某些可以觸發 JavaScript 的事件,例如,我們可以在用戶點擊某按鈕時產生一個事件,然后去執行某些操作
           

           事件是有三部分組成   事件源  事件類型  事件處理程序  

          1. 事件源  事件被觸發的對象     比如按鈕
          2. 事件類型   如何觸發   比如鼠標點擊觸發
          3. 事件處理程序  通過一個函數賦值的方式  完成

          2.執行事件的步驟 

          1. 獲取事件源

          2. 注冊事件(綁定事件)

          3. 添加事件處理程序(采用函數賦值形式)
           

          2.1 常見的鼠標事件 

          鼠標事件 觸發條件
          onclick 鼠標點擊左鍵觸發
          onmouseover 鼠標經過觸發
          onmouseout 鼠標離開觸發
          onfocus 獲取鼠標焦點觸發
          onblur 失去鼠標焦點觸發
          onmousemove 鼠標移動觸發
          onmouseup 鼠標彈起觸發
          onmousedown 鼠標按下觸發

          3. 操作元素 

          JS的 DOM 操作可以改變網頁內容、結構和樣式,我們可以利用 DOM 操作元素來改變元素里面的內容、屬性等。注意一下都是屬性 

          3.1 改變元素內容

          ① element.innerText 

          可用于獲取標簽中的內容。此時獲取的是從起始位置到終止位置的內容,但它去除 html 標簽, 同時空格和換行也會去掉

          獲取到 p 標簽再打印 p 標簽中的內容
          var p = document.querySelector('p');
          console.log(p.innerText);

          ② element.innerHTML

          獲取內容時,獲取的是起始位置到終止位置的全部內容,包括 html 標簽, 同時保留空格和換行

          獲取到 p 標簽再打印 p 標簽中的內容
          var p = document.querySelector('p');
          console.log(p.innerHTML);

          普通標簽使用,表單不能用

          3.2 修改元素屬性

            src 、href、id 、 alt 、title

          案例:點擊不同按鈕顯示不同圖片

          
          
          1. <title>Document</title>
          2. <style>
          3. img {
          4. width: 300px;
          5. margin-top: 20px;
          6. }
          7. </style>
          8. </head>
          9. <body>
          10. <button id="but1">按鈕1</button>
          11. <button id="but2">按鈕2</button>
          12. <br>
          13. <img src="../images/objpic07.jpg" alt="" title="圖片1">
          14. <script>
          15. var item1 = document.getElementById('but1');
          16. var item2 = document.getElementById('but2');
          17. var img = document.querySelector('img');
          18. item1.onclick = function() {
          19. img.src = '../images/objpic07.jpg';
          20. img.title = '圖片1';
          21. }
          22. item2.onclick = function() {
          23. img.src = '../images/objpic08.jpg';
          24. img.title = '圖片2';
          25. }
          26. </script>
          27. </body>

          3.3 修改表單元素的屬性

          可操作的表單元素的屬性: type 、value、 checked、 selected、 disabled

          按下按鈕修改表單框 里面的內容,通過修改 value
          input.value 等于 this.value  因為 this指向的是事件函數的調用者   

          案例:仿京東顯示隱藏密碼

           

          
          
          1. <title>Document</title>
          2. <style>
          3. .box {
          4. position: relative;
          5. width: 400px;
          6. border-bottom: 1px solid #ccc;
          7. margin: 100px auto;
          8. }
          9. .box input {
          10. width: 370px;
          11. height: 30px;
          12. border: 0;
          13. outline: none;
          14. }
          15. .box img {
          16. position: absolute;
          17. top: 2px;
          18. right: 2px;
          19. width: 24px;
          20. }
          21. </style>
          22. </head>
          23. <body>
          24. <div class="box">
          25. <label for="">
          26. <img src="../images/close.png" alt="" id="pic">
          27. </label>
          28. <input type="password" id="item">
          29. </div>
          30. <script>
          31. var item = document.getElementById('item');
          32. var pic = document.getElementById('pic');
          33. var flag = 0;
          34. pic.onclick = function() {
          35. if(flag == 0) {
          36. item.type = 'text';
          37. this.src = '../images/open.png';
          38. flag = 1;
          39. } else {
          40. item.type = 'password';
          41. this.src = '../images/close.png';
          42. flag = 0;
          43. }
          44. }
          45. </script>
          46. </body>

          3.4 修改樣式屬性

          ① element.style 行內樣式操作

          ② element.className 類名樣式操作

          行內樣式案例:顯示與隱藏文本操作(當Input獲取焦點,文本框初始內容消失,失去焦點,內容出現) 

          
          
          1. <title>Document</title>
          2. <style>
          3. input {
          4. color: #999;
          5. outline: none;
          6. height: 24px;
          7. }
          8. </style>
          9. </head>
          10. <body>
          11. <input type="text" value="手機">
          12. <script>
          13. var item = document.querySelector('input');
          14. item.onfocus = function() {
          15. if(this.value == '手機') {
          16. this.value = '';
          17. }
          18. this.style.color = '#333';
          19. this.style.border = '1px solid pink';
          20. }
          21. item.onblur = function() {
          22. if(this.value == '') {
          23. this.value = '手機';
          24. }
          25. this.style.color = '#999';
          26. this.style.border = '1px solid black';
          27. }
          28. </script>
          29. </body>

           類名樣式案例:密碼框驗證信息(提示輸入6~16位密碼,不滿或超出提示錯誤,正確則提示正確)

          
          
          1. <title>Document</title>
          2. <style>
          3. .box {
          4. width: 400px;
          5. margin: 100px auto;
          6. }
          7. input {
          8. outline: none;
          9. }
          10. .pic {
          11. height: 15px;
          12. display: inline-block;
          13. line-height: 15px;
          14. text-indent: 18px;
          15. font-size: 13px;
          16. color:blue;
          17. background: url(../images/mess.png) no-repeat;
          18. }
          19. .wrong {
          20. background: url(../images/wrong.png) no-repeat;
          21. color: red;
          22. }
          23. .right {
          24. background: url(../images/right.png) no-repeat;
          25. color: green;
          26. }
          27. </style>
          28. </head>
          29. <body>
          30. <div class="box">
          31. <input type="password" class="ipt">
          32. <p class="pic">請輸入6~16位的密碼</p>
          33. </div>
          34. <script>
          35. var item = document.querySelector('.ipt');
          36. var item2 = document.querySelector('.pic');
          37. item.onblur = function() {
          38. if(this.value.length < 6 || this.value.length > 16) {
          39. item2.className = 'pic wrong';
          40. item2.innerHTML = '您輸入的位數不對要求6~16位';
          41. } else {
          42. item2.className = 'pic right';
          43. item2.innerHTML = '您輸入的正確!';
          44. }
          45. }
          46. </script>
          47. </body>





          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          寫大事件項目的get,post類型的接口

          前端達人

          1.準備工作:npm下載相關包

          1.1初始化npm得到package.json文件 (不初始化也可以之前初始化的文件獲得package.json文件)

          npm init --yes

          1.2 express包   

          npm i express 

          1.3 multer 包

          npm i multer

          2.創建server文件:在同級文件夾下創建server文件(文件名可以自定義)

          3.登錄接口部分

           3.1 登錄接口代碼

          
          
          1. const express = require('express')
          2. //將這個express的方法賦值給app
          3. const app = express()
          4. //引入multer這個包
          5. const multer = require('multer')
          6. //上傳的文件會保存在這個目錄下
          7. const upload = multer({ dest: 'uploads/' })
          8. //使用中間件
          9. app.use(express.urlencoded());
          10. app.use(express.json());
          11. //登錄接口
          12. app.post('/api/login', (req, res) => {
          13. if (req.body.username && req.body.password) {
          14. res.json({
          15. "status": 0,
          16. "message": "登錄成功",
          17. })
          18. // res.send(req.body)
          19. console.log('req.body', req.body)
          20. } else {
          21. res.json({
          22. "status": 1,
          23. "message": "登錄失敗",
          24. })
          25. // res.send(req.body)
          26. console.log('req.body', req.body)
          27. }
          28. // res.send()
          29. })
          30. app.listen(8023, () => {
          31. console.log('8023端口運行成功,已經跑起來了...');
          32. })

          3.2 終端運行代碼

           3.3 在Postman中測試發送請求,填寫必要參數返回結果:

          3.4  在Postman中測試發送請求,不填寫必要參數返回結果:

          4. 獲取接口部分:

          4.1  獲取接口代碼

          
          
          1. //引入express框架
          2. const express = require('express')
          3. //將這個express的方法賦值給app
          4. const app = express()
          5. //引入multer這個包
          6. const multer = require('multer')
          7. //上傳的文件會保存在這個目錄下
          8. const upload = multer({ dest: 'uploads/' })
          9. //使用中間件
          10. app.use(express.urlencoded());
          11. app.use(express.json());
          12. //獲取接口
          13. app.get('/my/user/userinfo', (req, res) => {
          14. if (req.body.Authorization) {
          15. res.json({
          16. "status": 0,
          17. "message": "獲取成功",
          18. "data": {
          19. "id": 1,
          20. "username": "leopard",
          21. "nickname": "little-leopard",
          22. "email": "laotang@qq.com",
          23. "user_pic": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAe"
          24. }
          25. })
          26. console.log('req.body', req.body)
          27. } else {
          28. res.json({
          29. "status": 1,
          30. "message": "獲取失敗",
          31. })
          32. console.log('req.body', req.body)
          33. }
          34. })
          35. app.listen(8023, () => {
          36. console.log('8023端口運行成功,已經跑起來了...');
          37. })

          4.2 在終端運行

          4.3 在Postman中測試發送請求,填寫必要參數返回結果:

           

          4.4 在Postman中測試發送請求,不填寫必要參數返回結果:

          5.post接口上傳圖片

           5.1 上傳圖片代碼

          
          
          1. //引入express框架
          2. const express = require('express')
          3. //將這個express的方法賦值給app
          4. const app = express()
          5. //引入multer這個包
          6. const multer = require('multer')
          7. //上傳的文件會保存在這個目錄下
          8. const upload = multer({ dest: 'uploads/' })
          9. //使用中間件
          10. app.use(express.urlencoded());
          11. app.use(express.json());
          12. app.post('/my/user/avatar', upload.single('avatar'), (req, res) => {
          13. console.log(req.file);
          14. if (req.file) {
          15. res.json({
          16. "status": 0,
          17. "message": "上傳圖片成功"
          18. })
          19. console.log('req.body', req.body)
          20. } else {
          21. res.json({
          22. "status": 1,
          23. "message": "上傳圖片失敗"
          24. })
          25. console.log('req.body', req.body)
          26. }
          27. })
          28. app.listen(8023, () => {
          29. console.log('8023端口運行成功,已經跑起來了...');
          30. })

          5.2 Postman上傳圖片測試

           5.3終端查看



          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          作者:
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          JS 如何實現占位符

          前端達人

          占位符

          –首先了解一下占位符的概念。占位符就是先占住一個固定的位置,等著你再往里面添加內容的符號,廣泛用于計算機中各類文檔的編輯。
          –格式占位符(%)是在C/C++語言中格式輸入函數,如 scanf、printf 等函數中使用。其意義就是起到格式占位的意思,表示在該位置有輸入或者輸出。
          那么在JS中,如何實現占位符呢。

          JS操作

          首先可以說明在js中,是沒有占位符這一個概念的,那我們怎么實現該功能,這個時候就可以自己定義一個方法,去實現該功能。

          String.format = function() { //字符串中賦值變量 if (arguments.length == 0) return null; var str = arguments[0]; for ( var i = 1; i < arguments.length; i++) { var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm'); str = str.replace(re, arguments[i]); } return str; }; //使用方法 const h = 1; const l = 2; var key = String.format("{0}-{1}",h,l); console.log(key); //key:"1-2" 
                      
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17


























          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          node.js案例,寫一個簡單的get請求,請求有50%的概率,要求數據在一個json文件中

          前端達人

          • 案例目標:實現GET的主要屬性為req.method,并且生成隨機數

          1. 使用nodejs,實現一個Ajax的get請求方式
          2. 將lib里的data.json文件請求獲取出來
          3. data里面的數據為
            
                                    
            1. {
            2. "success":[
            3. {
            4. "data": "你贏了",
            5. "message":"請求成功",
            6. "code": "200"
            7. }
            8. ],
            9. "fail":[
            10. {
            11. "data": "你輸了",
            12. "message":"請求失敗",
            13. "code": "200"
            14. }
            15. ]
            16. }
          •  案例準備

          •  案例代碼

            
                                    
            1. // 1.定義核心模塊 http fs path
            2. const http = require('http')
            3. const fs = require('fs')
            4. const path = require('path')
            5. // 2.創建服務
            6. const server = http.createServer((req, res) => {
            7. // 2.1 如果url地址為/getList 執行代碼
            8. // -req.method 為請求類型
            9. // 生成隨機數,大于0.5為0,小于為1
            10. let render = Math.random() > 0.5 ? 0 : 1
            11. // console.log(render)
            12. // 2.2 拼接字符串,為讀取數據傳參
            13. // -__dirname為獲取的目錄地址
            14. // -lib為存放數據的名字,data.json為讀取的文件
            15. const filepath = path.join(__dirname, 'lib', 'data.json')
            16. // -console.log('拼接的地址', filepath)
            17. if (render === 0 && req.url === '/getList' && req.method === 'GET') {
            18. // 2.3 讀取data文件
            19. fs.readFile(filepath, 'utf8', (err, data) => {
            20. // - 打印錯誤信息
            21. if (err) {
            22. console.log('錯誤日志', err)
            23. return
            24. }
            25. // 讀取的為json數據,設置請求頭,如果不設置,則打印亂碼信息
            26. res.setHeader('content-type', 'application/json;charset=utf8')
            27. // - 返回數據
            28. let jsonArr = JSON.parse(data)['success']
            29. let jsonStr = JSON.stringify(jsonArr)
            30. res.end(jsonStr)
            31. })
            32. } else if (render === 1 && req.url === '/getList' && req.method === 'GET') {
            33. fs.readFile(filepath, 'utf8', (err, data) => {
            34. // - 打印錯誤信息
            35. if (err) {
            36. console.log('錯誤日志', err)
            37. return
            38. }
            39. // 讀取的為json數據,設置請求頭,如果不設置,則打印亂碼信息
            40. res.setHeader('content-type', 'application/json;charset=utf8')
            41. // - 返回數據
            42. let jsonArr = JSON.parse(data)['fail']
            43. let jsonStr = JSON.stringify(jsonArr)
            44. res.end(jsonStr)
            45. })
            46. }
            47. })
            48. // 3.啟動服務
            49. // 8111為端口號,默認8000,盡量使用8開頭,如果使用其他,咋不會正常運行,會報錯
            50. server.listen(8111, () => {
            51. // 服務提示信息,運行代碼后的提示
            52. console.log('端口1111已經開啟')
            53. })











          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          JavaScript作用域和閉包

          前端達人


          前言

          深入了解閉包和作用域鏈就需先了解函數預編譯的過程


          一、預編譯

          JavaScript:運行三部曲:
          語法分析–預編譯–解釋執行
          預編譯:
          發生在函數執行的前一刻。
          函數聲明整體提升,變量只聲明提升。
          1.函數預編譯的過程:
          1.創建AO對象Activation Object(執行期上下文,其作用就是我們理解的作用域,函數產生的執行空間庫)
          2.找形參和變量聲明,將變量和形參名作為AO屬性名,值為undefined
          3.將實參值與形參統一
          4.找到函數聲明,將函數名作為屬性名,值為函數體。
          例:

          function test (a, b){ console.log(a); c = 0; var c; a = 3; b = 2; console.log(b); function b (){}; function d (){}; console.log(b); } test(1); /*答案:1,2,2
          答題過程:找形參和變量聲明,將變量和形參名作為 AO 屬性名,值為 undefined, AO{
           a : 1,
           b : undefined,
           c : undefined
          }
          函數聲明 function b(){}和 function d(){},AO{
           a : 1,
           b : function b(){},
           c : undefined,
           d : function d(){}
          }
          執行 console.log(a);答案是 1
          執行 c = 0;變 AO{
           a : 1,
           b : function b(){},
           c : 0,
           d : function d(){}
          }
          var c 不用管,因為 c 已經在 AO 里面了
          執行 a = 3;改 AO{
           a : 3,
           b : function b(){},
           c : 0,
           d : function d(){}
          }
          執行 b = 2;改 AO{
           a : 3,
           b : 2,
           c : 0,
           d : function d(){}
          }
          執行 console.log(b);答案是 2
          function b () {}和 function d(){}已經提過了,不用管
          執行 console.log(b);答案是 2*/ 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47

          2.全局預編譯它和函數預編譯步驟一樣,但它創造的是GO(全局對象):
          1.生成了一個 GO 的對象 Global Object(window 就是 GO
          2.找變量聲明…
          3.找函數聲明…

          任何全局變量都是 window 上的屬性
          變量沒有聲明就賦值了,歸 window 所有,就是在 GO 里面預編譯。
          例 :

          function test(){ var a = b =123; console.log(window.b); } test(); 答案 a 是 undefined,b 是 123 先生成 GO{ b : 123 } 再有 AO{ a : undefined } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          想執行全局,先生成 GO,在執行 test 的前一刻生成 AO
          函數里找變量,因為GO和AO有幾層嵌套關系,近的優先,從近的到遠的, AO里有就看 AO,AO 沒有才看 GO。所以函數局部變量和全局變量同名,函數內只會用局部。

          二、作用域精講

          作用域定義:變量(變量作用于又稱上下文)和函數生效(能被訪問)的區域
          全局、局部變量
          作用域的訪問順序:函數外面不能用函數里面的。里面的可以訪問外面的,外面的不能訪問里面的,彼此獨立的區間不能相互訪問。

          1.[[scope]]: 每個 javascript 函數都是一個對象,對象中有些屬性我們可以訪問,但有些不可以,這些屬性僅供 javascript 引擎存取,[[scope]]就是其中一個。[[scope]]指的就是我們所說的作用域,其中存儲了運行期上下文的集合。

          2.執行期上下文: 當函數在執行的前一刻,會創建一個稱為執行期上下文的內部對象(AO)。
          一個執行期上下文定義了一個函數執行時的環境,函數每次執行時對應的執行上下文都是獨一無二的,所以多次調用一個函數會導致創建多個執行上下文,當函數執行完畢,執行上下文被銷毀。

          3.作用域鏈:[[scope]]中所存儲的執行期上下文對象的集合(GO和AO),這個集合呈鏈式鏈接,我們把這種鏈式鏈接叫做作用域鏈。

          4.查找變量: 在哪個函數里面查找變量,就從哪個函數作用域鏈的頂端依次向下查找(先查自己的AO,再查父級的AO,一直到最后的GO)。
          函數類對象,我們能訪問 test.name
          test.[[scope]]隱式屬性——作用域

          作用域鏈圖解:

          function a (){ function b (){ var bb = 234; aa = 0; } var aa = 123; b(); console.log(aa) } var glob = 100; a(); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          0 是最頂端,1 是次頂端,查找順序是從最頂端往下查
          在這里插入圖片描述
          在全局預編譯中函數a定義時,它的[[scope]]屬性中有GO對象。
          在這里插入圖片描述
          在函數a執行前先函數預編譯,創建自己的AO對象,并存儲在[[scope]]屬性上,與之前存儲的GO成鏈式。同時函數b被創建定義。
          在這里插入圖片描述
          在b被創建時,它生成的[[scope]]屬性直接存儲了父級的[[scope]],它有了父級的AO和GO。
          在這里插入圖片描述
          b函數執行前預編譯,生成自己的AO,存儲在[[scope]]屬性中。

          詳解過程: 注意[[scope]]它是數組,存儲的都是引用值。
          b 中 a 的 AO 與 a 的 AO,就是同一個 AO,b 只是引用了 a 的 AO,GO 也都是同一個。
          function b(){}執行完,干掉的是 b 自己的 AO(銷毀執行期上下文)(去掉連接線),下次 function b 被執行時,產生的是新的 b 的 AO。b 執行完只會銷毀自己的 AO,不會銷毀 a 的 AO。會退回到b被定義時(仍有父級的AO和GO)。
          function a(){}執行完,會把 a 自己的 AO 銷毀【也會把 function b的[[scope]]也銷毀】,只剩 GO(回歸到 a 被定義的時候),等下次 function a再次被執行時,會產生一個全新的 AO,里面有一個新的 b 函數。。。。。。周而復始。

          思考一個問題:如果 function a 不被執行,下面的 function b 和 function c 都是看不到的(也不會被執行,被折疊)。只有 function a 被執行,才能執行 function a 里面的內容a();不執行,根本看不到 function a (){}里面的內容,但我們想在a函數外面調用b函數怎么辦呢,于是閉包出現了。

          三、閉包

          閉包的定義

          當內部函數被保存到外部時,將會生成閉包。但凡是內部的函數被保存到外部,一定生成閉包。
          閉包的問題:閉包會導致原有作用域鏈不釋放,作用域中的局部變量一直被使用著,導致該作用域釋放不掉,造成內存泄露(就是占有過多內存,導致內存越來越少,就像泄露了一樣)
          例:

          function a(){ function b(){ var b=456; console.log(a); console.log(b); } var a=123; return b; } var glob = a(); glob(); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11

          答案 123,456。
          function a(){ }是在 return b 之后才執行完,才銷毀。而return b 把 b(包括 a 的 AO)保存到外部了(放在全局)當 a 執行完砍掉自己的 AO 時(砍掉對AO存儲地址的指針),因為b還保存著對a的AO的引用,所以內存清除機制不會清除掉a的AO, b 依然可以訪問到 a 的 AO。

          閉包的作用:

          1.實現共有變量

          function test(){ var num=100; function a(){ num++; } function b(){ num--; } return [a,b]; } var myArr=test(); myArr[0](); myArr[1](); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13

          答案 101 和 100。
          思考過程:說明兩個用的是一個 AO。
          myArr[0]是數組第一位的意思,即 a,myArr0;就是執行函數 a 的意思;
          myArr[1]是數組第二位的意思,即 b,myArr1; 就是執行函數 b 的意思。
          test doing test[[scope]] 0:testAO
          1:GO
          a defined a.[[scope]] 0 : testAO
          1 : GO
          b defined b.[[scope]] 0 : testAO
          1 : GO
          return[a, b]將 a 和 b 同時被定義的狀態被保存出來了
          當執行 myArr0;時
          a doing a.[[scope]] 0 : aAO
          1 : testAO
          2 : GO
          當執行 myArr1;時
          b doing b.[[scope]] 0 : bAO
          1 : a 運行后的 testAO
          2 : GO
          a 運行后的 testAO, 與 a doing 里面的 testAO 一模一樣
          a 和 b 連線的都是 test 環境,對應的一個閉包

          2.可以做緩存(存儲結構)

          function eater(){ var food=""; var obj={ eat : function (myFood){ console.log("i am eating"+food); food =""; }, push : function (myFood){ food = myFood; } } return obj; } var eater1 = eater(); eater1.push("banana"); eater1.eat(); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17

          答案 i am eating banana,eat 和 push 操作的是同一個 food
          在 function eater(){里面的 food}就相當于一個隱式存儲的機構
          obj 對象里面是可以有 function 方法的,也可以有屬性,方法就是函數的表現形式

          3.可以實現封裝,屬性私有化
          只能調用函數方法,不能修改函數的屬性。

          4.模塊化開發,防止污染全局變量


























          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          React 組件中的事件處理、組件(受控、非受控)、函數柯里化

          前端達人

          事件處理

          在React中獲取虛擬組件中的標簽的值

          1. 使用組件的 refs屬性
          2. 在虛擬組件的標簽中定義事件,在事件中通過 箭頭函數 獲取標簽的值
          3. 使用事件對象——event

          事件處理:

          • 通過onXxx屬性指定事件處理函數(注意大小寫)
            • React使用的是自定義(合成)事件, 而不是使用的原生DOM事件 ———為了更好的兼容性
            • React中的事件是通過事件委托方式處理的(委托給組件最外層的元素) ————為了高效
          • 通過event.target得到發生事件的DOM元素對象 ———不要過度使用ref

          使用event.target屬性:

          //創建組件 class Demo extends React.Component{ myRef = React.createRef() //展示輸入框的數據 showData = (event)=>{ alert(event.target.value); } render(){ return( <div> <input onBlur={this.showData} type="text" placeholder="失去焦點提示數據"/> </div> ) } } //渲染組件到頁面 ReactDOM.render(<Demo/>,document.getElementById('test')) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18

          React事件處理和Dom事件處理區別:

          1、在 語法 上的不同點:

          • React事件名采用駝峰命名法,即事件名首字母大寫。如onclick(Dom)——onClick(React)

          • 響應事件的函數在React中以 對象方式 賦值,Dom是以 字符串方式 賦值

            <button onclick= ' clickMe( ) '>提交</button> ——Dom方式 <button onClick={ clickMe( ) }>提交</button> ——React方式 
                    
            • 1
            • 2

          2、在阻止事件的默認行為有區別:React事件是合成的,DOM事件是原生

          • Dom:返回false
          • React:顯示的調用事件對象event.preventDefault

          React事件處理函數

          • 1、使用ES6的箭頭函數

            class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } handleClick=()=>{ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example')); 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
          • 2、在組件中定義事件處理函數

            class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } this.handleClick=this.handleClick.bind(this); } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example')); 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 21
            • 注:這種方法的好處是每次render渲染都不會重新創建一個回調函數,沒有額外的性能損失,但是如果在一個組件中有很多的事件函數時這種在構造函數中綁定this的方法會顯得繁瑣
          • 3、在給事件賦值時綁定this

            class MyComponent extends React.Component{ constructor(props){ super(props); this.state={ number:0 } } handleClick(){ ++this.state.number; console.log(this.state.number); } render(){ return( <div> <button type='button' onClick={this.handleClick.bind(this)}>點我</button> </div> ) } } ReactDOM.render(<MyComponent/>,document.getElementById('example')); 
                    
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 注:但是此方法在每次render時都會重新創建一個新的函數,性能有一定的損失,但在事件處理函數需要傳參數時,這種方法就比較好

          事件流

          在該示例中,3個div嵌套顯示,并且每個元素上均綁定onClick事件。當用戶點擊紅色區域的div元素時,可以看到,控制臺先后輸出了child -> parent -> ancestor,這是因為在React的事件處理系統中,默認的事件流就是冒泡。

          const style={ child:{ width:'100px', height:'100px', background:'red' }, parent:{ width:'150px', height:'150px', background:'blue' }, ancestor:{ width:'200px', height:'200px', background:'green' } } class Example extends React.Component{ render(){ return( <div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}> <div onClickCapture={ ()=> console.log('parent')} style={style.parent}> <div onClickCapture={ ()=> console.log('child')} style={style.child}></div> </div> </div> ) } } ReactDOM.render(<Example/>,document.getElementById('example')); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31

          在這里插入圖片描述

          • React默認的事件觸發方式:冒泡方式
          • 若將事件觸發改為捕獲方式:需要在事件名后帶上 Capture 后綴
          <div onClickCapture={()=> console.log('ancestor')} style={style.ancestor}> <div onClickCapture={ ()=> console.log('parent')} style={style.parent}> <div onClickCapture={ ()=> console.log('child')} style={style.child}></div> </div> </div> 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          事件委托

          在合成事件系統中,所有的事件都是綁定在document元素上,即雖然在某個React元素上綁定了事件,但是,最后事件都委托給document統一觸發。因此,在合成事件中只能阻止合成事件中的事件傳播

          React 阻止的事件流,并沒有阻止真正DOM元素的事件觸發,還是按照冒泡的方式,層層將事件交給上級元素進行處理,最后事件傳播到docuement,觸發合成事件,在合成事件中,child觸發時,e.stopPropagation() 被調用,合成事件中的事件被終止。因此,合成事件中的stopPropagation無法阻止事件在真正元素上的傳遞,它只阻止合成事件中的事件流。相反,如果綁定一個真正的事件,那么,合成事件則會被終止。

          • 默認事件流是冒泡的,所有事件統一由document觸發,在React中阻止冒泡方法是調用e.stopPropagation()
          • React的合成事件是可以找到原生的事件對象
          • React中的合成事件中只有一個全局對象event,該對象不是原生的event,但通過它可以獲得event對象的部分屬性。每個事件觸發完后React的全局對象event就會被清空,因此不能在異步操作使用

          事件類型:
          在這里插入圖片描述

          收集表單數據

          非受控組件

          表單數據由DOM本身處理。即不受setState()的控制,與傳統的HTML表單輸入相似,input輸入值即顯示最新值(使用 ref 從DOM獲取表單值),即不受React控制改變表單元素提交的值的方式,稱為:“非受控組件”

          class Login extends React.Component{ handleSubmit = (event)=>{ event.preventDefault() //阻止表單提交 const {username,password} = this alert(`你輸入的用戶名是:${username.value},你輸入的密碼是:${password.value}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用戶名:<input ref={c => this.username = c} type="text" name="username"/> 密碼:<input ref={c => this.password = c} type="password" name="password"/> <button>登錄</button> </form> ) } } //渲染組件 ReactDOM.render(<Login/>,document.getElementById('test')) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18

          受控組件

          在HTML中,標簽<input>、<textarea><select>的值的改變通常是根據用戶輸入進行更新。在React中,可變狀態通常保存在組件的狀態屬性中,并且只能使用 setState() 更新,而呈現表單的React組件也控制著在后續用戶輸入時該表單中發生的情況,以這種由React控制的輸入表單元素而改變其值的方式,稱為:“受控組件”。

          class Login extends React.Component{ //初始化狀態 state = { username:'', //用戶名 password:'' //密碼 } //保存用戶名到狀態中 saveUsername = (event)=>{ this.setState({username:event.target.value}) } //保存密碼到狀態中 savePassword = (event)=>{ this.setState({password:event.target.value}) } //表單提交的回調 handleSubmit = (event)=>{ event.preventDefault() //阻止表單提交 const {username,password} = this.state alert(`你輸入的用戶名是:${username},你輸入的密碼是:${password}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用戶名:<input onChange={this.saveUsername} type="text" name="username"/> 密碼:<input onChange={this.savePassword} type="password" name="password"/> <button>登錄</button> </form> ) } } //渲染組件 ReactDOM.render(<Login/>,document.getElementById('test')) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32

          受控和非受控元素都有其優點,根據具體情況選擇

          特征 非受控制 受控
          一次性檢索(例如表單提交)
          及時驗證 ×
          有條件的禁用提交按鈕 ×
          執行輸入格式 ×
          一個數據的幾個輸入 ×
          動態輸入 ×

          函數柯里化

          高階函數:如果一個函數符合下面2個規范中的任何一個,那該函數就是高階函數。

          1. 若A函數,接收的參數是一個函數,那么A就可以稱之為高階函數
          2. 若A函數,調用的返回值依然是一個函數,那么A就可以稱之為高階函數

          常見的高階函數有:Promise、setTimeout、arr.map()等等

          函數的柯里化:通過函數調用繼續返回函數的方式,實現多次接收參數最后統一處理的函數編碼形式。

          function sum(a){ return(b)=>{ return (c)=>{ return a+b+c } } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          函數柯里化的實現

          class Login extends React.Component{ //初始化狀態 state = { username:'', //用戶名 password:'' //密碼 } //保存表單數據到狀態中 saveFormData = (dataType)=>{ return (event)=>{ this.setState({[dataType]:event.target.value}) } } //表單提交的回調 handleSubmit = (event)=>{ event.preventDefault() //阻止表單提交 const {username,password} = this.state alert(`你輸入的用戶名是:${username},你輸入的密碼是:${password}`) } render(){ return( <form onSubmit={this.handleSubmit}> 用戶名:<input onChange={this.saveFormData('username')} type="text" name="username"/> 密碼:<input onChange={this.saveFormData('password')} type="password" name="password"/> <button>登錄</button> </form> ) } } //渲染組件 ReactDOM.render(<Login/>,document.getElementById('test')) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30



























          
          
          
          
          
          
          
          
          
          
          
          

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合