JavaScript
一、概述
- 脚本语言
- 解释性
- 解释器作为浏览器的一部分
- 弱类型、定义变量时不需要指定类型
- 动态类型,变量类型可以发生改变
- 基于原型继承
- 内置支持类型
作用:给页面添加动态功能
二、JS组成
- ECMASciprt:js标准语法
- 文档对象模型(DOM)
- 浏览器对象模型(BOM)
三、JS的导入
3.1 在页面元素中使用
<!-- 按钮被绑定了onclick事件,被点击后会触发弹框 -->
<input type="button" value="点击" onclick="alert('被点击了')">
3.2 在script标签中使用
script标签可以放在页面大多数位置,但是推荐放到最后,html的后面
注意:type属性可以不写,如果写,值应该是text/javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 绑定方法 -->
<p onclick="fn1()">111</p>
<input type="button" value="点击" onclick="fn1()">
</body>
</html>
<script type="text/javascript">
// 直接显示弹框
alert('打开页面自动弹框');
// 设置函数,让标签绑定该动作
function fn1(){
alert('点击生效弹框')
}
</script>
3.3 外部导入
使用script引入外部的js,可以在head中引入,也可以在大多数位置引入,推荐写到最后。
注意:
- type属性可以不写,如果写,值应该是text/javascript
- 结束标签必须要写,不能直接改成自结束
- 不能在中间写js代码
// 设置函数,让标签绑定该动作
function fn1(){
alert('点击生效弹框')
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 绑定方法 -->
<p onclick="fn1()">111</p>
<input type="button" value="点击" onclick="fn1()">
</body>
</html>
<script src="js/common.js"></script>
四、变量
var作为变量定义的关键字
弱类型,动态类型,命名规则与Java相似
<script>
//弱类型
var n = 10;
//类似java的sout,在控制台打印
console.log(n);
//动态类型,可以直接赋值,赋值是什么就是什么类型
n = "hello js";
console.log(n);
</script>
五、基本类型
基本类型有五种:
- Number
- String
- Boolean
- Undefined
- Null
typeof可以查看变量的类型
<script>
//数字不区分小数和整数
var a = 10;
console.log(a)//10
console.log(typeof(a))//number
var b = true;
console.log(b)//true
console.log(typeof(b))//boolean
var c = 3.14;
console.log(c)//3.14
console.log(typeof(c))//number
var d = "abc";
console.log(d)//abc
console.log(typeof(d))//string
var e ;
console.log(e)//undefined
console.log(typeof(e))//undefined
//只有对象才会被置为null
var f = null;
console.log(f)//null
console.log(typeof(f))//object
</script>
六、引用类型
对象类型:Object类型
语法:
<script>
var obj = new Object();
obj.name = "张"
obj.age = 10
console.log(obj.name);//张
console.log(obj.age)//10
var name = "name";
console.log(obj[name])//张
//直接键值对创建对象,访问时使用 变量.属性 即可
obj = {name:"刘",age:20,sex:'男'};//JSON(JavaScript Object Notation)格式
console.log(obj.name);//刘
// 可以直接将属性放入obj中去找对应的值
console.log(obj["name"])//刘
console.log(obj.age)//20
</script>
数组类型
- 和java中数组概念一致,而在JavaScript中使用Array类型
- 使用JSON表示法创建数组
**注意:**创建数组时可以不用指定长度
<script>
//定义数组,两种方式
var arr1 = new Array();
var arr2 = [1,2,3,4]
//求数组的长度,初始为0
console.log(arr1.length)//0
//设置数组的值
arr1[0] = 5;
arr1[2] = 10;
// 可以直接赋值指定索引位置的值
arr1[10] = 20;
console.log(arr1[0])//5
//访问没有赋值的索引值,则会显示 undefined
console.log(arr1[5])//undefined
console.log(arr1[10])//20
//求数组的长度,长度为赋值的元素索引+1
console.log(arr1.length)//11
//js数组是java的数组+集合
arr2[arr2.length] = 5;
console.log(arr2[4])//5
//通过push添加元素
arr2.push(10)//5
console.log(arr2)//[1,2,3,4,5,10]
//循环遍历
for (var i = 0; i < arr2.length; i++) {
//与java一致
console.log("i--->" + arr2[i])
}
//js与java中的forEach循环不同
for(i in arr2){
//遍历时i还是下标
console.log("==" + arr2[i])
}
//js元素的增删改
//splice可以增删改
arr3 = [1,2,3,4,5,6];
//添加一个10,在下标为1的位置
arr3.splice(1,0,10)
console.log(arr3)//[1,10,2,3,4,5,6]
//删除下标从1开始的5个元素,且添加一个20
arr3.splice(1,5,20)
console.log(arr3)//[1,20,6]
//改元素,将下标为1的元素换为50
arr3.splice(1,1,50)//[1,50,6]
</script>
七、运算符
7.1 算术运算符
与Java类似,不同之处在于,js中只有number类型,所以5/2结果为2.5
7.2 赋值运算符
与java类型
7.3 逻辑运算符
与Java类似
7.4 关系运算符
与Java类似
“==”:等于,判断值是否相等
“===”:全等于,判断值和类型完全相同
<script>
n = 10;
m = "10";
console.log(n == m) //true
console.log(n === m) //false
</script>
7.5 三目(三元)运算符
语法:布尔表达式?结果1:结果2
<script>
var s = 99;
//打印到网页上
document.write(s > 60?"及格":"不及格")
</script>
7.6 分支结构
- 和Java语言使用基本一致
- if
- switch
注意:
- 条件是一个布尔表达式
- 条件是个变量,如果值为0、null、undefined、NaN表示false,否则true。
- 如果变量没有定义,则出现异常
<script>
var s = 99;
if(s > 60)console.log("及格");else{console.log("不及格")}//及格
if(s)console.log("及格");else{console.log("不及格")}//及格
//当s为0作为if的条件时,为false
var s = 0;
if(s)console.log("及格");else{console.log("不及格")}//不及格
</script>
7.7 循环结构
- for循环
- for(初始化部分;循环条件;迭代部分){//循环操作}
- while循环
- while(布尔表达式){//循环操作}
八、函数
8.1 函数的定义与调用
函数定义的语法:
- function 函数名(参数列表){}
函数调用的语法:
- 函数名()
**注意:**在JS中,函数的调用时,如果函数有参数,可以传相应的参数,也可少传或不传,但是无论如何,传入的参数都是按顺序匹配
<script>
function m1(){
console.log("m1==" + 5)
}
function m2(m,n){
console.log("m1==" + m)
}
function m3(m = 10 , n){ // 10为默认值,没有传入参数时为10
console.log("m1==" + m)
}
function m4(){
return 5;//有返回值就return,没有就不用return
}
m1();//5
m2("hello",5)//hello
m2()//m1==undefined
m3()//10
m3("hello")//hello
var a = m4()
console.log(a)//5
</script>
8.2 函数变量
类似于Java中方法引用,或者C语言中的方法指针
<script>
var n = m1;//定义变量,值为一个函数
n();//调用该函数
function m1(){
alert(5)
}
</script>
8.3 函数参数
<script>
m2(m1);
var n = m1;
m2(n)
function m1(){
alert("hello")
}
//由于函数中m进行函数调用,意味着m参数必须传入一个函数
function m2(m){
m()
}
</script>
8.4 匿名函数
<script>
var n = function(){
alert("hello")
}
n();
//将匿名函数传入到函数的参数中
m2(function()){
alert("world")
})
function m2(m){
m()
}
</script>
8.5 函数返回值
<script>
function f1(){
// var n = function(){
// alert("hello")
// }
// function n(){
// alert("hello")
// }
// return n;
//使用匿名函数
return function(){
return function(){
alert("world")
}
}
}
var m = f1()
m()()
//调用f1函数,返回值是一个方法,然后继续调用方法,又返回方法,再次调用,所以三个()
f1()()()
</script>
九、弹窗函数
- alert:
- 只能点击确定按钮的弹窗
- confirm
- 可以点击确定或者取消的弹窗
- prompt
- 可以输入文本内容的弹窗
- 第一个参数是提示信息,第二个参数是用户输入的默认值
- 点击确定返回用户输入内容;点击取消或者关闭,返回null
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button onclick = "m1()">弹框</button>
<a href="http://www.baidu.com" onclick = "return m2()">百度</a>
<button onclick = "m3()">弹框后输入</button>
</body>
</html>
<script>
//触发时会显示弹框,只能点击确定
function m1(){
alert("被点击了,显示弹框")
}
//confirm(显示的信息) 返回值为确定(true)或者取消(false)
//当触发时会显示弹框,可以取消(false)和确定(true),需要对点击的按钮进行判断
//将confirm返回的值接收并返回到触发事件处
//onclick = “return 返回值”
//当点击取消时会不跳转页面
function m2(){
return confirm("你确定要跳转页面吗?")
}
//prompt(显示的信息,默认的输入信息),返回值是输入的信息
//触发时会显示弹框,让其输入,并且可以对输入内容进行过滤
function m3(){
while(1)break;
var age = prompt("请输入你的年龄:","123");
//将输入的内容转为整数类型
age = parseInt(age)
if(age){
alert("你的年龄为:" + age)
}else{
alert("年龄输入错误" + age)
}
}
</script>
十、系统函数
- parseInt():
- 解析一个字符串并返回一个整数
- parseFloat():
- 解析一个字符串并返回一个浮点数
- isNaN():
- 检查某个值是否为数字,不是数字返回true,是数字返回false
<script>
console.log(parseInt("10aa10"))//10
console.log(parseInt("10.25"))//10
console.log(parseInt("a10"))//NaN
console.log(parseInt("10.2aa"))//10
console.log(parseFloat(10))//10
console.log(parseFloat(10.25))//10.25
console.log(parseFloat("10.25aaa"))//10.25
console.log(parseFloat("aa10.25"))//NaN
console.log(parseFloat("10.25.25"))//10.25
console.log(isNaN("aa"))//true
console.log(isNaN("10.25a"))//true
console.log(isNaN("a10"))//true
console.log(isNaN("10.25"))//false
console.log(isNaN("10"))//false
</script>
十一、事件
11.1鼠标事件
- onclick:单击
- ondbclick:双击
- onmouseup:按键弹起
- onmousedown:按键按下
- onmouseover:当鼠标移入
- onmouseout:当鼠标移出
- onmousemove:当鼠标移动
- onmouseenter:当鼠标移入
- onmouseleave:当鼠标移出
- onmousewheel:滚轮滚动
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
div{
border: 1px solid red;
width: 100px;
height: 100px;
background-color: orange;
}
</style>
<body>
<div id = "div1" ></div>
</body>
</html>
<script>
var div1 = document.getElementById("div1")
div1.onclick= function(){
alert('鼠标点击了div块')
}
div1.onmousemove= function(){
alert('鼠标在div上移动')
}
div1.onmouseout= function(){
alert('鼠标移出了div块')
}
div1.onmouseover= function(){
alert('鼠标移入div块')
}
</script>
11.2 键盘事件
键盘操作
- onkeydown:键盘按下**(可以得到上下左右的返回值)**
- onkeyup:键盘弹起
- onkeypress:键盘敲击
11.3 其他事件
其他事件:
- onload:加载完成后执行,写在body标签中表示页面加载完成后执行
- onsubmit:表单提交事件,写在form标签中
- onchange:值改变事件,一般用在表单元素中
- onblur:失去焦点事件
- onfocus:获得焦点事件
十二、DOM操作
12.1 概述
- 通过HTML DOM,可访问JavaScript HTML文档的所有元素
- 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)
12.2 查找HTML元素
- 获取网页元素有三种方法
方法 | 描述 |
---|---|
getElementByld | 通过id找到HTML元素 |
getElementsByTagName | 通过标签名找到HTML元素 |
getElementsByClassName | 通过类名找到HTML元素 |
12.3 修改HTML内容
- document.write()方法
- 可用于直接向HTML输出流写内容
- innerHTML属性
- 获取或设置HTML内容
- HTML标签会被解析
- innerText属性
- 获取或设置HTML内容
- HTML标签会作为普通文本
12.4 修改HTML属性
两种方式:
- 对象.属性
- 获取或设置DOM对象的属性
- 使用方法:
- getAttribute(“属性名”),获取属性值,参数为DOM对象
- setAttribute(“属性名”,“属性值”),设置属性值
12.5 修改CSS
一般可以通过style属性来修改
**注意:**在样式的名称可能类型border-width,在js中使用驼峰式即borderWidth。
但是style只能得到行内的样式,而无法得到内部或外部加载的样式。
如果想要获取非行内样式,IE9以下的版本与其他浏览器有差异
//使用该方法可以得到内部或外部加载的样式,第一个参数为dom对象,第二个参数为属性名
function getStyle(elem,attr){
if(window.getComputedStyle){ //w3c标准,支持chrom,firefox,等等
return window.getComputedStyle(elem)[attr];
}else if(elem.currentStyle){ //IE其他版本
elem.currentStyle[attr];
}else{
return null;
}
}
12.6 设置DOM事件
通过DOM对象设置事件属性
- 语法:dom对象.onXXX = function(){…}
例如:var btn = document.getElementById(“btn”);
btn.onclick = function(){…}
12.7 事件的添加和移除
addEventListener()方法
向指定元素添加事件
不会覆盖已存在的事件
参数名 描述 event 事件类型 function 事件触发后调用的函数 useCapture 用于描述事件是冒泡还是捕获,默认为false冒泡、true捕获 removeEventListener()方法
- 移除事件
12.8 新建删除元素
- 新建元素
- document.createEkement(“标签”);
- 追加:appendChild();
- 添加:insertBefore();
- 删除元素
- 删除子元素:removeChild();
- 删除元素:remove();
//也可以使用拼接字符串实现添加元素
function f1(){
var arr = [
{name:"张三",age:"15",class:"一班"},
{name:"李四",age:"16",class:"二班"},
{name:"王五",age:"17",class:"一班"},
]
var t = document.getElementById("tbody1")
var content = "";
for (var i = 0; i < arr.length; i++) {
content += "<tr> <td>"+ arr[i].name +"</td> <td>" + arr[i].age + "</td><td>" + arr[i].class + "</td></tr>"
}
t.innerHTML = content
}
function f2(){
var t = document.getElementById("tbody1")
t.innerHTML = ""
}
十三、BOM
BOM浏览器对象模型,主要使用js操作浏览器
整个浏览器顶层为window,window下面又有几个常用对象属性:
- history
- location
- navigation
- screen
13.1 windows对象
是js的顶层对象,表示浏览器的窗口
所有的函数,变量均属于window。例如:windows.alert()、window.document,自定义的函数fn()也是属于windows的,介意写成window.fn1()
window.innerHeight:窗口高度
window.innnerWidth:窗口宽度
**注意:**得到的当前浏览器中的文档区域的宽度和高度。当窗口缩小或放大时,会改变值
window.open():打开新窗口
window.close():关闭窗口
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button onclick="f1()">打开新窗口</button>
<button onclick="f2()">关闭当前窗口</button>
</body>
<script>
function f1(){
alert(window.innerHeight + "====" +window.innerWidth)
// 打开一个窗口,第一个参数为新窗口的链接,第二个参数为窗口名,用于后续获取该窗口
let win = window.open('./表单案例.html');
// 通过窗口名获取上述窗口
let refWin = window.open('', 'abc');
}
function f2(){
window.close()
}
</script>
</html>
13.2 location对象
概述
- location对象用于获得当前页面的地址(URL),并把浏览器重定向到新的页面
属性:
属性名 描述 | location.href | 返回当前页面的URL |
| location.hostname | 返回web主机的域名 |
| location.protocol | 返回所使用的web协议 |
| location.port | 返回web主机的端口 |方法
- reload()重新加载页面
13.3 history对象
概述
- 包含用户在浏览器窗口中访问过的URL
属性
- length:返回浏览器历史列表中的URL数量
方法
方法名 描述 | back() | 加载history列表中的前一个URL |
| forward() | 加载history列表中的下一个URL |
| go() | 加载history列表中的某个具体页面 |go参数为正数就是下n个url,负数就是后退n个
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button onclick="f1()">跳转</button>
<button onclick="f2()">刷新</button>
<button onclick="f3()">前进</button>
<button onclick="f4()">后退</button>
<button onclick="f5()">go方法</button>
</body>
<script>
function f1(){
//显示主机名和端口号
//并跳转页面到
alert('主机名:' + location.hostname + '端口:' + location.port)
location.href = "https://www.baidu.com";
}
function f2(){
//刷新
location.reload()
}
function f3(){
//历史中的下一个
history.forward()
}
function f4(){
//后退
history.back()
}
function f5(){
//go方法
history.go(-1)
}
</script>
</html>
十四、定时器
定时器函数
函数名 | 描述 |
---|---|
setInterval | 每隔固定毫秒值就执行一次函数 |
setTimeout | 在固定时间之后执行一次调用函数 |
clearInterval(定时器id) | 清除定时执行 |
clearTimeout(定时器id) | 清楚延迟执行 |
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p id="time"></p>
<button onclick="f1()">开始</button>
<button onclick="f3()">暂停</button>
</body>
<script>
var s;
function f1(){
//每隔固定毫秒值就执行一次函数
s = setInterval(f2,1000)
}
function f2(){
var time = document.getElementById("time")
var date = new Date();
time.innerText = date.toLocaleString()
}
function f3(){
//停止计时器
clearInterval(s);
}
</script>
</html>
十五、正则表达式
- 概念
- 正则表达式是描述字符模式的对象
- 作用
- 用于对字符串模式匹配及检索替换
- 是对字符串执行模式匹配的强大工具
- 语法
- var patt = new RegExp(pattern,modifiers);
- var patt = /pattern/modifiers;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- 设置onsubmit提交时触发函数,判断是否都输入正确 -->
<form action="http://www.baidu.com" method="get" onsubmit="return fnsubmit()">
<!-- 当失去焦点时判断输入是否正确 -->
<input type="text" onblur="f1()" id="username" placeholder="姓名">
<span id = "usernameStyle"></span>
<br/>
<input type="password" onblur="f2()" name="userpasswd" id="userpasswd" placeholder="密码">
<span id = "userpasswdStyle"></span>
<br/>
<input type="email" onblur="f3()" name="email" id="email" placeholder="邮箱">
<span id = "emailStyle"></span>
<br/>
<input type="submit" value = "提交">
</form>
</body>
<script>
// 表单验证
function f1(){
var u = document.getElementById('username')
var us = document.getElementById('usernameStyle')
if(/^[\w]{6,16}$/.test(u.value)){
us.innerText = '合法'
us.style.color = 'green'
return true
}else{
us.innerText = '不合法'
us.style.color = 'red'
return false;
}
}
function f2(){
var u = document.getElementById('userpasswd')
us = document.getElementById('userpasswdStyle')
if( u.value.length > 0 && u.value.length < 15){
us.innerText = '合法'
us.style.color = 'green'
return true
}else{
us.innerText = '不合法'
us.style.color = 'red'
return false
}
}
function f3(){
var u = document.getElementById('email')
var us = document.getElementById('emailStyle')
if(/[\w]+@[\w]+\.[\w]+/.test(u.value)){
us.innerText = '合法'
us.style.color = 'green'
return true
}else{
us.innerText = '不合法'
us.style.color = 'red'
return false
}
}
// 验证都没输入时不会提交表单
function fnsubmit(){
return f1() && f2() && f3();
}
</script>
</html>
十六、创建对象的方式
var v = new Date();
16.1 直接使用属性赋值
**注意:**当方法中存在多层方法,就不能使用this.属性名,因为this只会引用调用者的属性,例如方法A中定义了方法B,那么方法B在方法A中被调用时,this就是指向的方法A。因此我们需要在外层创建一个临时变量来存放最初的调用者
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script>
function Student(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.say = function(){
var that = this;
console.log("姓名:" + this.name + "年龄:" + this.age + "性别:" + this.sex)
function Cla(name){
this.name = name;
//此时this.name打印Cla对象传的参数,并不是Student的参数,如果需要将Student的name传入,则需要在外面定义一个变量存放Student对象
//因为this在每个地方代表不同对象,所以使用临时变量访问
// console.log("姓名:" + that.name)//姓名:张三
console.log("姓名:" + this.name )//姓名:李四
}
new Cla("李四")//姓名:李四
}
}
var s = new Student("张三",16,'男')
s.say();//姓名:张三年龄:16性别:男
</script>
</html>
16.2 简单的单例模式
<script>
var Student = (function(){
// 将类封装到匿名函数中
function Student(){
console.log("创建了一个对象")
}
//创建一个变量存放对象
var instance;
//定义一个方法来第一次进入创建对象,
var _staic = {
getInstace: function(){
if(!instance){
//第一次进入就new一个对象
instance = new Student()
}
//返回创建的对象,只有第一次会创建
return instance;
}
}
//返回对象
return _staic;
})();
//只有一个对象,单例模式
var s = Student.getInstace()
var b = Student.getInstace()
</script>
十七、画布和绘制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#myCanvas{
background-color: orange;
}
</style>
</head>
<body>
<!-- 创建画布 -->
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
<script>
window.onload = function(){
//获取myCanvas画布
var c = document.getElementById("myCanvas")
//创建画笔
var ctx = c.getContext("2d")
//开始画画
ctx.beginPath()
//画笔颜色
ctx.strokeStyle = "black";
//填充颜色
ctx.fillStyle = "aqua";
//从哪个坐标开始画
ctx.moveTo(100,100)
ctx.lineTo(200,100)
ctx.lineTo(200,200)
ctx.lineTo(100,200)
//画画结束
ctx.closePath()
//画笔颜色填充(边框)
ctx.stroke()
//实心填充
ctx.fill()
}
</script>
</html>
画一个会变色的球
<script>
//创建定时器,0.5秒执行一次,随机变换颜色
setInterval( window.onload = function(){
//获取myCanvas画布
var c = document.getElementById("myCanvas")
//创建画笔
var ctx = c.getContext("2d")
//开始画画
ctx.beginPath()
//填充颜色(random随机的数字范围是0-1之间)
ctx.fillStyle = "#" + Math.floor(Math.random() * 0xffffff).toString(16);
//画一个圆,指定从 200,200 开始画,半径100,0-2PI,true为顺时针,false为逆时针
ctx.arc(200,200,100,0,Math.PI *2,false)
//画画结束
ctx.closePath()
//画笔颜色填充(边框)
ctx.stroke()
//实心填充
ctx.fill()
},500)
</script>
描绘图片
<script>
window.onload = function(){
let c = document.getElementById('myCanvas');
var cx = c.getContext("2d");
//创建image对象,将src链接图片
let image = new Image();
image.src = "img/1.jpg";
//设置定时器绘画,因为要等待image加载到内存才能开始画,所以需要定时器
setTimeout(function(){
cx.drawImage(image,0,0,200,200)
},100)
}
</script>
十八、案例
18.1 粒子喷泉
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#body{
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
</body>
<script>
//创建画布,并设置宽高和颜色,添加到body节点中
var canvas = document.createElement('canvas');
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.style.backgroundColor = "#333";
document.body.append(canvas);
//创建画笔
var ctx = canvas.getContext("2d");
//创建一个数组用来存放画的圆
var particles =[];
showParticles();
function showParticles(){
//定时刷新每一个粒子的位置
setInterval(function(){
//清空画布(此处不清空画布,原始位置粒子不会消失)
ctx.clearRect(0,0,canvas.width,canvas.height);
//创建粒子时指定粒子的起始位置,每个粒子都在同一位置创建
var p = new Particle(canvas.width/2,canvas.height/2);
//将每一个粒子保存到数组中
particles.push(p);
//循环更新所有粒子的位置
for(i in particles){
//更新粒子位置
particles[i].updateData();
}
},50)
}
//粒子类
function Particle(x,y){
//粒子的位置
this.x = x;
this.y = y;
//每个粒子新位置计算的公式
//横向范围在【-4,4】
//粒子上升位置存放在yVal中,只能上升最高-5,通过g来求出上升到最高后
//每次刷新下降0.1,相当于每秒下降2,因为刷新是50毫秒刷新一次
this.xVal = Math.random() * 8 - 4;
this.yVal = -5;
this.g = 0.1;
this.updateData = function(){
//更新后的位置
this.x += this.xVal;
this.y += this.yVal;
//每次+g,2.5秒后this.yVal就是正数,开始下降
this.yVal += this.g;
//随机粒子的颜色
ctx.fillStyle = "#" + Math.floor(Math.random() * 0xffffff).toString(16);
//开始画粒子
this.draw();
}
this.draw = function(){
//开始画
ctx.beginPath();
//画粒子,根据更新后的位置画粒子
ctx.arc(this.x,this.y,5,0,Math.PI*2,false);
//结束
ctx.closePath();
//填充颜色,颜色为随机
ctx.fill();
}
}
</script>
</html>