Javascript
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="点击我试试" onclick="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" onclick="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" onclick="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="输入" onclick="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="手机" onmouseover="fn1()" onmouseout="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 onload="fn1()">
<form onsubmit="return fn5()" action="列表.html" method="get">
<input type="text" onblur="fn3()" name="username" id="userTxt" placeholder="请输入用户名"/>
<span id="span1"></span>
<br />
<!--密码框-->
<input type="password" onfocus="fn4()" name="password" id="pwdTxt" value="" placeholder="请输入密码"/><br />
省份:<select id="sel" onchange="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" onclick="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" onclick="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="点击" onclick="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="点击" onclick="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" onblur="fn3()" name="username" id="userTxt" placeholder="请输入用户名"/>
<img id="img1" style="display: none;" src="img/icon1.png" />
<br />
<!--密码框-->
<input type="password" onfocus="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" onclick="fn1()"/>
<input type="button" value="设置事件2" onclick="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" onclick="fn1()"/>
<input type="button" value="设置事件2" onclick="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" onclick="fn1()"/>
<input type="button" value="设置div2事件2" onclick="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" onclick="fn1()"/>
<input type="button" value="设置div2事件2" onclick="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" onclick="fn1()"/>
<input type="button" value="设置div2事件2" onclick="fn2()"/>
<input type="button" value="移除事件" onclick="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" onclick="fn1()"/>
<input type="button" value="设置div2事件2" onclick="fn2()"/>
<input type="button" value="移除事件" onclick="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="添加元素" onclick="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="删除元素" onclick="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="开始" onclick="fn1()"/>
<input type="button" value="停止" onclick="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="开始" onclick="fn1()"/>
<input type="button" value="停止" onclick="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="点击" onclick="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="点击" onclick="fn1()"/>
<input type="button" value="打开窗口" onclick="fn2()"/>
<input type="button" value="关闭窗口" onclick="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="点击" onclick="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="点击" onclick="fn1()"/>
<input type="button" value="刷新" onclick="fn2()"/>
<input type="button" value="跳转页面" onclick="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="跳转页面" onclick="fn1()"/>
<input type="button" value="前进" onclick="fn2()"/>
<input type="button" value="go前进" onclick="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="点击" onclick="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" onblur="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();
})();