**章节导航:** [TOC] ***** Demo - 小米商城首屏:http://a-1.vip/demo/mi Demo - 扫雷项目:http://a-1.vip/demo/bomb Demo - 贪吃蛇:http://a-1.vip/demo/eat Demo - via 手机浏览器导航页:http://a-1.vip/demo/via Demo - 卡片展示:http://a-1.vip/demo/cardShow Demo - 抓到我算我输:http://a-1.vip/demo/random ***** ## :-: 数据类型、 ``` var demo = 123456; demo = typeof(demo) //判断变量的类型、 console.log(1, demo); //返回字符串 "number" 1、数据类型转换(显式类型) Number(mix) —— 到数值型 parseint(string,radix) —— 到整数型(12.9asd=12) parseFloat(string) —— 到浮点数类型(后面有字符串直接砍断,12.6px=12.6) String(mix) —— 到文本("不管放什么都会变成字符串") toString(radix) —— 也是转字符串,不过并没什么卵用、调用方法不同、 Boolean() —— 到布尔值 2、数据类型转换(隐式类型) isNaN() —— Number转换后判断是否为NaN,结果返回Boolean ++ -- +/- —— 转换成数值、(加号两侧有一个为字符串类型的值,就会被转换为字符串类型) - * / % → number && || ! < > <= >= == != 3、不发生类型转换的、 === —— 绝对等于 !== —— 绝对不等于 (例子: 1 === "1" false) ``` ``` // 基于不同条件执行不同动作。 switch ( val ) { case 1: // ··· return; case 2: // ··· return; case 3: // ··· return; default: // ··· return; } ``` ## :-: 取随机数的方法、 ``` Math.random() // 返回:0 ~ 1 的随机数、 // [函数] 生成从minNum到maxNum的随机数 function randomNum(minNum, maxNum) { switch (arguments.length) { case 1: return parseInt(Math.random() * minNum + 1, 10); break; case 2: return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); break; default: return 0; break; } } ``` ## :-: 数组(Array) 属性/方法([api](http://www.w3school.com.cn/jsref/jsref_obj_array.asp)) ``` // 数组的两种创建形式、 // 字面量形式 (建议) var arr = [1, 2, 3]; // 通过构造函数创建、 var arr1 = new Array(1, 2, 3); // 只传1个参数时,则表示创建整数个稀松数组、 var arr2 = new Array(9); // [,,,,,] // 1、属性 // arr.constructor —— 返回对创建此对象的数组函数的引用。 // arr.length —— 设置或返回数组的成员数、 // arr.prototype —— 使您有能力向对象添加属性和方法。 // 2.1、方法:会改变原数组、 // arr.push() —— 向数组的末尾添加'一个或更多'成员,并返回新的'长度'。 // arr.unshift() —— 向数组的开头添加'一个或更多'成员,并返回新的'长度'。 // arr.pop() —— 剪切并返回数组的最后一位成员、 // arr.shift() —— 剪切并返回数组的最前一位成员、 // arr.reverse() —— 颠倒数组中成员的顺序。 // arr.splice() —— 剪切'指定区间'的成员并返回。并向该'指定区间头位(第一个参数)'插入新成员(看演示)。 // arr.splice(从第几位开始,截取多少的长度,在切口处添加新的数据(一个或多个)); // arr.splice(1,2,'a','b','c') —— 删除并返回arr[1]、arr[2],在arr[1]位置新增'a','b','c'、 // arr.splice(1,0,'ab','c') —— 不会删除成员,并在指定位置插入新的数据、 // arr.sort() —— 对数组的元素进行排序、 // 演示 (fun参数传两个) var arr = [1, 6, 2, 3, 5, 4]; arr.sort(function(a, b) { // 当返回值为负数,前面的数放在前面、 // 当返回值为正数,后面的数放在前面、 // 当返回0时,不动、 // 总结:a - b 升序,b - a 降序、 return a - b; }); console.log(arr); // 返回数组:[1, 2, 3, 4, 5, 6] // 数组打乱(随机排序); arr.sort(function() { // 随机生成 0 ~ 1 的浮点数、 var mu = Math.random(); if (mu > 0.5) { return 1; } else { return -1; } }); // 数组打乱(随机排序) 简写形式 arr.sort(function() { // 随机生成 0 ~ 1 的浮点数、 return Math.random() - 0.5; }); console.log(arr); // 返回数组:[6, 5, 1, 3, 2, 4] // 2.2、方法:不改变原数组、 // arr.concat() —— 可拼接多个数组,参数为数组类型、 // arr.slice() —— 返回指定区间的数组、 // arr.slice(从该位开始截取,截取到该位); var arr = [1, 2, 3, 4, 5]; arr.slice(1, 3); // 返回:[2, 3] arr.slice(1); // 返回:[2, 3, 4, 5] arr.slice(); // 空截取:不传参数返回整个数组,可以将类数组转换成数组。(克隆数组) // arr.toString() —— 数组转字符串、 // arr.join() —— 数组合并为字符串,1个参数,字符串类型、(不传参默认',') // str.split('') —— 字符串拆分为数组,1个参数,字符串类型、 // 补充说明:arr[-1] 当数组的索引为负数时,表示取出倒数第几位、 // 数组跟对象的特点相似,一般都不容易报错、 ``` ## :-: 类数组de构建 ``` // 好处:既能当数组使,也可以当对象使、 var obj = { 0: 'a', 1: 'b', 2: 'c', abc: 123, push: Array.prototype.push, // 必有的属性、 length: 3, // 加入splice后外观上看起来就跟数组一样了、 splice: Array.prototype.splice } console.log(obj); // ["a", "b", "c", abc: 123] ``` ## :-: 原型链继承·圣杯模式、 ``` function inherit(Target, Origin) { function F() {}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constuctor = Target; Target.prototype.ubar = Origin.prototype; } ``` ## :-: <a href="http://www.w3school.com.cn/jsref/jsref_events.asp">Element 事件</a> ``` // 绑定事件有三种形式、 var div = document.getElementsByTagName('div')[0]; // Top 1 onclick div.onclick = function() { // 缺陷:只能绑定1个函数、 console.log(1); }; // Top 2 addEventListener div.addEventListener('click', function() { // 可以绑定多个'不同的'函数,IE9 以下不兼容、false参数与冒泡有关、 console.log(2); }, false); // Top 3 attachEvent div.attachEvent('on' + 'click', function() { // IE独有、 console.log(3); }); // 封装一个兼容性的写法、 // 参数:元素对象,事件类型(文本),执行的函数、 function addEvent(elem, type, handle) { if (elem.addEventListener) { elem.addEventListener(type, handle, false); } else if (elem.attachEvent) { elem.attachEvent('on' + type, function() { handle.call(elem); }); } else { elem['on' + type] = handle; } } // Demo function demo() { alert('alert demo'); } addEvent(div, 'click', demo); // 解除事件绑定的方法、 div.onclick = null; div.removeEventListener(type, fun, null); div.detach('on' + type, fun)); // 取消事件冒泡 div.onclick = function(e) { // W3C标准:取消事件冒泡、 e.stopPropagation(); // IE独有:取消事件冒泡、 e.cancelBubble = true; } // 事件冒泡:封装的兼容方法、 function stopBubble(event) { if (event.stopPropagation) { // W3C标准:取消事件冒泡、 event.stopPropagation(); } else { // IE独有:取消事件冒泡、 event.cancelBubble = true; } } // 取消右键出菜单事件、 document.oncontextmenu = function(e) { // W3C标准:取消右键菜单 e.preventDefault(); // IE独有:取消右键菜单 e.returnValue = false; // 句柄的写法,兼容性特别好、 return false; } // 事件冒泡:封装的兼容方法、 function cancelHandler(event) { if (event.preventDefault) { // W3C标准:取消右键菜单 event.preventDefault(); } else { // IE独有:取消右键菜单 event.returnValue = false; } } ``` ## :-: ECMS 文档对象、(document) ``` <div class="demo" id="a0"></div> <script> // var div = document.getElementsByClassName('class'); // var div = document.getElementById('a0'); var div = document.getElementsByTagName('div'); // 标签选择器 div[0].style.width = '100px'; //修改样式 div[0].style.height = '100px'; // div[0].style.backgroundColor = '#225'; div[0].style.border = '2px solid #f40' div[0].innerHTML = '改变dom元素的文本内容'; </script> ``` ``` // JavaScript的元素选择、像CSS一样选。 不足:静态的,不同步。用得少; var div = document.querySelector('div.demo>span'); //只能选一个 var div_arr = document.querySelectorAll('div.demo>span'); //选出来的是数组; ``` ``` var div = document.body.createElement('div') //创建一个div document.body.appendChild(div); //在body的尾部插入这个div元素 div.innerHTML = 'Hello World!' //写入div元素的内容 //元素的删除操作 var 变量 = div.removeChild(span); //删除子元素,返回当前被删除的元素值; span.remove(); //无参数,自我销毁; ``` ## :-: <a href="http://www.w3school.com.cn/jsref/jsref_obj_date.asp">时间对象(Data)</a> ``` var date = new Date(); console.log(date); //打印 Sun Nov 25 2018 20:22:11 GMT+0800 (中国标准时间) // .get 取 .set 设置 // .getTime() 取时间戳、 ``` ## :-: 定时器 ``` //定时器·循环 var Interval = setInterval(function() { //代码块、 }, 1000) clearInterval(Interval); //销毁定时器 //定时器·延时执行 (特点:只执行一次) var Interval = setTimeout(function(){ //代码块、 },1000) clearInterval(Interval); //销毁定时器 ``` ## :-: 置滚动条 ``` scroll(x, y); //绝对位置; scrollBy(x, y); //相对位置,这个可以累加; ``` ## :-: 改变元素样式 ``` var div = document.getElementsByTagName('div')[0]; //选中指定HTML元素、 var style = getComputedStyle(div, null); //返回当前div展示出来的所有样式,属性对象 (只读) 参数2为选择伪元素; console.log(style); var style = div.style; //返回当前div行间样式,属性对象; console.log(style); var style = div.style.color = '#f40'; //通过修改行间属性,间接的改变CSS显示样式; div.className = 'demo'; //通过改变class属性值,可以巧妙的改变其样式; div.id = 'demo'; ``` ## :-: call/appyl方法 ``` //改变this指向,传参列表不同、 Cra.call(this,'a','b','c'); var arr = ['a','b','c']; Cra.appyl(this,arr); Cra.appyl(this,['a','b','c']); //简写 ``` ## :-: 元素节点的4个属性、 ``` <div class="demo" id="a01">测试</div> <script> var div = document.getElementsByClassName('demo')[0]; //元素节点的4个属性、 div.nodeName //元素的标签名,大写形式表示、 只读 div.nodeValue //Text节点或Comment节点的文本内容、可读写 div.nodeType //该节点的类型,只读 div.attributes //Element节点的属性集合、类数组 </script> ``` ## :-: 节点树操作、 ``` // 查询 // ID选择器,唯一的、 var span = document.getElementById('id'); // 标签选择器,数组(arr)类型、 var div = document.getElementsByTagName('div')[0]; // 通过class选择,数组(arr)类型、 var div_1 = document.getElementsByClassName('class')[0]; // 创建 // 创建一个文本节点,并赋值到变量、 var text = document.createTextNode('创建文本节点'); // 创建一个元素节点,并赋值到变量、 var span = document.createElement('span'); var p = document.createElement('p'); // 插入 // 将文本节点(text),插入到html页面里去、 span.appendChild(text); // 将元素节点(Element),插入到html页面里去、 div.appendChild(span); // 相对于某元素前面插入;div是父级元素,在div里面的span元素节点前面插入p标签、 div.insertBefore(p, span); // 删除节点 // 通过父级删除节点,类似于剪切操作。会把节点返回出来; var span = div.removeChild(span); // 节点销毁自身,没有返回值、 div_1.remove(); // 替换 // 拿p元素,替换div父级元素下的span元素;返回被替换的span元素、 var span = div.replaceChild(p, span); // 元素属性 // 修改标签里面的文本内容、 div.innerHTML = '文本的内容'; // 元素的方法 // 设置元素的属性、(优点:可以自定义设置) div.setAttribute('class', 'demo'); // 取元素的属性、 div.getAttribute('class'); //返回 demo ``` ## :-: HTML结构解析完,异步加载、 ``` // 原生js实现,异步加载、可以实现按需加载、 function loadScript(url, callback) { var script = document.createElement("script"); script.type = "text/javascript"; if (script.readyState) { script.onreadystatechange = function() { if (script.readyState == "complete" || script.readyState == "loaded") { callback(); } } } else { script.onload = function() { callback(); } } script.src = url; document.head.appendChild(script); } // 演示例程、 loadScript('js/demo.js', function() { // 执行'js/demo.js'里面的函数、 abc(); a(); b(); }); ``` ## :-: DOM元素解析完成事件、 ``` document.addEventListener('DOMContentLoaded', function() { // DOM元素解析完成事件、 var div = document.getElementsByTagName('div'); console.log(div); }, false) // 类似于jQery、 $(function(){ // 执行函数体、 }); ``` ## :-: 正则表达式 ([api](http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp)) ``` // 转义符号: // \r —— 行结束符 \n —— 换行 (正常情况下 一个换行 = \r\n) // \t —— 制表符 // 正则表达式的写法 // var reg = new RegExp('[A-z]', 'g'); 第一种写法、 // var reg = /[A-z]/g; 第二种写法、 // i 不区分大小写、 // g 全局匹配、 // m 多汗匹配、 // (abc|bcd) 匹配abc或者bcd、 // 默认是贪婪匹配原则、 var reg = /[\w]/igm; var str = "abcdefgh\nasfkjjnef\nasjdafij\naskmf"; var demo = reg.test(reg); // 测验str中是否含有reg片段。返回 true、false console.log(demo); // 返回结果:true var demo = str.match(reg); // 挑选出正则匹配出来的片段,以数组形式展现、 console.log(demo); // 返回结果:数组类型、 // var reg = /(a)/1/g; /1 的意思是反向引用第1个括号的内容、 var str = 'aabb'; var str_1 = str.replace('a', 'z'); // 文本替换(只能替换掉第1个)、 console.log(1, str_1); // 返回结果:"zabb" var str_1 = str.replace(/a/, 'z'); // 文本替换(只能替换掉第1个)、 console.log(2, str_1); // 返回结果:"zabb" var str_1 = str.replace(/a/g, 'z'); // 文本替换(会全部替换掉)、 console.log(3, str_1); // 返回结果:"zzbb" // 以下是配合正则,高级文本替换。$1、$2分别表示第1和第2个括号的内容, var str_1 = str.replace(/(\w)\1(\w)\2/g, '$2$2$1$1'); console.log(4, str_1); // 返回结果:"bbaa" // 实例:用正则替换·转小驼峰、 var str = 'the-first-name'; var reg = /-(\w)/g; console.log(str.replace(reg, function($, $1) { // console.log($, $1); return $1.toUpperCase(); })); // 返回字符串(小驼峰):'theFirstName' // 正向预查(a(?=b) 选出后面带b的a) str = '1abaa1abuuhuaa'; reg = /[\w]{3}a(?=b)/g; console.log(str.match(reg)); // 返回数组:["aa1a"] "1ab'aa1a'buuhuaa" str = 'asdfv11aaaaaaaaaaaaaabbbbbbccccc'; reg = /([\w])\1*/g; console.log(str.replace(reg, '$1')); // 返回字符串:'asdfv1abc' ``` ## :-: new Fn(); —— 小测试、 ``` function Fn() { this.a = 123; this.b = [1, 515, 5, 16]; console.log('demo'); //会被正常执行、 // ····· 以下情况 不会改变构造函数的结果 ····· // return 123234; // 无效 // return '123234'; // 无效 // return true; // 无效 // ····· 以下情况 会改变构造函数的结果 ····· // return [3, 156, 5, 11, 5]; // 有效 // return { // b: 321 // }; // 有效 // return function() {console.log(123);}; // 有效 // ····· 特殊情况 ····· // return this.a; // 原始值,无效、 // return this.b; // 数组,有效、 // 总结:返回原始值时不会改变其结果,返回对象类型时会改变 new Fn() 后的结果、 } var fn = new Fn(); console.log(fn); ``` ## :-: <a href="http://www.w3school.com.cn/jsref/dom_obj_window.asp">Window 对象(BOM)</a> ``` window.alert('弹出提示框'); window.confirm('弹出选择框,true/false'); window.prompt('弹出输入框,返回输入的文本'); window.onbeforeunload = function() {return '关闭页面前,会弹出提示询问是否关闭';} // 弹出新的窗口、 窗口名(window.name='demo') 如第二个参数('demo')省略,则只创建标签页、 window.open('https://www.baidu.com', 'demo', 'width=300,height=200') window.open('https://www.baidu.com') // window.history对象 history.length; // 返回当前窗口(标签页)中,历史URL变动的次数、 history.back(); // 后退 history.forward(); // 前进 history.go(-1); // -2 = 后退2次,0 = 刷新,2 = 前进2次、 // window.location对象(可读/可写) // 属性、 location.href // 完整URL location.hostname // 域名 location.hash // 锚点(#) location.pathname // 路径部分 location.search // ?号后面的数据参数 location.protocol // 传输协议(如:http/https) // 方法、 location.assign('https://www.baidu.com'); // 加载新的文档、 location.reload(true); // 重新加载当前文档、可选参数:false = 直接取缓存加载、true = 重新加载云端的文档 ``` ## :-: js收官(碎片化知识) ``` <p> <!-- label标签可以绑定一个输入框, --> <label for="demo">当点击时输入框获得焦点、</label> <input type="text" id="demo"> </p> <!-- 特性(天生自带):id type value class --> <!-- 属性(后天有的):自己加的 date --> <script> // 图片·预加载 var oImg = document.createElement('img');\ // 创建img标签、 var oImg = new Image(); // img标签加载完成事件、 oImg.onload = function() { var div = document.getElementById('demo'); // 将img标签插入到div里去,此时this为img标签对象、 div.appendChild(this); } // 开始加载图片、 oImg.src = 'http://xx.com/demo/xxx.png'; </script> ``` ## :-: 判断变量是否为Document对象的方法、 ``` if (selector instanceof Element) { // 判断selector是dom对象、 } ```