JavaScript
- 一种网页脚本语言
- 可以使用任何文本编辑工具编写
- 由浏览器内置的JavaScript引擎执行代码
- 解释执行:事先不编译,逐行执行
- 基于对象:内置大量现成对象
JS代码
- js注释和java一致
- 把逻辑封装成函数,需要时调用
- function是关键字,用来声明函数f()是函数名,小括号内可以声明参数,大括号内为函数体
- js中函数都是公用的,不需要修饰符
- js中函数不需要声明返回值类型
- 如果不把js封装成函数,直接在js标签中写,这样的JS在网页执行时立即调用,改js执行的时机比body还早
JavaScript程序的使用
- 事件定义式
- 在事件定义时直接写js
<!-- 事件定义式 --> <input type="button" value="按钮一" onclick="alert('你好');"/>
- 嵌入式
- 使用script标签
- 该标签可以放在网页任意位置,但通常放在head较多
<input type="button" value="按钮二" onclick="f();"/> <script> function f(){ //js不区分单引号和双引号 alert("你好"); } </script>
- 文件调用式
-
代码位于单独的.js文件中
-
html页面应用.js文件
1)必须是双标签,哪怕没有内容,使用<script src="地址"></script>来调用 2)该标签不能即引入js,又定义js,只能干一件事(其实可以,为了方便记忆,暂且这么写)
//定义以.js为后缀的js文件 function f3(){ alert("你好"); } //调用 <script src="my.js"></script>
-
JS的基本语法
- 关键字var声明变量,不区分变量类型
var s = "hai";
var n = 3.14;
var b = true;
- 没有初始化的变量自动取值为undefined
- 不同数据在计算过程中会进行自动转换
- 数字+字符串:数字转为字符串
- 数字+布尔值:true转换为1,false转换为0
- 字符串+布尔值:布尔值转换为字符串true或false
- 布尔值+布尔值:布尔值转换为数值1或0
- 强制转换函数
- toString 所有数据类型均可转换为String类型
- parseInt 强制转换成整数,如果不能转换,则返回NaN(not a number)
- parseFloat 强制转换为浮点数,如果不能转换,返回NaN
console.log(parseInt(n)); // 在控制台上输出 console.log(parseInt(5.6)); console.log(parseInt("abc")) console.log(parseFloat("5.6"))
- 查询函数类型
- typeof 返回string,number等类型
- isNaN 判断传入的参数是不是NaN,能转为数或者是NaN返回false,否则返回true
- 函数
console.log(isNaN("56"));
console.log(isNaN("abc"));
- JS不区分整数小数
- ==判断值是否相等
- ===判断值是否相等,类型是否相同
- JS中可以用任意数据做条件,当使用任意非布尔值做条件时,任意的非空值等价于true,空值等价于false
- 空值:null/0/""/undefined/NaN
- 这样设计是为了简化条件表达式
var i = 1;
if(i){
console.log("你好");
}else{
console.log("hello world");
}
一.JS调试技巧
1.看错误信息
- 看浏览器控制台的信息
2.打桩
- 观察程序执行的过程
- 看每一步变量的值是否正确
3.排除法+二分法
- 每次删一半代码留一半代码
- 判断是哪一半含有语法错误
这种方法使用来定位语法错误的
JS常用内置对象
-
1.String
- 和Java类似
-
2.Number(*)
- toFixed(num) 转换为字符串,并保留小数点后一定位数字
var n = 3.1415926; console.log(n.toFixed(3));
-
3.Boolean
- true false 没有什么API
-
4.Array(*)
- 声明 1. var arr =[100,200,300] 2. var arr = new Array();等
- JS中的数组都是Object数组
- 数组倒转 Array.reverse()
- 数组排序 Array.sort() 默认按照数组字符串由小到大排序,一般要使用时直接替换比较方法来实现排序
- 可以通过替换比较方法来改变排序结果,在js里,方法也是对象,可以用作参数,由于该方法不需要复用,所以一般写成匿名函数
//2.Array(Js中的数组都是Object数组) // 2.1 如何创建数组 var a1 =["zhangsan",25,true]; //对数组类型没有约束 console.log(a1[0]); //创建数组时不知道存什么数据,创建一个空数组 var a2 = new Array(); a2.push("lisi"); a2.push(30); a2.push(false); console.log(a2[0]); //2.2数组倒转 var arr = [1,5,6,7,8,2,12]; arr.reverse(); console.log(arr); //2.3数组排序(按字符串排序) arr.sort(function x(a,b){//重写sort方法 return a-b; }); console.log(arr);
-
5.Math
console.log(Math.PI);//圆周率 console.log(Math.round(4.56));//四舍五入
-
6.Date
- 创建日期
- 转换为本地格式
- 获取时间分量
//创建客户机的当前时间 var date1 = new Date();//获取的是浏览器的时间 console.log(date1); //创建指定的当前时间 var date2 = new Date("1996/05/06 12:00:00"); console.log(date2); //转换为本地日期/时间格式的字符串 console.log(date1.toLocaleDateString()); console.log(date1.toLocaleTimeString()); //读写时间分量(某一个部位的值) // 读 getXXX() 写setXXX() var y = date1.getFullYear(); var m = date1.getMonth()+1;//月份是从零开始的 var d = date1.getDate(); var today = y+"年"+m+"月"+d+"日"; console.log(today);
-
7.RegExp(*) 正则对象
- 1.创建正则对象
- 1.直接创建 var reg =/正则表达式/模式 eg./\d/g
- 2.创建对象 var reg = RegExp(“正则字符串”,“模式”); RegExp("//d",“g”);
- 2.正则对象的方法
- reg.exec(str)
- 普通模式:判断字符串中是否有和reg匹配的第一个字符串
- 全局模式:第n次调用从str里找出和reg匹配的第n个字符串
- reg.test(str)
- 判断str里是否包含和reg匹配的字符串
- reg.exec(str)
- 3.匹配模式
- g:global,全局检测字符串
- i:ignore,忽略大小写来检测字符串
- 4.字符串支持正则的方法
- str.replace(reg,"") 将str中和reg匹配的所有字串都替换为目标,并没有修改原字符串,而是生成新的字符串
- str.match(reg) 从str中找出和reg匹配的子串
- str.search(reg) 从str中找出和reg匹配的第一个子串的索引
var str = "you can you up,no can no bb."; //4.1 创建正则对象 var reg = /no/; //正则对象的方法 //1)reg.exex(str) //普通模式 :从str中找出第一个于reg匹配的子串 console.log(reg.exec(str)); //全局模式:第n次调用则从str中找出与reg匹配的第n个子串 reg = /no/g; console.log(reg.exec(str)); console.log(reg.exec(str)); console.log(reg.exec(str)); console.log(reg.exec(str)); // 2)reg.test(str) // 判断str中是否包含与reg匹配的子串 console.log(reg.test(str)); //3).字符串支持正则的方法 console.log(str.replace(reg,"yes")); console.log(str);//字符串不可变 console.log(str.match(reg)); console.log(str.search(reg));
- 1.创建正则对象
-
8.Function(*)
- 默认返回undefined,可以使用return返回具体的值
- JS没有重载,调用时无论传入多少个参数,调用的都是一个函数,但是支持重载
- 将输入的值保存到argument数组中,以参数列表为基准,逐个将数组中的值赋给参数列表,若无值可赋,则为undefined;
//通过function关键字所声明的是一个函数(Function)对象
//浏览器加载到此处时,并没有调用此对象,仅仅是创建了此对象
function sum(){
var s = 0;
if(arguments.length>0){
for(var i=0;i<arguments.length;i++){
s= s+arguments[i];
}
}
return s;
}
//一般是在点击函数按钮时调用函数对象,也可以在页面加载时直接调用它
console.log(sum(1,2,3));
console.log(sum(4,5,6,7,8));
// 结论:没有重载,但可以实现和重载一样的调用方式
- 全局函数
- eval 将字符串当表达式运算
- isNaN(),praseInt(),等
//eval()方法的使用
function cal(){
//获取文本框
var input = document.getElementById("num");
//获取框中的值
var num =input.value;
//开始计算
//在使用eval时建议在字符串前后加上括号,可以避免一些奇怪的问题
try{
var value = eval("("+num+")");
input.value = value;
}catch(e){
input.value = "error";
}
}
一个简单的小案例,通过正则验证账号密码格式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
.ok {
color:green
}
.error {
color:red
}
</style>
<script>
//验证账号格式
function checkCode(){
//获取账号
var code = document.getElementById("code").value;
console.log(code);
var reg = /^\w{5,10}$/;
var span = document.getElementById("code_msg");
if(reg.test(code)){
//格式对了,变绿
span.className="ok";
return true;
}else{
//不对,变红
span.className="error";
return false;
}
}
function checkPwd(){
var pwd = document.getElementById("pwd").value;
console.log(pwd);
var reg = /^\w{10,20}$/;
var span2 = document.getElementById("pwd_msg");
if(reg.test(pwd)){
span2.className="ok";
return true;
}else{
span2.className="error";
return false;
}
}
</script>
</head>
<body>
<form action="http://fanyi.youdao.com/" onsubmit="return checkCode()+checkPwd()==2;">
<p>
账号:<input type="text" id="code"
onblur="checkCode();"/>
<span id="code_msg">* 5-10数字,字母,下划线</span>
</p>
<p>
密码:<input type="password" id="pwd"
onblur="checkPwd();"/>
<span id="pwd_msg">* 10-20数字,字母,下划线</span>
</p>
<p>
<input type="submit" value="登录"/>
</p>
</form>
</body>
</html>
BOM和DOM
- 外部对象就是浏览器提供(内部)的API,其中BOM包含了DOM
- BOM:浏览器对象模型
- window对象 调用window对象的属性或方法,可以省略"window."
- 弹出框
- alert 弹出框
- confirm 确认框
- prompt 输入框
- 弹出框
// 1.弹出框 /* 调用window对象的属性或方法,可以省略"window."*/ //1)弹出框 function f1(){ alert("你好!"); } //2)确认框 function f2(){ var v = confirm("你吃了吗?"); console.log(v); } //3)输入框 function f3(){ var v = prompt("你吃的什么?"); console.log(v); }
- 定时器
- 周期性定时器(setInterval(方法,延迟)): 每隔n毫秒执行一次函数,反复执行,直到达到停止条件为止
- 一次性定时器(setTimeout(方法,延迟)) 推迟n毫秒执行一次函数,执行完之后自动停止,也可以在未执行前手动停止
- 延迟的单位为毫秒
- 通常定义id来接收定时器,id的作用是停止定时器
- 停止定时器的方法分别为clearInterval(id)和clearTimeout(id),注意一次性定时器只能在未执行前停止,若已执行则取消无效
- onload(内容)
- 在页面加载完后调用内容
//2.定时器 //1)周期性定时器 每隔n毫秒执行一次函数,反复执行,知道达到停止条件为止 function f4(){ //启动定时器,返回定时器的ID,用来停止定时器 var n = 5; var id = setInterval( function(){ console.log(n); n--; if(!n){ // 停止这个定时器 clearInterval(id); console.log("砰!!!"); } } ,1000); // 启动定时器就相当于启动了一个支线程,当前f4方法相当于主线程, // 两个线程并发执行,不互相等待,因此主线程在启动完支线程后立刻向下执行, // 而支线却需要一秒后执行 console.log("bang"); } //2)一次性定时器 推迟n毫秒执行一次函数,执行完之后自动停止,也可以在未执行前手动停止 var id; function f5(){ // 启动定时器,若想在未执行定时器之前,就想将他停止,需要使用id id = setTimeout(function(){ console.log("ding ,ding ding"); },3000) } function f6(){ //若定时器已经执行则取消无效,若定时器还未执行则可以取消 clearTimeout(id); }
- window对象 调用window对象的属性或方法,可以省略"window."
- location对象
- 跳转 location.href = “”; //属性
- 重新载入 location.reload() 重新载入该页面,即刷新页面 //此为方法// 1.location 对象 // 跳转 function f1(){ var s = confirm("你确定要离开本页面吗?"); if(s){ location.href = "http://www.w3school.com.cn/index.html" ; // 属性 } } // 重新载入 function f2(){ location.reload();//方法 }
- screen对象
- 该对象只能获取,不能改变
- screen.height :获取屏幕高
- screen.width :获取屏幕的宽
- screen.availHeight: 获取屏幕的可用高
- screen.availWidth:获取屏幕的可用宽// 只能获取,不能改动 function f3(){ console.log(screen.height); console.log(screen.width); console.log(screen.availHeight); console.log(screen.availWidth); }
- history对象
- history.forward() 前进
- history.back() 后退
- history.go() 前进几步 或者后退几步 一般不用function f4(){ history.forward(); }
- navigator对象
- navigator.userAgent 获取用户的信息function f5(){ console.log(navigator.userAgent) }
DOM:文档对象模型 document object model
浏览器获得网页时会将其解析为对象,
以后想读写网页内容只需读写对象即可,
这套对象具有树形结构,称之为DOM树,
树结构的每级对象称之为节点.
节点上具有不同的分类,
学习DOM就是学习他的结构以及节点上的API
-
读取节点
- nodeName:节点名称
- 元素节点和属性节点:标签或属性名称
- 文本节点:永远是#text
- 文档节点:永远是#document
- nodeType:节点类型
- 返回数值
- 元素节点:返回1
- 属性节点:返回2
- 文本几点:返回3
- 注释节点:返回8
- 文档节点:返回9
- 读取节点内容(双标签之间的文本叫做内容,任何双标签都有内容)
- innerHTML
- 包含子标签,能够读取出子标签
- innerText
- 忽略子标签,将标签视为文本
- innerHTML
- 读写节点的值
- 表单控件中的数据叫值,只有如下表单控件才有值
- input,select,textarea
- 读取节点的属性
- 通过方法来读写属性(*) // .getAttribute(“src”)
- 通过标准的属性名来读写属性(*)// className ,id ,style
- 通过不标准的属性名来读写属性 (只有高版本浏览器才支持)// a.href img.src
// alert(2); //1.读写节点 //1.1读取节点的名称或类型,只能读,不能改 var p1 =document.getElementById("p1"); console.log(p1.nodeName); console.log(p1.nodeType); //1.2读写节点的内容 //双标签之间的文本叫做内容,任何双标签都有内容 //1)innerHTML 包含子标签 console.log(p1.innerHTML); p1.innerHTML = "1.<u>读写</u>节点"; //2)innerText 忽略子标签,将标签视为文本 var p2 = document.getElementById("p2"); console.log(p2.innerText); p2.innerText = "2.<u>查询</u>节点"; //1.3读写节点的值 //表单控件中的数据叫值,只有如下表单控件才有值 //input,select,textarea var b1 = document.getElementById("b1"); b1.value = "ANNIU"; console.log(b1.value); //1.4 读取节点的属性 //1)通过方法来读写属性(*) var image = document.getElementById("i1"); console.log(image.getAttribute("src")); image.setAttribute("src","../image/3.jpg"); image.removeAttribute("src"); //2)通过标准的属性名来读写属性(*) // className ,id ,style var p6 = document.getElementById("p6"); console.log(p6.style.color); //3)通过不标准的属性名来读写属性 (只有高版本浏览器才支持) // a.href img.src
- nodeName:节点名称
-
查询节点
- 根据ID查询节点
- 根据标签名查询节点
- document.getElementsByTagName("");
- 根据层次查询节点
- 查询某个节点的亲戚,(父亲,孩子,兄弟。。)
- 1)查询父亲
-2) 查询孩子var gz = document.getElementById("gz"); var ul=gz.parentNode console.log(ul);
console.log(ul.childNodes);//包括空格,比较不常用,了解即可 console.log(ul.getElementsByTagName("li"));//只含元素(重点掌握)
- 3)查询兄弟
//某节点.父亲.孩子们[i] var sz = gz.parentNode.getElementsByTagName("li"); console.log(sz[4]);
- 根据name查询节点 //一般用于查询一组单选/多选
var radio = document.getElementsByName("sex"); console.log(radio);
-
插入节点
- 1.先通过document.createElement(“类型”)创建新的节点,创建好为空的节点页面不显示
- 2.给该节点设置内容 innerHTML/innerText 设置内容
- 3.追加
- 节点.appendChild追加为该节点的孩子节点,为该节点的最后一个孩子节点
function f1(){ //创建新的li(空的) var newNode = document.createElement("li"); //给此li设置内容 newNode.innerHTML="罗马"; //再将他追加到ul下 var ul = document.getElementById("city"); ul.appendChild(newNode); }
- 父节点.appendBefor(插入节点,某一孩子节点),插入到某一父亲节点的某一孩子节点之前
function f2(){ var li = document.createElement("li"); li.innerHTML ="杭州"; //获取新节点的父亲和弟弟 var ul = document.getElementById("city"); var gz = document.getElementById("gz"); //把他插入到父亲下,弟弟前 ul.insertBefore(li,gz); }
- 节点.appendChild追加为该节点的孩子节点,为该节点的最后一个孩子节点
-
删除节点
- 父亲节点.removeChild(孩子节点);
function f3(){ //获取删除元素的父亲 var ul = document.getElementById("city"); //获取删除的元素 var gz = document.getElementById("gz"); //通过父亲删除元素 ul.removeChild(gz); }
-
这些对象由w3c规定,由浏览器的开发者设计并开发
-
可以通过JS访问这些对象
自定义对象
如何创建自定义对象的分类
1.1 直接量
- var student ={“key1”:“value1”,“key2”:“value2”…};
- {}代表一个对象,内含多组键值对
- key一般都是字符串,value可以是任意类型的数据
采用直接量创建的对象也叫JSON对象
//1.采用直接量的方式创建对象
function f1(){
var student ={"name":"zhangsan",
"age":"23",
"work":function(){alert("我好好学习");}
};
alert(student.name);
alert(student.age);
student.work();
console.log(student);
}
1.2 构造器(new的函数/首字母大写)
1)内置构造器
- 特殊用法的:Array,Date,RegExp,Function
- 通用:Object
//2.采用内置构造器创建对象
function f2(){
var student = new Object();
student.name ="张三";
student.age ="50";
student.work = function(){
alert("我看NBA");
}
alert(student.name);
alert(student.age);
student.work();
console.log(student);
}
2)自定义构造器
- 声明一个函数,首字母大写
- 声明参数,让调用者明白传什么参数
- 让对象记住这些参数
//3.采用自定义构造器创建对象
function Coder(name,age,work){
this.name=name;
this.age = age;
//指代当前对象
//.job 给此对象增加job属性
//==work将参数work赋值给此属性
this.job = work;
}
function f3(){
var coder = new Coder("李四","25",
function(){ alert("我写java")});
alert(coder.name);
alert(coder.age);
coder.job();
}
总结
- 无论用哪种方式创建出来对象都一样,都是Object
- 若创建的对象给别人使用 建议使用自定义构造器
- 若创建的对象给自己使用,用哪种都行
- 若没有函数建议用第一种,否则建议用第二种
事件
1.事件概述
###1.1 什么是事件
- 就是用户的动作,js调用的时机
1.2 事件的分类
- 鼠标事件
- 键盘事件
- 状态事件:某个条件(状态)时自动触发
- 上述为JS事件汇总
2. 事件的定义
1)直接定义事件
- 在元素上通过事件属性(onclick())直接绑定事件
- 优点:一目了然
- 缺点:JS与HTML耦合度高
<input type="button" value = "按钮一" onclick="f1(event)"/>
//直接定义事件
function f1(e){
console.log(e);
}
2)后绑定事件(*)
- 在页面加载后,使用JS获取元素并给他绑定事件
- 优点:耦合度低
- 缺点:不直观
<input type="button" value="按钮二" id="btn2"/>
//后绑定事件
window.onload =function(){
var btn = document.getElementById("btn2");
btn.onclick=function(e){
alert("张三");
console.log(e);
}
}
3)取消事件
- 在事件函数内return false
3.事件对象
3.1)什么是事件对象
- 当事件被触发时,有一些信息会被确定下来
- 如:左键右键,点击的位置(坐标),按键
- 开发项目时可能用到这些信息(较少)
- 浏览器为了方便开发者,将这些信息封装到一个对象里,这个对象叫做event,事件对象
3.2)如何获取事件对象
直接定义事件
- 在调用函数时直接传入event
- 在写函数时增加参数来接收他
<input type="button" value="按钮一" onclick="f1(event);"/>
function f1(e){
alert("按钮");
}
后绑定事件
- 触发事件时浏览器会自动给函数传入event
- 写这个函数时加参数接收他
var btn = document.getElementById("btn2");
btn.onclick=function(e){
alert("哈哈");
console.log(e);
事件处理机制
1)冒泡机制
- 事件是由内向外传播的
- 这种规律称为冒泡机制
//验证
<div onclick="alert('div')">
<p onclick="alert('p')">
<input type="button" value="按钮一" onclick="f1(event);"/>
</p>
</div>
//js代码
function f1(e){
alert("按钮");
}
- 停止冒泡
function f1(e){
alert("按钮");
//停止冒泡
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancalBubble = true;
}
}
2)冒泡机制的作用
- 可以简化的的定义
- 可以在父元素上定义一个时间,接收众多子元素的事件
知道事件源
3)事件源
- 事件发生的具体位置
- 事件发生的源头
- 通过事件对象可以获取事件源