Javascript
一、概述
脚本语言
解释性
解释器作为浏览器一部分
弱类型,定义变量时不需要指定类型。
动态类型,变量类型可以发生变化。
基于原型继承
内置支持类型
作用:给页面添加动态功能。
二、JS组成
ECMAScript:js标准语法
文档对象模型(DOM)
浏览器对象模型(BOM)
三、JS的导入
3.1 在页面元素中使用
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="点击我试试" οnclick="alert('Hello,world')"/> </body> </html>
3.2 在script标签中使用
script标签可以放在页面大多数位置,但是推荐放到最后,html的外面。
注意:type属性可以不写,如果写,值应该是text/javascript
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="点击我试试1" οnclick="fn1()"/> </body> </html> <script type="text/javascript"> function fn1(){ alert('Hello'); } </script>
3.3 外部导入
使用script引入外部的js,可以在head中引入,也可在大多数位置引入,推荐写在最后。
type属性可以不写,如果写,值应该是text/javascript
结束标签必须要写,不能直接改成自结束。
不能在中间写js代码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="点击我试试2" οnclick="fn2()"/> </body> </html> <script type="text/javascript" src="js/common.js" ></script>
四、变量
var作为变量定义的关键字。
弱类型,动态类型,命名规则与Java相似。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> </html> <script> var n = 100 // 弱类型 // 类似Java中的sout console.log(n) // 动态类型 n = "hello, world" console.log(n) </script>
五、基本类型
基本类型有5种:
Number
String
Boolean
Undefined
Null
<script> var age = 9; // number console.log(typeof(age)); console.log(age / 2); // 数字不区分小数整数,所以9/2 =4.5 var name = "mary"; console.log(typeof(name)); // string var flag = true; console.log(typeof(flag)); // boolean var phone; console.log(phone); // undefined console.log(typeof(phone)); // undefined var person = null; console.log(person); // null console.log(typeof(person)); // object </script>
六、引用类型
对象类型:Object类型。
语法:
<script> // 使用对象类型 var obj = new Object(); obj.name = "张三"; obj.sex = "男"; obj.say = function(){ alert("hello, world"); } console.log(obj.name); console.log(obj.sex); var n = "name"; console.log(obj[n]); console.log(obj["sex"]); obj.say(); // 使用map var m = {"name":"李四", sex:"男"} // JSON(JavaScript Object Notation)格式 console.log(m.name); console.log(m.sex); console.log(m["name"]); console.log(m["sex"]); </script>
数组类型:
<script> // 定义数组,两种方式 var arr1 = new Array(); var arr2 = [1,2,3,4]; // 设置数组的值 arr1[0] = 5; arr1[1] = 10; console.log(arr1[1]); console.log(arr1.length) // 2 arr1[10] = "hello"; console.log(arr1[10]); console.log(arr1.length) // 11 console.log(arr1[5]); // undefined // js中数组有java中集合的作用 arr2[arr2.length] = 5; console.log(arr2[4]); // 通过push添加元素 arr2.push(10); console.log(arr2[5]); // 循环遍历 for (var i=0;i<arr2.length;i++) { console.log("i==" + arr2[i]); } // for in循环 // 注意:i还是下标 for(var i in arr2){ console.log("==" + arr2[i]); } // splice可以删除,可以修改,可以添加 var arr3 = [1,2,3,4,5,6]; // 从下标3开始删除2个元素 // arr3.splice(3, 2) // 从下标3开始删除0个元素,添加8和9,相当于添加 // arr3.splice(3, 0, 8, 9) // 从下标3开始删除2个元素,添加8和9,相当于修改 arr3.splice(3, 2, 8, 9) console.log(arr3) </script>
七、运算符
7.1 算术运算符
与Java类似,不同之处在于,js中只有number类型,所以5/2结果为2.5
7.2 赋值运算符
与Java类似
7.3 逻辑运算符
与Java类似
7.4 关系运算符
大多与Java类似
==:比较值是否相等,所以数字2与字符串"2"是相等的。
===:即比较值也要比较类型,所以数字2与字符串"2"不相等。
<script> var n = 2; var m = "2"; console.log(n == m) // true console.log(n === m) // false </script>
7.5 三目(三元)运算符
与Java类似
7.6 分支结构
if结构与Java用法一致。
但是判断条件与Java有区别,Java中判断条件必须是布尔值。而JS中0、null、undefine、NaN表示false,其他表示true。
// 以下代码是可以执行的
if(1){
}
注意:NaN是not a number的缩写,表示不是数字。如果变量没有定义,则会报错。
变量没有定义和undefine区别:
var a; console.log(a); // undefine console.log(b); // 会报错 b is not define console.log(a.name); // 会报错
switch与Java一致。
7.7 循环结构
JS中的for的基本用法,while、do-while、break、continue与Java一致。
注意:for循环中一定不要写int i,JS中没有int
for...in循环
var arrstr = ["mary", "jack", "tom", "andy"]; for(var i = 0; i < arrstr.length; i++){ console.log(arrstr[i]); } // 注意for in循环中的变量还是下标,与Java的foreach不同 for(var s in arrstr){ console.log(arrstr[s]); }
八、函数
8.1 函数的定义与调用
函数定义的语法:
function 函数名(参数列表){
}
函数调用的语法:
函数名()
注意:在JS中,函数的调用时,如果函数有参数,可以传相应的参数,也可以少传或不传,但是无论如何,传入的参数都是按顺序匹配。
function m1(){ alert(5); } function m2(m, n){ alert(m); } function m3(m = 10, n){ // 10为默认值,没有传参时值为10 alert(m); } function m4(){ return 5; // 有返回值就return,没有就不用return } m2(8); // 显示8 m2("hello", 5); // 显示hello m2(); // 显示undefine m3(); // 显示10 m3("hello"); // 显示hello var n = m4(); // 得到函数调用的返回值 alert(n);
8.2 函数变量
类似于Java中方法引用。或者C语言中的方法指针。
var n = m1; // 定义变量,值为一个函数 n(); // 调用该函数 function m1(){ alert(5); }
8.3 函数参数
m2(m1); var n = m1; m2(n); function m1(){ alert("hello"); } // 由于函数中m进行函数调用,意味着m参数必须传入一个函数 function m2(m){ m(); }
8.4 匿名函数
var n = function(){ alert("hello"); }; n(); // 将匿名函数传入到函数的参数中 m2(function(){ alert("world"); }); function m2(m){ m(); }
8.5 函数的返回值
function f1(){ // 第一种写法,函数中定义函数 // var n = function(){ // alert("hello"); // } // 第二种写法,函数中定义函数 // function n(){ // alert("hello"); // } // return n; // 使用匿名函数 return function(){ return function(){ alert("world"); } } } var m = f1(); m()(); f1()()();
九、弹窗函数
alert(msg)弹出一个确定按钮的窗口。
confirm(msg)弹出一个有确定和取消按钮的窗口。
<script> function fn1(){ if(confirm("确定要删除吗?")){ alert("你点击了确定") }else{ alert("你点击了取消") } } </script>
prompt(msg, default)弹出一个可以输入内容的窗口。
msg:提示信息
default:输入框中的默认值
返回值为输入的内容,如果没有输入任何内容,点击确定后返回值为空串,如果点击取消,返回null
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="输入" οnclick="fn2()"/> </body> </html> <script> function fn2(){ var r = prompt("请输入姓名", "mary") if(r){ alert("你点击了确定") }else{ alert("你点击了取消或者没有输入任何内容") } } </script>
十、系统函数
parseInt():将一个内容转换成整数。
<script> var n = 5.5; console.log(parseInt(n)); // 将小数转换成整数 n = "123"; console.log(parseInt(n) + 1); // 将字符串转换成整数 n = "235a34563"; console.log(parseInt(n) + 1); // 236,将字符串转换成整数 n = "a234"; console.log(parseInt(n)); // 得到NaN </script>
parseFloat():将一个内容转换成小数。
<script> var n = 5.5; console.log(parseFloat(n)); // 将小数转换成小数 n = "123.3"; console.log(parseFloat(n) + 1); // 将字符串转换成小数 n = "235a34563"; console.log(parseFloat(n) + 1); // 236,将字符串转换成小数 n = "a234"; console.log(parseFloat(n)); // 得到NaN </script>
isNaN():不是数字返回true,是数字返回false
不会关心类型,只会判断值是否不是数字。
<script> console.log(isNaN("235a")); // true console.log(isNaN("235")); // false console.log(isNaN(235)); // false </script>
十一、事件
鼠标操作:
onclick:单击
ondbclick:双击
onmouseup:按键弹起
onmousedown:按键按下
onmouseover:当鼠标移入
onmouseout:当鼠标移出
onmousemove:当鼠标移动
onmouseenter:当鼠标移入
onmouseleave:当鼠标移出
onmousewheel:滚轮滚动
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> div{ width: 600px; height: 240px; border: 1px solid #ccc; display: none; } </style> </head> <body> <input type="button" value="手机" οnmοuseοver="fn1()" οnmοuseοut="fn2()"/> <div id="div1"> <ul> <li>苹果</li> <li>华为</li> <li>小米</li> </ul> </div> </body> </html> <script> function fn1(){ // 得到div1 document.getElementById("div1").style.display = "block"; } function fn2(){ // 得到div1 document.getElementById("div1").style.display = "none"; } </script>
键盘操作:
onkeydown:键盘按下
onkeyup:键盘弹起
onkeypress:键盘敲击
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> *{ padding: 0px; margin: 0px; } </style> </head> <body> <div id="div1" style="width: 50px;height: 50px;background-color: red;position: absolute;top: 50px;left: 50px;"></div> </body> </html> <script> var d = document.getElementById("div1"); document.onkeydown = function(e){ // 得到按键的编码 // alert(e.keyCode); if(e.keyCode == 37){ // left d.style.left = (parseInt(d.style.left) - 5) + "px"; }else if(e.keyCode == 38){ // up d.style.top = (parseInt(d.style.top) - 5) + "px"; }else if(e.keyCode == 39){ // right d.style.left = (parseInt(d.style.left) + 5) + "px"; }else if(e.keyCode == 40){ // down d.style.top = (parseInt(d.style.top) + 5) + "px"; } }; </script>
其他事件:
onload:加载完成后执行,写在body标签中表示页面加载完成后执行
onsubmit:表单提交事件,写在form标签中
onchange:值改变事件,一般用在表单元素中。
onblur:失去焦点事件
onfocus:获得焦点事件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body οnlοad="fn1()"> <form οnsubmit="return fn5()" action="列表.html" method="get"> <input type="text" οnblur="fn3()" name="username" id="userTxt" placeholder="请输入用户名"/> <span id="span1"></span> <br /> <!--密码框--> <input type="password" οnfοcus="fn4()" name="password" id="pwdTxt" value="" placeholder="请输入密码"/><br /> 省份:<select id="sel" οnchange="fn2()" name="province"> <option value="">请选择</option> <option value="1">湖北</option> <option value="2">湖南</option> </select><br /> 城市:<select id="sel1" name="city"> </select><br /> <!--提交按钮,点击后会提交表单到action对应的地址--> <input type="submit" value="提交"/> </form> </body> </html> <script> var u = document.getElementById("userTxt"); var p = document.getElementById("pwdTxt"); var s = document.getElementById("sel"); var s1 = document.getElementById("sel1"); var span1 = document.getElementById("span1"); function fn1(){ u.value = ""; p.value = ""; s.value = ""; } function fn2(){ if(s.value == "1"){ s1.options.length = 0; s1.options.add(new Option("武汉", "1")); s1.options.add(new Option("鄂州", "2")); s1.options.add(new Option("黄石", "3")); }else if(s.value == "2"){ s1.options.length = 0; s1.options.add(new Option("长沙", "4")); s1.options.add(new Option("株洲", "5")); s1.options.add(new Option("岳阳", "6")); } } function fn3(){ if(u.value.length < 6){ // innerHTML可以显示标签样式 // innerText只能显示文本 span1.innerHTML = "<font color='red'>用户名长度不能低于6位<font>"; // 获得焦点 // u.focus(); // 将内容全选 // u.select(); } } function fn4(){ p.value = "123456"; } function fn5(){ if(u.value.length < 6){ alert("用户名不合法") return false } if(p.value.length < 6){ alert("密码不合法") return false } if(s.value == ""){ alert("必须选择一个省份") return false } return true } </script>
十二、DOM操作
当页面加载后,页面上HTML元素,统称为文档对象模型(DOM)。
DOM操作,即使用js对文档对象模型中的元素进行操作。
对HTML元素本身进行增删改查操作
对HTML元素的样式进行操作
12.1 查找HTML元素
主要有三种方法:
getElementById(""):通过id属性获取某个元素。
getElementsByTagName(""):通过标签名称得到一组元素。
getElementsByClassName(""):通过class名称得到一组元素。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> .c2{ width: 50px; height: 50px; } </style> </head> <body> <input type="checkbox" οnclick="fn2()" id="chk"/><br /> <input type="checkbox" class="c1 c2"/> <input type="checkbox" class="c1"/> <input type="checkbox" class="c1"/> <input type="checkbox" class="c1"/> <input type="checkbox" class="c1"/> <input type="checkbox" class="c1"/> <input type="checkbox" class="c1"/> <!--button标签默认是submit,需要设置type属性--> <button type="button" οnclick="fn1()">点击</button> </body> </html> <script> function fn1(){ var arr = document.getElementsByTagName("input"); for(i in arr){ arr[i].checked = true; } } function fn2(){ // 得到复选框是否被勾选的状态 var c = document.getElementById("chk").checked; // 得到class属性中有c1的元素 var arr = document.getElementsByClassName("c1"); for(i in arr){ arr[i].checked = c; } } </script>
12.2 修改HTML元素内部内容
有两种方式:
innerText:只能显示文本内容,如果有标签会以文本的方式显示。
innerHTML:可以显示标签的效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1 align="center">Hello, world</h1> <input type="button" value="点击" οnclick="fn1()"/> </body> </html> <script> function fn1(){ var arr = document.getElementsByTagName("h1"); // 只会以文本的方式显示 // arr[0].innerText = "<font color='red'>AAAA</font>"; // 可以显示出红色的字体 arr[0].innerHTML = "<font color='red'>AAAA</font>"; } </script>
12.3 修改属性
有两种方式:
对象.属性
通过getAttribute("属性名")获取属性值,通过setAttribute("属性名", "属性值");来设置属性值。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <a id="a1" href="https://www.baidu.com">百度</a> <img id="img1" src="img/13.png" width="200px"/><br /> <input type="button" value="点击" οnclick="fn1()"/> </body> </html> <script> function fn1(){ var a1 = document.getElementById("a1"); a1.innerText = "千锋"; a1.setAttribute("href", "https://www.qfedu.com"); // a1.href = "https://www.qfedu.com"; var img1 = document.getElementById("img1"); img1.src = "img/14.png"; } </script>
12.4 修改css
一般可以通过style属性来修改。
注意:在样式的名称可能类似border-width,在js中会使用驼峰式即borderWidth。
但是style只能得到行内的样式,而无法得到内部或外部加载的样式。
如果要想获取非行内样式,IE9以下的版本与其他浏览器有差异。
function getStyle(elem, attr){ if(window.getComputedStyle){ // w3c标准,支持chrome,firefox,safari,IE9+等 return window.getComputedStyle(elem)[attr]; }else if(elem.currentStyle){ // IE其他版本 elem.currentStyle[attr]; }else{ return null; } }
<input type="text" οnblur="fn3()" name="username" id="userTxt" placeholder="请输入用户名"/> <img id="img1" style="display: none;" src="img/icon1.png" /> <br /> <!--密码框--> <input type="password" οnfοcus="fn4()" name="password" id="pwdTxt" value="" placeholder="请输入密码"/><br /> <script> function fn3(){ if(u.value.length < 6){ document.getElementById("img1").style.display = "inline"; }else{ document.getElementById("img1").style.display = "none"; } } </script>
12.5 事件的添加和移除
如果直接在标签中写事件,意味着该事件是静态,不能够动态操作。可以通过下面两种方式,动态给元素添加事件:
元素.onXxxx = function(){}
元素.addEventListener(事件名, 函数, 冒泡或捕获)
使用元素.onXxxx = function(){},可以多次赋值,但是后面的事件会覆盖前面的事件。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="设置事件1" οnclick="fn1()"/> <input type="button" value="设置事件2" οnclick="fn2()"/> <input id="btn1" type="button" value="事件2"/> </body> </html> <script> function fn1(){ var btn1 = document.getElementById("btn1"); btn1.onclick = function(){ alert("事件2"); }; } function fn2(){ var btn1 = document.getElementById("btn1"); btn1.onclick = function(){ alert("事件2事件2"); }; } </script>
上面的事件如果都设置了,只会保留后设置的事件。
使用元素.addEventListener(事件名, 函数, 冒泡或捕获), 三个参数含义分别为:
事件名:设置事件的名称,不需要写on,例如点击事件:click
函数:可以写已经定义了的函数名称,也可以写匿名函数
冒泡或捕获:可以不设置此参数,默认为false(冒泡),可以设置为true(捕获)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <input type="button" value="设置事件1" οnclick="fn1()"/> <input type="button" value="设置事件2" οnclick="fn2()"/> <input id="btn1" type="button" value="事件2"/> </body> </html> <script> function fn1(){ var btn1 = document.getElementById("btn1"); btn1.addEventListener("click", function(){ alert("事件2"); }); } function fn2(){ var btn1 = document.getElementById("btn1"); btn1.addEventListener("click", function(){ alert("事件2事件2"); }); } </script>
上面的案例,给元素添加了两次点击事件,当元素点击时,会分别执行两个事件,不会覆盖。
冒泡和捕获:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> #div1{ width: 200px; height: 200px; background-color: orange; } #div2{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <input type="button" value="设置div1事件1" οnclick="fn1()"/> <input type="button" value="设置div2事件2" οnclick="fn2()"/> <div id="div1"> <div id="div2"> </div> </div> </body> </html> <script> function fn1(){ var div1 = document.getElementById("div1"); div1.addEventListener("click", function(){ console.log("div1事件") }); } function fn2(){ var div2 = document.getElementById("div2"); div2.addEventListener("click", function(){ console.log("div2事件"); }); } </script>
上面的操作,当给元素设置了两次事件后,由于div2在div1中,默认是冒泡,所以当点击div2时,会先执行div2的点击事件,再执行div1的点击事件。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> #div1{ width: 200px; height: 200px; background-color: orange; } #div2{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <input type="button" value="设置div1事件1" οnclick="fn1()"/> <input type="button" value="设置div2事件2" οnclick="fn2()"/> <div id="div1"> <div id="div2"> </div> </div> </body> </html> <script> function fn1(){ var div1 = document.getElementById("div1"); div1.addEventListener("click", function(){ console.log("div1事件") }, true); } function fn2(){ var div2 = document.getElementById("div2"); div2.addEventListener("click", function(){ console.log("div2事件"); }, true); } </script>
上面将冒泡修改为捕获,所以当点击div2时,会先执行div1的点击事件,再执行div2的点击事件。
事件的移除:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> #div1{ width: 200px; height: 200px; background-color: orange; } #div2{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <input type="button" value="设置div1事件1" οnclick="fn1()"/> <input type="button" value="设置div2事件2" οnclick="fn2()"/> <input type="button" value="移除事件" οnclick="fn3()"/> <div id="div1"> <div id="div2"> </div> </div> </body> </html> <script> function fn1(){ var div1 = document.getElementById("div1"); div1.addEventListener("click", function(){ console.log("div1事件") }); } function fn2(){ var div2 = document.getElementById("div2"); div2.addEventListener("click", function(){ console.log("div2事件") }); } function fn3(){ var div2 = document.getElementById("div2"); div2.removeEventListener("click", function(){ console.log("div2事件") }); } </script>
上面的移除div2事件的代码移除经测试后,无法实现,因为使用的匿名函数,应该改为以下方式:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> #div1{ width: 200px; height: 200px; background-color: orange; } #div2{ width: 100px; height: 100px; background-color: blue; } </style> </head> <body> <input type="button" value="设置div1事件1" οnclick="fn1()"/> <input type="button" value="设置div2事件2" οnclick="fn2()"/> <input type="button" value="移除事件" οnclick="fn3()"/> <div id="div1"> <div id="div2"> </div> </div> </body> </html> <script> function fn1(){ var div1 = document.getElementById("div1"); div1.addEventListener("click", function(){ console.log("div1事件") }); } function fn2(){ var div2 = document.getElementById("div2"); div2.addEventListener("click", fn4); } function fn4(){ console.log("div2事件"); } function fn3(){ var div2 = document.getElementById("div2"); div2.removeEventListener("click", fn4); } </script>
12.6 新建和删除元素
当需要动态的新建和删除元素时,可以使用js来进行处理。
使用document.createElement("标签名"); 创建元素
使用appendChild将元素放入到指定位置。
也可以使用insertBefore来将元素放入到指定的位置。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> #div1{ width: 400px; height: 400px; background-color: orange; } </style> </head> <body> <div id="div1"> <span id="span1">111</span> </div> <input type="button" value="添加元素" οnclick="fn1()"/> </body> </html> <script> function fn1(){ var h = document.createElement("hr"); // 将h添加到div1的里面的最后 // var div1 = document.getElementById("div1"); // div1.appendChild(h); // 将h添加到span1中的最前面 var span1 = document.getElementById("span1"); var refElement=span1.childNodes[0]; span1.insertBefore(h, refElement); } </script>
删除元素:
元素.remove(); 删除某个元素
父元素.removeChild(子元素); 删除父元素中的某个子元素
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> #div1{ width: 400px; height: 400px; background-color: orange; } </style> </head> <body> <div id="div1"> <span id="span1">111</span> <span id="span2">222</span> <span id="span3">333</span> <span id="span4">444</span> </div> <input type="button" value="删除元素" οnclick="fn2()"/> </body> </html> <script> function fn2(){ // 要删除span var span1 = document.getElementById("span1"); // // 删除自己 // span1.remove(); var div1 = document.getElementById("div1"); // 删除子元素 // div1.removeChild(span1); } </script>
十三、js定时器
setTimeout(函数名,延迟时间)多久后,执行相应的函数(仅执行一次)
clearTimeout(定时器名):停止
注意:时间单位为毫秒
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1 id="aa"></h1> <input type="button" value="开始" οnclick="fn1()"/> <input type="button" value="停止" οnclick="fn2()"/> </body> </html> <script> var h = document.getElementById("aa"); var s; function fn1(){ // 1秒后执行fn3 s = setTimeout(fn3, 1000); } function fn3(){ var d = new Date(); h.innerText = d.toLocaleString(); s = setTimeout(fn3, 1000); } function fn2(){ // 停止 clearTimeout(s); } </script>
setInterval(函数名,延迟时间)每隔多久后,执行相应的函数(执行多次)
clearInterval(定时器名):停止
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1 id="aa"></h1> <input type="button" value="开始" οnclick="fn1()"/> <input type="button" value="停止" οnclick="fn2()"/> </body> </html> <script> var h = document.getElementById("aa"); var s; function fn1(){ // 每隔1秒后执行fn3 s = setInterval(fn3, 1000); } function fn3(){ var d = new Date(); h.innerText = d.toLocaleString(); } function fn2(){ // 停止 clearInterval(s); } </script>
案例:倒计时
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input id="btn1" type="button" value="点击" οnclick="fn4()"/> </body> </html> <script> var btn1 = document.getElementById("btn1"); function fn4(){ var n = 10; var e = setInterval(function(){ btn1.disabled = true; btn1.value = n--; if(n < 0){ clearInterval(e); btn1.disabled = false; btn1.value = "点击"; } }, 1000) } </script>
十四、BOM
BOM浏览器对象模型,主要是指使用js操作浏览器。
整个浏览器顶层为window,window下面又有几个常用的对象属性:
history
location
navigator
screen
14.1 window对象
是js的顶层对象,表示浏览器的窗口。
所有的函数、变量均属于window。例如:window.alert()、window.document,自定义的函数fn1()也是属于window的,可以写为window.fn1()
window.innerHeight:窗口高度
window.innerWidth:窗口宽度
注意:得到的当前浏览器中的文档区域的宽度和高度。当窗口缩小或放大时,会改变值。
window.open():打开新窗口
window.close():关闭窗口
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="点击" οnclick="fn1()"/> <input type="button" value="打开窗口" οnclick="fn2()"/> <input type="button" value="关闭窗口" οnclick="fn3()"/> </body> </html> <script> function fn1(){ alert(window.innerWidth + "===" + window.innerHeight); } function fn2(){ // 打开窗口 window.open("元素的创建和删除.html", "aaa") } function fn3(){ // 关闭当前窗口 window.close() } </script>
14.2 当前屏幕对象
screen.availWidth:浏览所能够最大占据屏幕的宽度
screen.availHeight:浏览所能够最大占据屏幕的高度
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="点击" οnclick="fn1()"/> </body> </html> <script> function fn1(){ alert(screen.availWidth + "===" + screen.availHeight); } </script>
14.3 location对象
地址栏对象。用来对地址进行操作。能够跳转页面,或者刷新页面。
属性:
href:地址
hostname:主机名
protocol:协议
port:端口号
注意:可以通过修改href属性来跳转页面。
方法:
reload():刷新页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="点击" οnclick="fn1()"/> <input type="button" value="刷新" οnclick="fn2()"/> <input type="button" value="跳转页面" οnclick="fn3()"/> </body> </html> <script> function fn1(){ console.log("href=" + location.href); console.log("hostname=" + location.hostname); console.log("protocol=" + location.protocol); console.log("port=" + location.port); } function fn2(){ location.reload(); } function fn3(){ // 通过修改href属性来跳转页面 location.href = "冒泡捕获.html"; } </script>
14.4 history对象
history主要是操作浏览器的历史记录。
主要用前进、后退。
back():后退一次
forward():前进一次
go(n):前进或后退n次,n为正数表示前进,n为负数表示后退。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="跳转页面" οnclick="fn1()"/> <input type="button" value="前进" οnclick="fn2()"/> <input type="button" value="go前进" οnclick="fn3()"/> </body> </html> <script> function fn1(){ location.href = "location对象.html"; } function fn2(){ history.forward(); } function fn3(){ history.go(2); } </script>
14.5 navigator对象
查看浏览器的信息。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" value="点击" οnclick="fn1()"/> </body> </html> <script> function fn1(){ console.log("appName=" + navigator.appName); console.log("appVersion=" + navigator.appVersion); console.log("appCodeName=" + navigator.appCodeName); console.log("platform=" + navigator.platform); console.log("userAgent=" + navigator.userAgent); } </script>
十五、正则表达式
是用来描述字符模式的对象。
作用:用来检查、搜索、替换字符串的模式。
基本语法:
var reg = new RegExp("pattern", "modifier");
var reg = /pattern/modifier
15.1 修饰符
i:不区分大小写
g:所有的都会匹配,而不是匹配到一个就停止
m:执行多行匹配
15.2 字符
[abc]:查找字符串中的任意一个字符。
[^abc]:查找不是字符串中的任意一个字符。
[0-9]:匹配一个数字
[a-z]:匹配一个小写字母
[A-Z]:匹配一个大写字母
[A-z]:匹配一个大小写字母
(red|green|blue):匹配其中的一个单词
15.3 元字符
.
:匹配任意一个字符,除了换行和行结束符
\w
:匹配单词字符,字母数字下划线
\W
:匹配非单词字符
\d
:匹配数字字符
\D
:匹配非数字字符
\s
:匹配空白字符
\S
:匹配非空白字符
15.4 量词
用来表示数量。
n+:表示至少一个
n*:表示0个到多个
n?:表示0个到1个
n{x}:表示x个
n{x,}:表示x个到多个
n{x,y}:表示x个到y个
^
表示开始$
表示结束
15.5 使用
正则表达式对象.test("字符串"); 返回true或者false
String对象.match("正则");返回一个或多个的匹配
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text" id="txt1" οnblur="fn1()"/><br /> <input type="text"/> </body> </html> <script> function fn1(){ var t = document.getElementById("txt1").value; // 验证邮箱 var reg = /^[A-z0-9]+@[A-z0-9]+[\.](com|cn|org|edu|net|gov)$/; // 验证手机号 // var reg = /^1(39|86|30|92|58)[0-9]{8}$/; // 验证用户名 // var reg = /^[\w]{6,16}$/; if(reg.test(t)){ alert("合法") }else{ alert("不合法") } } </script>
十六、创建对象的方式
var v = new Date();
16.1 直接使用属性赋值
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> </html> <script> function Student(name, age, sex="男"){ this.name = name; this.age = age; this.sex = sex; this.say = function(){ return "name = " + this.name + ", age = " + this.age + ", sex =" + this.sex; } this.say1 = function(){ // 定义变量接收this对象当前的引用 var that = this; function Cla(id, name){ this.id = id; this.name = name; this.say2 = function(){ return "id=" + this.id + ", name=" + this.name + ", studentname=" + that.name; } } var c = new Cla(1, "1班"); return c.say2(); } } var s = new Student("张三", 20, "女"); console.log(s.say1()); </script>
16.2 使用prototype
function Student(name, age, sex="男"){ this.name = name; this.age = age; this.sex = sex; } Student.prototype = { say:function(){ return "name = " + this.name + ", age = " + this.age + ", sex =" + this.sex; }, say1:function(){ // 定义变量接收this对象当前的引用 var that = this; function Cla(id, name){ this.id = id; this.name = name; this.say2 = function(){ return "id=" + this.id + ", name=" + this.name + ", studentname=" + that.name; } } var c = new Cla(1, "1班"); return c.say2(); } }; var s = new Student("张三", 20, "女"); console.log(s.say1());
注意:多个方法用逗号隔开。此处是键值对。
16.3 简单的单例模式
var Stu = (function(){ function Student(){ console.log("构造函数被调用") } var instance; var _static = { name: "Stu", getInstance : function(){ if(!instance){ instance = new Student(); } return instance; } } return _static; })(); var s = Stu.getInstance()
十七、画布和绘制
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/canvas.css"/> <script src="js/canvas.js" type="text/javascript" charset="utf-8"></script> </head> <body> <canvas id="myCanvas"></canvas> </body> </html>
window.onload = function(){ // 得到canvas(画布) var canvas = document.getElementById("myCanvas"); // 设置画布的大小 canvas.width = window.innerWidth; canvas.height = window.innerHeight; // 设置背景颜色 canvas.style.backgroundColor = "black"; // 得到上下文(画笔) var context = canvas.getContext("2d"); var i = 0; // 循环执行画圆 setInterval(function(){ context.clearRect(0,0, canvas.width, canvas.height); // 开始画画 context.beginPath(); // 设置实心画笔的颜色 context.fillStyle = "#" + Math.floor(Math.random() * 0xffffff).toString(16); // 设置空心画笔颜色 //context.strokeStyle = "#FFFFFF"; // 画一个宽度为50,高度为50的矩形 // context.rect(100,100,200,100); // 画线 // context.moveTo(100,100); // context.lineTo(200,200); // context.lineTo(100, 200); // context.lineTo(0,100); // 画圆 context.arc(200+i*20,200+i*20,100,0,Math.PI * 2,false); // 结束画画 context.closePath(); // 填充实心内容 context.fill(); // 填充空心内容 // context.stroke(); // i递增 //i++; }, 200); };
// 绘制图片 window.onload = function(){ var canvas = document.createElement("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; canvas.style.backgroundColor = "#333333"; document.body.appendChild(canvas); var context = canvas.getContext("2d"); // 创建一个图片对象 var img = new Image(); img.src = "img/2.png"; // 绘制图片 // 延时执行 setTimeout(function(){ //5个参数时含义 图片,x坐标,y坐标, 宽度,高度 /* 1、图片,2、图片中的起始x,3、图片中的起始y 4、图片中取得的宽度,5、图片中取得的高度 6、在画布中显示的x、7、在画布中显示的y 8、在画布中显示的宽度、9、在画布中显示的高度 */ context.drawImage(img, 100, 100, 500, 500); }, 500); };
十八、案例
18.1 案例1-模拟喷泉
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="js/particle.js" type="text/javascript" charset="utf-8"></script> <style type="text/css"> body{ margin: 0px; } </style> </head> <body> </body> </html>
window.onload = function(){ // 创建一个画布对象 var canvas = document.createElement("canvas"); // 设置大小和颜色 canvas.width = window.innerWidth; canvas.height = window.innerHeight; canvas.style.backgroundColor = "#333333"; // 将画布放置到body里 document.body.appendChild(canvas); // 得到画笔 var context = canvas.getContext("2d"); // 定义一个存放所有粒子的数组 var particles = [ ]; // 调用显示粒子 showParticle(); // 创建并显示粒子的方法 function showParticle(){ // 循环操作 setInterval(function(){ // 清空画布 context.clearRect(0,0,canvas.width, canvas.height); // 创建粒子 var p = new Particle(canvas.width * 0.5, canvas.height * 0.5); // 将粒子装入存放粒子的数组 particles.push(p); // 循环更新所有粒子的位置 for (var i = 0;i<particles.length;i++) { // 更新位置 particles[i].updateData(); } }, 50); } function Particle(x, y){ // 原坐标 this.x = x; this.y = y; // 初始出现的改变的y的值 this.yVal = -5; // 改变的x的值 this.xVal = Math.random() * 8 - 4; // 定义一个下降的重力加速度 this.g = 0.1; // 更新位置 this.updateData = function(){ // X值的变化 this.x = this.x + this.xVal; // Y值的变化 this.y = this.y + this.yVal; // 每次改变Y值速度的变化 this.yVal = this.yVal + this.g; // 生成一个随机颜色 context.fillStyle = "#" + Math.floor(Math.random() * 0xffffff).toString(16); // 将更新位置后的圆绘制出来 this.draw(); }; // 绘图的方法 this.draw = function(){ // 开始画图 context.beginPath(); // 画圆 context.arc(this.x, this.y,5,0,Math.PI * 2, false); // 结束画图 context.closePath(); // 填充 context.fill(); }; } };
18.2 俄罗斯方块
俄罗斯方块.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>俄罗斯方块</title> <link rel="stylesheet" href="css/common.css" /> </head> <body> <canvas id="tetris" width="320" height="640"></canvas> <canvas id="nextShape" width="200" height="160"></canvas> <canvas id="score" width="200" height="160"></canvas> </body> <script type="text/javascript" src="js/common.js" ></script> </html>
common.css
*{ padding: 0; margin: 0; } body{ background: url(../img/bg.png); } #tetris{ border: 2px solid white; border-radius: 5px; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; } #nextShape{ position: absolute; left: 40px; bottom: 160px; border-radius: 5px; background: orange; } #score{ position: absolute; left: 40px; top: 160px; border-radius: 10px; background: orange; }
common.js
// 定义一个俄罗斯方块的类 Tetris var Tetris = (function() { // 定义存放形状矩阵的数组 var layouts = [ [ [1, 1, 0], [0, 1, 1] ], [ [0, 1, 1], [1, 1, 0] ], [ [1, 0, 0], [1, 1, 1] ], [ [0, 0, 1], [1, 1, 1] ], [ [0, 1, 0], [1, 1, 1] ], [ [1, 1, 1, 1] ], [ [1, 1], [1, 1] ] ]; // 分数 var score = 0; // 行数 var row = 20; // 列数 var col = 10; // 构造函数 function Tetris() { // 创建游戏面板对象 this.board = new Board(); // 创建提示方块的对象 this.nextShape = new NextShape(); // 绘制提示的头部内容 this.nextShape.drawHeader(); this.score = new Score(); this.score.drawHeader(); // 回调 KeyBoard.call(this); // 调用自己的初始化方法 this.init(); } Tetris.prototype = { init: function() { // 调用添加键盘监听事件的方法 this.addEventHandlers(); var self = this; // 在图片源加载到内存的时候才能绘制出图片 this.board.shape.block.image.onload = function() { // 初始化board对象 self.board.init(); // 定时器 刷新canvas画布 self.timer = setInterval(function() { self.board.tick(); }, 1000); } } } // 创建游戏面板的类 Board function Board() { // 获取面板类的canvas画布 this.canvas = document.getElementById("tetris"); // 获取画笔 this.ctx = this.canvas.getContext("2d"); // 当前方块 this.shape = new Shape(); // 下一个方块 this.nextShape = new Shape(); // 存放已经下落的方块 this.list; } // 原型 定义方法 Board.prototype = { // 定义初始化的方法 init: function() { this.initList(); this.drawGridLine(); this.shape.init(); // 调用形状类的绘制形状的方法 this.shape.drawShape(this.ctx); // 初始化下一个形状 this.nextShape.init(); // 绘制下一个形状 window.Tetris.nextShape.drawNextShape(this.nextShape); window.Tetris.score.drawScore(); }, // 初始化list initList: function() { this.list = []; for (var i = 0; i < row; i++) { this.list[i] = []; for (var j = 0; j < 10; j++) { this.list[i][j] = 0; } } }, // 把下落的块堆积起来的方法 addShapeToList: function() { for (var y = 0; y < this.shape.layout.length; y++) { for (var x = 0; x < this.shape.layout[0].length; x++) { // 判断形状的某个位置上是否有方块 if (this.shape.layout[y][x] > 0) { // 有方块就保存到list二位数组中,其值为方块的颜色值加1 this.list[this.shape.currentY + y][this.shape.currentX + x] = this.shape.color + 1; } } } }, // 绘制已存在的方块的方法 drawList: function() { for (var y = 0; y < row; y++) { for (var x = 0; x < col; x++) { // 判断list中该位置上是否存在方块 if (this.list[y][x] > 0) { this.ctx.drawImage(this.shape.block.image, (this.list[y][x] - 1) * 32, 0, 32, 32, x * 32, y * 32, 32, 32); } } } }, // 定义画网格线条的方法 drawGridLine: function() { // 循环绘制横线 for (var i = 0; i < row; i++) { this.ctx.strokeStyle = "#ffffff"; this.ctx.beginPath(); this.ctx.moveTo(0, i * 32); this.ctx.lineTo(320, i * 32); this.ctx.closePath(); this.ctx.stroke(); } // 循环绘制竖线 for (var i = 0; i < col; i++) { this.ctx.strokeStyle = "#ffffff"; this.ctx.beginPath(); this.ctx.moveTo(i * 32, 0); this.ctx.lineTo(i * 32, 640); this.ctx.closePath(); this.ctx.stroke(); } }, // 定义方块自动下落的方法 tick: function() { if (this.validMove(0, 1)) { // 方块的Y坐标自动增加1 this.shape.currentY++; this.refresh(); } else { this.addShapeToList(); // 添加形状之后,调用消除方块的方法 this.clearLineBlock(); window.Tetris.score.drawScore(); // 表示方块下落到最下面 this.shape = this.nextShape; // 重新随机产生方块 this.nextShape = new Shape(); this.nextShape.init(); window.Tetris.nextShape.drawNextShape(this.nextShape); this.refresh(); } }, // 定义刷新画布的方法 refresh: function() { // 清除画布 this.ctx.clearRect(0, 0, 32*col, 32*row); this.drawGridLine(); this.drawList(); this.shape.drawShape(this.ctx); }, // 碰撞检测的方法 // x 表示方块在横向上的移动 // y 表示方块在纵向上的移动 validMove: function(x, y) { // 方块下一个位子的横坐标 var offsetX = this.shape.currentX + x; // 方块下一个位子的纵坐标 var offsetY = this.shape.currentY + y; // 判断方块是否掉出画布 if (offsetY + this.shape.layout.length > row) { // 返回 false 表示无效的移动 return false; } // 左右边界的碰撞检测 if (offsetX < 0 || offsetX + this.shape.layout[0].length > col) { return false; } // 方块与方块之间的碰撞检测 for (var y = 0; y < this.shape.layout.length; y++) { for (var x = 0; x < this.shape.layout[0].length; x++) { if (this.list[offsetY + y][offsetX + x] > 0 && this.shape.layout[y][x] > 0) { if(offsetY == 1){ clearInterval(window.Tetris.timer); alert("游戏结束"); } return false; } } } return true; }, // 消除一行或多行的方块 clearLineBlock: function() { // 循环遍历 list数组 for (var y = row - 1; y > 0; y--) { // 假设该行全部有方块,可以消除 var flag = true; for (var x = 0; x < col; x++) { // 如果该行元素存在空的,则假设不成立 if (this.list[y][x] == 0) { flag = false; } } // 如果标记为true,说明该行可以消除 if (flag) { for (var i = y; i > 0; i--) { for (var j = 0; j < col; j++) { // 消除一行方块,把上一行的数据往下挪 this.list[i][j] = this.list[i - 1][j]; } } // 因为数据往下挪,所以该行还得遍历 score += 100; y++; } } } } // 定义形状类 function Shape() { // 创建方块对象 this.block = new Block(); // 存放形状的矩阵 this.layout; // 形状的颜色 this.color; // 当前X坐标 this.currentX; // 当前Y坐标 this.currentY; } Shape.prototype = { init: function() { // 初始化矩阵 this.layout = layouts[Math.floor(Math.random() * 7)]; // 初始化颜色 this.color = Math.floor(Math.random() * 7); // 初始化横纵坐标 this.currentX = Math.floor((col - this.layout[0].length) / 2); this.currentY = 0; }, // 绘制形状的方法 drawShape: function(ctx) { // 两层循环遍历二维数组 // this.layout.length表示矩阵的高度 // this.layout[0].length表示矩阵的宽度 for (var y = 0; y < this.layout.length; y++) { for (var x = 0; x < this.layout[0].length; x++) { if (this.layout[y][x] > 0) { ctx.drawImage(this.block.image, this.color * 32, 0, 32, 32, (this.currentX + x) * 32, (this.currentY + y) * 32, 32, 32); } } } } } // 定义方块类 function Block() { // 创建图片对象 this.image = new Image(); // 指定图片源 this.image.src = "img/blocks.png"; // // 绘制方块的方法 // this.drawBlock = function(ctx) { // // 绘制图片的方法 // /* 第一个参数:图片源 // * 第二、三个参数:截取图片的起始点 // * 第四、五个参数:截取图片的大小 // * 第六、七个参数:绘制在canvas上的起始点 // * 第八、九个参数:绘制在canvas上的大小 // */ // ctx.drawImage(this.image, 32, 0, 32, 32, 64, 0, 32, 32); // } } // 键盘监听的类 function KeyBoard() { var self = this; var keys = { 37: "left", 38: "top", 39: "right", 40: "bottom" } // 添加监听 事件的方法 this.addEventHandlers = function() { // 添加键盘的监听事件 document.addEventListener("keydown", this.keyPress, true); } // 监听键盘事件的方法 this.keyPress = function(event) { // ASCII码 // alert(event.keyCode); // 判断按下的键是不是上下左右四个键 if (keys[event.keyCode]) { self.keyPressEvent(keys[event.keyCode]); } } // 键盘按下之后的任务代码方法 this.keyPressEvent = function(code) { switch (code) { // 方块向左移动 case "left": if (this.board.validMove(-1, 0)) { this.board.shape.currentX--; this.board.refresh(); } break; case "top": // 矩阵变形的操作 var lay = []; for (var x = 0; x < this.board.shape.layout[0].length; x++) { lay[x] = []; for (var y = 0; y < this.board.shape.layout.length; y++) { lay[x][y] = this.board.shape.layout[this.board.shape.layout.length - y - 1][x]; } } // 变形之后的偏移量 // var offsetX = this.board.shape.currentX + lay[0].length; // var offsetY = this.board.shape.currentY + lay.length; // // 正确的坐标 // var xZuoBiao = this.board.shape.currentX; // var yZuoBiao = this.board.shape.currentY; // // if (offsetX > col) { // xZuoBiao = col - lay[0].length; // } // if (offsetY > row) { // yZuoBiao = row - lay.length; // } if(lay[0].length + this.board.shape.currentX > col){ return; } // // 变形之后的矩阵和已存在的方块之间的碰撞检测 for(var y=0;y<lay.length;y++){ for(var x=0;x<lay[0].length;x++){ if(this.board.list[this.board.shape.currentY+y][this.board.shape.currentX+x] >0 && lay[y][x] > 0){ return; } } } // // this.board.shape.currentX = xZuoBiao; // this.board.shape.currentY = yZuoBiao; this.board.shape.layout = lay; this.board.refresh(); break; case "right": if (this.board.validMove(1, 0)) { this.board.shape.currentX++; this.board.refresh(); } break; case "bottom": if (this.board.validMove(0, 1)) { this.board.shape.currentY++; this.board.refresh(); } break; } } } // 下一个方块提示的类 function NextShape(){ this.canvas = document.getElementById("nextShape"); this.ctx = this.canvas.getContext("2d"); } NextShape.prototype = { // 绘制提示的头部 drawHeader:function(){ this.ctx.fillStyle = "black"; // 设置字体 this.ctx.font = "26px April"; // 设置文字对齐方式 this.ctx.textAlign = "center"; // 绘制文本,文本内容,x坐标,y坐标 this.ctx.fillText("Next",100,40); // 绘制矩形 this.ctx.fillRect(5,60,190,95); this.ctx.fill(); }, // 绘制提示的方块 drawNextShape:function(shape){ // 把显示形状的位置重新绘制成黑色 this.ctx.fillStyle = "black"; this.ctx.fillRect(5,60,190,95); this.ctx.fill(); for(var y=0;y<shape.layout.length;y++){ for(var x=0;x<shape.layout[0].length;x++){ if(shape.layout[y][x] > 0){ this.ctx.drawImage(shape.block.image,shape.color*32,0,32,32,40+x*32,80+y*32,32,32); } } } } } // 得分的类 function Score(){ this.canvas = document.getElementById("score"); this.ctx = this.canvas.getContext("2d"); } Score.prototype = { // 绘制提示的头部 drawHeader:function(){ this.ctx.fillStyle = "black"; // 设置字体 this.ctx.font = "26px April"; // 设置文字对齐方式 this.ctx.textAlign = "center"; // 绘制文本,文本内容,x坐标,y坐标 this.ctx.fillText("Score",100,40); // 绘制矩形 this.ctx.fillRect(5,60,190,95); this.ctx.fill(); }, drawScore:function(){ // 把显示形状的位置重新绘制成黑色 this.ctx.fillStyle = "black"; this.ctx.fillRect(5,60,190,95); this.ctx.fillStyle = "white"; this.ctx.font = "26px April"; this.ctx.textAlign = "center"; this.ctx.fillText(score,100,100); this.ctx.fill(); } } // 返回Tetris类的一个对象 return new Tetris(); })();