javascript学习笔记
javascript
为什么要学习javascript:
Javascript是实现网页动态效果的基石,在web再发中扮演重要的角色,被广泛的应用到各个领域:
- 网页游戏
- 地图搜索(google、daidu)
- 股市信息查询
- Web聊天
……
在web开发中,js是必不可少的技术!同时js也是ajax/jquery/extjs等框架的基础。
学习内容:
⊙javascript基本语法
⊙javascript面向对象编程
⊙bom与dom编程
⊙正则表达式
javascript介绍-基本介绍
⊙javascript是一种广泛用于客户端web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。
脚本语言是什么?
- 脚本语言介于HTML和C,C++,JAVA,C#等编辑语言之间
- 脚本语言与编程语言有相似的地方,其函数与编程语言类似,也有变量。与编程语言之间最大的区别是编程语言的语法和规则更为严格和复杂一些。
- 脚本语言是一种解释性语言,例如Python、vbscript,javascript等等,它不像c/c++邓可以编辑成二进制代码,可以执行的文件存在。
- 脚本语言一般都有相应的脚本引擎来解析执行,javascript的脚本引擎就是浏览器
- javascript最主要的设计目的就是让网页中的元素可以被编程,也就是让网页动起来,甚至你可以编写js版本的坦克大战游戏。
- javascript不能独立运行,他要嵌入其他编程语言中才能运行(html、asp、asp.net、jsp、php…)
- javascript只能用于b(brower浏览器)/s(server服务器)开发,即我们常说的web开发(比如网站开发,web应用等)
- javascript主要针对客户端编程,也就是说js运行一般在客户端
- javascript也可以对服务器编程(比较少!)
- 脚本语言往往不能独立使用,他和html/jsp/php/asp/asp.net
- 脚本语言有自己的变量,函数,控制语句(顺序、分支、循环)
- 脚本语言实际上是解释性语言(即在执行的时候,直接对源代码进行执行)
- java程序.java->.class->jvm javascript->浏览器(js引擎来解释执行的)
**js在客户端(浏览器)执行原理图
➡ 因为浏览器的差异,我们会看到在不同的浏览器中使用js编辑,会有差异,比如:在某个控件绑定响应时,w3c dom标准是addEventListener(),而在ie使用attachEven(),还有就是有些方法在ie中可以使用,而在ff中却不能使用,这些都是我们在实际开发中要注意的问题。
因为js是由浏览器解释执行的,因此这里右一个问题,不同的浏览器可能对js的支持不一样。
js的开发工具选择
- 记事本
- eclipse
案例1:打开网页出现hello world!
<head>
<title>text</title>
<!--js代码一般放在head标签间的,但实际上也可以在别的位置-->
<script language="JavaScript">
window.alert("hello world!");
</script>
<link rel="stylesheet" type="text/css" href="my.css">
</head>
问题:
- js的位置
可以随意
- js必须用
<script labguage=”javascript”>window.alert(“hello world!”)</javascript>
必须用一对<script></script>标签包起来,如果没有包起来,则浏览器则视其为普通文本。
- 在一个html文件中(jsp/php/asp)可以出现多对<script>片段,浏览器会按照先后顺序依次执行
案例2:对前面的程序该进成一个简单的加法运算程序
<script language="JavaScript"> //js中变量的定义(在js中变量用var表示,不管实际类型。) var num1=456; var num2=89; var result=num1+num2; window.alert('结果是'+result);//alert函数 </script>
js变量的类型究竟怎样决定
- js是弱数据类型语言(即在定义变量的时候,统一使用var表示,甚至可以去掉var这个关键字)
- js中的变量的数据类型是由js引擎决定的
比如:
var name = “xiezhenyu”;//name是字符串
var kk = 2;//kk是数
var yy;//yy是undefined(没有定义)
如果name = 234;//这时name自动变成数
不声明变量直接使用
x = 345;//也可以
js基本语法
○javacsript中的标识符:
标识符是指javascript中定义的符号,例如,变量名、函数名、数组名等。标识符可以由任意顺序的大小写字母、数字、下划线(_)、和美元符($)组成,但标识符不能以数字开头,不能是javascript中的保留/关键字。
合法的标识符举例:indentifier、username、user_name、_userName、$username
非法标识符举例:int、98.3、Hello World
○javascript严格区分大小写computer和Computer是两个完全不同的符号
○javascript程序代码的格式
每条功能执行语句最后必须用分号(;)结束,每个词之间用空格、制表符、执行符或者大括号、小括号这样的分隔符隔开。
○语句块使用{}来表示
○javascript程序的注释
/*…*/中可以嵌套“//”注释,但不能嵌套“/*…*/”。
js基本数据类型
- 基本数据类型
分为:
- 数值
举例:var a = 89;//a就是整数
var b = 35.6;//b就是小数
NaN(not a number):
var a = "sss"; window.alert(parseInt(a));
infinity(无穷):
window.alert(6/0);
isNaN();//window.alert(isNaN(“123”));//返回真
isFinity();
- 字符
- 布尔型
js中非0的数都为真
通过typeof可以看到变量的具体数据类型是什么。(window.alert("num1是"+typeof num1);)
<script language="JavaScript"> //js中变量的定义(在js中变量用var表示,不管实际类型。) var num1=456; window.alert("num1是"+typeof num1); num1 = "sss";//js是动态语言 window.alert("num1是"+typeof num1); </script>
- 复合类型
分为:
- 数字
- 对象
- 特殊数据类型
分为:
- null
比如:var a = null;
- undefine
比如:var tt;
window.alert(tt);//没有定义tt
js数据类型的转换
- 自动转换
var a = 123;//a是整数
a = “hello”;//a的类型就是string
- 强制转换
比如:
var a = “12345”;
a = parseInt(a);//使用系统函数强制转换
var b = 90;//b是number
b = b+“”;//b是字符串
js的运算符
+、-、*、/、++、--、+=、-=、/=、%=
%(取模 就是计算两个数的余数,通常用来判断两个数是否能够整除,主要用于整数)
案例:
<script language="JavaScript"> var a = 90; var b = 8; if(a%b==0){ window.alert("能整除"); } else{ window.alert("不能整除"); } </script>
介绍 windou.prompt,和document.write函数:
<script language="JavaScript">
var a = window.prompt("请输入值");
document.writeln("您的输入是:"+a);
</script>
关系运算符
==、>、<、>=、<=、!=
案例:编写一个程序,该程序可以接收两个数(可以是整数,也可以是小数),并判断两个数是大于?小于?还是等于?
<script language="JavaScript">
var num1=window.prompt("请输入第一个数");
var num2=window.prompt("请输入第二个数");
num1=parseFloat(num1);
num2=parseFloat(num2);
if(num1>num2){
window.alert("num1>num2");
}else if(num1<num2){
window.alert("num1<num2");
}else{
window.alert("num1=num2");
}
</script>
逻辑运算符
&&(与)、||(或)、!(非)
????在逻辑运算中,0,“”,false,null,undefined,NaN均表示为false。
案例:
<script language="JavaScript">
var a=90;
var b=9;
if(a>b&&++a>345){
window.alert('ok');
}else{
window.alert('no');
}
window.alert("a="+a);
</script>
注意:在||中,将返回第一个不为false那个值(对象亦可),或者是返回最后一个值(如果全部都是false的话)。
||返回的结果,不一定是布尔值。
比如:
<script language="JavaScript">
var a=90;
var b=0;
var c = a||b;
window.alert(c);
</script>
输出:90
<script language="JavaScript">
var a=true;
var b=false;
var c = a||b;
window.alert(c);
</script>
输出:true
<script language="JavaScript">
var a=false;
var b=false;
var d=0;
var c = b||a||d;
window.alert(c);
</script>
输出:0
位运算和移位运算
js中也有位运算和移位运算,其规范和Java一致
案例:
<script language="JavaScript">
var a=4>>2;
//4的二进制 00000100 ->右移2 00000001
//-4 源码 10000000 00000100 ->反码 11111111 11111011 ->补码11111111 11111100 ->右移2 1111111111 111111 ->反码 11111111 11111110 ->源码10000000 00000001
window.alert(a);
</script>
javascript的控制语句
- 顺序控制
对编程而言,不控制器流程就是顺序执行
- 分支控制
2.1单分支
if(条件表达式){
//执行语句
}
2.2双分支
if(条件表达式){
}else{
}
例子:
<script language="JavaScript">
var age=20;
if(age>18){
window.alert("大于18");
}else{
window.alert("小于18")
}
</script>
2.3多分支
if(条件表达式1){
}else if(条件表达式2){
}else if(条件表达式3){
}……//可以有多个else if
else{//可以没有
}
强调一点:一旦找到一个满足条件的入口,执行完毕后就直接结束整个多分支
- 循环控制
for循环:
for(循环初值;循环条件;步长){
语句;//循环体
}
while循环:
while(条件表达式){
//执行语句
}
do…while循环:
do{
//执行语句
}while(条件语句);
switch基本语法
switch(变量){
case 常量1:
//执行语句
break;
case 常量2:
//执行语句
break;
…………
default:
}
结论:
- js的switch语句数据类型可以是js支持的任何类型(数组和对象除外)
- case后面的数据类型可以任意(数组和对象除外)
- break 作用是跳出整个switch
- 如果没有匹配类型这执行default
javascript函数
- 为什么需要函数
- 函数的基本概念
为完成某一个功能的代码(语句,指令)的集合
- 基本语法
function 函数名(参数列表){
//代码
return 值;//可以选择
}
说明:
1参数列表:表示函数的输入
2函数主体:表示为了实现某一功能代码块
3函数可以有返回值,也可以没有
- 案例:
入门案例
<script language="JavaScript">
//输入两个数,再输入一个运算符(+,-,*,/),得到结果->函数
var num1=window.prompt('请输入第一个数');
var num2=window.prompt('请输入第二个数');
var operator=window.prompt('请输入运算符');
num1=parseFloat(num1);
num2=parseFloat(num2);
//如何调用函数
document.write("res="+jiSuan(num1,num2,operator));
//定义函数
function jiSuan(num1,num2,operator) { //特别强调 参数名不要带 var
var res;
if(operator=="+"){
res=num1+num2;
}else if(operator=="-"){
res=num1-num2;
}else if(operator=="*"){
res=num1*num2;
}else {
res=num1/num2;
}
return res;
}
</script>
如果其他的html,php,jsp要使用该函数
把上面的函数单独提出,写到js,然后在需要的地方引入即可
myjs.js
//定义函数
function jiSuan(num1,num2,operator) { //特别强调 参数名不要带 var
var res;
if(operator=="+"){
res=num1+num2;
}else if(operator=="-"){
res=num1-num2;
}else if(operator=="*"){
res=num1*num2;
}else {
res=num1/num2;
}
return res;
}
在需要的文件引入:
<script language="JavaScript" src="myjs.js"></script>
函数调用的方式
1普通调用
函数名(实际参数…)
2通过指向函数的变量去调用
var myvar=函数名;
myvar(实际参数);
3关于接收函数返回值的问题
var myvar=test("abc");
//如果test没有返回值,但是你又接收了,则返回的就是undefined;
//如果有返回值,则是什么就是什么
window.alert(myvar);
函数(方法)-理解
函数的调用过程,内存分析
案例:
function abc(num1) {
if(num1>3){
abc(--num1);//递归
}
document.writeln(num1);
}
abc(5);
输出3 3 4
分析图:
特别强调,js的函数天然支持可变参数,比如:
//编写一个函数,可以接收任意多个数,并计算他们的和
function abc2() {
//在js中有一个 arguments,可以访问所有传入的值
//window.alert(arguments.length);
//遍历所有的参数
for(var i=0;i<arguments.length;i++){
window.alert(arguments[i]);
}
}
abc2(1,2,3,'hello world!');
小练习:
编写一个函数,从页面输入一个整数(1-9),打印除对应的乘法表
.js
function cfb(num1) {
for(var i=1;i<=num1;i++){
for(var j=1;j<=i;j++){
document.writeln(i+"x"+j+"="+i*j+" ");
}
document.writeln("<br>");
}
}
.html
var a=window.parseInt(window.prompt("请输入一个整数"))
cfb(a);
一维数组
1 为什么需要数组
需求:王大爷有6只乌龟,他们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。请问这六只乌龟的总体重是多少?平均体重是多少?
//使用传统的方法解决问题很麻烦
var weigth1=3;
var weigth2=5;
var weigth3=1;
var weigth4=3.4;
var weigth5=2;
var weigth6=50;
var all_weigth=weigth1+weigth2+weigth3+weigth4+weigth5+weigth6;
2 解决方法
使用数组这种数据类型(引用类型/复杂类型/复合类型)数组的基本概念:用于存放一组数据。
特别强调:js中的数组,可以存放各种类型(数值/字串)
var weigths=[3,5,1,3.4,2,50]; var all_weigth=0; var avg_weigth=0; //数组的遍历 for(var i=0;i<weigths.length;i++){ all_weigth+=weigths[i]; } avg_weigth=all_weigth/weigths.length; //如果想知道数据类型是什么 window.alert(avg_weigth.constructor); document.writeln("总体重是"+all_weigth+"<br>"); document.writeln("平均体重是"+avg_weigth.toFixed(2));
3数组细节
基本用法:
var 数组名=[元素值]
元素值可以是任意类型
var arr=[45,”asdas”,true];
数组在内存中存在形式
js中的数组是引用传递
数组的引用
基本用法:
数组名称[下标]
比如:
var a =[23,”hello world”,4.5]
如果访问a[2] 则输出4.5
如果访问a[3] 则输出undefined
结论:不能访问不存在的元素。数组的小标是从0开始编号的
js的数组可以动态增长
var a=[2,3]; window.alert("size="+a.length); //动态的增长 a[2]=56; window.alert("size="+a.length); alert(a[2]);
对字符串分割分成一个字符串数组
split函数可以查文档
比如:
var str="hello world abc 谢振瑜"; var arr=str.split(" ",2); for(var i=0;i<arr.length;i++){ document.write(arr[i]+" "); }
数组的历遍
arr=[45,90,0];
arr["gg"]=9000;//下标也可以用字符串表示
for(var key in arr){
window.alert(key+"= "+arr[key]);
}
数组小节:
1数组可以存放任意类型的数据
2数组大小不必事先指定,可以动态增长
3数组名可以理解为指向数组首地址的引用
4数组元素从0开始编号
多维数组 --- 二维数组
举例:
var arr=[[“zhenyu”,123,4.5],[“a”,”b”,”c”]]
看看如何遍历二维数组:
var arr=[["zhenyu",123,4.5],["a","b","c"]];
//遍历
for(var i=0;i<arr.length;i++){
//输出第一行(二维数组一个元素[数组])
for(var j=0;j<arr[i].length;j++){
document.writeln((arr[i][j]+" "));
}
document.writeln("<br>");
}
//如果直接访问“c”
window.alert(arr[1][2]);
数组的排序
冒泡排序法:
var arr=[5,0,-56,900,12,9000,-128];
var flag=false;
//大的排序次数
for(var i=0;i<arr.length-1;i++){
//小的循环
for(var j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
//交换
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=true;
}
}
if(flag){
flag=false;
}else {
break;
}
}
for(var i=0;i<arr.length;i++){
document.writeln(arr[i]+" ");
}
查找:
1顺序查找
2二分查找
*二分查找有一个前提:该数组是有序的,如果不是有序的数组,则不能使用二分查找。
代码:
var arr=[1,4,6,8,9,90,800];
//思路:找到数组的中间数(midVal),和你要查找的数(findVal)进行比较,如果
//midVal>findVal 则说明findVal在数组的左边,就把该数组二分(就只在左边查找。)
function binarySearch(arr,findVal,leftIndex,rightIndex) {
var midIndex=Math.floor((leftIndex+rightIndex)/2);
var midVal=arr[midIndex];
//进行查找有一个前提,放在无穷递归
if(leftIndex>rightIndex){
//提示找不到
document("找不到");
return;
}
//比较
if(midVal>findVal){
//在左边找
binarySearch(arr,findVal,leftIndex,midIndex-1);
}else if(midVal<findVal){
//在右边找
binarySearch(arr,findVal,midIndex+1,rightIndex);
}else{
document.writeln("找到了 下标为"+midIndex);
return;
}
}
//测试
binarySearch(arr,0,0,arr.length-1);
js面向(基于)对象编程
澄清概念
js中基于对象==js面向对象
js中没有类class,但是它取了一个新的名字叫原型对象,因此 类==原型对象
为什么需要对象
/*
张老养了两只猫:一只名叫小白,今年3岁,白色。还有一只名叫小花,今年十岁,花色。
请编写一个程序,当用户名输入的小猫名字时,就显示该猫的名字,年龄,颜色。如果用户
输入的小猫名字错误则显示,张老太太没有这只猫。
*/
var cat1_name="小白";
var cat1_age=3;
var cat1_color="白色";
//传统方法比较麻烦,解决方法,把,猫的属性集中创建一种新的数据类(原型对象/类)
//用面向对象的方法来解决上面的问题
//这里就是一个Cat类
function Cat() {
}
//如果你这样用
//Cat();//函数
var cat1=new Cat();//类
//这时cat1就是一个对象(实例)
cat1.name="小白";
cat1.age=3;
cat1.color="白色";
//从上面的代码我们可以看出
//1.js中的对象的属性可以动态的添加
//2.属性没有限制
window.alert(cat1.name);
类(原型对象)和对象的区别和联系
- 类是抽象的概念,代表一类事物。
- 对象是具体,代表一个实体。
- 对象是以类(原型对象)为模版创建起来的。
创建对象的方式有五种
- 工厂方法—使用new object创建对象并添加相关属性
- 使用构造函数来定义类(原型对象)
- 使用prototype
- 构造函数及原型混合方式
- 动态原型方式
目前先讲 2.使用构造函数来定义类(原型对象),然后再创建对象实例
基本语法:
function 类名/原型对象名(){
}
创建对象:
var 对象名=new 类名();
现在特别说明:
- js中一切都是对象
function Person() {}
window.alert(Person.constructor);
var a = new Person();
window.alert(a.constructor);//a 对象实例的构造函数
window.alert(typeof a);//a 的类型是什么
var b=123;
window.alert(b.constructor);
window.alert(typeof b);
var c="123";
window.alert(c.constructor);
window.alert(typeof c);
打印结果
如何判断某个对象是不是某个类型
function Person() {}
//如何判断一个对象实例是不是Person类型
var a = new Person();
if(a instanceof Person){
window.alert("a是Person ok1");
}
if(a.constructor==Person){
window.alert("a是Person ok2");
}
补充说明:(带var 和不带 var的区别)
//全局变量
var abc=89;
function test() {
//在函数里如果你不带上var,则表示使用全局变量的 abc变量
//如果你带上var 则表示在test()中,定义一个新的abc遍历
abc=900;
}
test();
window.alert(abc);
访问对象的属性的方法两种:
- 普通方法
对象名.属性名
- 动态访问
对象名[“属性名”]
function Person() {};
var p1=new Person();
p1.name="谢振瑜";
window.alert(p1.name);
var val="na"+"me";
window.alert(p1[val]);
对象引用问题的说明:
function Person() {};
var a=new Person();
a.age=10;
a.name="小明";
var b=a;
b.name="小白";
window.alert(b.age+"名字"+b.name+"名字"+a.name);
b=null;
window.alert(a.age+"a名字"+a.name);
window.alert("b.age"+b.age);
a=null
(图)
js还提供一种方式,主动释放对象内存
delete a.age;
delete 对象名.属性名;//这样就会立刻释放对象的这个属性空间
this
问题的提出:
function Person() {};
var p1=new Person();
p1.name='以轩';
p1.age=20;
window.alert(p1.name+" "+p1.age);
var p2=new Person();
window.alert(p2.name);//这里会输出什么?
这里我们可以看到window.alert(p2.name);会输出undefined
在实际编程中,我们可能有这样的需求,当我们创建一个对象后,就希望该对象自动的拥有某些属性 比如:当我们创建一个Person后,就希望该对象自动拥有name个age的属性,这又该怎么办?
使用this来解决:
function Person() {
this.name="以轩";
this.age=20;
}
var p1=new Person();
var p2=new Person();
document.writeln(p1.name+" "+p2.name);
可能有人这样考虑问题:
function Person() {
var name=abc; //如果这样去使用name这个属性是私有的
this.name2="以轩";//this.name 表示 name2 这个属性是公开的
this.age=20;
this.show=function () {//这个就是Person类的一个公开的方法
window.alert(name);
}
function show2() {//这时Person类的一个私有方法,只能在Person类中使用
window.alert(name);
}
}
var p1=new Person();
p1.show2();//这里会报错
记住一句话:
哪个对象实例调用this所在的函数,那么this就代表哪个对象实例。
function test1() {
alert(this.v);
}
var v=90;
window.test1();//==test1();输出90
注意事项:
this不能在类定义的外部使用,否则调用者就变成window了。
对象—成员函数(方法)
比如:我们希望对象不但有属性,还希望他有行为。(行为在程序中要靠函数来体现)
- 添加speak函数,输出 我是一个好人
- 添加jisuan函数,可以计算从1+…+1000的结果
- 添加jisuan函数,该方法可以接收一个数n,计算1+…+n;的结果
- 添加add成员函数,可以计算两个数的和
-
function Person(name,age) {
//这个就是使用传入的实际的参数,去初始化属性。
this.name=name;
this.age=age;
//输出自己的名字 这里 this.show 就是一个公开的函数,函数名是show
this.show=function () {
document.writeln("名字="+this.name);
}
//添加jisuan函数,可以计算从1+...+1000的结果
this.jisuan=function (n) {
var res=0;
for(var i=1;i<=n;i++){
res+=i;
}
return res;
}
}
var p1=new Person("宋江",90);
p1.show();
document.writeln("<br>"+p1.jisuan(100));
给一个对象添加(指定)函数的几种方式
方式一:
function 类名(){
this.属性;
}
var 对像名=new 类名();
function 函数名(){
//执行
}
对象名.属性名=函数名;//这样就相当于把函数赋给 对象名.属性名,此时这个属性名就表示一个函数。
具体案例:
function Person() {
this.name="abc";
this.age=900;
}
function show1() {
document.writeln("hello"+this.name);
}
//创建一个排p1对象
var p1=new Person();
//把show函数给p1.abc
p1.abc=show1;
p1.abc();//调用
方式2:
对象名.属性名 = function(参数列表){
//代码
}
//调用
对象名.属性名(实际参数);
具体案例:
function Person() {
this.name="abc";
this.age=900;
}
var p1=new Person();
p1.abc= function show1() {
document.writeln("hello" + this.name);
}
p1.abc();
方式三:
前面的几种方法有一个问题:那就每个对象 独占代码,这样如果对象很多,则会影响效率。
js设计者,给我们提供了另一个方法 原型法:对多个对象可以共享函数
代码:
//这里希望所有的对象共享某个函数 function Dog() { } //使用prototype[类] 去绑定一个函数给shout Dog.prototype.shout=function () { window.alert("小狗"); } var dog1=new Dog(); dog1.shout(); var dog2=new Dog(); dog2.shout();//这里ok
对代码的原理说明(图)
补充:==的作用
1当==的两边都是字符串的时候,则比较内容相等不相等
2当==的两边是数字,则比较数的大小是否相等
3当==的两边是对象或者是对象函数,则比较地址是否相等
加深对类和对象的认识
如何给类添加方法(如何给某类型的所有对象添加方法)
给js的Array对象扩展一个find(val)方法,当一个Array对象调用该方法的时候,如果能找到val则返回下标。否则返回-1
代码:
Array.prototype.find=function (val) { //开始遍历数组 this for(var i=0;i<this.length;i++){ if(val==this[i]){ return i; } } return -1; } document.writeln(arr1.find("John"));
闭包
解释:
- 闭包和垃圾回收(GC)相关联的
- 闭包实际上是涉及到一个对象的属性,何时被GC处理的问题
- 怎样才能对对象的属性形成一个闭包
/*闭包(closure)*/
function A() {
var i=0;
function b() {
window.alert(i++);
}
return b;
}
//闭包<--->GC
A();//此时内存中会有i的空间。但这句过后可能会回收i
var c=A();//这时c可能会用到i就不会立马当成垃圾回收
c();//0
c();//1,从而证明i变量被闭包
成员函数的细节
- 成员函数的参数可以是多个。
function 函数名(参数1……){ }
- 函数可以没有返回值,但最多只能有一个返回值。
- js中不支持函数的重载,js在调用一个函数的时候,是根据函数名来调用,如果有多个函数名相同,则认最后那个函数。
- 直接定义一个函数或者变量实际上这些函数和变量就是全局函数和全局变量(本质上他们是属于window对象的)
面向对象综合案例
采用面向对象思想设计超级马里奥游戏人物(示意图)
游戏的分析:
- 看看如何通过按钮来控制Mario的位置
- 设计相关的对象(Mario x,y)
- mario碰到边界给一个提示
- mario可以去找另外一个物体
基本代码:
html:
<!DOCTYPE html>
<html>
<head>
<title>text</title>
<link rel="stylesheet" type="text/css" href="my.css">
<script language="JavaScript" src="myjs.js"></script>
</head>
<body>
<div class="gamediv">
<img id="mymario" style="width: 80px;height: 80px; left:0px;top: 0px;" src="imges/6.png"/>
<img id="diren" style="width: 80px;height: 80px; left: 270px;top: 200px;" src="imges/8.jpg"/>
</div>
<table class="controlcenter">
<tr><td colspan="3">游戏键盘</td></tr>
<tr><td>**</td><td><input type="button" value="向上" οnclick="mario.move(2);"/></td><td>**</td></tr>
<tr><td><input type="button" value="向左" οnclick="mario.move(3);"/></td><td>**</td><td><input type="button" value="向右" οnclick="mario.move(1);"/></td></tr>
<tr><td>**</td><td><input type="button" value="向下" οnclick="mario.move(4);"/></td><td>**</td></tr>
</table>
</body>
</html>
css:
body{
margin: 0px;
}
.gamediv{
width: 500px;
height: 400px;
background-color: pink;
}
.gamediv img{
position: absolute;/*绝对定位*/
}
/*表格样式*/
.controlcenter{
width: 200px;
height: 200px;
border: 1px solid black;
}
.controlcenter td{
border: 1px solid black;
}
js:
//数据
function shuJu(val) {
//mario
var mymario=document.getElementById("mymario");
var diren=document.getElementById("diren");
var mymarioTop=mymario.style.top;
var mymarioLeft=mymario.style.left;
var direnTop=diren.style.top;
var direnLeft=diren.style.left;
switch (val){
case 1://马里奥纵坐标
mymarioTop=parseInt(mymarioTop.substr(0,mymarioTop.length-2));
return mymarioTop;
break;
case 3://马里奥横坐标
mymarioLeft=parseInt(mymarioLeft.substr(0,mymarioLeft.length-2));
return mymarioLeft;
break;
case 2://敌人纵坐标
direnTop=parseInt(direnTop.substr(0,direnTop.length-2));
return direnTop;
break;
case 4://敌人横坐标
direnLeft=parseInt(direnLeft.substr(0,direnLeft.length-2));
return direnLeft;
break;
}
}
//马里奥
function Mario() {
//mario
this.move=function (direct) {
switch (direct){
case 1:
//window.alert("mario右移动");
//这里为了改变img的left值和top值,我们需要先得到img这个元素(对象)
mymario.style.left=(shuJu(3)+10)+"px";
Pen.penzhuang();
break;
case 2:
mymario.style.top=(shuJu(1)-10)+"px";
Pen.penzhuang();
break;
case 3:
mymario.style.left=(shuJu(3)-10)+"px";
Pen.penzhuang();
break;
case 4:
mymario.style.top=(shuJu(1)+10)+"px";
Pen.penzhuang();
break;
}
}
}
//创建马里奥对象
var mario=new Mario();
//创建碰撞对象
var Pen=new pen();
//碰撞
function pen() {
this.penzhuang=function () {
if(Math.abs(shuJu(1)-shuJu(2))<80&&Math.abs(shuJu(3)-shuJu(4))<80){
window.alert("恭喜你杀掉了敌人!!");
}
}
}
效果图:
构造函数
基本用法:
function 类名(参数列表){
属性=参数值;
}
举例:
function Person(name,age) {
this.name=name;
this.age=age;
}
//创建Person对象的时候,就可以直接给名字和年龄
var p1=new Person("avc",80);
window.alert(p1.name);
????在给一个对象初始化属性值的时候,也可以指定函数属性
案例:
function juSuan(num1,num2,oper) {
if(oper=="+"){
return num1+num2;
}else if(oper=="-"){
return num1-num2;
}else if(oper=="*"){
return num1*num2;
}else {
return num1/num2;
}
}
function Person(name,age,fun) {
this.nama=name;
this.age=age;
this.myfun=fun;
}
var p1=new Person("aa",9,juSuan);
window.alert(p1.nama);
window.alert(p1.myfun(89,90,"+"));
创建对象的又一种形式
如果一个对象比较简单,我们可以直接创建
var dog={name:”小狗” ,age: 8};
var dog={name:"xiaogou" ,age: 8,fun1:function (){window.alert("hello")} };
window.alert(dog.name);
window.alert(dog.constructor);
有时我们会看到这样一种调用方法
函数名.call(对象实例);
//这样调用,该函数的this就是这个对象实例
案例:
var dog={name:'hello'};
function test() {
window.alert(this.name);
}
test();
window.test();
test().call(dog);//<==>dog.test();
for..in循环
案例:
var dog=
{name:'小明',sayHello:function (a,b) { window.alert("结果="+(a+b));}}
//循环列出dog对象的所有属性和方法 对象名['属性名']
for(var key in dog){
window.alert(dog[key]);
}
js面向(基于)对象编程——三大特征
- 封装
1什么是封装
封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其他部分只有通过被授权的操作(函数),才能对属性进行操作。
2封装-访问控制修饰符
电视的开关,对音量、颜色、频道的控制是公开的,谁都可以操作,但是滴哦机箱后盖,主机的操作却不是公开的,一般是由专业维修人员来玩。
3js提供有一下几种控制方法和属性的访问(1.公开级别:对外公开。2.私有级别:类本身可以访问,不对外公开)
案例:
function Person(name,agei,sal) { this.name=name;//公开属性 var age=agei;//私有属性 var salary=sal;//私有属性 //在类中如何定义公开方法(特权方法),私有方法(内部方法) //如果希望操作私有的属性,则可用公开方法实现 this.show=function () { window.alert(age+" "+salary); } //私有方法,可以访问对象的属性 function show2() { window.alert(age+" "+salary); } } var p1=new Person("zy",20,50000); window.alert(p1.name+" "+p1.age);//p1.age会出现underfined p1.show();//可以使用 p1.show2();//不能使用这个方法
????前面写过,通过prototype给所有的对象添加方法,但是这种方式不能去访问私有的变量和方法
举例说明:
function Person() {
this.name="abc";
var age = 90;
this.abc=function () {
window.alert("abc");
}
}
Person.prototype.fun1=function () {
window.alert(this.name);//ok
window.alert(age);//不可以
this.abc();
}
var p1=new Person();
p1.fun1();
- 继承
1继承的必要性(为什么需要继承)
问题:
function MidStu(name,age) { this.name=name; this.age=age; this.show=function () { window.alert(this.name+" "+this.age); } //计算学费 this.payFee=function () { window.alert("应缴"+money*0.8); } } function Puoi1(name,age) { this.name=name; this.age=age; this.show=function () { window.alert(this.name+" "+this.age); } //计算学费 this.payFee=function () { window.alert("应缴"+money*0.5); } } //解决代码冗余问题-->继承
上面的代码存在冗余的问题
解决方案可以使用继承(对象冒充来实现继承效果的)
function Stu() { this.name=name; this.age=age; this.show=function () { window.alert(this.name+" "+this.age); } } function MidStu(name,age) { this.stu=Stu; this.stu(name,age);//js中实际上是通过对象冒充来实现继承,这句话不能少(因为js是动态语言,如果不执行则不能实现继承效果) } function Pupil(name,age) { this.stu=Stu; this.stu(name,age); } var midStu=new MidStu("振瑜",20); midStu.show();
继承小结:
1js通过前面的方式可以实现多重继承(通过对象冒充)
2Object类是js所有类的基类
- 多态
概念:所谓多态,就是指一个引用(类型)在不同情况下的多种状态。在java中多态指通过父类的引用来调用不同子类中实现的方法。
js实际上是无态的,是一种动态语言,一个变量的类型在运行过程中由引擎决定的,所以说,js天生就支持多态。
多态和继承相结合经典案例:
代码:
//主人
function Master() {
//给动物喂食物
this.feed=function (animal,food) {
document.writeln("主人给"+animal.name+"喂食"+food.name);
}
}
//写食物
function Food(name) {
this.name=name;
//...
}
function Fish(name) {
this.food=Food;
this.food(name);
}
function Bone(name) {
this.food=Food;
this.food(name);
}
//动物
function Animal(name) {
this.name=name;
//...
}
function Cat(name) {
this.animal=Animal;//对象冒充
this.animal(name);
}
function Dog(name) {
this.animal=Animal;
this.animal(name);
}
var cat=new Cat("小猫咪");
var dog=new Dog("小狗");
var fish=new Fish("小鱼");
var bone=new Bone("骨头");
var master=new Master();
master.feed(cat,fish);
js的函数重载和重写
重载:js中不支持重载(即不可以通过参数的个数来决定调用哪个函数),但是因为js本身支持可变参数,所以,它可以看成天然支持重载
function abc(){
if(argument.length=…){
}else if(){
}
}
重写:子类可以重新写函数来覆盖父类的某个方法
举例:
父类:
function Stu() {
this.name=name;
this.age=age;
this.show=function () {
window.alert(this.name+" "+this.age);
}
}
子类:
function MidStu(name,age) {
this.stu=Stu;
this.stu(name,age);//js中实际上是通过对象冒充来实现继承,这句话不能少(因为js是动态语言,如果不执行则不能实现继承效果)
//MidStu可以覆盖stu父类的show方法
this.show=function () {
window.alert("MidStu show()");
}
}
js的内部类
javascript中本身提供一些,可以直接使用的类 这种类就是内部类
主要有:
Object/Array/Math/Boolean/String/RegExp/Date/Number
内部类的分类
从使用的方式看,分为静态类和动态类
静态类 使用 类名.属性/方法
比如Math.abs(-5);
动态类 使用 var 对象=new 动态类();对象.属性/方法
比如 //显示当前日期 var nowdate=new Date(); window.alert(nowdate.toLocaleString());
Math
Math是静态类,提供了常用的数学函数和常数函数,一下是几个常用的函数,其他的参考javascript的参考文档。
- abs(x) 返回数的绝对值
- ceil(x) 对一个数进行上舍入
- floor(x) 对一个数进行下舍入
- max(x,y) 求x,y中较大的数
- min(x,y) 求x,y中较小的数
- round(x) 就x进行四舍五入
- random() 一个大于0小于1的16为小数位的数字
思考:如何随机得到一个1~100的整数
window.alert(Math.round(Math.random()*100));
Date
Date类提供了日期和时间的操作,下面是几个最常用的函数,起得的参考javascript文档。
- Date()------------返回当前日期和时间
- getDate()----------从Date对象返回一个月中的某一天
- getDay()-----------从Date对象返回一周中的某一天
- getMonth()--------从Date对象返回月份
- getYear()----------从Date对象返回年
- getHours()---------从Date对象返回小时数
- getMinutes()-------从Date对象返回分钟
- getSeconds()-------从Date对象返回秒数
例子:
//Date
var date=new Date();
window.alert(date.getYear());
window.alert(date.toLocaleString());
思考:当用户浏览网页的时候,根据当前时间,给出问候语
思路:
1把小时和分钟转成 距离0:0的秒数(小时数)
var date=new Date();
function showHello(date) {
var hour=date.getHours();
var minte=date.getMinutes();
var second=hour*3600+minte*60;
//1.思路 把当前时间 转成距离0:0的秒数(小时数)
if(second>=6*3600&&second<=9*3600){
window.alert("早上好");
}else if(second>=12*3600&&second<=14*3600){
window.alert("中午好");
}
}
showHello(date);
String
String是动态类,提供了对字符串的各种操作,下面是几种常用的函数,其他的参考javascript帮助文档。
- indexOf()-------------------返回某个字符串在该字符串中首次出现的位置
- split()-----------------------把字符串分割为字符串数组
- substr()---------------------提取从start下标开始的指定数目字符
- substring()------------------提取字符串中介于两个指定下标之间的字串
- charAt()---------------------返回指定位置的字符
- length----------------------属性,可以得到字符串的长度
- toString()--------------------js中所有内部对象的成员方法,作用是将对象中的数据转成某个格式的字符串。
- match()/replace()/search()------用得很多,但是涉及到正则表达式,这三个函数在学习正则表达式的时候做笔记
案例:
var str="abc123456";
window.alert(str.length);
var str2="abc def oop";
var arr=str2.split(" ");//如果(“”)就是一个一个分割
window.alert(arr);
var str3="abcdef"
window.alert(str.substr(1,3));//bcd
window.alert(str3.substring(1,3));//bc
Array
Array类(动态类)提供了对数组的操作使用Array类可以轻松的创建数组,并对数组进行删除、排序和合并等操作。
通过Array对象创建数组
- var myArr1=new Array();
可动态的添加元素:myArr1[0]=3; myArr1[1]=”hello”
- var myArr2=new Array(12,34,3.56,”白骨精”);
myArr2[0]=”牛魔王”; myArr2[1]=”红孩儿”; myArr2[2]=”铁扇公主”;
案例
var myarr=new Array();
//动态添加数据
myarr[0]="zy";
myarr[1]=20;
window.alert(myarr.length+" "+myarr);
myarr.pop();//删除最后一个元素,并输出
window.alert(myarr.length+" "+myarr);
myarr.push("abcd");
window.alert(myarr.length+" "+myarr);
Boolean
Boolean类是一个把布尔值打包的布尔对象,这个对象在实际编程中,用的不多,了解即可。
- toString() 把逻辑值转化为字符串,并返回结果
- valueOf() 返回Boolean对象的原始值
Number类
Number类是该对象是原始值的包装类。常用的函数有:
- toString() 把一个Number对象转化为一个字符串,并返回结果。
- toFixed() 把数字转换为字符串,结果的小数点后有指定位数的数字
例子:
var b=10;
//把10变成二进制
window.alert(b.toString(2));
系统函数
解码某个编码的 URI。 |
|||
解码一个编码的 URI 组件。 |
|||
把字符串编码为 URI。 |
|||
把字符串编码为 URI 组件。 |
|||
对字符串进行编码。 |
|||
计算 JavaScript 字符串,并把它作为脚本代码来执行。 |
|||
返回一个 JavaObject 的 JavaClass。 |
|
|
|
检查某个值是否为有穷大的数。 |
|||
检查某个值是否是数字。 |
|||
把对象的值转换为数字。 |
|||
解析一个字符串并返回一个浮点数。 |
|||
解析一个字符串并返回一个整数。 |
|||
把对象的值转换为字符串。 |
|||
对由 escape() 编码的字符串进行解码。 |
属性
方法 |
描述 |
||
代表正的无穷大的数值。 |
|||
代表 java.* 包层级的一个 JavaPackage。 |
|
|
|
指示某个值是不是数字值。 |
|||
根 JavaPackage 对象。 |
|||
指示未定义的值。 |
js事件驱动机制(编程)
概述:
js是采用事件驱动机制响应用户操作的。比如通过鼠标或者按键在浏览器窗口或者网页元素(按钮,文本框…)上执行的操作,我们称之为事件。
由鼠标或者热键引发的一串程序的动作,称之为事件驱动。
对事件进行处理程序或函数,我们称之为事件处理程序。
如何理解事件驱动机制
事件的分类:
- 鼠标事件
当用户在页面上用鼠标点击页面元素时,对应的DOM节点会触发鼠标事件。主要有click、dblclick、mousedown、mouseover、mouseup、mousemove等
- 键盘事件
当用户用键盘输入信息时,会触发键盘操作事件。主要包括keydown、keypress、keyup三个。
- HTML事件
在html节点加载变更等相关的事件,比如window的onload、unload、abord、error,文本框的select、change等等。
- 其他事件
页面中一些特殊对象运行过程中产生的事件,比如xmlhttprequest对象的相关事件。
入门案例:
案例1,监听鼠标点击事件,并显示鼠标的x,y坐标
html:
<body οnmοusedοwn="test1(event)">
</body>
js:
function test1(e) {
window.alert("x="+e.clientX+" y="+e.clientY);
}
案例2,点击按钮显示当前时间
html:
<body>
<input type="button" οnclick="test1()" value="显示当前的时间"/>
</body>
js:
function test1(e) {
window.alert(new Date());
}
案例3,点击按钮对界面的颜色进行操作(要用js操作外部css)
html:
<head>
<title>Title</title>
<link rel="stylesheet" href="studycss.css" type="text/css"/>
<script src="studyjs.js"></script>
</head>
<body>
<input type="button" οnclick="test1(event)" value="显示当前的时间"/>
<!--如何通过修改style来改变style-->
<div id="div1" class="style1">div1</div>
<input type="button" value="黑色" οnclick="test2(this)"/>
<input type="button" value="红色" οnclick="test2(this)"/>
</body>
css:
.style1{
width: 600px;
height: 400px;
background-color: black;
}
js:
//js如何访问元素色style属性,进行样式修改
function test2(e) {
//获取样式表my.css中的所有class选择器都获取
//document.styleSheets[0];这里的0表示第一个css外部文件
var ocssRules = document.styleSheets[0].rules;
//从ocssRules取出你希望的class
//这里ocssRules[0];这里0表示css中的第一个规则
var style1=ocssRules[0];
if(e.value=="黑色"){
style1.style.backgroundColor="black";
}else if(e.value=="红色"){
style1.style.backgroundColor="red";
}
}
????访问外部css文件总结:
注意:
document.styleSheets[0].rules;是在IE浏览器中使用
document.styleSheets[0].cssRules;是在火狐中使用
如何区分当前浏览器是什么类型:
思路:通过判断不同浏览器有没有这个属性来区分是那个版本的浏览器
一个事件可以被多个函数监听
html
<input type="button" value="黑色" οnclick="test2(this),test3(this)"/>
js
function test2(e) {
window.alert('ok1');
}
function test3(e) {
window.alert('ok2');
}
结论:写在前面的函数先被调用,写在后面的后面调用
特别说明:
并不是所有的html元素都有相同的event事件(对象),这个在做项目的时候特别注意,比如提交按钮有onsubmit事件,但是输入框就没有的,具体参考js帮助文档。
window有三个事件:
onload:页面打开
onbeforeunload:关闭页面前
onunload:关闭页面后
习题:完成一个js版本的计算器
html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<link rel="stylesheet" href="studycss.css" type="text/css"/>
<script src="studyjs.js"></script>
</head>
<body>
<table class="t1">
<tr><td colspan="4"><input id="t" type="text"/></td></tr>
<tr><td><input οnclick="Power()" type="button" value="POWER"></td><td><input οnclick="Clear()" type="button" value="Clear"></td><td><input οnclick="Back()" id="back" type="button" value="Back"></td></tr>
<tr><td><input οnclick="a1()" type="button" value="1"></td><td><input οnclick="a2()" type="button" value="2"></td><td><input οnclick="a3()" type="button" value="3"></td><td><input οnclick="a4()" type="button" value="4"></td></tr>
<tr><td><input οnclick="a5()" type="button" value="5"></td><td><input οnclick="a6()" type="button" value="6"></td><td><input οnclick="a7()" type="button" value="7"></td><td><input οnclick="a8()" type="button" value="8"></td></tr>
<tr><td><input οnclick="a9()" type="button" value="9"></td><td><input οnclick="a0()" type="button" value="0"></td><td><input οnclick="ap()" type="button" value="."></td><td><input οnclick="deng()" type="button" value="="></td></tr>
<tr><td><input οnclick="jia()" type="button" value="+"></td><td><input οnclick="jian()" type="button" value="-"></td><td><input οnclick="chen()" type="button" value="*"></td><td><input οnclick="chu()" type="button" value="/"></td></tr>
</table>
</body>
</html>
css:
.t1{
width: 300px;
height: 250px;
border:1px solid black;
text-align: center;
background-color: green;
}
.t1 td{
border:1px solid black;
width: 50px;
height: 20px;
background-color: pink;
}
js:
function a1() {
document.getElementById("t").value=document.getElementById("t").value+"1";
}
function a2() {
document.getElementById("t").value=document.getElementById("t").value+"2";
}
function a3() {
document.getElementById("t").value=document.getElementById("t").value+"3";
}
function a4() {
document.getElementById("t").value=document.getElementById("t").value+"4";
}
function a5() {
document.getElementById("t").value=document.getElementById("t").value+"5";
}
function a6() {
document.getElementById("t").value=document.getElementById("t").value+"6";
}
function a7() {
document.getElementById("t").value=document.getElementById("t").value+"7";
}
function a8() {
document.getElementById("t").value=document.getElementById("t").value+"8";
}
function a9() {
document.getElementById("t").value=document.getElementById("t").value+"9";
}
function a0() {
document.getElementById("t").value=document.getElementById("t").value+"0";
}
function ap() {
document.getElementById("t").value=document.getElementById("t").value+".";
}
function deng() {
if(b=="+"){
document.getElementById("t").value=parseFloat(document.getElementById("t").value)+a;
}else if(b=="-"){
document.getElementById("t").value=parseFloat(document.getElementById("t").value)-a;
}else if(b=="*"){
document.getElementById("t").value=parseFloat(document.getElementById("t").value)*a;
}else if(b=="/"){
document.getElementById("t").value=parseFloat(document.getElementById("t").value)/a;
}
}
function jia() {
a=parseFloat(document.getElementById("t").value);
b="+";
document.getElementById("t").value=null;
}
function jian() {
a=parseFloat(document.getElementById("t").value);
b="-";
document.getElementById("t").value=null;
}
function chen() {
a=parseFloat(document.getElementById("t").value);
b="*";
document.getElementById("t").value=null;
}
function chu() {
a=parseFloat(document.getElementById("t").value);
b="/";
document.getElementById("t").value=null;
}
function Power() {
document.getElementById("t").value=parseFloat(document.getElementById("t").value)*parseFloat(document.getElementById("t").value);
}
function Clear() {
document.getElementById("t").value=null;
}
function Back() {
document.getElementById("t").value=document.getElementById("t").value.substr(0,document.getElementById("t").value.length-1);
}
效果图:
DOM编程
为什么要学习DOM编程:
- 通过dom编程,我们可以写出各种网页游戏
- dom编程也是ajax的重要基础
dom编程简介
DOM=Document Object Model(文档对象模型),根据W3C DOM规范,DOM是HTML与XML的应用编程接口(API),DOM将整个网页映射为一个由层次节点组成的文件。
js把浏览器,网页文档中的html元素都用相应的内置对象来表示,这些对象与对象间的层次关系称为dom,针对网页(html、jsp、php、aspx、net)的dom就是html dom。目前学习的就是html dom。
关于js的xml文件的dom编程,这里参数不学习。学到ajax的时候做笔记。
这几个特别重要的概念
- 上面说的内置对象就是dom对象,准确的说就是html dom对象。
- dom编程时,会把赫塔米勒文档看做是一颗dom树(对照超级马丽的代码来说明dom编程。)(首先要画出html dom图)
- dom编程的核心就是各个dom对象。
bom介绍
通过使用BOM,可移动窗口、更改状态栏文本。bom是w3c组织提出的,它建议所有的浏览器都应当遵循这样的设计规范,可以说bom和dom关系密切,互相影响,bom为纲,dom为目,我们可以简单的理解dom就是bom的具体实现。
bom(browser object model)浏览器对象模型
因为做浏览器的厂家很多,w3c定义了一个做浏览器的规范
bom和dom:bom为纲,dom为目,我们可以简单的理解dom就是bom的具体实现。
dom对象层次一览图(简略版)
window对象
window对象表示一个浏览器窗口或一个框架。在客户端javascript中,window对象是全局对象,要引用当前窗口根本不需要特殊的语法,可以把那个窗口的属性作为全局变量来用。
在使用window对象的方法和属性的时候,可以不带window,比如:window.alert(“谢振瑜!”),可以直接写成alert(“谢振瑜!”);
常用的方法:
- alert()*****************显示消息和一个确认按键的警告框
- confirm()**************显示消息以及确认按钮和取消按钮的对话框
- complile()*************
- setInterval()***********按照指定的周期(毫秒计)来循环调用函数或计算表达式
- clearInterval()*********取消由setInterval()设置的计时器
- setTimeout()**********指定的毫秒数后调用函数或计算表达式
- clearTimeout()*********取消由setTimeout()设置的计时器
案例1:confirm
function test(){
var res=window.confirm(“你要删除!”);
if(res){
window.alert(“删除!”);
}else{
window.alert(“放弃删除!”);
}
}
案例2:(setInterval())
html:
<img src="imges/1.jpg" id="xr"/>
js:
//让动态图片动起来
var n=1;
function runCat() {
//得到img对象
var a=document.getElementById("xr");
a.src="imges/"+((n++%5)+1)+".jpg";
}
setInterval("runCat()",1000);
这里需要准备相应的图片
案例3:clearInterval()
//让动态图片动起来
var n=1;
var count=0;
function runCat() {
count++;
if(count==3){
//停止这个计时器
clearInterval(myTimer);
}
//得到img对象
var a=document.getElementById("xr");
a.src="imges/"+((n++%5)+1)+".jpg";
}
var myTimer=setInterval("runCat()",1000);
案例4:setTimeout()
在指定的毫秒数后调用函数或计算表达式(但是只调用一次)
//让动态图片动起来
var n=1;
var count=0;
function runCat() {
count++;
if(count==3){
//停止这个计时器
clearInterval(myTimer);
setTimeout("reRun()",5000);
count=0;
}
//得到img对象
var a=document.getElementById("xr");
a.src="imges/"+((n++%5)+1)+".jpg";
}
var myTimer=setInterval("runCat()",1000);
function reRun() {
myTimer=setInterval("runCat()",1000);
}
补充说明:
在元素间的文本就是通过 对象.innerText
history对象
Contains information about URLs visited by the client,即:该对象包含客户端访问过的URL信息。
从dom层次图看,history是由javascript runtime engine 自动创建的,所以你也可以认为history就是一个js对象。
location对象
navigator对象
Contains information about the browser,即:该对象包含当前浏览器的各信息。
从dom层次图来看,bavigator是window对象的成员属性,但实际navigator也是javascript runtime enigne 自动创建的,所以你也可以认为navigator就是一个js对象。
screen对象
Contains information about the client’s screen and rendering capabilities,即:该对象包含有关客户机显示屏幕的信息。
从dom层次图来看,screen是window对象的成员属性,但实际screen也是javascript runtime enigne 自动创建的,所以你也可以认为screen就是一个js对象。
event对象
event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态,事件通常与函数结合使用。
从dom对象的层次图看,event对象是window对象的属性,其实在其他的dom对象都存在event事件(一种event对象就代表一类事件),理解这一点非常重要!
如何绑定事件监听
- 直接在某个html控件上指定
<input type="button" value="haha" οnclick="test()"/>
- getElementById(“”)获取控件后,再绑定
<input type="button" value="haha" id="but1"/>
<script language="JavaScript">
function test() {
window.alert("hahaha");
}
document.getElementById("but1").onclick=test;
</script>
- 通过addEventListener()或者是attachEvent()来绑定
<input type="button" value="haha" id="but1"/>
<script language="JavaScript">
function test() {
window.alert("hahaha");
document.getElementById("but1").detachEvent("onclick",test);
}
document.getElementById("but1").attachEvent("onclick",test);
</script>
- 一个事件可以有多个事件监听者(函数)
例子:要求用户在一个输入框中输入一个数,如果不是数字,则给出提示。
html:
<body>
<input type="text" οnkeydοwn="test(event)" id="text1"/>
<input type="button" οnclick="test()" value="提交"/>
</body>
js:
function test(event) {
//用户每按下一个键就去判断是不是一个数
if(event.keyCode<48||event.keyCode>57){
window.alert("你输入的不是数");
window.event.returnValue=false;
}
}
document对象
Document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学好dom编程的关键所在。
Document对象是window对象的一个成员属性,通过window.document来访问,当然也可以直接使用document。
1、write:向文档输入文本或是js代码
2、writeln:向文档输入文本或是js代码,与write不一样的地方是,writeln是换行输出
这两个对浏览器看,输出效果没有区别
3、getElementById():规定html文档中id号要唯一,如果不唯一,则只取第一个元素;id不用数字开头;
例子:
html:
<body>
<a id="a1" href="http://www.sohu.com">连接到souhu</a><br>
<a id="a2" href="http://www.sina.com">连接到sina</a><br>
<a id="a3" href="http://www.163.com">连接到163</a><br>
<input type="button" value="tesing" οnclick="test1()"/>
</body>
js:
function test1() {
var myhref=document.getElementById("a1");
window.alert(myhref.innerText);
}
4、getElementByName
通过元素的名字来获取对象集合
案例:
html:
<body>
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="旅游">旅游
<input type="checkbox" name="hobby" value="音乐">音乐
<input type="button" value="tesing" οnclick="test1()"/>
</body>
js:
function test1() {
//id不能唯一,但是name可以重复
var hobbies=document.getElementsByName("hobby");
//window.alert(hobbies.length);
for(var i=0;i<hobbies.length;i++){
//判断是否选择
if(hobbies[i].checked){
window.alert("你的爱好是"+hobbies[i].value);
}
}
}
5、getElementByTag
通过标签名字来获取对象集合
案例:
html:
<body>
<input type="checkbox" name="hobby" value="足球">足球
<input type="checkbox" name="hobby" value="旅游">旅游
<input type="checkbox" name="hobby" value="音乐">音乐
<input type="button" value="tesing" οnclick="test1()"/>
<input type="button" value="获取所有input" οnclick="test2()"/>
</body>
js:
//通过标签名称来获取对象(元素)
function test2() {
var myObjs=document.getElementsByTagName("input");
for(var i=0;i<myObjs.length;i++){
window.alert(myObjs[i].value);
}
}
如何动态创建/删除html元素
举例子:
html:
<body>
<input type="button" οnclick="test1()" value="动态创建一个超链接"/>
<input type="button" οnclick="test2()" value="动态删除一个超链接"/>
<div id="div1" style="width: 200px;height: 400px;border: 1px solid red;">div1</div>
</body>
js:
function test1() {
//创建元素
var myElement=document.createElement("a")//""里面写希望创建的html元素标签
//给新的元素添加必要的信息
myElement.href="http://www.sina.com";
myElement.innerText="链接到新浪";
myElement.style.left="100px";
myElement.style.top="100px";
myElement.style.position="absolute";
myElement.id="id1";
//添加到document.body
//document.body.appendChild(myElement);
//将这个元素添加到div
document.getElementById("div1").appendChild(myElement);
}
function test2() {
//删除一个元素
document.getElementById("div1").removeChild(document.getElementById("id1"))
}
特别说明:
删除一个元素是有前提的:必须获的父元素
//第一种方法(比较不灵活)
document.getElementById(“div1”).removeChild(document.getElementById(“id1”));
//第二种方法(比较灵活,推荐)
document.getElementById(“id1”).parentNode.removeChild(document.getElementById(“id1”));
对dom的加强
在dom编程中,一个html文档会当做dom树对待,dom会把所有的html元素映射成Note节点(对象),的属性和方法
常用的dom的每个Node节点属性和方法
图片补充:
属性:parentNode
body对象
body对象代表文档的主体(html body)。
body对象是document对象的一个成员属性,通过document.body来访问。
使用body对象,要求文档的主体创建后才能使用,也就是说不能再文档的body体还没有创建就去访问body,这个后面会举例说明。
innerText和innerHTML的区别:
举例说明:
function test() {
//innerText浏览器会做文本来解析
document.getElementById("myspan").innerText="<a href='http://www.sohu.com'>到sohu</a>";
//innerHTML浏览器会作为html来解析
document.getElementById("myspan").innerHTML="<a href='http://www.sohu.com'>到sohu</a>";
}
案例:
一个小太阳,当它碰到边框后,就自动改变方向,很多流氓网站就有这种广告,很多。
代码:
html:
<body style="background-image: url('imges/1.jpg');">
<div id="sundiv" style="position: absolute">
<img src="imges/7.png"/>
</div>
</body>
js:
//定义全局变量
directX=1;//x轴的方向
directY=1;//y轴的方向
sunX=0;//小太阳的坐标x
sunY=0;//小太阳的坐标y
function sunMove() {
sunX+=directX;
sunY+=directY;
//修改div的letf、top
sundiv.style.top=sunY+"px";
sundiv.style.left=sunX+"px";
//判断什么时候转变方向
//x方向 (offsetWidth可以放回当前这个对象实际宽度)
if(sundiv.offsetWidth+sunX>=document.body.clientWidth||sunX<=0){
directX=-directX;
}
//y方向
if(sundiv.offsetHeight+sunY>=document.body.clientHeight||sunY<=0){
directY=-directY;
}
}
setInterval("sunMove()",10);
知识点:
四种浏览器对 clientHeight、offsetHeight、scrollHeight、clientWidth、offsetWidth 和 scrollWidth 的解释差异 :
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth (包括边线的宽)
网页可见区域高:document.body.offsetHeight (包括边线的宽)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
这里说说四种浏览器对 document.body 的 clientHeight、offsetHeight 和 scrollHeight 的解释。
这四种浏览器分别为IE(Internet Explorer)、NS(Netscape)、Opera、FF(FireFox)。
clientHeight
四种浏览器对 clientHeight 的解释都没有什么异议,都认为是内容可视区域的高度,也就是说页面浏览器中可以看到内容的这个区域的高度,一般是最后一个工具条以下到状态栏以上的这个区域,与页面内容无关。
offsetHeight
IE、Opera 认为 offsetHeight = clientHeight + 滚动条 + 边框。
NS、FF 认为 offsetHeight 是网页内容实际高度,可以小于 clientHeight。
scrollHeight
IE、Opera 认为 scrollHeight 是网页内容实际高度,可以小于 clientHeight。
NS、FF 认为 scrollHeight 是网页内容高度,不过最小值是 clientHeight。
简单地说
clientHeight 就是透过浏览器看内容的这个区域高度。
NS、FF 认为 offsetHeight 和 scrollHeight 都是网页内容高度,只不过当网页内容高度小于等于 clientHeight 时,scrollHeight 的值是 clientHeight,而 offsetHeight 可以小于 clientHeight。
IE、Opera 认为 offsetHeight 是可视区域 clientHeight 滚动条加边框。scrollHeight 则是网页内容实际高度。
同理
clientWidth、offsetWidth 和 scrollWidth 的解释与上面相同,只是把高度换成宽度即可。
注:以上也是转的,对自己有点参考而已,有些值要跟据页面方式而定!我用的Ajax就完全没法用上面的方法定高!
javaScript窗口属性:
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth (包括边线的宽)
网页可见区域高:document.body.offsetHeight (包括边线的宽)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
在IE、FireFox、Opera下都可以使用
document.body.clientWidth
document.body.clientHeight
即可获得,很简单,很方便。
而在公司项目当中:
Opera仍然使用
document.body.clientWidth
document.body.clientHeight
可是IE和FireFox则使用
document.documentElement.clientWidth
document.documentElement.clientHeight
原来是W3C的标准在作怪啊
练习题:
代码:
html:
<body>
<div id="gamediv" style="width: 500px;height: 500px;border: 1px solid black;position: absolute">
<div id="sundiv" style=" position: absolute ;top: 20px;left: 20px;">
<img src="imges/7.png"/>
</div>
</div>
</body>
js:
//定义全局变量
directX=1;//x轴的方向
directY=1;//y轴的方向
sunX=0;//小太阳的坐标x
sunY=0;//小太阳的坐标y
function sunMove() {
sunX+=directX;
sunY+=directY;
//得到gamediv的top、left
gameWidth=parseInt(gamediv.style.width.substr(0,gamediv.style.width.length-2));
gameHeigth=parseInt(gamediv.style.height.substr(0,gamediv.style.height.length-2));
//修改sundiv的letf、top
sundiv.style.top=sunY+"px";
sundiv.style.left=sunX+"px";
//判断什么时候转变方向
//x方向 (offsetWidth可以放回当前这个对象实际宽度)
if(sundiv.offsetWidth+sunX>=gameWidth||sunX<=0){
directX=-directX;
}
//y方向
if(sundiv.offsetHeight+sunY>=gameHeigth||sunY<=0){
directY=-directY;
}
}
setInterval("sunMove()",1);
效果图:
练习题2:
随意拖拽窗口:用户用鼠标点中,浮动窗口,可以随意拖拽该窗口。
style对象
style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合。
style对象的定义:Pepresents the current settings of all possible inline styles for a given element,即表示当前元素的样式设置。
style不是针对某一个html元素,而是对所有的html元素而言的,也就是说,我们可以通过document.getElementById(“id”).style.property=”值”,来控制网页文档的任何一个元素(对象)的样式,当然这个很重要的。
坦克转向:
- 做四个图片
src=“???”
<img src=”???”/>
- 一次加载一个背景图,通过显示该背景的不同部分,实现转向效果
background-position-y说明:
代码:
html:
<body>
<div id="tank" style=" background-position-y: 0px;background-image: url('imges/2.png');width: 40px;height: 40px"></div>
<input type="button" value="上" οnclick="change(this)"/>
<input type="button" value="右" οnclick="change(this)"/>
<input type="button" value="下" οnclick="change(this)"/>
<input type="button" value="左" οnclick="change(this)"/>
</body>
js:
function change(e) {
if(e.value=="上"){
tank.style.backgroundPositionY="0px";
}else if(e.value=="右"){
tank.style.backgroundPositionY="120px";
}else if(e.value=="下"){
tank.style.backgroundPositionY="80px";
}else if(e.value=="左"){
tank.style.backgroundPositionY="40px";
}
}
效果图:
按键表格:
web版坦克大战1.0版本
html:
<body οnkeydοwn="dosomething(event)">
<div id="filed" style="background-color: black;width: 500px;height: 500px;">
<div id="mytank" style=" background-position-y: 0px;background-image: url('imges/2.png');width: 40px;height: 40px;position: absolute"></div>
</div>
<script src="studyjs.js"></script>
</body>
js:
//用面向对象的方法开发,web版本的坦克大战1.0版本(可以通过asdw键来控制坦克走向)
//tank对象
function Mytank(x,y,direct) {
this.x=x;//坦克的纵坐标
this.y=y;//坦克的横坐标
this.direct=direct;//坦克的方向
this.speed=3;//坦克的速度
//初始化
mytank.style.left=this.x+"px";
mytank.style.top=this.y+"px";
mytank.style.backgroundPositionY="0px";
//event表示按键的事件本身
this.move=function move(event) {
//a表示向左 3
//s表示向下 2
//d表示向右 1
//w表示向上 0
switch (event.keyCode){
case 65://a表示向左 3
this.x-=this.speed;
this.direct=3;
mytank.style.backgroundPositionY="40px";
break;
case 83://s表示向下 2
this.y+=this.speed;
this.direct=2
mytank.style.backgroundPositionY="80px";
break;
case 68://d表示向右 1
this.x+=this.speed;
this.direct=1;
mytank.style.backgroundPositionY="120px";
break;
case 87://w表示向上 0
this.y-=this.speed;
this.direct=0;
mytank.style.backgroundPositionY="0px";
break;
}
//统一改变位置
mytank.style.left=this.x+"px";
mytank.style.top=this.y+"px";
}
}
//判断用户希望干什么
function dosomething(event) {
if(event.keyCode==65||event.keyCode==83||event.keyCode==68||event.keyCode==87){
hero.move(event);
}else if(event.keyCode==69){
Gun.gunmove();
}
}
//创建坦克
var hero=new Mytank(200,360,0);
仿sohu频道切换效果
布局分析:
代码:
html:
<body>
<div class="div1">
<div class="navi">
<ul>
<li οnmοuseοver="change('zs',this)" οnmοuseοut="change2(this)">招生</li>
<li οnmοuseοver="change('rz',this)" οnmοuseοut="change2(this)">热招</li>
<li>出国</li>
</ul>
</div>
<!--超链接-->
<div id="zs" class="zs" >
<ul>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
<li><a href="#">招生招生招生招生</a></li>
</ul>
</div>
<div id="rz" class="rz" >
<ul>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
<li><a href="#">热招热招热招热招</a></li>
</ul>
</div>
</div>
</body>
css:
body{
font-size: 12px;
margin: 0px;
}
.div1{
width: 160px;
height: 230px;
/*background-color: pink;*/
}
.navi{
width: 21px;
height: 230px;
float: left;
}
.navi ul{
padding: 0px;
margin-left: 0px;
margin-top: 0px;
float: left;
}
.navi li{
list-style-type: none;
height: 51px;
width: 21px;
margin-top: 2px;
background-color: silver;
float: left;
text-align: center;
/*padding-bottom: 0px;*/
padding-top: 15px;
}
.zs,.rz{
width: 100px;
height: 205px;
float: left;
margin-left: 3px;
/*background-color: pink;*/
}
.zs ul,.rz ul{
padding: 0px;
float: left;
}
.zs li,.rz li{
list-style-type: none;
line-height: 23px;
}
.rz{
display: none;
}
js:
function change(val,obj) {
obj.style.backgroundColor="#FFC12D";
if(val=="zs"){
zs.style.display='block';
rz.style.display='none';
}else if(val=="rz"){
zs.style.display='none';
rz.style.display='block';
}
}
function change2(obj) {
obj.style.backgroundColor="silver";
}
效果图:
Style 对象属性
案例:
使用js实现购物车的功能(简易功能)
html:
<body>
<h1>我的购物车</h1>
<input type="checkbox" name="fruit" οnclick="gouwu(this)" value="10"/>苹果 10元<br>
<input type="checkbox" name="fruit" οnclick="gouwu(this)" value="20"/>香蕉 20元<br>
<input type="checkbox" name="fruit" οnclick="gouwu(this)" value="30"/>西瓜 30元<br>
<input type="checkbox" name="fruit" οnclick="gouwu(this)" value="40"/>栗子 40元<br>
<input type="checkbox" name="fruit" οnclick="gouwu(this)" value="50"/>哈密瓜 50元<br>
<a href="#" οnclick="selectCheck(this)">全选</a>
<a href="#" οnclick="selectCheck(this)">取消</a><br>
总价格是:<span id="myspan">0元</span>
</body>
js:
this.gouwu=function gouwu(obj) {
var fruits=document.getElementsByName("fruit");
var totalprice=0;
//遍历所有的checkbox,计算新的总价
for(i=0;i<fruits.length;i++){
if(fruits[i].checked){
totalprice+=parseFloat(fruits[i].value);
}
}
myspan.innerText=totalprice+"元";
}
function selectCheck(obj) {
var fruits=document.getElementsByName("fruit");
if(obj.innerText=='全选'){
for(i=0;i<fruits.length;i++){
fruits[i].checked=true;
}
}else {
for(i=0;i<fruits.length;i++){
fruits[i].checked=false;
}
}
gouwu(fruits);
}
效果图:
表单(form)案例1:
html:
<body>
<h1>个人信息</h1>
<form>
U:<input type="text" name="username"/><br>
P:<input type="password" name="pwd"/><br>
<input type="submit" name="提交"/><br>
</form>
<h1>兴趣爱好</h1>
<form>
爱好一:<input type="text" name="hobby1"/><br>
爱好二:<input type="text" name="hobby2"/><br>
<input type="submit" name="提交"/><br>
</form>
<input type="button" value="tesing" οnclick="test()"/>
</body>
js:
function test() {
//如何取得所有的表单
var allforms=document.forms;
//可以通过allform 去访问指定表单
//alert(allforms[0].username.value); 等价于下面的写法
alert(allforms.item(1).hobby1.value);
}
表单案例2:
当用户输入的信息,不满足要求时,在提交的时候,给出相应的提示
html:
<body>
<h1>用户注册</h1>
<form>
<table>
<tr><td class="td1">用 户名</td><td class="td2"><input class="style1" type="text" name="username"/><span id="span1"></span></td></tr>
<tr><td>密 码</td><td><input class="style1" type="password" name="pwd1"/><span id="span2"></span></td></tr>
<tr><td>确认密码</td><td><input class="style1" type="password" name="pwd2"/><span id="span3"></span></td></tr>
<tr><td>年 龄</td><td><input class="style1" type="text" name="age"/></td></tr>
<tr><td>电子邮箱</td><td><input class="style1" type="text" name="email"/></td></tr>
<tr><td>电话号码</td><td><input class="style1" type="text" name="phone"/></td></tr>
<tr><td><input οnclick="return checkinfo()" type="submit" value="注册新用户"/></td><td><input type="reset" value="重新填写"/></td></tr>
</table>
</form>
</body>
css:
.style1{
width: 140px;
}
.td1{
width: 100px;
}
.td2{
width: 300px;
}
#span1,#span2,#span3{
font-size: 10px;
color: red;
}
js:
function checkinfo() {
span1.innerText="";
span2.innerText="";
span3.innerText="";
//获取表单输入的用户名
if(document.forms[0].username.value.length>6||document.forms[0].username.value.length<4){
span1.innerText="用户名应在4-6位间";
return false;
}
//判断密码是否ok
if(document.forms[0].pwd1.value.length<=3){
span2.innerText="密码要求大于3位";
return false;
}
if(document.forms[0].pwd1.value!=document.forms[0].pwd2.value){
span3.innerText="输入的两次密码不一样";
return false;
}
}
效果图:
特别说明:
验证表单的时候,可以在
<form action=”” οnsubmit=”函数”/>
也可以
<input type=”submit” οnclick=”函数”/>
案例3:
用户输入信息,点击添加好汉到上表格中。
如果编号重复给出提示
html:
<body>
<h1>英雄排行榜</h1>
<table border="1px" id="mytab">
<tr><td>排名</td><td>姓名</td><td>外号</td></tr>
<tr><td>1</td><td>宋江</td><td>及时雨</td></tr>
<tr><td>2</td><td>卢俊义</td><td>玉麒麟</td></tr>
</table>
<h1>请输入新的好汉</h1>
编号:<input type="text" id="no"/><br>
名字:<input type="text" id="username"/><br>
外号:<input type="text" id="nickname"/><br>
<input type="button" οnclick="addHero()" value="添加"/>
</body>
css:
.style1{
width: 140px;
}
.td1{
width: 100px;
}
.td2{
width: 300px;
}
#span1,#span2,#span3{
font-size: 10px;
color: red;
}
js:
function addHero() {
//遍历整个表格看看有没有重复的编号
for(var i=0;i<mytab.rows.length;i++){
//取出一行
//mytab.rows[i] 第i行
var eachRow=mytab.rows[i];
//对该行遍历
//eachRow.cells 表示eachRow所有列
if(eachRow.cells[0].innerText==no.value){
window.alert("编号不能重复");
return ;
}
}
//获取用户输入的信息
var newTableRow=mytab.insertRow(mytab.rows.length);
newTableRow.insertCell(0).innerText=no.value;
newTableRow.insertCell(1).innerText=username.value;
newTableRow.insertCell(2).innerText=nickname.value;
}
效果图:
正则表达式
为什么需要正则表达式
问题1:
给你一个字符串(或者一篇文章),请你找出所有四个数字连在一起的字串,并且这四个数字要满足:第一位与第四位相同,第二位与第三位相同,比如1221,5775……
问题2:
比如验证电子邮件,身份证,是不是数
解决之道:
js设计者给我们提供了一个新的技术 正则表达式(RegExp)regular expression
基本概念:
在计算机中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或者其他的工具里,正则表达式通常被用来检索或者替换那些复合某个模式的文本内容。许多程序设计语言都支持正则表达式进行字符串操作。
所谓正则表达式,就是用某种模式去匹配一类字符串的一个公式,反应到js中就是一个RegExp对象。
这里强调,正则表达式不是js的专利产品,实际上很多程序设计语言都支持正则表达式进行字符串操作,入下图:
快速入门案例:
给你一个字符串(或者一篇文章),请你找出所有四个数字连在一起的子串。
代码:
html:
<body>
<textarea id="content" rows="10" cols="20"></textarea>
<input type="button" value="测试" οnclick="test1()"/>
</body>
js:
function test1() {
//的到用户的内容
var con=content.innerText;
var myReg=/(\d){4}/gi;//这是一个正则表达式对象,可以检索到4个连续的数字
while (res=myReg.exec(con)){//res是检索出来的结果,但是一个结果就对应一个数组,该数组的res[0]就在找到的那个文本
window.alert("找到"+res);
}
}
效果图:
小结:
- 创建一个RegExp对象有两只方法
- 隐式创建:var reg=/正则表达式/gi g表示全局匹配,i表示区分大小写吗,写上就是不区分, m考虑换行
- 显式创建:var reg=new RegExp(“正则表达式”,”gi”);
练习:
- 如何检索五个连续的数字
代码:
html:
<body>
<textarea id="content" rows="10" cols="20"></textarea><br>
<input type="button" value="测试" οnclick="test1()"/><br>
<span id="span1"></span>
</body>
js:
function test1() {
//得到用户的内容
var b="";
var con=content.innerText;
var myReg=/(\d){5}/gi;
while (res=myReg.exec(con)){
var a=res[0]+",";
b+=a;
}
span1.innerText="检查结果是="+b;
}
效果图:
- 指定查找某个字符串,比如“谢振瑜”,如果找到则提示
代码:
html:
<body>
<textarea id="content" rows="10" cols="20"></textarea><br>
<input type="button" value="测试" οnclick="test1()"/><br>
<span id="span1"></span>
</body>
js:
function test1() { //得到用户的内容 var con=content.innerText; var myReg=/谢振瑜/gi; while (res=myReg.exec(con)){ var a=res[0]; } if(a=="谢振瑜"){ span1.innerText="找到了!"; } else { span1.innerText="没有找到!"; } }
效果图:
正则表达式
String对象和正则表达式相关的方法
- search
检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。
语法:
stringObject.search(regexp)
返回值:
stringObject 中第一个与 regexp 相匹配的子串的起始位置。
注释:如果没有找到任何匹配的子串,则返回 -1。
例子:
var str="Visit W3Cschool!";
window.alert(str.search(/W3Cschool/));
- match()
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。
语法:
stringObject.match(searchvalue)
stringObject.match(regexp)
返回值:
存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。
例子:
function test1() {
var con=content.innerText;
var myreg=/abc/gi;
res=con.match(myreg);
for(var i=0;i<res.length;i++){
window.alert(i+" "+res[0]);
}
}
- replace
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
语法:
stringObject.replace(regexp,replacement)
返回值:
一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。
例子:
function test2() {
var con=content.innerText;
//把四个数,换成 这里原来有四个数
var a=/(\d){4}/gi;
var newCon=con.replace(a,"这里原来有四个数");
content.innerText=newCon;
}
- split()
RegExp对象属性
1 index
2 lastindex
3 input
4 leftContent
5 rigthContent
举例:
//index, leftContent, rigthContent
function test3() {
var con=content.innerText;
var myReg=/(\d){4}/gi;
while(res=myReg.exec(con)){
window.alert("index="+RegExp.index+" "+RegExp.leftContext+" "+RegExp.rightContext);
}
}
子表达式和捕获、反向引用的概念
思考:aabbccdd数字(第一位和第二位相同、第二位和第三位相同…)
function test4() {
var con=content.innerText;
var myReg=/(\d)\1(\d)\2(\d)\3(\d)\4/gi;
while(res=myReg.exec(con)){
window.alert(res[0]);
}
}
思考:请在字符串中检索商品编号,形式如:12321-333999111这样的号码,要求满足前面是一个五位数,然后一个-号,然后是一个九位数,连续的每三位相同
function test4() {
var con=content.innerText;
//var myReg=/(\d){5}-(\d)\2\2(\d)\3\3(\d)\4\4/gi;
var myReg=/(\d){5}-((\d)\3\3){3}/gi;
while(res=myReg.exec(con)){
window.alert(res[0]);
}
}
元字符
如果要想灵活运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合符和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
一、限定符
用于指定其前面的字符和组合项连续出现多少次
{n}说明:
n表示出现的次数,比如a{3},1{4},{\d}{2}
但是这里要注意一点,1{3}去匹配1111111的话,会得到两个111
{n,m}说明:
n表示至少出现的n次最多m次
比如:用1{3,4}去匹配1111111的话,会先得到一个1111在得到一个111。js在默认匹配中使用的是贪婪匹配的原则,尽可能匹配多的字符串。
+说明:
+表示出现1次到任意次
比如:/1+/gi去匹配1111111的话,会得到全部的1,即输出1111111
*说明:
*表示出现0次到任意多次
比如:/a1*/gi去匹配a111的话,会得到a111
?说明
?表示出现0次到1次
比如:/a1?/gi 去匹配a111的话,会得到a1
二、字符匹配符
[a-z]说明:
[a-z]表示课一匹配a-z中任意一个字符
比如:/[A-Z]/gi去匹配allc8,会得到
[^a-z]说明:
[^a-z]表示不是a-z中的任意一个字符
比如:用/[^a-z]/gi去匹配allc8,会得到8
三、特殊字符
在字符串中,可能你会遇到比较特殊的字符,针对这种情况,正则表达式通过\xn的方式来匹配
\xn的x是固定的,n是一个十六进制的数,比如\x21就去匹配ascii码表中十六进制是21的字符
四、定位符
定位符用于规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的。
^符号说明:
匹配目标字符串的开始位置
比如:/^xie/gi去匹配”xiezhenyu xie xie”,会得到最开始位置的xie,如果”axiezhenyu”则一个也取不到
$符号说明:
匹配目标只付出的结束位置
比如:/xie$/gi去匹配”xiezhenyu xie xie”,会得到最后位置的xie,如果”xiezhenyu xie xie xiea”则一个也取不到
五、转义符号\
需要用到转移符号的字符有以下:
. * + ( ) $ / \ ? [ ] ^ { }
六、选择匹配符
有时候,我们在匹配某个字符的时候是选择性的,即:既可以匹配这个,有可以匹配那个,这时候需要用到选择匹配符
比如:用/xie|谢/gi去匹配“xie 谢”的话,会得到xie和谢
综合案例:
验证电子邮件格式是否合法:
1、只能有一个@
2、@前面是用户名,可以是a-z A-Z 0-9 _-字符
3、@后面是域名,可以是xiezhenyu.com或者qq.com并且域名只能是英文字母
代码:
function test6() {
var con=content.innerText;
var myReg=/^[a-zA-Z0-9_-][email protected]([a-zA-Z0-9]+\.)+(com|cn|net|org)$/gi;
if(myReg.test(con)){
window.alert("是邮箱");
}else {
window.alert("不是邮箱");
}
}