<div id="wrap" onclick="alert(123);">123</div> <a href="javascript:void(0);">gogogogogo</a> <a href="javascript:alert('a標籤被點擊了!');">233333</a>
<script type="text/javascript" language="JavaScript"> //type和language是聲明語言格式,推薦不寫 alert('潭州教育!轉義字符\\') </script>
let a = confirm('確認不要媳婦啦?'); console.log(a); //得到用戶選擇的結果, "boolean" let b = prompt('請輸入你媳婦的名字:'); console.log(b); //用戶輸入的結果, 取消-> null -> "object" 肯定 -> string
ES6 定義變量,4種方式 - let - const 常量,不可更改,初始必須賦值 - function - class ES5 定義變量,2種方式 - var - function
變量命名規則:javascript
// number let x = 10; // string let x = "10"; let x = '10'; let x = `456`; //模板字符串 ES6中新的字符串定義方式 let x = "true"; // boolean let x = true; let x = false; //布爾值有兩種,true 和 false // undefined let x; let x = undefined; const x = undefined; //const不容許初始不賦值 // symbol let x = Symbol(123); let y = Symbol(123); // x和y都是獨一無二的 Symbol(變量) // object let x = [10,true,10]; //數組是對象的一種 function 和 class 定義的變量 typeof 顯示"function", 其本質是object
let a = typeof NaN; //number let b = typeof a; //b是string類型 let c; //undefined let d = null; //typeof在檢測null類型時返回object類型,其本質是null類型 let e = Symbol(123); //symbol let f = document; //object let g = function(){ //typeof在檢測function數據會返回"function",其本質是object }; console.log(typeof(b)); console.log(typeof c); console.log(typeof d); console.log(typeof e); console.log(typeof f); console.log(typeof g);
let a = document.getElementById("wrap"); //a就是節點對象 console.log(a); // <div id="wrap"></div> //ClassName不惟一,因此Elements有s let b = document.getElementsByClassName("box"); console.log(b); //類(似)數組 HTMLCollection(3) [div.box, div.box, div.box] console.log(b.length); // 3 console.log(b[0]); // <div class="box">1</div> b[1].innerHTML = '阿飛'; let d = document.getElementsByName('name'); //應用在input標籤 console.log(d); // NodeList [input]
注意:打印的是標籤,不是類數組節點php
console.log(document.body); // body標籤及其子標籤 console.log(document.head); // head標籤及內容 console.dir(document.title); //標題 //獲取HTML,此處是引用,儘管在後面改變,但引用也會跟上 console.log(document.documentElement); //打印的是整個html頁面 document.title = "阿飛"; document.documentElement.id = '狗蛋';
let aaP = document.getElementById("wrap") .getElementsByTagName("div")[0] .getElementsByTagName("p"); //一層層查找,但性能仍然較querySelector好 console.log(aaP); // HTMLCollection(3) [p, p, p] let aP = document.querySelectorAll("#wrap div p"); //All多個,參數相似css選擇器 console.log(aP); // NodeList(3) [p, p, p] /*最低支持IE8*/ let sP = document.querySelector("#wrap div p"); //只能選到第一個 打印出的就是標籤
w3c容許的標籤屬性,既是合法 合法的標籤屬性,直接 . 操做css
- `class`比較特殊,須要使用`className`代替操做 - `style` 這個屬性很是特殊,是個對象
let oDiv = document.getElementById("wrap"); //oDiv.title = '狗蛋'; 直接寫 oDiv.className = 'wrap'; //屬性class是保留詞,這裏用className oDiv.id = 'goudan'; oDiv.innerHTML = '<p>666</p>'; //雖然改了id,但oDIV仍指向這個節點對象總體,id只是其中一個屬性,不能影響總體 //oDiv.innerHTML += '456'; 能夠直接+= let oGouDan = document.getElementById("goudan"); console.log(oDiv === oGouDan); //徹底相等
/* css樣式 js中css屬性名用駝峯法: 操做複合樣式的時候,去掉 - 號,後面的第一個字母大寫 */ let oWrap = document.getElementById("wrap"); console.log(oWrap.style); oWrap.style.height = "100px"; oWrap.style.backgroundColor = "pink"; //將background-color改成駝峯命名法,backgroundColor oWrap.style.cssText +="width:100px;height:100px;background-color:pink"; // 也能夠這樣寫 / oWrap.className += " box"; / /* 操做className代替複雜的css樣式設置 */
let oWrap = document.getElementById("wrap"); //獲取自定義標籤屬性 console.log(oWrap.getAttribute("afei")); //設置自定義標籤屬性 oWrap.setAttribute("afei","456"); oWrap.setAttribute("zhuque","123"); //移除自定義屬性 oWrap.removeAttribute("afei"); //能夠操做合法屬性,但通常不用,沒有直接.操做方便 console.log(oWrap.getAttribute("id"));
<div id="wrap"><i>阿飛飛</i> 小浪浪 海文文 銀時時 朱雀雀</div> <input id="inp" type="text"> <button id="btn">按鈕</button> <script> /* .innerHTML .innerText 火狐低版本 .textContent .value */ // let oWrap = document.getElementById("wrap"); // // console.log(oWrap.innerHTML); //獲取HTML // console.log(oWrap.innerText); //只獲取文本 // // oWrap.innerHTML = "<b>朱雀雀真...</b>"; //oWrap.innerText = "<b>豬八戒...</b>"; document.getElementById("btn").onclick = function(){ alert(document.getElementById("inp").value); } </script>
<head> <meta charset="UTF-8"> <title>Title</title> <style> div#wrap.on.goudan[title]{ width:150px; height:150px; background-color:pink; border:5px solid #999; } </style> </head> <body> <div id="wrap" class="on goudan" title=""></div> </body>
let a = 10; let b = "20"; //alert(a + b); // 彈出 "1020",結果是字符串 //alert("123" + {}); // 123[object Object] //alert("123" + document); // 123[object HTMLDocument] //alert("123" + undefined); // 123undefined console.log(true + 8); // 返回9 //沒意義 // console.log({}+{}); //[object Object][object Object] // console.log([]+{}); //[object Object] // console.log([]+[]); // //同級運算從左到右 alert(1 + 2 + "3"); // 返回 "33" alert("8" + 1 + 2); // 返回 "812" // 將字符串轉成數字, 前面帶一個 + console.log(+"86867");
// 數組和任何東西相加,都會轉換成字符串 [1,2,3]+3 // "1,2,33" [1,2,3]+true // "1,2,3true" [1,2,3]+null // "1,2,3null" [1,2,3]+undefined // "1,2,3undefined" [1,2,3]+'' // "1,2,3" [1,2,3]+NaN // "1,2,3NaN" undefined+[] // "undefined" {}+[] // "[object Object]"
- * / %都會變成數字再進行運算 出現非法運算(字符串非數字字符串進行計算)時,會出現NaN(not a number) let a = '50p'; //非數字 let b = "40"; console.log(a - b); // NaN console.log(a * b); // NaN console.log(a / 20); // NaN console.log(a % 20); // NaN console.log(typeof(NaN)); //NaN是number類型,但不是一個數字 console.log(NaN + 10); // 返回NaN
let a = 10; console.log(a++); //返回10 // let a = 10; // let b = 5; // console.log(a++ + b); //返回15 let a = "5"; a ++; // ++ 或 -- 會強行變數字進行計算,最終a的值也是數字 console.log(a); // 6
/* 單引號 或者 雙引號 描述的字符串,內部不能換行 ` ` 模板字符串能夠 */ let oWrap = document.getElementById("wrap"); let x = "阿飛老師有點皮" // oWrap.innerHTML = "<ul>"+ // "<li>"+ // "<p>"+ // "<a href=''>"+x+"</a>"+ // "</p>"+ // "</li>" + // "</ul>"; /* ${}能夠直接引用變量,{}內是JS代碼 */ oWrap.innerHTML = `<ul> <li> <p> <i>${x}</i> <b>\$\{\}</b> </p> <p>\`\`是ES6的特色</p> </li> </ul>`;
let a = 15; a -= 1; //a = a - 1 a *= 2; //a = a * 2 a /= 3; //a = a / 3 a %= 4; //a = a % 4 alert(a);
/* == 只比較值相等與否,不關心數據類型 === 值與數據類型都要相等 != 不等 !== 不全等 */ let a = 10; let b = "10"; console.log(a == b); //true console.log(a === b); //false console.log(a !== b); //true console.log(a != b); //false
/* 基礎數據類型 (棧內存) 只比較值與類型 number string boolean undefined null symbol 引用數據類型 (堆內存) 比較地址 object */ /* a 和 b 是不一樣的對象,有本身的地址 */ let a = [10]; let b = [10]; console.log(a == b); //false console.log(a === b); //false console.log(a[0] === b[0]); //true //console.log(false == [0]); //這樣不科學的,建議 ===
/* > < >= <= */ //字符串比較,從首位的ASCII碼開始比較 let a = '3'; let b = '20'; console.log(a > b); // '3' > '2' 的ACSII碼,因此返回 true
/* && 與 //只考慮布爾值時:真真爲真,其餘都是假 真正的做用:遇到假就停,而後取假值,不然取後面的值 || 或 //只考慮布爾值時:假假爲假,其餘都是真 真正的做用:遇到真就停,而後取真值,不然取後面的值 ! 非 //只考慮布爾值時:取反 真正的做用:取數據對應布爾值的非 那些數據在被轉成布爾值的時候是 false: 0 undefined null false '' "" NaN */ // let a = true && false; // console.log(!a); let a = 5 && 0; console.log(a); //取假值,返回 number 0 let b = 8 && 9; console.log(b); // 返回 9 console.log(NaN || 7 || 0); //返回7 console.log(!1); //返回 false console.log(!0); //返回 true //取一個數據對應的布爾值 console.log(!! NaN); //NaN的布爾值是false
/* 逗號運算符,從左到右 從上到下 運算 */ let a = (4,5,6); //算到6後中止 console.log(a); //返回 6
/* 運算符優先級 . [] () ++ -- - ~ ! delete new typeof void * / % + - < <= > >= == != === !== && || 三目 = , */ // let a = 8 || 9 && 0; // console.log(a); //返回8 let a = 10; let b = 5; //瀏覽器會惰性運算,||的左邊已經肯定,右邊不會計算 // a = 8 || 5 && (b=6); //console.log(a); //8 //console.log(b); //5 ,b的賦值沒有計算 a = 0 || 5 && (b=6); //返回 a = 6, b = 6 console.log( 6 || (b=6) && 10 || 11); //返回6 console.log(b); //b仍未賦值
/* 二進制 位運算時會將數值轉換爲32位整型來進行運算, 因此位運算遇到小數時,直接處理掉小數部分當成整數來運算。 */ let a = 15; // 00000000 00000000 00000000 00001111 // -15的二進制 // 11111111 11111111 11111111 11110000 取反碼 // 11111111 11111111 11111111 11110001 反碼+1 /** * 位運算操做符:按位非`~` 、按位與`&`、按位或`|`、按位異或`^` *左移`<<`、 無符號右移`>>>`、 有符號右移`>>` */ //按位取反, 知足條件 a + ~a=-1 let a = 7; // 0111 console.log(~a); // -8 ( 1..1000 結果 取反 +1 ) (0...0111 -> 0...1000) //按位與 console.log(10 & 8); // 1010 & 1000 = 1000 => 8 //按位或 //左移 a << 2; //a * 2^2;
/* 哪些數據是假: 六大假 0 undefined null false "" NaN 當條件、真語句、假語句都是一條語句時,咱們可使用三目來改寫if 條件 ? 真語句 :假語句 */ 4<5 ? alert('真') : alert('假'); let val = true; //三目運算符的 優先級 低於 + let name = "val is" + val ?"狗蛋":"大錘"; //"val is true" ? "狗蛋" : "大錘" console.log(name); // 多級三目,從左到右 function f(n) { let a = n>100 ? n-100 : n>99 ? n-99 : n; console.log(a); }
let a = '海文'; // if (a === "阿飛") { // alert(a + "老師通常帥!"); // }else if (a === "小浪") { // alert(a + "老師??"); // }else if (a === "海文") { // alert(a + "斯文"); // }else if (a === "朱雀") { // alert(a + "可愛"); // }else{ // alert(a + "喵喵喵"); // } //switch 是全等判斷 switch (a) { case "阿飛": alert(a + "帥!"); break; case "小浪": alert(a + "也帥!"); break; case "海文": alert(a + "斯文"); break; case "朱雀": alert(a + "可愛"); break; default: alert("喵喵喵?"); break; }
let a = true; function b() { console.log(123); } // if (a) { // b(); // } a && b(); //遇到假中止,b()會運行 //先與再或,勉強能夠代替三目運算 let x = 5; let y = 6; //console.log(x<y ? 2 : 3); console.log(x<y && 2 || 3);
// 2+2^2+2^3+2^4+...+2^10 let a = 1; let sum = 0; for(let i = 1; i <= 10; i++){ console.log("i=" + i); a *= 2; //a = a*2 sum += a; console.log("sum=" + sum); }
/* 5 3 6 3 7 4 8 4 9 5 10 5 */ let oWrap = document.getElementById("wrap"); let HTML = ''; let num = 11; let mid = 0; //計算oWrap的寬高 if(num & 1){ //奇數判斷 mid = (num+1)/2; }else{ mid = num/2; } oWrap.style.width = num*50 + 'px'; oWrap.style.height = mid*50 + 'px'; for(let i = 0; i < num; i++){ let x = i>(mid-1) ? num-i-1 : i; //箭頭朝下 let y = i>(mid-1) ? i+1-mid : mid-1-i; //箭頭朝上 HTML += `<div style="margin-top:${y*50}px;">${i+1}</div>`; } oWrap.innerHTML = HTML;
/* break: switch裏面的break只對switch有用,不會影響到外面的for if裏面的 break ,結束上級 for 循環 continue: 該次循環結束,進入下一個循環 */ for(let i=0;i<10;i++){ switch (i) { case 5: break; //做用不到for } console.log(i); } for(let i=0;i<9;i++){ if(i===5){ //continue; //執行到continue,即刻中止,進入下一個循環 break; //結束 for 循環 } console.log(i); } //break只能跳出一個for,要想跳出第二層,定義一個僞變量表示for循環,break aaa; aaa:for(let i=0;i<5;i++){ for(let j=0;j<4;j++){ if(i*j ===6){ break aaa; } console.log(`i===${i},j===${j}`); } }
//let在for循環內定義時,是局部變量 for(let i = 0;;) //var在for循環內定義時,至關於所有變量 for(var i = 0;;) let i = 0; for(;i<4;i++){ } console.log(i); //返回4 //全局變量下的for循環能夠用while代替 var i =0; for(;i<5;){ console.log(i); i++; } var j=0; while(j<5){ console.log(j); j++; } // do while let x = 5; do{ console.log(x); x++; }while(x<5);
/* let a = function () { alert(1); } a(); //函數加括號,自執行 */ /* a(); //能夠放在function以前,let、var函數表達式定義的函數,不容許提早調用 function a () { alert(1); } */ /* let、var定義的函數,不容許提早調用 a(); var a = function () { alert(1); } */ let a = function b() { alert(2); console.log(b); //在函數裏面能夠獲取b,此時b === a console.log(b === a); } a(); //b(); //顯示b()未定義,函數外面不能使用b
/* 使用fuction直接定義的函數不能直接加括號執行,只能經過名字再加括號執行 function a() { alert(3); } a(); */ //let定義的函數表達式,能夠直接在後面加括號執行 let b=function () { console.log(4); }(); console.log(b); //undefined,此時b不能表明函數,b成爲了函數的返回值 //匿名函數只能傳參或賦值,不容許直接出現 //[function () {}] //容許 // function{} //不容許 //匿名函數加括號變成函數表達式,括號可內可外 (function () { console.log(5); })(); (function () { console.log(6); }()); //改變函數的返回值,也是函數表達式 +function(){ //一元運算符 + - 能夠變爲函數表達式 console.log(7); }(); ~function () { //位運算非 console.log(8); }(); !function () { //邏輯運算非 console.log(9); }();
/* 參數 形參 實參 不定參 */ //定義函數的時候()裏面是容許寫變量名字的,這些變量名字就是形參,形參只針對函數內容起做用 function a(x,y=200){ alert(x+y); } //函數調用的時候,()裏面寫的就是實參 a(7); function f(a,b,c) { console.log(a); console.log(b); console.log(c); } f(1,8); //從左到右進入形參,沒有傳入實參的,顯示undefined f(1,5,3,4); //實參多了,多的那個無效 function sum(a,b) { console.log(a+b); } sum(7,8); sum(45,1); //求 n 個數的和,每次不必定是相同的個數,實參傳入幾個數,就求幾個數的和 function sum(a,b,c,d) { //不定參 它是一個類數組,存儲着 全部實參 // console.log(arguments); let s = 0; for(let i=0,len=arguments.length;i<len;i++){ s+=arguments[i]; } console.log(s); } sum(4,5,6); sum(1,2,3,4); sum(8,6);
console.log(this); //打印Window 是頂層屬性 // window.alert(4); // alert(a); //未定義 報錯 // alert(requestAnimationFrame); //不存在即報錯 if(window.requestAnimationFrame){ //直接判斷時,若是不支持,直接報錯,不能進行判斷,此時最好用類屬性判斷 console.log(requestAnimationFrame); } /* 函數聲明,默認位於window對象內 函數(聲明式or表達式同樣)自執行,this指向window */ function a() { console.log(this === window); } console.log(a === window.a); // 相等 a(); //let定義的函數不掛載window內,var定義的函數在window內 let b = function () { console.log(this); //this都是指向window } console.log(b === window.b); b(); /* 對象內的this,找 爸爸 所在的對象 */ let afei = { name:'阿飛', x : function () { console.log(this); } } afei.x(); //對象方法自執行。this指向對象 let zhuque = { xx:{ name:"朱雀的xx", a:function () { console.log(this === zhuque.xx); } } } zhuque.xx.a(); // 打印 父級的對象
//函數運行到return即中止,return後面的不執行 function a() { alert(1); return 2; alert(3); } console.log(a());
let關鍵詞定義的變量,起做用的範圍就是包含這個變量最近的html
var關鍵詞,只有在function內定義的變量,纔是局部變量,while、if、for內定義的都是全局變量前端
同名函數會被覆蓋java
function a() { alert(2); } function a(x,y) { //覆蓋上一個定義 alert(x+y); } a();
動態有三個,意思是存儲節點的變量會隨着頁面的改變實時改變,少了或者多了node
靜態有如下,獲取後,選擇器被改也指向原對象es6
<div id="wrap"> <p class="goudan"></p> <p class="goudan"></p> <p class="goudan"></p> </div> <script> //getElementsByClassName是個動態的 let aP = document.getElementsByClassName("goudan"); // 有三個 let oP = aP[0]; // 這種就是靜態的,不存在因修改而改變 oP.className = 'dachui'; //改變了 aP,只剩兩個 「goudan」 oP.title = 'ppp'; aP[0].className = "a2121"; //aP是動態數組, aP[0].innerHTML = "112121212"; //由於aP[0]的類名被改變了,動態獲取的內容更新了,如今又少了一個 </script>
//script標籤是最大的做用域,也是全局做用域 //若是var、function在全局做用域裏面定義變量。至關於給window添加了屬性 var b = 10; console.log(window.b,this); //window的屬性 //ES5定義變量的關鍵詞 var funtion //做用域是往上離變量最近的函數 function a() { var g = 10; // var在function內定義的纔是局部做用域 console.log(g,this.b,this); //函數自執行this指向window } a(); //任意做用域裏面,若是不加var直接產生了沒有定義過的變量,那麼這個變量至關於window的屬性 //可是實際開發不容許這樣寫 function aa() { bb = "bb"; // 賦值產生變量才行,若是直接使用則會報錯 } aa(); console.log(bb); //面試題 function f() { var x=y=5; console.log(x); //x是局部的5 } f(); console.log(y); //y未聲明,所以算是window的屬性,y=5 //console.log(x); //由於x是局部變量,外部訪問不到,故報錯
//做用域鏈,操做變量時,一層層的做用域查找變量聲明的地方, //若是沒有找到,調用變量會報錯 //若是是賦值,在非嚴格模式下,變量成爲windows的屬性 var x=10; function a() { x=15; //本做用域找不到,去父級做用域找,找到後並賦值 var y=5; //局部做用域 return x+y; } console.log(a()); console.log(x); //全局變量被修改了,所以是15
var、function解析順序 第一步:定義 找出當前做用域裏面全部的var和function定義的變量名,不賦值,賦值是執行 此時function定義的函數,是個完整的函數,因此函數定義能夠在函數執行的先後任意位置 第二步:執行 從上到下執行
alert(x); // 返回不是報錯,是undefined,變量已有,但未賦值 var x=10; //let x=10; // 報錯 /* 1.定義 var x; 2.執行 alert(x); //undefined x=10; */ alert(b); function b() { } /* 1.定義 function b(){} 2.執行 alert(b); */
/* 定義過程當中,多個var聲明同一個變量,咱們只須要留一個 多個函數聲明重名,只留最後一個函數 var和function重名,不管前後,只留function */ function v() { alert(5); } function v() { // 被打印 alert(10); } var v; console.log(v);
函數執行每次都會產生一個新的做用域 (父級也是新的) ,彼此不相干web
/* JS自帶變量回收機制,只有全局變量不會被回收,除非網頁關閉; 閉包:一個使用了外部函數的參數或者變量的函數(做用域嵌套做用域,ES5只有函數能產生做用域) */ function a() { var x=10; function b() { x++; console.log(x,this); } return b; } //函數執行每次都會產生新的做用域, var c=a(); //c指向函數體內的函數b,局部變量x只在a()時產生了一次,因此不會回收 //alert(c); c是函數 //c()每次執行使用的都是同一個父級做用域下的變量x c(); //11 c(); //12 c(); //13 c(); //14 //a()每次執行後返回的都是新的做用域,使用的變量x是新的, a()(); //11 a()(); //11 a()(); //11
閉包的做用之一,閉包避免局部變量被回收面試
<div id="wrap"> <p>aaaaaaaaaaa</p> <p>bbbbbbbbbbb</p> <p>cccccccccc</p> <p>dddddddddd</p> <p>eeeeeeeeee</p> </div> <script> //閉包的做用之一,閉包避免局部變量被回收,onclick不知道何時觸發,因此num不會被回收 (function () { var num=10; document.onclick = function () { num++; alert(num); } })(); let oP = document.getElementsByTagName("p"); //ES6只要是{}就是做用域,{}內的onclick使用了父級的i,因此i沒有回收,子做用域能夠調用 //產生了5次閉包,存了5個i,子做用域之間的i不相干 //5個閉包是5個單獨的做用域,let i是5個父級做用域 for(let i=0;i<5;i++){ oP[i].onclick = function () { alert(++i); } } //var不能產生做用域,不是閉包,函數做用域用的是同一個變量i,(擴號內執行的結果是5) //i最後是5,因此每次點擊都是同一個i for(var i=0;i<5;i++){ oP[i].onclick = function () { alert(i); } }; //強行給var加閉包,創造一個父級做用域,使得點擊事件用上父級做用域的變量,產生5個閉包,存下5個變量 for(var i=0;i<5;i++){ function a(x){ oP[x].onclick = function() { alert(x); }; } a(i); //a(i)執行了5次,產生了5次閉包 } //等於自執行 for(var i=0;i<5;i++){ (function a(x){ oP[x].onclick = function() { alert(x); }; })(i);//a(i)執行了5次,產生了5次閉包 } //能夠簡寫自執行 for(var i=0;i<5;i++){ !function a(x){ oP[x].onclick = function() { alert(x); }; }(i);//a(i)執行了5次,產生了5次閉包 } </script>
練習
fn()(); var a = 0; function fn(){ alert(a); var a = 3; function c(){ alert(a) } return c; } /* 1.定義 var a; function fn(){} 2.執行 fn() ===> 新做用域 1.定義 var a; function c(){} 2.執行 alert(a) undefined a=3 return c; fn()() ===>新做用域 alert(a),a從父級找,彈出3 */
var a = 5; function fn(){ var a = 10; alert(a); function b(){ a ++; alert(a); } return b; } var c = fn(); c(); fn()(); c(); /* 10 11 10 11 12 */
console.log(5 === 5); console.log([] === []); //引用,須要比地址,false var h = function () {}; var l = function () {}; console.log(h === l); //false function a() { return function () {}; } var b = a(); var c = a(); console.log(b ===c); //false
只要是在做用域裏面let過的變量,那就不容許提早使用
/* ES6定義變量 let const function class let 和 const沒有預解析,不一樣於var 先對定義function,進行解析 */ alert(a); //報錯 let a = 10; let a = 20; function b() { //從上到下讀 //暫時性死區,只要是在做用域裏面let過的變量,那就不容許提早使用 alert(a); let a = 30; //死區了,報錯 } b(); //var的做用域只認函數 if(false){ var a=10; } console.log(a); //undefined //let的做用域是大括號 if(true){ let a=1; } console.log(a); //沒法訪問局部做用域 //for的小括號()是{}的父級做用域,但var不認這是做用域 const g = 10; //不容許從新賦值的常量 const a = []; //對象不能被從新賦值 a[0] = 10; //但容許改變其內容 console.log(a);
function a() { console.log(this); } a(); /* 普通模式下, 自執行this指向window, 嚴格模式下, this指向undefined 被動模式下,this指向觸發事件的對象 */ document.onclick = a;
/* call()內第一個參數是函數內this的指向,後面跟的是實參,調用後會執行 */ function a(x,y) { console.log(x); console.log(y); console.log(this); } a(8,9); //自執行 //a.call(); //call()不加參數與自執行a()效果同樣 a.call(document,8,9); //this指向document /* apply(),與call()相似,可是隻有兩個參數,第二個是傳參的數組 */ a.apply(document,[8,9]); //this指向document //多個參數要用數組的形式傳入
bind以後至關於生成一個新的函數,還未執行
/* bind不能執行 */ function a(x,y) { console.log(x); console.log(y); console.log(this); } //a.bind(document); 這樣直接寫是沒有效果的,只是至關於生成了一個新的函數,將this綁定給document function b(x) { x(); } b( a.bind(document) ); //bind後生成了有this新指向的函數,bind是定義函數,不能直接執行,須要手動執行 a.bind(document)(10,20); //新的函數內的this指向 document a.bind(10)(0,1); //新的函數內this指向number 10
//bind定義this指向 document.onclick = function (x,y) { console.log(x); console.log(y); console.log(this); }.bind({name:'阿飛'},200,250); //這裏相似於call傳參,bind產生新函數
oWrap.classList.[attr] attr = add、remove、toggle
let aDiv = document.querySelectorAll("#wrap .title"), aList = document.querySelectorAll("#wrap .friend .list"), len=aDiv.length; for(let i=0;i<len;i++){ aDiv[i].onclick = function () { //toggle,若是有就刪除,沒有就添加 aList[i].classList.toggle("show"); } } //classList 方法還有 add remove oWrap.classList.add("afei"); //直接添加類名
// ES6 定義變量的解構賦值 let a = 10, b = 20, c = 30; //結構模式對應,賦值效果同上 let [a,b,c] = [10,20,30]; //多了 顯示 undefined let [a,b,c,d] = [20,30,41]; // d = undefined //不用let的變量賦值語句,變量默認是window的屬性 [a,b] = [20,30,41]; //變種寫法 function fn() { let x=[]; for(let i =0;i<5;i++){ x[i]=i*i; } return x; } let [a,b,c,d,e] = fn(); //對象的解構賦值,屬性是用來對應的,只有變量定義了 let {a:x,b:y} = {a:10,b:20}; console.log(x); console.log(a); // 報錯,屬性不是定義的 let {x:x,y:y} = {a:10,b:20,y:30}; console.log(x); //找不到右邊對象的x屬性,因此變量x顯示未定義 console.log(y); //屬性對應才能賦值 y=30 //注,屬性和變量相同時,能夠只寫一個 let {x,y} = {x:10,y:30}; console.log(x,y); //ES6新增簡寫規則 let a = 10, b = 20, c = { a, b }; /*屬性名和變量名相同,能夠簡寫,對象c的定義同下 c = { a:a, b:b } */ console.log(c);
let [a,[b,c],d] = [1,[2,3],4]; console.log(a,b,c,d); let [a,b,{x,y}] = [1,2,{x:10,y:20}]; console.log(a,b,x,y);
只有右邊**嚴格等於undefined**時取默認值 不容許前面的默認值用後面的變量值
/*使用解構賦值,取默認值的方法*/ function fn(data) { let a = data.a; let b = data.b; let c = data.c || 100; // 要確保傳入的值不是假,不然走默認值,這種不嚴格 // 必須嚴格的走 全等undefined,再添加默認值 if(c === undefined){ c = 100; } } fn({a:10,b:20}); //ES6的默認值寫法,左邊寫一個等於,只有右邊嚴格等於undefined時取默認值 function fn(data) { let {a:a=1,b:b=2,c:c=100} = data; //左邊嚴格上說不能認爲是對象,只有右邊是對象 console.log(a,b,c); // c = null } fn({a:10,b:20,c:null}); // 這裏 null===undefined 不成立, //數組默認值寫法 let [d,e,f=90] = [7,8]; console.log(d,e,f); //默認值是表達式時,若是不須要默認值,則默認值沒法執行 function f1() { console.log("12"); } let [x = f1()] = [1]; // x=1, f1未執行 let [y = f1()] = [undefined]; // y=undefined, 是f1執行後的返回值 //不容許前面的默認值用後面的變量值 let [m=n,n]=[undefined,1]; console.log(m,n); //報錯
undefined null 等不能進行點操做,會報錯的
//基礎數據類型雖然能夠點操做,但沒有意義,拿不到包裝對象; //點操做本質上是針對數據的包裝對象進行操做,每一次的包裝對象都是新產生的對象,不能肯定 //undefined null 等不能進行點操做,會報錯的 let a='阿飛'; a.index = 20; //不能給字符串添加自定義屬性,不會報錯,顯示undefined,這是操做的a的包裝對象,用了即消失,存不下來 console.log(a,a.index); //第二次的點操做是操做的全新的包裝對象,用後即消失 /* let b={}; b.index = 20; //對象能夠添加自定義屬性 console.log(b); */ let a = new String("阿飛"); //這裏的a是字符串對象 a.index = 20; //a的包裝對象是 new String(),能夠添加自定義屬性 console.log(a+"朱雀",a.index);
let a = '阿飛'; //console.log(new String(a)); //能夠打印包裝對象屬性爲String的對象 //針對a的包裝對象的charAt console.log(a.charAt(1)); //取出字符串中的第幾位字符 console.log(a[0]); // a的包裝對象有a的內容,對象訪問時能夠的,可是IE6,7不支持,最好用charAt //包裝對象不能賦值,沒有意義;使用即消失,存不了 a[0]="5"; console.log(a[0]);
/* charCodeAt() 調用第幾個字符的編碼, String.fromCharCode() 與之相反,從ASCII碼到字符 */ let a = "阿A飛"; let b = `阿 飛`; console.log(a.charCodeAt(1)); // 65 console.log(b.charCodeAt(1)); //換行碼是 10 console.log(String.fromCharCode(39134)); // 飛 //加密,利用ASCII碼 let c = "小卑鄙我愛你"; let d = ""; for(let i=0,len=c.length;i<len;i++){ let code = c.charCodeAt(i)+520; console.log(code); d += String.fromCharCode(code); } console.log(d);
/*substring(x,y) 從第x位到第y位截取,x要,y不要*/ // slice能夠倒着截取 let a="abc阿飛789456"; let b = a.substring(3,5); //包含3,不包含5 console.log(b); //阿飛 let bb=a.substring(5,3); //沒有先後要求,會自動調整 console.log(bb); //阿飛 let c = a.substring(3); //從3到結尾 console.log(c); //阿飛789456 let d = a.substring(-2,3); //沒有負值,會認爲0 console.log(d); // abc let e = a.slice(-5,-2); //負值表示從後開始數,倒着數,要知足前後順序 console.log(e); // 894
//主要針對英文字母大小寫 /* toLocaleUpperCase() */ let a = "abc"; let b = a.toLocaleUpperCase(); console.log(b); console.log(b.toLocaleLowerCase());
/* 找位置,返回num */ let a = "我以爲阿飛老師是最皮的"; console.log(a.indexOf("阿飛")); //指定位置開始找,後面加一個參數 console.log(a.indexOf("老師",3)); //找不到返回 -1
// 使用split()進行切割,返回一個包含分開特定字符先後元素的數組 let a = "阿飛,朱雀,心艾,嵐嵐,丫丫,艾米"; let b = a.split(","); console.log(b); console.log(b.join("php")) // let c = a.split(""); // console.log(c);
function fn(a,b) { console.log(arguments); // [ 0:["1,2", "阿飛", ""], 1:5 , 2:6 ] console.log(a+b); // 1,2,阿飛,5 } //fn(1,2); let b=5; let a = 6; fn`1,2${b}阿飛${a}`;
增長,返回數組長度,刪除,返回被刪的內容
/* push 參數:任意數據 功能:直接改變原數組 返回值:返回改變後數組的長度 pop 參數:null 功能:改變原數組,刪除最後一位 返回值:刪除的元素 shift 功能:改變原數組,刪除第一位 返回值:刪除的元素 unshift 功能:改變原數組,從第一位添加 返回值:數組長度 */ let a = ["阿飛","無慮"]; console.log(a.push("小浪","海文")); console.log(a); console.log(a.pop()); console.log(a); console.log(a.shift()); console.log(a); console.log(a.unshift("first")); console.log(a); //騷操做, // pop()返回的是刪除的最後一個函數,後面跟參數執行 let x = [5,function(x){alert(x)}]; x.pop()(x[0]);
//類數組除了.length,不能執行其餘api let a = ["阿飛","無慮","朱雀"]; console.log(a.indexOf("朱雀")); //2 //數組截取 let b = a.slice(1); console.log(b); // ["無慮", "朱雀"]
返回被切割的部分
//數組切割,單個參數時,包含前面而不含後面的 let a = ['阿飛','無慮','小浪']; console.log(a.splice(1)); //從第1個切,切到最後 ["無慮", "小浪"] console.log(a); // ["阿飛"] //第二個參數表示切除幾個 console.log(a.splice(1,1)); //從第1個開始切除1個 ["無慮"] console.log(a); // ["阿飛", "小浪"] //添加與替換 a.splice(1,1,'朱雀','心艾'); //切除一個,替換了2個 ["無慮"] console.log(a); // ["阿飛", "朱雀", "心艾", "小浪"]
二分法排序
不加參數,默認升序, 數組被改變了,但引用地址沒變,仍相等
//通常只是針對num類型數組排序,其餘類型沒有意義 // sort()從小到大排序,升序 // reverse() 反序,元素從後往前排,能夠先升序再反序實現降序排列 // 返回值是排列完成以後的數組, let a=[12,78,50,20,32,40,90]; a.sort(); console.log(a); a.reverse(); console.log(a); console.log(a.sort() === a); //改變以後仍是a自己,相等 //降序 console.log(a.sort().reverse()); //JS二分法排序 a-b: 爲升序 b-a: 爲降序 a.sort(function (a,b) { return a-b; }) console.log(a);
let a = [ {name:'阿飛',age:20}, {name:'朱雀',age:30}, {name:'丫丫',age:18}, {name:'心艾',age:80}, {name:'嵐嵐',age:22}, {name:'發發',age:22}, {name:'艾米',age:28} ]; //a.sort(); 沒法直接對對象排序 a.sort(function (a,b) { return b.age-a.age; //後者減前者,降序 }) console.log(a);
// concat 拼接數組 let a = [1,2,3]; let b = [4,5,6]; let c = a.concat(b); //將b拼接到a的後面 console.log(a,b); //不改變原數組 console.log(c);
// 只有 Array 可使用 isArray()方法 let a = [1]; let b = document.querySelectorAll("div"); console.log(Array.isArray(a)); console.log(Array.isArray(b)); //經常使用於判斷類數組,其沒有數組經常使用的方法
let a = ["阿飛",'心艾','朱雀']; let b = a.join("<==>"); //一般將字符串數組元素拼接成一個新的長的字符串 console.log(a); //不改變原數組 console.log(b); //b是返回的長字符串 阿飛<==>心艾<==>朱雀
//forEach 遍歷數組,必需要有函數做爲參數,自動執行length次,不支持函數return /* 接收函數,該函數第一個形參表明每一位的數據, 第二個形參表明每一位的序號, 第三個形參表明原數組 */ let a = [4,5,6,7,8,9]; let b=a.forEach(function (x,y,z) { console.log(x,y,z); }); console.log(b); //undefined //與forEach效果同樣 for(let i=0;i<a.length;i++){ (function (x,y,z) { console.log(x,y,z); })(a[i],i,a); }
//map是有返回值的數組遍歷,返回一個基於原數組結構的數組 let a = [1,2,4,5]; let b = a.map(function (x,y,z) { console.log(x,y,z); return x*x; }); console.log(a); //map不改變a console.log(b); //b是基於a結構的新生數組 [1, 4, 16, 25]
**ES6 的Map對象,可用於記數**
let a = [1,2,4,5]; let c = new Map() a.map(function (val,index) { c.set(index,value) // 實例方法,設置 map數據 }) console.log(c); // Map對象實例 Map(4) {0 => 1, 1 => 2, 2 => 4, 3 => 5} c.get(3); // 5 按set時的index查找 c.has(0); // true index c.keys(); // MapIterator {0, 1, 2, 3} c.values(); // MapIterator {1, 2, 4, 5} [...c]; // [[0,1], [1,2], [2,4], [3,5]]
/* 遍歷 func:過濾 生成一個過濾後的數組,return true 留下,false 過濾掉 */ let a=[10,20,5,7,89,41]; let b=a.filter(function (x,y,z) { console.log(x,y,z); return x>10; //將x>10的留下,新生一個數組 }); console.log(a); //不改變原數組 console.log(b); //b是過濾後的數組
let a = [1,2,3]; console.log(...a); //去除數組括號,拆解成單個,ES6兼容,babel可轉 console.log(1,2,3); //與上等價 //param形參 function f(param) { console.log(param); // 只有一個形參 1 } //f(1,2,3); f(...a); /* let c = (...a); //這樣作是不容許的 console.log(c); */
...數組拼接
// ...數組拼接 let a = [1,2,4]; let b = [5,6,7]; //let c = a.concat(b); let c = [...a,...b]; console.log(c);
...解構賦值
//b是數組,拆開後賦值, ...b只能放在後面,表示接受所有 let [a,...b]=[1,2,3,4]; console.log(a); // 1 console.log(b); // [2, 3, 4]
...與iterator接口
//常見的Iterator遍歷器接口 / Array String nodelist arguments / // Nodelist是節點對象集合 function fn(a,b,c) { console.log(a,b,c); } fn("753"); // 753 undefined undefined fn(..."753"); // 7 5 3
...與NodeList
let aP = document.getElementsByTagName("p"); // 類數組不能用數組的遍歷 // aP.forEach(function (val,index) { // }); //ES5就有辦法將 aP 先搞成數組,以後再使用forEach //slice不傳參數就不切割,數組切割,方法slice使用call改變切割對象執行,返回一個真數組 let x = [].slice.call(aP); //生成一個新數組 console.log(x); x.forEach(function (node,index) { node.onclick = function () { alert(index); } }) //ES5 類數組=>真數組遍歷遍歷 [].slice.call(aP).forEach(function (node,index) { node.onclick = function () { alert(index); } }); //ES6 , ...將Nodelist拆了,加上[]成爲真數組 console.log([...aP]); [...aP].forEach(function (n,i) { n.onclick = function () { alert(i); } });
...與function
//任何拆解都要放在最後面 function fn(a,...b) { console.log(a); console.log(b); } fn(4,5,6); function fn(...argu) { console.log(argu); //ES6的...能夠直接代替arguments } fn(7,8,9);
/* Math 對象 屬性: 方法: */ //小數表示方式: 0表示正負 10表示小數點的位置爲2 10.1010的整數部分爲2,小數部分是1010/2^4, 10/16 //var a = 0 10 10.1010; //表示 2.625 /* Math.abs() 1.傳入的值是正確的,返回一個新的絕對值結果,字面量賦值 2.傳入的值是數字字符串,會取value值取絕對值 3.單個數字元素的數組也會取值,多個數字元素也是NaN 4.傳入的值其餘類型,返回NaN,表示not a number */ console.log(Math.abs(["-888"])); // 888 //Math.pow(x,y)表示x的y次方 console.log(Math.pow(2,10)); // 1024 //開方,y小於1 console.log(Math.pow(256,1/2)); // 16 //過氣的開二次方 console.log(Math.sqrt(256)); // 16 //取整,floor接地氣,往小了取整,正負同樣 console.log(Math.floor(2.5),Math.floor(-2.01)); //2 -3 //向上取整 console.log(Math.ceil(2.5),Math.ceil(-2.9)); //3 -2 //四捨五入取整 console.log(Math.round(4.49),Math.round(-4.6)); //4 -5 //去小數點取整 console.log(Math.trunc(-5.999991)); // -5
/* 圓周 2PI 360deg PI/6 30deg PI/3 60deg sin 正弦 對/斜 cos 餘弦 鄰/斜 tan 正切 對/鄰 反三角 arcsin */ console.log(Math.sin(Math.PI/6),Math.cos(Math.PI/3),Math.tan(Math.PI/4)); //結果有小數,不精確 console.log(Math.asin(0.5),Math.PI/6);
/* Math.random() 返回一個[0,1)的數 */ //console.log(Math.random(),Math.round(Math.random()*10)); // 生成一個n到m的隨機數,m取不到 const rdm = function(n=0,m=n+1){ return Math.floor((m-n)*Math.random()+n); } console.log(rdm(1,7));
/* 非數學對象 parseInt(a,b) a 須要轉換的數值,隱式轉換成字符串 b 進制(2,36) 10+26 */ console.log(parseInt("123abc")); //返回字符串中的整數部分,遇到NaN中止 返回123 //第二個可選參數是進制 console.log(parseInt("ff",16)); //按16進制解析,結果是10進制255 console.log(parseInt("0xa")); // 10 /* parseFloat()返回帶小數點的 在底層parseFloat會先判斷傳入的參數類型,轉換成字符串; 若是傳入對象,會默認調用對象的toString()方法 */ console.log(parseFloat("12.3254a")); console.log({}.toString()); // 打印 "[object Object]" //ES6次方簡寫 console.log(3**2); //表示3的平方
// cbrt是取立方根結果,相似 Math.pow(27,1/3) console.log(Math.cbrt(27),Math.pow(27,1/3)); //3 3 // exp是天然對數e的冪函數,e^ln2 = 2; console.log(Math.exp(Math.LN2),Math.exp(Math.LN10)); //2 10 // 轉成最近的單精度浮點數的數字 console.log(Math.fround(100.1));
let a={ name:'阿飛', 'age':18, marry:true, handsome:true } //for in循環,遍歷對象,也能夠是數組 for(let key in a){ console.log(key,":",a[key]); }
//對象的屬性是無序的,通常按照字母前後順序展現 let a={ name:'阿飛', age:18, marry:true } console.log(a); //這裏a是引用,後面改了,這邊也能相應 //增 a.GF = ['朱雀','丫丫','嵐嵐','茜茜']; //改 a.age = 21; //刪除 delete a.marry; //查找,是否存在 console.log('age' in a);
//json 是一個格式很是標準長得像對象的字符串 //通用字符串,基本上全部語言都能識別的字符串格式 //let a = '{"name":"阿飛","age":18,"marry":true}'; let a={ 'name':'阿飛', age:18, marry:true }; //將一個對象轉爲JSON格式 JSON.stringify() 反序列化 let b=JSON.stringify(a) console.log(b); //將JSON序列化, JSON.parse() 解析成對象 let c = '{"a":10,"b":"狗蛋","c":true}'; //必須是標準嚴格的JSON格式才能解析,裏面必須用雙引號包起來"" console.log(JSON.parse(c));
let [a,b=10]=[5]; // a=5 b=10 let {x:hh,y:tt=20} = {x:11}; // hh=11 tt=20 // function fn([a,b]) { // console.log(a,b,arguments); // } // fn([5]); function fn({a=10,b=100}) { console.log(a,b,arguments); }; //fn({a:5}); //fn({a,b}); fn({}); // 10 100 //無實參取形參的默認值{x,y},有實參對應實參的默認值{x:10,y:30} function ffn({x,y} = {x:10,y:30}) { console.log(x,y); } ffn(); //10 30 ffn({}); //un un
/* ES6 箭頭函數 () => */ /* 形參 返回值 */ let fn = v => v; //ES5寫法以下 var fn = function (v) { return v; } /* 加法寫法 */ var fn = function (a,b) { return a+b; } let fn = (a,b) => {a+b}; /* 函數內容較多 */ var fn=function (a,b) { let c = a+2; let d = b-3; return(c+d); } let fn = (a,b)=>{ let c = a+2; let d = b-3; return(c+d); } /* 若是返回對象時,須要再加上() */ var fn = function () { return {a:10,b:20}; } let fn = () => ({a:10,b:20}) /* document.onclick = function () { console.log(this); } */ //一般用在回調函數內,方便使用 let arr=[1,2,3]; arr.forEach((value,key)=>{ console.log(value); }); let b = arr.map(v=>v*v); //結果平方返回 console.log(b);
/* setTimeout 一次執行定時器 param1:回調函數,或者是字符串包裹的js腳本,或者是引號包裹的全局做用域內的函數自執行 param2:數字(毫秒單位) */ setTimeout(function () { alert("timeout!"); },1000); let fn = function () { alert(1); return function () { alert(3); } }; setTimeout(fn(),1000); //不能是返回值,第一個參數是函數 let str = "let a=10;alert(a);"; //能夠接收字符串參數,當成JS代碼來讀 setTimeout(str,2000); let fn = function () { // 若是fn不在全局做用域內,則 "fn()"找不到將報錯 alert(4); }; setTimeout("fn()",1500); //默認在全局中執行引號的內容,做用域在全局
/* setInterval 循環定時 */ let num=0; let fn = function () { console.log(++num); } setInterval(fn,1000/60); //最小時間間隔最可能是60次每秒,
主程序執行完以後才執行定時器隊列
//讀到setTimeout時將定時器放入隊列中,主程序執行完以後才執行隊列 //因此先彈出3,後彈出4 setTimeout(function () { //進入隊列後執行 alert(4); },0); !function fn() { //先執行 alert(3); }();
回調函數帶參時,放在定時器第二個參數以後
//定時器的函數有參數時,直接放在第二個參數以後 (function () { function fn(a,b) { console.log(a+b); } //setInterval(fn(2,7),1000); //這樣會直接執行 /* setInterval('fn(2,7)',1000); //雙引號內的內容默認丟在全局中執行,全局中找不到fn,報錯 window.fn = fn; //將局部fn賦值到window */ setInterval(fn,1000,25,14); //參數接着放 })();
/* 返回值是按定時器出現順序從1號開始的編號,做用是用來清除定時器的 編號不區分做用域 */ let x = setTimeout(function(){alert(3);},50000); let y = setTimeout(function(){alert(4);},60000); let z = setTimeout(function(){alert(5);},70000); let w = setInterval(function(){alert(6);},80000); let v = setInterval(function(){alert(7);},90000); console.log(x,y,z,w,v); // 1 2 3 4 5
clearInterval(t)
clearTimeout(t)
let x = setTimeout(function(){console.log("a")},2000); // 1 let y = setTimeout(function(){console.log("b")},2000); // 2 console.log(x,y); clearTimeout(y); //清除編號爲2的定時器 // 定時器的隊列編號跟做用域不要緊,按出現順序編號 (function () { let x = setTimeout(function(){console.log("a")},2000); // 3 let y = setTimeout(function(){console.log("b")},2000); // 4 console.log(x,y); })();
canselAnimationFrame()
/* H5出的新的API requestAnimationFrame() 不須要第二個參數,間隔是瀏覽器的刷新頻率,單次執行 主要是讓動畫很流暢,瀏覽器準備好就刷新 CSS3關於動畫的API底層都是它 取消 canselAnimationFrame() */ let oW = document.getElementById("wrap"); let start=0; function m(){ start += 2; oW.style.left = start+'px'; requestAnimationFrame(m); } requestAnimationFrame(m); // 兼容 window.requestAnimationFrame = window.requestAnimationFrame || function (fn) { setTimeout(fn,1000/60); }; window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
關鍵點: oImg.style.transitionDuration = 0+'s';
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap{ overflow: hidden; position: relative; width:520px; height:280px; margin:50px auto; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #wrap .img{ position: absolute; top:0; left:0; width:1000%; height:100%; transition-property: left; } #wrap .img li{ position: relative; float:left; width:10%; height:100%; } #wrap .tab{ position: absolute; left:0; right:0; bottom:15px; z-index:5; width:80px; margin:auto; background-color: rgba(255,255,255,.3); border-radius: 10px; font-size:0; text-align:center; } #wrap .tab li{ float: left; width:10px; height:10px; margin:3px; border-radius: 10px; background-color: white; cursor:pointer; } #wrap .tab li.active{ background-color: #ff5000; } #wrap>span{ display: none; z-index:5; position: absolute; top:0; bottom: 0; width:30px; height:30px; margin:auto; background-color: rgba(0,0,0,.3); border-radius: 30px; color:#fff; font-size:22px; line-height:30px; cursor: pointer; } #wrap:hover>span{ display: block; } #wrap>span:hover{ background-color: rgba(0,0,0,.5); } #wrap .left{ left:-12px; text-indent: .5em; } #wrap .right{ right:-12px; text-indent: .1em; } </style> </head> <body> <div id="wrap"> <ul class="img"> <li> <img src="img/05.webp"> </li> <li> <img src="img/01.webp"> </li> <li> <img src="img/02.jpg"> </li> <li> <img src="img/03.jpg"> </li> <li> <img src="img/04.png"> </li> <li> <img src="img/05.webp"> </li> <li> <img src="img/01.webp"> </li> </ul> <ul class="tab"> <li class="active"></li> <li></li> <li></li> <li></li> <li></li> </ul> <span class="left"><</span> <span class="right">></span> </div> <script> (function () { //定義變量 let oWrap = document.getElementById("wrap"), aTabLi = document.querySelectorAll("#wrap .tab li"), oImg = document.querySelector("#wrap .img"), aImgLi = document.querySelectorAll("#wrap .img li"), //作不到無縫 oLeft = document.querySelector("#wrap .left"), oRight = document.querySelector("#wrap .right"), len = aImgLi.length-1, lastIndex=1, timer=''; //作一個定時器動畫 window.requestAnimationFrame = window.requestAnimationFrame || function (fn){setTimeout(fn,1000/60);}; window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; oImg.style.left = '-'+lastIndex*100+'%'; //初始是顯示第一個 //封裝動做事件 function move(x) { aTabLi[x].classList.remove("active"); oImg.style.transitionDuration = .3+'s'; //動畫時間 oImg.style.left = '-'+lastIndex*100+'%'; //動畫步驟 if(lastIndex === len){ //到達最後一個了!len = 6 requestAnimationFrame(function () { //偷天換日,改到第一個 lastIndex=1; aTabLi[0].classList.add("active"); }); //座標移動該怎麼不被動畫發現呢,延時吧,等於duration 0.3s setTimeout(function () { oImg.style.left = '-'+lastIndex*100+'%'; oImg.style.transitionDuration = 0+'s'; },300); }else if(lastIndex === 0){ //到達第0個了!len-1 = 5 requestAnimationFrame(function () { //偷天換日,改到第一個 lastIndex=len-1; aTabLi[4].classList.add("active"); }); //座標移動該怎麼不被動畫發現呢,延時吧,等於duration 0.3s setTimeout(function () { oImg.style.left = '-'+lastIndex*100+'%'; oImg.style.transitionDuration = 0+'s'; },300); }else{ aTabLi[lastIndex-1].classList.add("active"); } } //tab點擊事件 [...aTabLi].forEach((oTabLi,index)=>{ oTabLi.onclick = function () { if(index === lastIndex-1)return; let x = lastIndex-1; lastIndex = index+1; move(x); } }); //left點擊事件 , lastIndex = 0 1 2 3 4 oLeft.onclick = function () { let x = lastIndex-1; // [0,4] lastIndex --; move(x); } //right點擊事件 oRight.onclick = function () { let x = lastIndex-1; //x從0開始 lastIndex++; move(x); } //定時器 timer = setInterval(function () { let x = lastIndex-1; //x從0開始 lastIndex++; move(x); },3000); //中止 oWrap.onmouseenter=function () { clearInterval(timer); } //繼續 oWrap.onmouseleave=function () { timer = setInterval(function () { let x = lastIndex-1; //x從0開始 lastIndex++; move(x); },3000); } })(); </script> </body> </html>
/*Date類 new Date() 本地此時此刻的日期對象/時間戳 */ let d = new Date(); //獲取的是對象 console.dir(d); console.log(d.getTime()); // 時間戳 let t = new Date(d.getTime()); console.log(t); //如下API返回數字 number console.log(d.getFullYear()); //獲得 年 console.log(d.getMonth()+1); //獲得 月(從0開始計數,應該+1返回) console.log(d.getDate()); //日 console.log(d.getHours()); //時 console.log(d.getUTCHours()); //0時區 UTC console.log(d.getMinutes()); //分 console.log(d.getSeconds()); //秒 console.log(d.getDay()); //星期 星期日是0 console.log("===================="); console.log(d.toUTCString());
let x = new Date(); //日期對象能夠作減法,會自動調用getTime進行相減 //定時器都不是 精準的計時 setInterval(function () { let y=new Date(); console.log(y-x); x=y; },50); //週期很小,則偏差較大
//無參是獲取,有參是設置 let x=new Date(2018,8-1,8,1,1,1); //月份從0開始的,因此設置8月應輸入7 let x=new Date(2018); //只有一個參數時,會被認爲是毫秒時間戳,從1970年開始加 let x=new Date(2018,5-1); //默認1日,0時0分0秒 console.log(x); let a = new Date().getTime(); console.log(new Date(a-3600000)); //打印一個小時前的時間
<p>404 頁面未找到~~</p> <div><span>8</span>秒後,返回 <a href="">主頁</a></div> <script> (function () { let oS = document.querySelector("div span"); let oVal = 8; setInterval(function () { oS.innerHTML = --oVal; if(oVal === 1){ window.location.href = "http://web.tanzhouedu.com"; } },1000) })(); </script>
(function () { let oW = document.getElementById("wrap"); let x = new Date(2020,2-1,24); //過年時間 function fn(){ let d = x - new Date(); //差了多少秒 let DD = Math.floor(d/1000/60/60/24); //天 let HH = Math.floor(d/1000/60/60%24); let MM = Math.floor(d/1000/60%60); let SS = Math.floor(d/1000%60); if(DD<10) DD = '0'+DD; if(HH<10) HH = '0'+HH; if(MM<10) MM = '0'+MM; if(SS<10) SS = '0'+SS; oW.innerHTML = `距離過年還有 <span>${DD}</span> 天 <span>${HH}</span> 小時 <span>${MM}</span> 分 <span>${SS}</span> 秒;`; }; fn(); setInterval(fn,1000); })();
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ position: absolute; left:0; top:0; width:100px; height:100px; background-color: pink; } </style> </head> <body> <div id="wrap"></div> <script> (function () { let oWrap = document.getElementById("wrap"); let startVal = 0; function m() { startVal +=3; oWrap.style.left = startVal + 'px'; requestAnimationFrame(m); //推薦,保證前一個動畫執行完成後,進入下一次動畫 //setTimeout(m,1000/60); } m(); })(); </script> </body> </html>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap{ width:50px; height:50px; margin-left:300px; /*百分比在IE顯示百分比,要轉成px*/ background-color: pink; opacity: .8; filter:alpha(opacity=80); /*標準IE瀏覽器的兼容,opacity 0-100 */ } </style> <script src="move.js"></script> </head> <body> <div id="wrap"></div> <script src="move.js"></script> <script> var oW = document.getElementById("wrap"); Move(oW,"marginLeft",600,3); Move(oW,"width",500,3); Move(oW,"height",500,3); Move(oW,"opacity",0,.01); //opacity沒有單位 </script> </body> </html>
'use strict'; /* * 運動框架 * param: * ele - object 必須 表示要進行運動的節點 * attr - string 必須 表示要改變的css屬性 * target - number 必須 表示屬性的終點值 * step - number 選填 表示運動速度的正值,默認5 *return: * */ window.Move = function () { //兼容定時器 window.requestAnimationFrame = window.requestAnimationFrame || function (fn) { setTimeout(fn, 1000 / 60); }; window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; //框架函數 return function Move(ele, attr, target) { var step = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5; //ele.style.marginLeft 只能獲取行內樣式 //console.log(getComputedStyle(ele)); //原生JS,存儲着節點對象所有的樣式 //獲取存儲着ele展現樣式的對象 var cssObj = ele.currentStyle || getComputedStyle(ele); //解決兼容性問題IE8用currentStyle //初始的值 var sVal = parseFloat(cssObj[attr]); //去掉單位,變成數字 //兼容IE的opacity if(attr === "opacity" && isNaN(sVal))sVal=1; //考慮初始值與目標值大小的問題 var bool = sVal>target; if(sVal > target){ step = -Math.abs(step); //負值 }else if (sVal < target){ step = Math.abs(step); //正值 }else{ return; } function f() { sVal += step; // + -step if (bool?sVal<=target:sVal>=target) { sVal = target; }else { requestAnimationFrame(f); } if(attr === 'opacity'){ ele.style[attr] = sVal; ele.style.filter = "alpha(opacity="+100*sVal+")"; // IE瀏覽器兼容 }else if(attr === 'zIndex'){ ele.style[attr] = sVal; //不加單位 }else{ ele.style[attr] = sVal + 'px'; //加單位 } } requestAnimationFrame(f); }; }();
/* 元素節點的nodeType是 1 nodeName是 大寫的標籤名 nodeValue=null 元素屬性的nodeType是 2 nodeName是 屬性名 nodeValue=屬性值 文本節點的nodeType是 3 nodeName是 #Text nodeValue=文本內容 註釋節點的nodeType是 8 nodeName是 #comment nodeValue=註釋內容 */ let oW = document.getElementById("wrap"), oC = document.getElementsByClassName("content")[0]; console.dir(oW); console.log(oW.nodeType); //1 元素節點 console.log(oW.nodeName); //DIV console.log(oW.childNodes); //子節點,包含全部節點類型 console.log(oW.attributes[2].nodeType); // 2 // console.log(typeof oC.childNodes[0].nodeValue); oW.attributes[2].nodeValue = '朱雀'; //不建議這樣修改,應該座標是不肯定的 console.log(oW.attributes[2]); // afei='朱雀'
<div id="wrap"> 阿飛飛 <p>gg</p> <p>ss</p> <a href="">gg</a> </div> <script> let oW = document.getElementById("wrap"); console.log(oW.childNodes); //IE不兼容,谷歌連換行也能獲取,不實用 //經常使用 !!!!!! console.log(oW.children); //只獲取子元素節點哦 ,有三個子元素(標籤) //innerHTML是刷新整個內容,要求必須刷新後再get元素,這樣很不方便 </script>
<div id="wrap"> 阿飛飛 <p>pp</p> <p id="on">gg</p> <a href="#">123</a> </div> <script> let oW = document.getElementById("wrap"); let oN = document.getElementById("on"); let oP = document.querySelector("p"); oP.onclick = function(){ //節點的變化不影響其操做和屬性 alert(5); } //建立文本節點對象 let text = document.createTextNode("朱雀"); //console.dir(text); //建立元素節點對象 let oDiv = document.createElement("div"); //從後面添加子節點 appendChild oW.appendChild(text); //oW.appendChild(oDiv); //在某個子元素的前面添加 (a,b) a是新元素節點 //oW.insertBefore(oDiv,oP); //放在子元素第一位 oW.insertBefore(oDiv,oW.children[0]); //oW.childNodes[0] 全部的第一位 </script>
<div id="wrap"> <p>阿飛</p> <p>朱雀</p> </div> <div id="box"></div> <script> let oBox = document.getElementById("box"); let aP = document.getElementsByTagName("p"); //轉移子元素,原來元素的屬性和方法不會改變 oBox.appendChild(aP[0]); </script>
<div id="wrap"> <p>555</p> <p>666</p> </div> <div class="box"></div> <script> //只有父級節點才能刪除子節點 let oW = document.getElementById("wrap"); let oBox = document.getElementsByClassName("box")[0]; let oP = document.getElementsByTagName("p")[1]; //父級刪除了子節點,但變量oP 仍保留了被刪除的節點 oW.removeChild(oP); document.onclick = function () { oBox.appendChild(oP); //oP仍可使用 } </script>
<div id="wrap"> <p>11</p> <p>22</p> <p>33</p> </div> <script> let oW = document.getElementById("wrap"); console.log(oW.firstChild); //第一個子節點,文本節點->換行符 console.log(oW.firstElementChild); //第一個元素子節點, <p>11</p> console.log(oW.children[0]); //第一個元素子節點, <p>11</p> var aChild = oW.children; //是動態的更新,根據兒子變化而變化, var p1 = aChild[0]; //元素節點 var p2 = aChild[1]; var p3 = aChild[2]; console.log(p1.nextSibling); //下一個兄弟節點(文本換行符) //標準瀏覽器 console.log(p1.nextElementSibling); //下一個兄弟元素(若是沒有,打印null) console.log(p2.nextElementSibling); // console.log(p3.nextElementSibling); //沒有返回null //上一個兄弟節點 previousElementSibling console.log(p2.previousElementSibling); //IE兼容,只有nextSibing,下一個兄弟元素節點 function getNextSibing(ele) { if(ele.nextElementSibling !== undefined){ return ele.nextElementSibling; }else{ return ele.nextSibling; //IE的 } } console.log(getNextSibing(p1)); console.log(getNextSibing(p2)); console.log(getNextSibing(p3)); </script>
<head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ position: relative; } </style> </head> <body> <div id="wrap"> <p id="btn">4545454</p> </div> <script> let oBtn = document.getElementById("btn"), oW = document.getElementById("wrap"); console.log(oBtn.parentNode); // === oW typeof oW = "object" console.log(oW.parentNode); // body //自刪除 //oBtn.parentNode.removeChild(oBtn); console.log(oBtn.offsetParent); //定位父級 oW </script> </body>
節點的事件不被克隆
<div id="wrap"> <p class="gg">745545</p> </div> <div id="btn">444</div> <script> //節點具備惟一性,只有clone能夠 默認不復制裏面的內容,參數爲true內容也克隆, 事件不能複製 let oP = document.getElementsByClassName("gg")[0], oBtn = document.getElementById("btn"); oP.onclick =function () {alert(1);}; //事件不能clone //oBtn.appendChild(oP); 直接appendChild是移動節點,並未增長 let clone = oP.cloneNode(true); //克隆得到一個新的節點對象 oBtn.appendChild(clone); </script>
<div id="wrap"> 123 </div> <div id="btn">456</div> <script> let oW = document.getElementById("wrap"), oB = document.getElementById("btn"); oW.replaceChild(oB,oW.childNodes[0]); </script>
(function () { let oW = document.getElementById("wrap"); //生成10個小球 (function () { //節點片斷,暫時存放節點的對象 let oF = document.createDocumentFragment(); //生成十個小球,一次性append進oW內,省的渲染屢次 for(let i=0;i<10;i++){ let oP = document.createElement("p"); oF.appendChild(oP); } oW.appendChild(oF); })(); //運動 (function () { let aP = [...oW.children]; let MaxL,MaxT; window.onresize = (function r(){ MaxL = window.innerWidth - 100; MaxT = window.innerHeight - 100; return r; })(); //隨機初始速度 let speedArr = []; aP.forEach((ele,index)=>{ speedArr[index] = { stepX : Math.floor(Math.random()*12+4), stepY : Math.floor(Math.random()*12+4) }; }); //隨機顏色 function changeColor(ele) { let [r,g,b] = [ Math.floor(Math.random()*256), Math.floor(Math.random()*256), Math.floor(Math.random()*256) ]; ele.style.backgroundImage = `radial-gradient(white,rgb(${r},${g},${b}))`; } //遍歷運動 !function m(){ aP.forEach((ele,index)=>{ let left = ele.offsetLeft + speedArr[index].stepX; let top = ele.offsetTop + speedArr[index].stepY; if(left >= MaxL){ left = MaxL; speedArr[index].stepX = -speedArr[index].stepX; changeColor(ele); } if(left <=0){ left = 0; speedArr[index].stepX = -speedArr[index].stepX; changeColor(ele); } if(top>=MaxT){ top = MaxT; speedArr[index].stepY = - speedArr[index].stepY; changeColor(ele); } if(top<=0){ top = 0; speedArr[index].stepY = - speedArr[index].stepY; changeColor(ele); } ele.style.left = left+'px'; ele.style.top = top + 'px'; }); requestAnimationFrame(m); }(); })(); })();
window.innerWidth
document.documentElement.clientWidth
<div id="wrap"></div> <script> /* Window視圖屬性 獲取頁面顯示區的寬高,IE8及如下不兼容 */ console.log(window.innerWidth); console.log(window.innerHeight); document.body; document.head; document.title; document.documentElement; //獲取html元素節點 console.log(document.documentElement === document.querySelector("html")); // true //Document文檔視圖 下面的IE兼容 console.log(document.documentElement.clientWidth); //html頁面寬度 console.log(document.documentElement.clientHeight); //html頁面高度 </script>
/* number類型 clientHeight/clientWidth width+padding offsetHeight/offsetWidth width + padding + border scrollHeight/scrollWidth 滾動寬度,超出視圖仍顯示正常寬度,無論有沒有超出隱藏 */ let oWrap = document.getElementById("wrap"); console.log(getComputedStyle(oWrap).width); //獲取元素css樣式設置的寬度,有單位 console.log(oWrap.clientWidth); //width + padding console.log(oWrap.offsetWidth); //width + padding + border //scrollWidth 元素佔用的寬度,生成滾動條,內容不超出時數值等於clientWidth console.log(oWrap.scrollWidth); //若是有超出部分,正確的反映出超過以後的寬度,無論有沒有加超出隱藏
只有距離定位父級的左值和上值 ,沒有右下
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ /*position: relative;*/ margin:50px; } p{ width:10px; height:10px; background-color: pink; } </style> </head> <body> <div id="wrap"> 8888 <p></p> </div> <script> /* 只有距離定位父級的左值和上值 */ let oP = document.querySelector("#wrap p"); //wrap沒加position,則定位父級是body console.log(oP.offsetLeft); //到定位父級的距離 console.log(oP.offsetTop); //到定位父級的距離 //獲取元素到文檔body的距離 function getOffset(ele) { let dis = { top:0,left:0 }; while(ele !== document.body){ dis.top += ele.offsetTop; dis.left += ele.offsetLeft; ele = ele.offsetParent; //定位父級 } return dis; } console.log(getOffset(oP)); </script> </body> </html>
<body style="height:2000px;"> <div id="wrap"></div> <script> document.onclick = function () { //頁面滾動高 console.log(document.documentElement.scrollTop); //document.body.scrollTop 谷歌棄用了,可是手機可能還未改 //最好這樣寫去獲取頁面的滾動高 console.log(document.body.scrollTop || document.documentElement.scrollTop); //保險起見 } </script> </body>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ overflow-y:auto ; /*y豎直方向有滾動條*/ width:300px; height:500px; background-color: pink; margin:50px auto; } #wrap p{ height:2000px; } </style> </head> <body> <div id="wrap"> <p></p> </div> <script> let oW = document.getElementById("wrap"); oW.onclick = function(){ console.log(oW.scrollTop); //oW元素豎直方向的滾動高度 } </script> </body> </html>
<body style="height: 2000px"> <div id="wrap"></div> <script> document.onclick = function () { document.documentElement.scrollTop = 500; } </script> </body>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ /*position: relative;*/ margin:50px; } p{ width:10px; height:10px; background-color: pink; } </style> </head> <body> <div id="wrap"> 8888 <p></p> </div> <script> let oP = document.querySelector("#wrap p"); console.log(oP.getBoundingClientRect()); // DOMRect {x: 50, y: 71, width: 10, height: 10, top: 71, bottom:81, left:50, right:60} //top bottom left right 對應 邊 到 body的距離 // x y是座標 </script> </body> </html>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ position: absolute; top:1500px; width:100px; height:100px; background-color: pink; } </style> </head> <body style="height: 3000px;"> <div id="wrap"></div> <script> let oW = document.getElementById("wrap"); document.onclick = function () { //oW.scrollIntoView(false); //true是跳轉到視圖頂部,false跳轉到視野底部 oW.scrollIntoView(true); } </script> </body> </html>
/* event事件對象 事件函數執行時,第一個形參就是事件對象:存儲着和該次事件相關的一些信息 IE8及如下瀏覽器,使用event全局變量來表示事件對象 該對象裏面比較重要的一些屬性 clientX/clientY 事件觸發時,鼠標距離可視區的距離 pageX/pageY 鼠標距離文檔的位置(IE8 不兼容) */ //IE的事件函數沒有形參 //兼容 document.onclick = function (ev) { ev = ev || window.event; // IE的Event是全局變量 console.log(ev); }
document.onmousedown = function () { console.log("down"); document.onmousemove = function () { console.log("move"); } } document.onmouseup = function () { console.log("up"); document.onmousemove = null; //默認屬性是null }
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> #wrap{ position: absolute; left: 0; top:0; width:100px; height:100px; background-color: pink; } </style> </head> <body> <div id="wrap"></div> <script> let oW = document.getElementById("wrap"); oW.onmousedown = function (ev) { //獲取鼠標初始的位置 let sX = ev.clientX; let sY = ev.clientY; //獲取按下時,盒子的位置 let sLeft = oW.offsetLeft; let sTop = oW.offsetTop; document.onmousemove = function (eve) { //獲取鼠標當前的位置 let mX = eve.clientX; let mY = eve.clientY; //計算鼠標位置的變化量 let x = mX - sX; let y = mY - sY; //盒子當前的位置 = 盒子按下的位置 + 變化量 oW.style.left = sLeft + x + 'px'; oW.style.top = sTop + y + 'px'; }; }; document.onmouseup = function () { console.log("up"); this.onmousemove = null; } </script> </body> </html>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} div.box{ position: absolute; left:0; top:0; width:100px; height:100px; background-color: #db3a45; border-radius: 50%; } </style> </head> <body> <div id="wrap"> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> <script> (function () { let aBox = [...document.getElementsByClassName("box")]; //最大邊距 let MaxLeft,MaxTop ; window.onresize = (function s() { MaxLeft = window.innerWidth-100; MaxTop = window.innerHeight-100; return s; })(); //步長 let step = [ { stepX:3, stepY:4, }, { stepX:5, stepY:6, }, { stepX:6, stepY:7, }, { stepX:7, stepY:8, }, { stepX:8, stepY:9, }, { stepX:9, stepY:10, }, { stepX:10, stepY:11, }, { stepX:11, stepY:12, }, { stepX:12, stepY:13, }, { stepX:13, stepY:14, }, ]; aBox.forEach((ele,index)=>{ ball(ele,index); }); //rgb函數 function color() { let r = Math.floor(Math.random()*256), g = Math.floor(Math.random()*256), b = Math.floor(Math.random()*256); return `rgb(${r},${g},${b})`; } //小球運動函數 function ball(ele,index) { //初始位置 let left = ele.offsetLeft, top = ele.offsetTop; !function m() { //步長 left += step[index].stepX; top += step[index].stepY; //left if(left>=MaxLeft){ left=MaxLeft; ele.style.backgroundColor = color(); step[index].stepX = -step[index].stepX; } if(left<=0){ left=0; ele.style.backgroundColor = color(); step[index].stepX = -step[index].stepX; } //top if(top>=MaxTop){ top = MaxTop; ele.style.backgroundColor = color(); step[index].stepY = -step[index].stepY; } if(top<0){ top = 0; ele.style.backgroundColor = color(); step[index].stepY = -step[index].stepY; } ele.style.left = left+'px'; ele.style.top = top+'px'; requestAnimationFrame(m); }(); } })(); </script> </body> </html>
冒泡觸發順序:從子元素開始到窗口
<div id="box"> box1 <div id="box1"> box2 </div> </div> <script> /* 事件的冒泡 子元素觸發了事件 若是父元素也有同類型的事件的話,父元素也會觸發 觸發的順序是從子級開始,向父級方向 冒泡的觸發順序 box2 -> box1 -> body -> html 冒泡觸發順序 從子元素開始到窗口,(從兒子到爸爸)window 阻止冒泡 event.stopPropagation() 阻止傳播 IE不兼容 box2 box1 */ var box = document.getElementById("box"), box1 = document.getElementById("box1"); document.onclick = function(){ console.log("我也觸發了事件"); } box.onclick = function () { console.log(1); } box1.onclick = function (event) { event = event ||window.event; //event.stopPropagation(); //冒泡中止(主流瀏覽器) console.log(2); //ie阻止冒泡的 屬性 //event.cancelBubble = true; //兼容性寫法 event.stopPropagation ? event.stopPropagation():event.cancelBubble=true; } </script>
捕獲與冒泡順序相反
var oW = document.getElementById("wrap"); //DOM 0級事件, 相同名字的事件被覆蓋,只能監聽一個事件 oW.onclick = function () { console.log(1); //被覆蓋 }; oW.onclick = function () { console.log(2); }; /* 事件監聽(默認事件冒泡) 用到事件的地方最好就是使用 DOM2級來監聽 監聽事件 主流瀏覽器 事件類型 "click" ele.addEventListener(事件類型,回調方法,捕獲|冒泡) 1.this指向節點自己 2.捕獲與冒泡 默認是false 冒泡事件 true爲捕獲,與冒泡的順序相反,從最大父級到子級開始(也能使用阻止冒泡的方式) ie瀏覽 ie8 事件類型 "onclick" oW.attachEvent(事件類型,回調方法) 1.this再也不指向節點自己,指向window ie8沒有事件捕獲,默認是冒泡事件 移除事件 主流瀏覽器 ele.removeEventListener(事件類型,回調方法,捕獲|冒泡); IE8 ele.detachEvent(事件類型,回調方法); */ //事件監聽DOM 2級事件 //IE8 oW.attachEvent("onclick",function (e) { e = e||window.event; console.log(this); //this 再也不指向監聽事件的節點自己 console.log(e); }); /* 主流瀏覽器 */ oW.addEventListener("click",function () { console.log("我又監聽了一次點擊事件,理解一下DOM 2級事件"); }) var callback = function () { console.log(1); }; oW.addEventListener("click",callback); //文檔雙擊,註銷事件 //該事件必須事先用變量保存,removeEventListener的參數必須與添加事件監聽的參數同樣,才能移除 document.ondblclick = function () { oW.removeEventListener('click',callback); }
<div id="wrap"> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> <p>默認行爲</p> </div> <script> //事件的默認行爲是右邊鼠標顯示的可選事件 oncontextmenu /* 阻止默認行爲 DOM 0級在事件裏面直接 return false, DOM 2級 主流瀏覽器 event.preventDefault(); ie event.returnValue = false; */ //DOM 0級在事件裏面直接 return false, document.oncontextmenu = function () { return false; } //DOM 2級 preventDefault document.addEventListener('contextmenu',function (e) { e.preventDefault(); }) //IE8 document.attachEvent('oncontextmenu',function (e) { e = e||window.event; e.returnValue = false; }) //阻止默認的滾輪事件 wrap.addEventListener('mousewheel',function (e) { e.preventDefault(); }) </script>
let oW = document.getElementById("wrap"); /* 谷歌以及ie event.wheelDelta 滾動的幅度 -120 下滾 120 上滾 火狐的 滾動事件名都不同 DOMMouseScroll 只能經過DOM 二級事件監聽 event.detail 滾動的幅度 3 下滾 -3 上滾 只有谷歌和ie有onmousewheel事件屬性,默認值爲null 火狐根本就沒有onmousewheel屬性,爲undefined */ /* oW.addEventListener("mousewheel",function (e) { console.log(e.wheelDelta); }) */ //只能經過建立一個新的節點來判斷兼容 if(document.createElement("div").onmousewheel === null){ console.log("谷歌"); }else{ console.log("火狐"); }
var oW = document.getElementById("wrap"); //元素的事件 var fn = addEvent(oW,'click',function () { this.style.backgroundColor = 'red'; }); //文檔雙擊移除事件 addEvent(document,"dblclick",function () { removeEvent(oW,'click',fn); }) //滾輪事件 addEvent(oW,'mousewheel',function () { console.log('我滾動了'); }) //添加監聽事件 function addEvent(ele,eType,callback,capture) { //主流瀏覽器 if(ele.addEventListener){ //兼容一下火狐的滾輪事件 if(eType === 'mousewheel' && document.createElement("div").onmousewheel === undefined){ eType = 'DOMMouseScroll'; } ele.addEventListener(eType,callback,capture); return callback; }else{ //處理ie的this指向,ie低版本不支持bind var codeCall = function(){ callback.call(ele); } ele.attachEvent('on'+eType,codeCall); return codeCall; } } //移除事件 function removeEvent(ele,eType,callback,capture) { ele.removeEventListener? ele.removeEventListener(eType,callback,capture) : ele.detachEvent("on"+eType,callback); }
//自定義滾動 addEvent(oW,'mousewheel',function (event) { event = event || window.event; var dir; if(event.detail){ //火狐的滾動值 dir = event.detail / 3; //下滾 }else{ dir = event.wheelDelta / -120; //下滾 } //console.log(dir); this.scrollTop += dir*50; })
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> #wrap{ position: relative; width:400px; height:500px; margin:20px auto; overflow: hidden; user-select: none; } #wrap .content{ position: absolute; left:0; top:0; width:370px; font-size:14px; } #wrap .content li{ width:100%; padding:5px 0 5px 10px; margin-bottom:1px; background-color:#eeeef0; line-height:30px; } #wrap .scrollbar{ position: absolute; right:0; top:0; width:20px; height:496px; background-color: #ccc; background-color:rgba(200,200,200,.5); border-radius: 10px; border:2px solid #aaa; box-shadow: 0 0 20px #ccc ; } #wrap .scrollbar .bar{ position: absolute; left:0; top:0; width:20px; height:80px; background-color: white; border-radius:10px; } </style> </head> <body> <div id="wrap"> <ul class="content"> <li> <p>1. It is never too old to learn.</p> <p>活到老,學到老。</p> </li> <li> <p>2. There is no royal road to learning.</p> <p>學問無坦途。書山有路勤爲徑,學海無涯苦做舟.</p> </li> <li> <p>3. A man becomes learned by asking questions.</p> <p>不恥下問纔能有學問。</p> </li> <li> <p>4. A young idler, an old beggar.</p> <p>少壯不努力,老大徒傷悲。</p> </li> <li> <p>5. Study to be what you wish to seem. </p> <p>學習可成爲你所理想的人物。</p> </li> <li> <p>6. By reading we enrich the mind, by conversation we polish it.</p> <p>讀書令人充實,交談令人精明。</p> </li> <li> <p>7. Books and friends should be few but good.</p> <p>讀書如交友,應求少而精。</p> </li> <li> <p>8. Readingis to the mind while exercise to the body.</p> <p>讀書健腦,運動強身。</p> </li> <li> <p>9. A good beginning makes a good ending.</p> <p>良好的開端就是成功的一半。 善始者善終。</p> </li> <li> <p>10. No matter how bad your heart has been broken, the world doesn’t stop for your grief. The sun comes right back up the next day.</p> <p>無論你有多痛苦,這個世界都不會爲你中止轉動。太陽照樣升起。</p> </li> <li> <p>11. Experience is the mother of wisdom.</p> <p>實踐出真知。</p> </li> <li> <p>12. Don't trouble trouble until trouble troubles you.</p> <p>不要自尋煩惱。</p> </li> <li> <p>13. Everybody dies, but not everybody lives.</p> <p>人人都會死,但非人人都曾活過。</p> </li> <li> <p>14. Doing is better than saying.</p> <p>行勝於言。</p> </li> <li> <p>15. Commitment in many, can do. It is just a lie.</p> <p>承諾再多,都作不到。那也只不是是謊話。</p> </li> <li> <p>16. No cross, no crown.</p> <p>不經歷風雨,怎能見彩虹。</p> </li> </ul> <div class="scrollbar"> <div class="bar"></div> </div> </div> <script> (function () { var oW = document.getElementById("wrap"), oContent = document.querySelector("#wrap .content"), oScroll = document.querySelector("#wrap .scrollbar"), oBar = document.querySelector("#wrap .bar"), docMove= function () {}; //內容區的滾動事件 createEvent(oW,"mousewheel",function (event) { event = event||window.event; //兼容IE var sT = oContent.offsetTop; var dir = 0; var top = 0; if(event.detail){ //火狐 dir = event.detail / 3; //下滑 }else{ //谷歌和IE dir = event.wheelDelta / -120; //下滑值 } if(dir>0){ top = Math.max((sT-dir*50),-756); }else{ top = Math.min((sT-dir*50),0) } oContent.style.top = top + 'px'; oBar.style.top = -top/1.82 + 'px'; event.stopPropagation ? event.stopPropagation():(event.cancelBubble=true); },false); //自定義滾輪區的點擊事件 createEvent(oScroll,'click',function (event) { event = event||window.event; var y_ = event.clientY - oBar.offsetHeight/2 - oW.offsetTop; if(y_<=0) y_=0; if(y_>=416)y_=416; oBar.style.top = y_+'px'; oContent.style.top = -y_*1.82 + 'px'; //阻止子級冒泡 event.stopPropagation ? event.stopPropagation():(event.cancelBubble=true); },true); //自定義滾輪的滾動(點擊時拖放) createEvent(oBar,'mousedown',function (event) { event = event||window.event; var sT = oBar.offsetTop; var sY = event.clientY; var top = 0; docMove = createEvent(document,'mousemove',function (event) { event = event||window.event; var _Y = event.clientY - sY; if(_Y>0) top = Math.min((sT+_Y),416); if(_Y<0) top = Math.max((sT+_Y),0); oBar.style.top = top+'px'; oContent.style.top = -top*1.82 + 'px'; }) }) //清除移動事件 createEvent(document,'mouseup',function (){ removeEvent(document,'mousemove',docMove); }); //雙擊清除移動事件 createEvent(document,"dblclick",function () { removeEvent(document,'mousemove',docMove); }); //生成監聽事件 function createEvent(ele,eType,callback,capture) { if(ele.addEventListener){ //主流 //兼容火狐的滾動事件 if(eType === 'mousewheel' && document.createElement("div").onmousewheel === undefined){ eType = "DOMMouseScroll"; } //生成監聽 ele.addEventListener(eType,callback,capture); return callback; }else{ //IE8 var codeCall = function(){ callback.call(ele); } ele.attachEvent('on'+eType,codeCall); return codeCall; } } //清除事件 function removeEvent(ele,eType,callback,capture) { if(ele.removeEventListener){ //兼容火狐的滾動事件 if(eType === 'mousewheel' && document.createElement("div").onmousewheel === undefined){ eType = "DOMMouseScroll"; } ele.removeEventListener(eType,callback,capture); }else{ ele.detachEvent("on"+eType,callback); } } })(); </script> </body> </html>
<div id="wrap"></div> <a href="" id="x">455454</a> <form action="" method="" id="form"> <input type="text" name="user"> <input type="radio" name="sex"> <input type="radio" name="sex"> <input type="submit"> </form> <script> //表單是 .name 就能直接獲取對象 // name相同,獲取的是相同name的數組 // checkbox多選框,name不要同樣 let oForm = document.getElementById("form"); console.log(oForm.sex); // RadioNodeList(2) [input, input, value: ""] oForm.user.value = "阿飛飛"; /* onfocus 焦點事件 onblur 失去焦點事件 並非全部的元素都能添加焦點事件,只有能得到焦點的元素才能添加焦點事件 頁面tab鍵能得到焦點的元素(document,a,window,以及表單相關的元素能夠) */ let ox = document.getElementById("x"); x.onfocus = function () { // TAB鍵觸發 console.log("我得到焦點了"); } x.onblur = function () { console.log("嚶嚶,我失去焦點了"); } //window的焦點事件 window.onfocus = function () { document.title = "烏龍閣的博客"; } window.onblur = function () { document.title = "握草,出BUG!快來看看啊"; }
/* 頁面失去焦點時,定時器setTimeout速度降低,可能影響佈局渲染 requestAnimationFrame會當即中止 */ let num=0; let timer = null; function m(){ document.title = ++num; timer = setTimeout(m,50); //requestAnimationFrame(m); }; m(); window.onblur = function () { clearTimeout(timer); } window.onfocus = function () { clearTimeout(timer); m(); }
<form action="" method="" id="form"> <input type="text" name="user"> <input type="radio" name="sex"> <input type="radio" name="sex"> <input type="submit"> <select name="gg" id="h"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> </form> <div id="wrap"> 文字文字文字文字文字文字文字文字 </div> <script> /* 輸入框的onchange,判斷獲取焦點時與失去焦點時的差別 oninput 響應實時變化事件 */ let oForm = document.getElementById("form"); /* oForm.user.onchange = function () { console.log(1); } */ /* oForm.user.oninput= function () { console.log(1); } */ oForm.gg.onchange=function () { console.log("選項發生了改變",oForm.gg.value); } //onselectstart 選中文字時,觸發事件 document.getElementById("wrap").onselectstart = function () { console.log(2); return false; //阻止默認操做 } //表單的提交事件,提交後跳轉一個頁面 oForm.onsubmit = function () { console.log("提交"); return false; //拒絕提交(用於判斷是否知足提交條件) } </script>
<form action="" method="" id="form"> <input type="text" name="user"> <input type="text" name="user1"> <input type="text" name="user2"> </form> <button id="btn"> 按鈕 </button> <script> let oForm = document.getElementById("form"); let oBtn = document.getElementById("btn") /* API focus() 加焦點 blur() 失去焦點 submit() 提交api */ let aInp = [...oForm.children]; //動態的 aInp.forEach((ele,index)=>{ ele.oninput = function () { if(this.value.length >= 5){ //大於5個離開 this.disabled = true; aInp[index+1] && aInp[index+1].focus(); //存在則轉移到下一個焦點 } }; ele.onblur = function () { if(this.value.length<5){ //不滿5個不能離開 this.focus(); } } })
//等待所有加載完畢 window.onload = function () { } //只須要結構加載完畢便可 window.onready = function () { }
/* 按鍵按下: keydown keypress keydown 在 keypress以前觸發 down響應全部按鍵 press事件只響應能鍵入值的按鍵,enter也能響應,不響應功能鍵(退格,上下左右) 按鍵擡起: keyup 按鍵擡起時響應 */ document.onkeydown = function () { console.log("處於按下去狀態ing"); } document.onkeypress = function(){ console.log("press"); } document.onkeyup = function () { console.log("按鍵擡起了!"); }
/* 事件event只包含鍵盤的屬性,沒有鼠標的信息 e.keyCode */ document.onkeydown = function (e) { console.log(e); console.dir(e.keyCode); if(e.keyCode === 123){ // 123 阻止按鍵 F12 打開調試面板 return false; } }
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap{ position: absolute; left:200px; top:200px; width:100px; height:100px; background-color: pink; } </style> </head> <body> <div id="wrap"></div> <script> let oW = document.getElementById("wrap"); document.onkeydown = function (ev) { let keyCode = ev.keyCode; switch (keyCode) { case 65: //a oW.style.left = oW.offsetLeft-5+'px'; break; case 87: //w oW.style.top = oW.offsetTop-5+'px'; break; case 83: //s oW.style.top = oW.offsetTop+5+'px'; break; case 68: //d oW.style.left = oW.offsetLeft+5+'px'; break; } }; //運動 </script> </body> </html>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap{ position: absolute; left:200px; top:200px; width:100px; height:100px; background-color: pink; } </style> </head> <body> <div id="wrap"></div> <script> let oW = document.getElementById("wrap"); let ifDown = { 65:{ bool:false, timer:null, setTimer(){ oW.style.left = oW.offsetLeft-5+'px'; this.timer = requestAnimationFrame(this.setTimer.bind(this)); }, clearTimer(){ cancelAnimationFrame(this.timer); } }, 87:{ bool:false, timer:null, setTimer(){ oW.style.top = oW.offsetTop-5+'px'; this.timer = requestAnimationFrame(this.setTimer.bind(this)); }, clearTimer(){ cancelAnimationFrame(this.timer); } }, 83:{ bool:false, timer:null, setTimer(){ oW.style.top = oW.offsetTop+5+'px'; this.timer = requestAnimationFrame(this.setTimer.bind(this)); }, clearTimer(){ cancelAnimationFrame(this.timer); } }, 68:{ bool:false, timer:null, setTimer(){ oW.style.left = oW.offsetLeft+5+'px'; this.timer = requestAnimationFrame(this.setTimer.bind(this)); }, clearTimer(){ cancelAnimationFrame(this.timer); } } } //按下啓動定時 document.onkeydown = function (ev) { let keyCode = ev.keyCode; if(!ifDown[keyCode]) return; ifDown[keyCode].bool || ifDown[keyCode].setTimer(); ifDown[keyCode].bool = true; }; //擡起清除定時 document.onkeyup = function (ev) { let keyCode = ev.keyCode; if(!ifDown[keyCode]) return; ifDown[keyCode].clearTimer(); ifDown[keyCode].bool = false; } </script> </body> </html>
不用正則時,通常用 !isNaN(121)=true 來提取數字
/* 正則表達式 對象 配合一些api來驗證字符串 */ let a="456阿飛789朱雀12"; //["456","789,"12"] let b="454sjjdsiaodao5454"; let c="sds45sd45s21a"; console.log(fn(a)); console.log(fn(b)); console.log(fn(c)); console.log("*************************"); console.log(zz(a)); console.log(zz(b)); console.log(zz(c)); function zz(str) { return str.match(/\d+/g); } function fn(str) { let len = str.length; let s =""; let arr = []; for(let i=0;i<len;i++){ let n=str.charAt(i); if(!isNaN(n)){ //數字字符不是NaN,其餘字符是NaN //console.log(n); s+=n; }else{ //NaN s && arr.push(s); s=""; } } s && arr.push(s); return arr; }
建立正則表達式對象的兩種方法
驗證正則的方法
/* 正則表達式對象 兩種建立方式 1. 雙斜槓包括的字符 2. new RegExp("") */ let a = /abc/; console.log(typeof a); //object let b = new RegExp("abc"); //和第一種建立的效果同樣 /*api1 test() 正則.test(字符串) 匹配成功返回true,不然返回false */ let a = /abc/; //匹配完整連續的abc字符串 console.log(a.test("阿飛abc朱雀"));; /* / /不能傳變量 */ let s = "abc"; //let a=/s/; //這種定義方式,是沒有辦法根據變量來制定正則的 let a = new RegExp(s); //能夠用變量 console.log(a.test("阿飛abc朱雀"));
字符串中實現轉義 "\\" 打印 "\"
/* \轉義符號,默認在字符串中的\有特殊意義,不能單獨出現 */ console.log("阿飛\"love\"朱雀\n123456\t789021"); //轉義符號將有特殊意義的字符變成沒有特殊意義 let str = "/\\"; let a=/\/\\/; //用轉義字符"\"轉義"/"和"\" console.log(a.test(str)); /* 轉義符號配合一些字母使用,有很是獨特的意思 \s 各類空格, \t \n \r " " \S 非空格,\s的補集 \d 數字 \D \d的補集 \w 數字、字母、下劃線 通常匹配用戶名的 \W \b 連詞符 起始 結束 (空格 以及 (除了\w以外) 全部內容都是獨立部分) \B */ let a = /\s/; let s = " "; let a=/\d\d/; //連續兩個數字 let s="fffff79pppp"; let a = /\w/; let s = "abc"; /* 算做"afei"獨立的字符 "I am afei-1" "I am afei阿飛" "I am afei.abc" \b只能用於匹配英文,中文自己就不獨立,不能使用\b獨立匹配 */ let a = /\bafei\b/; //要匹配獨立的部分 let s = "I am afei.abc"; //能夠 "afeihui"就不行 console.log(a.test(s));
驗證正則的方法 match
/* 修飾符(寫在//後面 i 不區分大小寫 g 全局匹配 m 換行匹配 */ let a = /g/i; let s = "G"; console.log(a.test(s)); /* .match() 字符串.match(正則) 尋找匹配的內容,拿到並組成一個數組返回,不然返回null */ let a = /xx/ig; let s = "XxgfxxhxXx"; //xXx只能識別前兩個 console.log(s.match(a)); //加了g後是純粹的數組,沒有別的屬性
/* 量詞 { } {n} n個 {n,m} n~m包含n也包含m {n,} n~無窮大 包含n 默認按多的取(貪婪模式) 量詞後面加問號"?"就成了(惰性模式) 幾個特殊量詞有專屬的符號代替 {1,} + 至少一個 {0,} * 至少0個 {0,1} ? 要麼有要麼沒有 */ let a = /\d\d\d\d\d\d\d\d\d\d\d/g; let s = "阿飛18860900316阿飛"; let a = /飛\d{11}/g; //{11}只表示\d重複11次 let s = "阿飛18860900316阿飛15357875321"; let a = /\d{2,4}?/g; // 惰性匹配,因此只匹配2個的 let s = "1-23-234-456阿飛18860900316阿飛15357875321"; // ["23", "23", "45", "18", "86", "09", "00", "31", "15", "35", "78", "75", "32"] let a = /\d{2,}/g; //至少2個 let s = "1-23-234-456阿飛18860900316阿飛15357875321"; // ["23", "234", "456", "18860900316", "15357875321"] //let a = /\d+/g; //最少一個取 //let a = /\d+?/g; //匹配到後,一個個取 //let a = /\d*?/g; //返回的全是空 至關於 //g let a = /\d??/g; //全是空 let s = "gh777scsf45dsdsd454s35"; console.log(s.match(a));
加了括號的成爲子項,使用全局g,則不打印子項
獲取第一個子項 s.match(a)[1]
匹配失敗,返回null
/* 子項 ( ) */ let a = /(ab)+/; // 不加括號,只能匹配abbbb let s = "abababab"; // ["abababab", "ab", index: 0, input: "abababab", groups: undefined] let a = /gg(ab)+f(f)/; //加了括號的子項也會打印出來,使用全局g,則不打印子項 let s = "ababggababffababa"; //不加g,打印子項["ggababff", "ab", "f", index: 4, input: "ababggababffababa", groups: undefined] //利用子項,只獲取子項中的號碼 let a = /阿飛:(\d{11})/; let s = "阿飛:12121212321,朱雀:32321232123"; console.log(s.match(a),s.match(a)[1]); // ["阿飛:12121212321", "12121212321", index: 0, input: "阿飛:12121212321,朱雀:32321232123", groups: undefined] "12121212321"
/* | 或者 [] 字符集,一個字符集只匹配一個字符 [a-z] 字符區間("-"在"[]"內有了特殊意義) [abc] 或者的意思 [^abc] 放在正則字符的首位,表示除了這些,(不放在首位表示一個單純的字符) [{}?*.+()] 這些原來有特殊意義的字符放在[]內沒有了特殊意義,就是單純的字符 [a-z] [A-Z]全部的字母 */ let a = /abc|edf/g; //或者匹配 let s = "edfabcedfabc"; let a = /(阿飛|朱雀)老師/g; //用子級匹配,加外面公用的 let s = "朱雀老師美,阿飛老師帥"; let a = /1|2|3|4|5|6|7/g; //1或者7中的任何一個 let a = /[1-7]{5}/g; //區間,表明1到7之間任何一個連續5個 //ascii碼的匹配,注意要有先後順序 let a = /[2-B]/g; let s = "23456789:;C<=>?@AB"; //unicode字符編碼也能匹配 let a = /[阿-飛]/g; //意義不大 let s = "阿飛老師"; let a = /[abc0-9]/g; //a或b或c,0到9 let s = "2345abc"; //匹配全部的數字和字母 let a = /[a-zA-Z0-9]/g; let s = "2345abcAfejnfjGHjfbj"; let a = /[^abc]/g; //除了,取反只能放在首位 let s = "2345abcAfejnfjGHjfbj"; let a = /[{}?*./+()[\]\-]/g; //字符集內的字符失去了特殊意義 let s = "2345abcAfejnfjGHjfbj"; console.log(s.match(a));
/* 起止字符 ^ 起始位置 $ 結束位置 */ let a = /^abc$/; //只能匹配"abc",空格都不能夠有 //let s = "gabcgg"; //必須是a起始的字符串才能匹配 let s = "gabcgg"; console.log(s.match(a)); // console.log("ddabcdd".match(/(a|^)bc/)); // abc a是子項 console.log("bcjfjfjfjfj".match(/(a|^)bc/)); // bc 子項爲""
/* . 匹配任意字符 除了換行等以外 \n \r [.]的.是單純的匹配字符. */ let a = /./g; let s = ".123\r46\n5"; console.log(s.match(a)); //匹配全部的字符 /[\s\S]/ /[\w\W]/
/* /a/ new RegExp() \s \S \w \W \d \D \b \B 修飾詞 igm 量詞{} *+? 惰性?取短的 子項() 字符集[] | ^ $ . */ let reg={ //qq:5~10,只能是數字,第一位不是0 qq: /^[1-9]\d{4,9}$/, //用戶名:6~18,數字字母_,必需要字母開頭 user:/^[a-z]\w{5,17}$/i, //密碼:6~18,數字字母_全部符號 pwd:/^[\w<>,.?/\-+=*@#$%^&()[\]`~|\\{}<>]{6,18}$/, //手機號: tel:/^1[3-9]\d{9}$/, //郵箱 mail:/^[a-z1-9_]\w{0,17}@[0-9a-z]{2,}(\.[a-z]{2,4}){1,2}$/i, //身份證 IDCard:/^[1-9]\d{5}(18|19|20)\d{2}(0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])|(0[469]|11)(0[1-9]|[12][0-9]|30)|(02(0[1-9]|[12][0-9]))\d{3}[0-9x]$/i, } // let a = reg.qq; let b = reg.mail; // let s = "3045282682"; // console.log(a.test(s)); console.log(b.test("1886@163.com")); // let a = reg.IDCard; // console.log(a.test("341221199411178765")); //大月 //31天 /* /(0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])/ //30天 /(0[469]|11)(0[1-9]|[12][0-9]|30)/ //2月 /(02(0[1-9]|[12][0-9]))/ //一塊兒 /(0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])|(0[469]|11)(0[1-9]|[12][0-9]|30)|(02(0[1-9]|[12][0-9]))/ /((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01])|(0[469]|11)(0[1-9]|[12][0-9]|30)|(02(0[1-9]|[12][0-9])))/ */
捕獲的是子項 RegExp.$1 最近的一次正則結果中的子項
捕獲用 \n 表示,表明一個子項
let a = /a(b)(c)/; let s = "abc"; console.log(a.test(s)); let a = /(阿飛|朱雀)老師/; let s = "abc阿飛老師"; let s1 = "abc朱雀老師"; a.test(s); s1.match(a); console.log(RegExp.$1); //離它最近一次正則結果的子項1 朱雀 console.log(RegExp.$9); //最多存9個子項 沒有就是 空 //捕獲組,1表示重複第1個子項,沒有加g,因此第一次匹配到後就結束匹配 let a = /(\d)\1/; //捕獲組,重複子項 aa bb let a = /(\d\d)\1/; //捕獲組,重複子項 abab let a = /(\d(\d))\1\2/; //捕獲組,重複子項 ababb let a = /(\d\d)\1{9}/; //捕獲組,能夠用量詞 abab*n let a = /(\d(\d))\2\1/; //捕獲組,重複子項 abbab let s = "797994545545"; console.log(s.match(a));
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap{ position: relative; width:430px; height:550px; margin:50px auto 0; background-color: #00baff; } #wrap .title{ height:40px; line-height: 40px; background-color: #008ccf; color:white; font-size: 24px; text-align: center; font-weight: bold; } #wrap input{ display: inline-block; width:250px; height:40px; padding-left: 20px; margin-left: 80px; margin-top:20px; } #wrap input.error{ border: 2px solid red; } #wrap input.ok{ border:2px solid #479552; } #wrap img{ display: none; width:30px; height:30px; vertical-align: middle; } #wrap input[type=submit]{ width:270px; padding:0; background-color: #008ccf; outline-style: none; color:white; font-weight: bold; cursor:pointer; } #wrap label{ overflow: hidden; display: block; height:0; margin-left: 80px; color:red; font-size: 12px; } #alert{ position: absolute; left: 0; right:0; top:0; bottom:100px; visibility: hidden; width:150px; height:40px; margin: auto; background-color: black; color:white; text-align: center; line-height: 40px; opacity: 0; transition: bottom .4s,opacity .5s ; } #alert.on{ visibility:visible; bottom: 0; opacity: 1; } </style> </head> <body> <div id="wrap"> <p class="title">註冊</p> <form action="" method="" id="form"> <input type="text" name="name" id="name" placeholder="請輸入您的用戶名"> <img src="img/yes.png"> <label for="name">錯誤:用戶名以字母開頭,長度爲6~16位</label> <input type="password" name="pwd" id="pwd" placeholder="請輸入您的密碼"> <img src="img/yes.png"> <label for="name">錯誤:注意密碼長度爲6~18位</label> <input type="password" name="repwd" id="repwd" placeholder="請再次輸入您的密碼"> <img src="img/yes.png"> <label for="name">錯誤:兩次密碼輸入不一致</label> <input type="text" name="phonenumb" id="phonenumb" placeholder="請輸入您的手機號"> <img src="img/yes.png"> <label for="name">錯誤:手機號格式不正確</label> <input type="text" name="qq" id="qq" placeholder="請輸入您的QQ號"> <img src="img/yes.png"> <label for="name">錯誤:QQ號碼格式不正確</label> <input type="text" name="mail" id="mail" placeholder="請輸入您的郵箱"> <img src="img/yes.png"> <label for="name">錯誤:郵箱格式不對,請從新輸入</label> <input type="submit" value="提交" id="submit"> <div id="alert">請先輸入密碼!</div> </form> </div> <script> (function () { let aLabel = document.querySelectorAll("#wrap label"), aImg = document.querySelectorAll("#wrap img"), oName = document.getElementById("name"), oPwd = document.getElementById("pwd"), oRepwd = document.getElementById("repwd"), oPnumb = document.getElementById("phonenumb"), oQQ = document.getElementById("qq"), oMail = document.getElementById("mail"), alert = document.getElementById("alert") ; //驗證規則 let reg={ //用戶名 name:/^[a-z]\w{5,15}$/i, //密碼 pwd:/^[\w~`!@#$%^&*()\-+=[\]{}'";:,.<>/?\\]{6,18}$/, //手機號 tel:/^1[3-9]\d{9}$/, //qq qq:/^[1-9]\d{4,9}$/, //郵箱 mail:/^[a-z1-9_]\w{0,17}@[0-9a-z]{2,}(\.[a-z]{2,6}){1,2}$/i }; let isCheck=[]; //定義添加驗證函數 function addCheckEvent(ele,reg,index) { //輸入時,取消對勾 ele.addEventListener("focus",function () { aImg[index].style.display = "none"; }) //離開時驗證 ele.addEventListener("blur",function () { if(!ele.value){ ele.className=""; ele.className=""; aImg[index].style.display = "none"; //不顯示對勾 aLabel[index].style.height = 0+'px'; //錯誤不提示 return; }; //未填寫則返回 //驗證成功 if(reg.test(ele.value)){ ele.className="ok"; //綠框 isCheck[index]=true; //表示驗證過 aImg[index].style.display = "inline-block"; //對勾 aLabel[index].style.height = 0+'px'; //錯誤不提示 }else{ ele.className="error"; //紅框 isCheck[index]=false; //未驗證經過 aImg[index].style.display = "none"; //不顯示對勾 aLabel[index].style.height = 16+'px'; //提示錯誤 ele.focus(); //鎖定焦點 } }); } //1. 驗證用戶名 addCheckEvent(oName,reg.name,0); //2.驗證密碼 addCheckEvent(oPwd,reg.pwd,1); //3.二次密碼focus oRepwd.addEventListener("focus",function () { //先取消對勾 //aImg[2].style.display = "none"; //判斷第一次密碼輸入狀態 if(!oPwd.value){ //密碼未輸入 setTimeout(function () { alert.classList.add("on"); //動畫提示 oPwd.focus(); }); setTimeout(function () { alert.classList.remove("on"); //定時消失 },2000); } }) //二次密碼驗證blur oRepwd.addEventListener("blur",function () { if(!oRepwd.value){ oRepwd.className=""; aImg[2].style.display = "none"; //對勾 aLabel[2].style.height = 0+'px'; //錯誤不提示 return; }; //未填寫則返回 if(isCheck[1]){ //第一次密碼已經驗證 if(oRepwd.value === oPwd.value){ //密碼同樣 oRepwd.className="ok"; //綠框 isCheck[2]=true; //表示驗證過 aImg[2].style.display = "inline-block"; //對勾 aLabel[2].style.height = 0+'px'; //錯誤不提示 }else{ //不經過 oRepwd.className="error"; //綠框 isCheck[2]=false; //表示驗證過 aImg[2].style.display = "none"; //對勾 aLabel[2].style.height = 16+'px'; //錯誤不提示 oPwd.focus(); //鎖定第一次輸入密碼 } } }) //4.驗證手機號 addCheckEvent(oPnumb,reg.tel,3); //5.驗證QQ號 addCheckEvent(oQQ,reg.qq,4); //6.驗證郵箱 addCheckEvent(oMail,reg.mail,5); })(); </script> </body> </html>
/* 斷言,JS只有正向斷言,放在後面,括號不算子項 (?=a) 格式限定後面緊接着必須是a,但不但願匹配結果中有a (?!a) 格式限定後面緊接着不能是a */ // let r = /(阿飛|朱雀)老師,\1老師/; // let s = "阿飛老師,阿飛老師"; let r = /Window(?=XP)/; //但願格式是WindowXP,但不但願結果中有XP,全部用? 這個()不是子項 let s = "WindowXPx"; let r = /Window(?!XP)/; //不但願格式是Window後接着XP,?! 這個()不是子項 let s = "Window111"; console.log(s.match(r)); console.log(RegExp.$1);
/* replace str.replace(正則,字符串|函數); 替換匹配到的內容變成第二個參數的內容 (若是是字符串直接替換,若是是函數,替換返回值) */ let reg = /(阿飛|風嶼|海文)(老師|先生|大大)/g; let str = "阿飛老師是個純粹的大豬蹄,風嶼先生真自戀,海文大大脾氣很差"; let newStr = str.replace(reg,"小浪"); let newStr = str.replace(reg,(...rest)=>{ //通過了不少運算以後,獲得用來替換的字符串 console.log(rest); return '小浪'; }); let newStr = str.replace(reg,(a,b,c)=>{ //通過了不少運算以後,獲得用來替換的字符串 console.log(a,b,c); //a表示正則形參,b表示第一個子項,c表示第二個子項 return '小浪'+c+c.slice(1); }); console.log(newStr);
<div id="wrap"> <input type="text"> <button class="btn">發送</button> <ul></ul> </div> <script> let Btn = document.getElementsByClassName("btn")[0], Input = document.getElementsByTagName("input")[0], oU = document.getElementsByTagName("ul")[0] ; Btn.onclick = function () { let str = Input.value; if(str === "")return; let reg=/傻[,./<>\-+=\d]*逼|草|操|cao|艹|你[爸媽]|王八蛋|/g; str = str.replace(reg,($0)=>{ let s=""; [...$0].forEach(()=>s+="□") return s; }) let oLi = document.createElement("li"); oLi.innerText = str; oU.appendChild(oLi); Input.value=""; } </script>
/* 適合小數據的存儲,字符串緩存,存在本地的 1.不一樣的瀏覽器存放的cookie位置不同,也是不能通用的 2.cookie的存儲是以域名形式進行區分的 3.cookie的數據能夠設置名字的 4.一個域名下存放的cookie的個數是有限制的,不一樣的瀏覽器存放的個數不同 5.每一個cookie存放的內容大小也是有限制的,不一樣的瀏覽器存放大小不同 本地文件不支持cookie,火狐瀏覽器支持,經過Webstorm打開支持 */ /* 若是不給cookie設置過時時間,那麼瀏覽器關閉以後,cookie就清除了 在存儲本地cookie確定是須要設置過時時間的 expires 一個日期對象轉換成的字符串,默認是UTC時間 */ //每條cookie都須要單獨設置,不支持一次賦值設置多個cookie document.cookie = "user=阿飛;pwd=123"; 沒用的 let date = new Date(new Date().getTime()-7*24*3600*1000); document.cookie = "goudan=阿飛;expires="+date.toUTCString(); //date轉成UTC時間進行賦值 document.cookie = "pwd=123"; //獲取所有cookie console.log( document.cookie );
let Cookie ={ //設置,修改 set(mJson,day) { //設置過時時間,不設置day默認undefined,計算時 = NaN,此時設置的cookie關閉瀏覽器釋放 let date = new Date(new Date().getTime()+day*24*3600*1000).toUTCString(); Object.entries(mJson).forEach(([key,value])=>{ document.cookie = `${key}=${value};expires=${date}`; }) }, //獲取 get(key) { //不傳值返回所有cookie構建的對象 if(!key){ let json=document.cookie; let obj={}; while(json){ let reg=/(^|\s)(\w+)=([^;]+)(;|$)/; let arr = json.match(reg); json = json.split(arr[0])[1].toString(); obj[RegExp.$2]=RegExp.$3; } return obj; }else{ let str = document.cookie; // /(^|\s)aaa=([^;]+)(;|$)/ let reg = new RegExp("(^|\\s)"+key+"=([^;]+)(;|$)"); if(reg.test(str)){ return RegExp.$2; }else{ return undefined; //匹配不成功返回undefined } } }, //刪除 remove(key) { Cookie.set({ [key]:"" //清空 },-1); } }; Cookie.set({ a:'阿飛', b:123, goudan:"afei" },7); //7天 //測試get console.log(Cookie.get("goudan")); //刪除cookie Cookie.remove("b");
//ES6寫法 ,屬性名的變量寫法 let a = "name"; let obj= { [a]:"阿飛" // 這裏a加【】代指變量 「name」 }; console.log(obj); let afei= { name :"阿飛", age:18, sex:0 }; console.log(Object.keys(afei)); //提取對象全部屬性名,返回數組 console.log(Object.values(afei)); //提取對象全部值,返回數組 console.log(Object.entries(afei)); //提取對象的鍵值,返回二位數組
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> </head> <body> <div id="wrap"> 歡迎訪問本站!您上次訪問本站的時間爲:2018-11-10,20:50:20 </div> <script> //封裝的cookie let Cookie ={ set(mJson,day) { let date = new Date(new Date().getTime()+day*24*3600*1000).toUTCString(); Object.entries(mJson).forEach(([key,value])=>{ document.cookie = `${key}=${value};expires=${date}`; }) }, get(key) { //不傳值返回所有cookie構建的對象 if(!key){ let json=document.cookie; let obj={}; while(json){ let reg=/(^|\s)(\w+)=([^;]+)(;|$)/; let arr = json.match(reg); json = json.split(arr[0])[1].toString(); obj[RegExp.$2]=RegExp.$3; } return obj; }else{ let str = document.cookie; let reg = new RegExp("(^|\\s)"+key+"=([^;]+)(;|$)"); if(reg.test(str)){ return RegExp.$2; }else{ return undefined; //匹配不成功返回undefined } } }, remove(key) { Cookie.set({ [key]:"" //清空 },-1); } }; (function () { //lastTime存儲上一次的時間 let oW = document.getElementById("wrap"); let lastTime = Cookie.get("lastTime"); let date = new Date().getTime(); function showText(lastTime) { if(lastTime){ let date = new Date(lastTime-0); return `歡迎訪問本站!您上次訪問本站的時間爲:${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()},${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; }else{ return "您是第一次訪問本站喲!"; } } oW.innerText = showText(lastTime) ; Cookie.set({ lastTime:date },9999); })(); </script> </body> </html>
/* Ajax 異步的javascript和xml 同步 一心一意 異步 三心二意 功能 無刷新頁面的狀況下,實現與後臺的數據交互,同時在頁面進行更新 跨域 默認不容許跨域請求資源 安全問題 前端能不能請求到數據,是後端說了算 */ //建立 ajax對象 const ajax = new XMLHttpRequest(); //監聽狀態的改變 /* 0~4 0 初始化狀態 ajax已經被建立 1 open()方法已經調用 2 send()方法已調用 3 全部的響應已經收到 4 http響應已經徹底接收 */ ajax.onreadystatechange = function(){ if(ajax.readyState === 4 & ajax.status === 200){ //前端 就可以接收到數據了 //console.log(ajax.response); //把對應的數據 轉換成對應的數據類型 console.log(JSON.parse(ajax.response)); } } //路徑不能出現中文 //本地測試 //ajax.open('get','./data.php',true); //經過什麼樣的方式,向什麼樣的後端服務器 發送什麼的請求(true表示異步) //ajax.send(); //執行請求命令 //真實服務器, 數據先行, 數據驅動視圖 ajax.open('get','http://www.tanzhouweb.com/48/data.php',true); ajax.send();
//調用方式 ajax({ url:"www.baidu.com", method:"get", data:{ name:"peter", age:18 }, success:function(msg){ }, error:function(err){ } })
function ajax(json){ var method = json.method.toUpperCase() || "GET"; var data = json.data || {}; var xhr = new XMLHttpRequest(); switch(method){ case 'GET': xhr.open(method,json.url+"?"+jsonUrl(json.data),true); xhr.send(null); break; case 'POST': xhr.open(method,json.url,true); //設置post請求頭 xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send(jsonUrl(json.data)); break; } } xhr.onreadystatechange=function(){ if(xhr.readyState === 4){ if(xhr.status>=200 || xhr.status<=300 || xhr.status === 304){ json.success(xhr.responseText); //responseText 纔是服務器返回數據 }else{ json.error(xhr.status); } } } function jsonUrl(data){ var arr=[]; for(var key in data){ arr.push(key+'='+data[key]); } return arr.join("&"); }
/* jsonp 一種跨域問題的解決方案 */ function getData(data) { console.log(data); } //核心本質 就是後端服務器 返回一個函數調用 getData('js') createJsonp(); function createJsonp() { const s = document.createElement('script'); // s.src='http://www.tanzhouweb.com/48/jsonp.php?callback=getData'; s.src='http://localhost/data.php?callback=getData'; document.body.appendChild(s); }
設置響應頭,res.writeHeader(200,{'Access-Control-Allow-Origin':'*'})
/* cmd檢測nodejs的安裝 node -v npm -v */ //經過 node的原生模塊 http 搭建服務器 提供數據接口 const http = require('http'); http.createServer(function () { res.writeHeader(200,{ 'Access-Access-Control-Allow-Origin':'*' }) res.end("hi~這裏是node服務器返回的數據"); }).listen(6060);
express
const express = require('express'); const app = express(); //在中間件設置容許先後端跨域 app.use((req,res,next)=>{ res.set('Access-Control-Allow-Origin','*'); next(); })
/* OOP 封裝 繼承 多態 */ var afei = teacher(1111,'阿飛',18); var zhuque = teacher(2222,'朱雀',20); //封裝一個對象函數 function teacher(id,name,age) { var o = {}; o.id = id; o.name=name; o.age=age; o.showID = function () { //堆內存佔用了多個 alert(this.id); } return o; }
/* new Date() new Image() new XMLHttpRequest() new RegExp() new Array() new 關鍵詞 後面緊跟一個 函數 經過new執行函數對函數的影響: ①:函數內部生成一個全新的對象,函數的this指向這個對象 ②:函數默認返回上述對象 */ //fn(); //函數自執行;非嚴格模式指向window,嚴格模式指向undefined function fn() { // console.log(this); //new的this指向全新的對象,只有this能指向這個對象 this.x = 10; } new fn(); //先初始化一個空{},而後將{}的proto即隱式原型指向fn的prototype,而後執行了fn.call({})將this做用域交予{},完成實例化 console.log(new fn()); // fn {x: 10}
var afei = new Teacher(1111,'阿飛',18); var zhuque = new Teacher(2222,'朱雀',20); console.log(afei.showID === zhuque.showID); //false 每一個對象都佔用一個堆內存存放函數 //構造函數 / 類 function Teacher(id,name,age) { this.id = id; this.name=name; this.age=age; this.showID = function () { //堆內存佔用了多個 alert(this.id); } }
/* 原型 prototype 是一個對象數據類型 它是構造函數的一個屬性 每個實例都共享這個原型的屬性 */ //構造函數 function Teacher(id,name,age) { this.id = id; this.name=name; this.age=age; } // console.dir(Teacher); Teacher.prototype.x = 10; //原型也是對象 Teacher.prototype.showID=function () { //全部實例公用一個showID屬性 alert(this.id); } var afei = new Teacher(1111,'阿飛',18); // 實例 var zhuque = new Teacher(2222,'朱雀',20); console.log(afei); console.log(afei.x,zhuque.x,afei.__proto__===zhuque.__proto__); console.log(afei.__proto__ === Teacher.prototype); //實例的__proto__ 全等於 構造函數的 prototype屬性 // 構造函數的原型是對象數據類型 {x: 10, showID: ƒ, constructor: ƒ} //afei.showID(); console.log(afei.showID === zhuque.showID); // true 共享一個堆內存
/* 當訪問對象的屬性時,先從自身找,自身沒有,才進入原型中找;原型找不到去原型的原型裏面找,直到Object.prototype 爲止,由於Object沒有__proto__屬性,原型鏈到此結束 實例沒有 prototype 屬性;Object沒有__proto__屬性 構造函數的隱式原型是Function: A.__proto__ === Function.prototype 構造函數的原型是其實例的隱式原型:A.prototype === new A().__proto__ Function比較特殊 Function.__proto__.__proto__ === Object.prototype goudan.__proto__ = Fn.prototype Fn.prototype.__proto__ = Object.prototype */ function Fn() { this.x=10; //實例的x屬性 } Fn.prototype.x=20; //原型的x屬性 console.log(Fn.prototype.constructor === Fn); //true 構造屬性 var goudan = new Fn(); // 實例 console.log(goudan.x); console.log(goudan.__proto__ === Fn.prototype); //true Fn的原型 console.log(Fn.prototype); console.log(Fn.prototype.__proto__ === Object.prototype); //true Fn.prototype 是 Object的原型 // 構造函數的原型 是 Object 的實例化對象 //Object不存在 .__proto__ 屬性,
/* 私有屬性寫在構造函數裏面 公共屬性寫在原型上 先有原型,再有實例 */ function Teacher(n,a,i) { this.name = n; this.age = a; this.id = i; } /* Teacher.prototype.showID=function () { alert(this.id); } */ Teacher.prototype = { //重寫了 prototype屬性,注意保留constructor屬性 constructor:Teacher, showID:function () { alert(this.id); }, showName:function () { alert(this.name); }, showAge:function () { alert(this.age); } } var afei = new Teacher("阿飛",18,1111); afei.showID();
/* 原型鏈繼承 構造函數的原型 = 一個函數的實例化對象 實現繼承該函數的原型鏈 */ function C() {} C.prototype.x = 10; function B() {} B.prototype = new C(); // B的原型指向C function A() {} A.prototype = new B(); Object.prototype.x = 40; //頂層鏈 var a = new A(); console.log(a.x); // 10 原型鏈查找,就近原則
/* 獲得一個實例的構造函數 */ function A() {} var a = new A(); console.log(a.constructor); // A(){} a沒有constructor,其實是原型 A.prototype.constructor //注意。原型鏈可能致使不肯定 function B() {} B.prototype = {}; // 這裏將原型置爲{},上一級原型不存在constructor, var b = new B(); console.log(b.constructor); // Object() { [native code] } 再向上級找,找到Object原型的構造函數 //全部大括號構建對象都至關於new一個Object對象 // let x={}; // 原型 = Object.prototype let x = new Object();
先繼承私有屬性,而後是原型
function A(n,a) { this.name = n; this.age = a; } A.prototype.getName = function () { return this.name; } //ES5實現繼承(組合繼承) function B(n,a,i) { A.call(this,n,a); //1.繼承了A的私有屬性 this.id = i; //新增的私有屬性 } //2.再繼承A的原型,這裏只繼承原型,因此使用中間構造函數,若是用new A(),原型會有A的屬性 function Fn(){}; Fn.prototype = A.prototype; B.prototype = new Fn(); //這裏只傳遞了原型,但原型缺乏構造函數 // 新增原型 B.prototype.constructor = B; // 補上構造函數 B.prototype.xx=10; // 新增原型 var afei = new A('阿飛',18); var xinai = new B('心艾',20,5555); console.log(afei); console.log(xinai);
/* instanceof運算符用於測試構造函數的prototype屬性是否出如今對象的原型鏈中的任何位置 對象 instanceof 構造函數(通常是頂層構造函數Object,Array,Function) */ function deepclone(obj) { var o = obj instanceof Array?[]:{}; for(var key in obj){ if(typeof obj[key] === 'object'){ o[key] = deepclone(obj[key]); }else{ o[key] = obj[key]; } } return o; } var a = { a:20, b:50, k:{ //不支持複雜類型 aa:1, cc:{ h:2333 } } } var b = deepclone(a); //深拷貝後,引用值類型不會被影響 b.c = 40; b.k.bb = 2; b.k.cc.i=120; console.log(a); console.log(b);
/* JSON只會傳數字和字符串,不能存 函數 等其餘類型 */ var a = { a:20, b:50, k:{ aa:1, cc:{ h:2333 } }, f:function () { //JSON 不支持函數類型,因此過濾掉 console.log(1) } } console.log(JSON.stringify(a)); //沒有函數 f var b = JSON.parse(JSON.stringify(a)); //這樣實現的b也和a不同了 b.z=30; b.k.o=80; console.log(b); console.log(a);
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap,#wrap1{ position: relative; width:300px; height:300px; border:1px solid pink; margin:50px auto; } #wrap .con,#wrap1 .con{ position: absolute; top:30px; left:0; width:300px; height: 270px; } #wrap .con ul,#wrap1 .con ul{ width:100%; height:100%; } #wrap .con li,#wrap1 .con li{ display: none; position: absolute; width:100%; height:100%; } #wrap .con li.active,#wrap1 .con li.active{ display: block; } #wrap .tab,#wrap1 .tab{ position: absolute; left:0; top:0; width:100%; height:30px; } #wrap .tab li,#wrap1 .tab li{ float: left; width:99px; height:30px; border-right:1px solid red; background-color: #abcded; cursor: pointer; } #wrap .tab li.active,#wrap1 .tab li.active{ background-color: pink; } </style> </head> <body> <div id="wrap"> <div class="con"> <ul> <li class="active" style="background-color: red">A內容</li> <li style="background-color: #06aaff">B內容</li> <li style="background-color: #f9a886">C內容</li> </ul> </div> <div class="tab"> <ul> <li class="active">A</li> <li>B</li> <li>C</li> </ul> </div> </div> <script> (function () { //對象 function Tab({conEle,tabEle,conClass='active',tabClass='active'}){ this.conEle = conEle; this.tabEle = tabEle; this.conClass = conClass; this.tabClass = tabClass; this.lenth = this.tabEle.length; this.index = 0; this.addClick(); } Tab.prototype = { constructor : Tab, addClick:function () { for(var i=0;i<this.lenth;i++){ (function (i) { //函數做用域造成閉包 this.tabEle[i].onclick=function () { this.change(i); }.bind(this); }).call(this,i); } }, change:function (i) { this.conEle[this.index].classList.remove(this.conClass); this.tabEle[this.index].classList.remove(this.tabClass); this.index = i; this.conEle[this.index].classList.add(this.conClass); this.tabEle[this.index].classList.add(this.tabClass); } }; //實例化 new Tab({ conEle:document.querySelectorAll("#wrap .con li"), tabEle:document.querySelectorAll("#wrap .tab li"), }); })(); </script> </body> </html>
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap2{ position:relative; width:780px; height:380px; margin:50px auto 0; user-select:none; } #wrap2 .img{ width:100%; height:330px; } #wrap2 .img ul{ width:100%; height:330px; } #wrap2 .img ul li{ position:absolute; width:100%; height:330px; opacity: 0; transition: opacity .3s; } #wrap2 .img ul li.active{ opacity: 1; z-index:2; } #wrap2 .tab{ position:absolute; left:0; bottom:0; width:100%; height:50px; } #wrap2 .tab ul{ width:100%; height:50px; } #wrap2 .tab ul li{ float:left; z-index:4; width:20%; height:100%; background-color: #121112; color:#fff; text-align:center; line-height:50px; cursor: pointer; } #wrap2 .tab ul li.active{ background-color: #303030; color:#e9c06c; } </style> </head> <body> <div id="wrap2"> <div class="img"> <ul> <li class="active"><img src="img/1.jpg" alt=""></li> <li><img src="img/2.jpg" alt=""></li> <li><img src="img/3.jpg" alt=""></li> <li><img src="img/4.jpg" alt=""></li> <li><img src="img/5.jpg" alt=""></li> </ul> </div> <div class="tab"> <ul> <li class="active">開黑嗎?</li> <li>我壓縮賊六</li> <li>只要E的夠快</li> <li>隊友的問號</li> <li>就追不上我</li> </ul> </div> </div> <script> (function () { //對象 function Tab({conEle,tabEle,conClass='active',tabClass='active'}){ this.conEle = conEle; this.tabEle = tabEle; this.conClass = conClass; this.tabClass = tabClass; this.lenth = this.tabEle.length; this.index = 0; this.addClick(); } Tab.prototype = { constructor : Tab, addClick:function () { for(var i=0;i<this.lenth;i++){ (function (i) { this.tabEle[i].onclick=function () { this.change(i); }.bind(this); }).call(this,i); } }, change:function (i) { if(this.index === i)return; this.conEle[this.index].classList.remove(this.conClass); this.tabEle[this.index].classList.remove(this.tabClass); this.index = i; this.conEle[this.index].classList.add(this.conClass); this.tabEle[this.index].classList.add(this.tabClass); } }; function TabAuto({conEle,tabEle,conClass='active',tabClass='active',wrap}) { Tab.call(this,{conEle,tabEle,conClass,tabClass}); //繼承私有屬性 this.wrap = wrap; this.timer = null; this.autoplay(); this.addTimer(); } function Fn(){} Fn.prototype = Tab.prototype; TabAuto.prototype = new Fn(); //繼承原型 TabAuto.prototype.constructor = TabAuto; TabAuto.prototype.autoplay = function () { this.timer = setInterval(function () { var i = this.index; i++; i = i%this.lenth; this.change(i); }.bind(this),2000); } TabAuto.prototype.addTimer = function () { this.wrap.onmouseenter = function () { clearInterval(this.timer); }.bind(this); this.wrap.onmouseleave = function () { this.autoplay(); }.bind(this); } //實例化 new TabAuto({ conEle:document.querySelectorAll("#wrap2 .img li"), tabEle:document.querySelectorAll("#wrap2 .tab li"), wrap:document.getElementById("wrap2") }); })(); </script> </body> </html>
function fn(x) { if(x<10){ return '0'+x; }else{ return ''+x; } }
/* ES5的構造函數和原型是分開的,ES6的類都定義在一個{}內 */ function A(n,a) { this.name = n; this.age = a; } A.showName = function () { // 這裏的函數是 構造函數A的屬性,並不屬於原型的函數 alert(this.name); } A.prototype.showName = function(){ //這裏纔是給原型的函數,A的實例化對象能調用的函數 alert(this.name) } /*ES6 構造函數,也就是私有屬性,寫在constructor裏面 其餘內容就是原型裏面的內容 原型裏面加屬性(能夠在外面加,A.prototype.x=10) 每一個方法結束後,千萬不要寫 , 號 */ class A{ constructor(n,a) { this.name = n; this.age = a; } showName(){ } x(){ return 10; } } // A.prototype.x=10;
class A{ constructor(n,a) { this.name = n; this.age = a; } showName(){ alert(this.name); } showAge(){ alert(this.age); } x(){ return 10; } } class B extends A{ constructor(n,a,id){ super(n,a); //必要的super,把父類的私有屬性繼承一下(傳參),相似ES5的 call this.id = id; } x(){ //return A.prototype.x()+10; //原型的super表明 A.ptototype return super.x()+10; } } let a = new A('阿飛',18); let b = new B('朱雀',81,111); console.log(a); // {name: "阿飛", age: 18} console.log(b); // {name: "朱雀", age: 81, id: 111} console.log(a.x()); // 10 console.log(b.x()); // 20
<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="keywords" content="關鍵詞"> <meta name="description" content="描述"> <meta name="author" content="Danew"> <style> body{font-family: "Microsoft YaHei",serif;} body,dl,dd,p,h1,h2,h3,h4,h5,h6{margin:0;} ol,ul,li{margin:0;padding:0;list-style:none;} img{border:none;} #wrap2{ position:relative; width:780px; height:380px; margin:50px auto 0; user-select:none; } #wrap2 .img{ width:100%; height:330px; } #wrap2 .img ul{ width:100%; height:330px; } #wrap2 .img ul li{ position:absolute; width:100%; height:330px; opacity: 0; transition: opacity .3s; } #wrap2 .img ul li.active{ opacity: 1; z-index:2; } #wrap2 .tab{ position:absolute; left:0; bottom:0; width:100%; height:50px; } #wrap2 .tab ul{ width:100%; height:50px; } #wrap2 .tab ul li{ float:left; z-index:4; width:20%; height:100%; background-color: #121112; color:#fff; text-align:center; line-height:50px; cursor: pointer; } #wrap2 .tab ul li.active{ background-color: #303030; color:#e9c06c; } </style> </head> <body> <div id="wrap2"> <div class="img"> <ul> <li class="active"><img src="img/1.jpg" alt=""></li> <li><img src="img/2.jpg" alt=""></li> <li><img src="img/3.jpg" alt=""></li> <li><img src="img/4.jpg" alt=""></li> <li><img src="img/5.jpg" alt=""></li> </ul> </div> <div class="tab"> <ul> <li class="active">開黑嗎?</li> <li>我壓縮賊六</li> <li>只要E的夠快</li> <li>隊友的問號</li> <li>就追不上我</li> </ul> </div> </div> <script> (function () { class Tab{ constructor({conEle,tabEle}) { this.conEle = conEle; this.tabEle = tabEle; this.index = 0; this.lenth = this.tabEle.length; this.addClick(); } addClick(){ [...(this.tabEle)].forEach((ele,index)=>{ ele.onclick = function() { this.change(index); }.bind(this); }) } change(i){ if(this.index === i)return; this.conEle[this.index].classList.remove('active'); this.tabEle[this.index].classList.remove('active'); this.index = i; this.conEle[this.index].classList.add('active'); this.tabEle[this.index].classList.add('active'); } } class TabAuto extends Tab{ constructor({conEle,tabEle,wrap}){ super({conEle,tabEle}); // 繼承父類私有屬性 this.wrap = wrap; this.timer = null; this.autoplay(); this.addTimer(); } autoplay() { this.timer = setInterval(()=>{ let i = this.index; i++; i = i%this.lenth; this.change(i); },2000); } addTimer() { this.wrap.onmouseenter = ()=> { clearInterval(this.timer); }; this.wrap.onmouseleave = ()=>{ this.autoplay(); }; } }; //實例化 new TabAuto({ conEle:document.querySelectorAll("#wrap2 .img li"), tabEle:document.querySelectorAll("#wrap2 .tab li"), wrap:document.getElementById("wrap2") }); })(); </script> </body> </html>
/* 函數的小括號,會被當成做用域 */ let x=5; function fn(x,y=x) { console.log(x,y); } fn(1); // 1 1
做用是遍歷拿到數組的value值
對象使用for of
遍歷時,先拿到對象的成員, for (let [key,value] of Object.entries(obj))
let arr=[ '阿飛', '風嶼', '小浪', '海文' ]; console.log(Object.keys(arr),Object.values(arr)); // 一維數組 console.log(Object.entries(arr)); // 二維數組 let obj={ name:'afei', age:18, sex:'男', marry:true } /* for of只限於用於 iterator接口 */ for (let string of arr) { console.log(string); //拿到數組的值value } for (let objElement of Object.values(obj)) { console.log(objElement); } for (let objElement of Object.entries(obj)) { //打印數組 console.log(objElement); } for (let [key,value] of Object.entries(obj)) { //結合使用適合遍歷obj的鍵和值 console.log(key,value); }
let x={ aa:1, bb:2 }; let y={ bb:0, cc:3, dd:4 }; let z = {...x,...y} x.aa=10; console.log(x); console.log(z);
Object.getOwnPropertySymbols(obj);
獲取對象內部全部的symbol屬性,返回一個數組
Symbol.for('a')
的名字好比a相同,就表明相同的Symbol
//獨一無二的Symbol console.log(Symbol() === Symbol()); //false let obj = {name:'阿飛'}; let n=Symbol(); //獨一 obj[n]='朱雀'; n=Symbol(); //n被賦值,只是‘朱雀’取不到了,但仍存在 obj[n]='心艾'; console.log(obj[n]); //獲取的是 心艾 obj[Symbol.for('name')]='朱雀'; // obj中添加一個屬性 // {name: "阿飛", Symbol(): "朱雀", Symbol(): "心艾", Symbol(name): "朱雀"} //獲取全部的Symbol let symbolArr = Object.getOwnPropertySymbols(obj); // [Symbol(), Symbol(), Symbol(name)] console.log(obj[symbolArr[0]]); //找到朱雀 //傳值是別名 console.log(Symbol('a'),Symbol.for('a')); //Symbol的名字相同,仍不一樣 console.log(Symbol('a')===Symbol('a')); //false //Symbol.for的名字相同,就表明相同的Symbol console.log(Symbol.for('a') === Symbol.for('a')); //true
new Set(data)
data必須是能被迭代的數據
實例的add方法,能夠追加數據到對象內
/* 對象 特色:沒有重複值 只接收一個參數,必須能被迭代的數據,字符串,數組,NodeList,argument,Set,Net */ let set = new Set([1,2,3]); let set = new Set("阿飛老師阿飛老師朱雀老師"); //默認去重 set.add('心艾'); //add的內容被 當成一條數據傳入,不被拆開 set.add('心'); console.log(set); // 心艾 和 心 並不會去重 //去重 let arr=[1,2,4,5,6,1,2,4,2,3]; let s = new Set(arr); console.log([...s]);
map.set(key,value);
隊列設置
/* Map可使用一個對象當成鍵名 支持各類數據類型當鍵使用,對象,實例, */ let map = new Map(); // let key = 'name'; // let value = '阿飛'; let key = {goudan:'狗蛋'}; //對象當成鍵 let value = 'afei'; map.set(key,value); console.log(map); //取值 console.log(map.get(key));
var a={m:'n'}; var b= a.toString(); console.log(b,typeof b,b.length); // [object Object] string 15
//Proxy 能夠理解成,在目標對象以前架設一層「攔截」,外界對該對象的訪問,都必須先經過這層攔截, // 所以提供了一種機制,能夠對外界的訪問進行過濾和改寫。 let o ={ a:1, b:2 } let obj = new Proxy(o,{ //攔截對象的獲取 get(target,key,receive){ console.log(target); // {a: 1, b: 2} console.log(key); // a console.log(receive); // Proxy {a: 1, b: 2} return target[key]; // 1 }, //攔截對象的賦值 set(target,key,value,receive){ console.log(target); //{a: 1, b: 2} console.log(key); //a console.log(value); //123 console.log(receive); // Proxy {a: 1, b: 2} } //... 針對框架開發使用 }) console.log(obj.a); //觸發get obj.a = 123; //觸發set
new Promise()
返回一個promise對象
Promise.all([new Promise(),newPromise()]).then().catch()
批量執行,all傳入的是數組包裹的promise對象,都成功走then回調,都失敗,走catch回調,只顯示失敗的
Promise.race([new Promise(),newPromise()]).then().catch()
競爭執行,哪一個實例先改變狀態(不論resolve仍是reject),那麼then和catch就走哪一個實例
//回調地獄->解決異步編程 setTimeout(()=>{ console.log("123") },0) console.log("abc") //resolve 表示成功 reject表示失敗 let x = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve("200"); //成功,永遠在當前環境的最後執行 console.log("我先打印,再進入resolve事件") },0) }).then((val)=>{ //then表示成功回調 console.log("成功回調"+val); },(err)=>{ //第二個函數是失敗回調 console.log("失敗回調"+err); }) //all 只有數組成員都成功才執行then let p = Promise.all([ new Promise((resolve,reject)=>{ resolve('1'); }),new Promise((resolve,reject)=>{ resolve('1'); }),new Promise((resolve,reject)=>{ reject('0'); }) ]).then(data=>{ console.log(data); //都成功[1,1,0] }).catch(err=>{ console.log(err); //有一個失敗,就走失敗,這裏只顯示失敗的 '0' }) /* Promise.race() 有競爭的意思 只要`p1`、`p2`、`p3`之中有一個實例率先改變狀態,`p`的狀態就跟着改變。 那個率先改變的 Promise 實例的返回值,就傳遞給`p`的回調函數。 */ let p1 = Promise.race([ new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('1'); },100); }),new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('2'); },101); }),new Promise((resolve,reject)=>{ setTimeout(()=>{ reject('3'); },99); }) ]).then(data=>{ console.log('resolve '+data); //只顯示最快的 3,不管是 resolve仍是reject }).catch(err=>{ console.log('reject '+err); })