JavaScript
1、初识JavaScript
在网页中:
- html表示网页的结构
- CSS表示网页的样式
- JavaScript表示网页的行为
三大核心
(1)ECMAScript:javaSript的标准语法
(2)BOM(Browser Object Model):一整套操作浏览器的属性和方法
(3)DOM(Document Object Model):一整套操作文档流的属性和方法
->通过JS语法让页面发生变换,让文档变换
书写位置
-
行内式
(1) a标签(本身有行为)
-> 因为a标签,本身有动作行为出现,需要区分你是跳转还是执行JS代码
-> 如果不是跳转在href属性里写一个JavaScript声明:Js代码;
(2) 非a标签 -
内嵌式
->在html文件的任意标签内书写一个script标签,在此标签中书写JS代码
->推荐在head标签或者body标签的末尾<script type = "text/javascript"> js代码 </script>
-
外链式
->**在script标签的src属性中引用JS文件,JS代码书写在JS文件中
->注意:使用外链式之后,再在script标签中书写JS代码没意义(哪怕只写了src属性,无法使用内嵌式)****
<script src = "js文件路径"> </script>
示例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test</title> <script type="text/javascript"> alert('我是内嵌式js代码') </script> </head> <body> <!-- 行内式 --> <h1>alter()方法</h1> <a href="javascript: alert('helloword!');">点击试试</a> <a href="alert('hell!');">不加javascript再点击试试</a> <div onclick="alert('hello')"> div点击试试 </div> <!-- 内嵌式 --> <!-- 外联式 --> <!-- <script src="helloword.js"> --> </body> </html>
输出语法
1.alert():
-> 以浏览器弹出层形式展示内容,堵塞后面的代码执行
-> 只要不是纯数字,单双引号无所谓
2.console():
->在浏览器控制台输出,方便调试,不影响页面展示,不会堵塞后面的代码执行
3.document.write()
=>直接在html页面显示
特殊: ->由于是直接输出到文档流,故可以解析标签
2、变量与数据类型
2.1定义变量
=>声明变量格式: var 变量名 (标识符规则和规范与java类似)
=>不使用var 关键字也可以声明一个变量(不推荐)
2.2数据类型
Number 数值
- 包括一切数字(浮点数,任意进制数如0x十六进制,0八进制)
- NaN: Not a Number, 即是一个数值类型,但不是数字
- 科学计数法(如:2e5)
Undefined 空(未定义)
- undefined
Null 空
- null
String 字符串
用单或者双引号或者反引号(`)包裹表示
模板字符串:
let name = "lili"; //模板字符串
let yourName = "你的名字:${name}" //使用${name}引用了name的内容;
常用方法:substring 截取字符串
//[) 含头不含尾
substring(1); //从第一个截取到最后一个;
substirng(1,3); //从第一个截取到第三个;
Boolean 布尔值
0 /0.0 / null / undefined / NaN 这些都视为fasle ,其他一律为真(true)
- true 在计算机存储的时候是1
- false 在计算机存储的时候是0
引用数据类型
Object
Function
typeof检测数据类型
关键字typeof(以String类型返回)
用法一: typeof 变量
var n2 = typeof n1 ; //将n1的数据类型以字符串的形式返回给n2
用法二: typeof(),相较于用法一没有局限性
数据类型转换
Number类型
1. Number()
- 语法: Number(要转换的数据)
- 返回值: 转换好的数据,转换不了(如含有字符串),则返回NaN
2. parseInt() 取整,依次转换
- 语法:parseInt(转换的的数据)
- 特点: 一位一位的转换,每识别到一个数字就返回一个,直到遇到非数字(包括小数点)就不往下看了,第一位是非数字直接返回NaN
parseInt("2a5") ; // 返回 2
parseInt("123.456") //返回 123
3.parseFloat() 比parseFloat()多认识一个小数点
4. 非加法数学运算
- a-0
- a*1
- a/1
String类型
1. Stirng()
- 语法: String(转换的数据)
- 特点: 任意的数据都能转
2. toString()
- 语法: 转换的数据.toString()
- 特点: Undefined和null不能转换
3. + 与java同样的字符串链接符
Boolean 类型
Boolean()
- 语法:Boolean(转换的数据)
- 特点: **只有这五个是false,分别是: 空字符串'' NaN,null , Undefined ,,0 **
其他全是true - 注意!:即使[] =='' 的结果为true,Boolean([])的结果也还是true
3、运算符号
1.数学运算符
与java基本一致,比java多个幂运算符号
如:
2**10 //结果为1024 ,2的10次方
3**2 //结果为9.即3的2 次方
2.比较运算符号
与java不同或者新增的是:
- == : 只比较值,不管数据类型
- === :既比较值又比较数据类型
console.log(1=='1'); //true
console.log(1==true); //true
console.log(null==undefined); //true
console.log(NaN==NaN); //false,因为NaN的值不确定
console.log(NaN===NaN); //false
- !===即三等于的的取反,值不一样就算true**
- !==,即双等于的取反,数据类型和值都不一样才是true**
3.逻辑运算符号
与java一致
4.if语句
与java一致,注意:条件位置处,必须Boolean的值 / 表达式 / 变量,如果不是Boolean类型的话,JS会自动进行转换
例如这些 if(0 /0.0 / null / undefined / NaN){ } 这些 if 都会认为是false。因为*0/0.0/null/undefined/NaN* 这些值转换为布尔值都是 false, 除此以外一律为真。
5.switch语句
与java基本一致,只能判断===
其他语句也基本与java一致
4、函数
- 一种引用数据类型
- 对一段代码的封装
4.1 定义函数
声明式定义:
- 语法: function 函数名(){}
赋值式定义:
- 语法: var 函数名 = function(){}
4.2 函数调用
声明式定义函数和赋值式定义的调用的区别
- 声明式函数:可以在声明前后调用
- 赋值式函数: 只能在赋值后调用
4.3 函数参数
实参和形参不对应的情况也不会报错
- 形参多: 多的形参为undefined
- 实参多: 形参不接受
4.4 arguments(参数数组)
- 函数自带的变量
- 表示所有实参的集合(伪数组)
arguments的属性:
- length表示参数的个数
1.预解析
是指在代码之前做的准备工作,类似C语言的预处理,JS代码的一种运行机制
1.1 var 声明变量
实际上在代码的执行时,会*预先解析var声明的变量
注: 用var声明的变量是全局变量,而在ES6标准后可使用 let 来声明局部变量
let 局部变量 ;
1.2 定义函数
- 声明式定义函数 :在预计解析时将函数准备好
(不建议多用,因为全局可用太乱了) - 赋值式定义函数:预计解析时只是声明有这么一个变量
2.当预解析时函数与变量同名
2.1 预解析的最高级
与其他编程语言有所不同
- 只要有JS代码中可以预解析的内容,无论要解析的语句在会先进行解析(哪怕是return或者if语句判断为false)
console.log(num); //不会报错
if(false){
var num = 100; //(1) 代码最执行执行预解析,var num,if语句只判断是否赋值
}
console.log(num);
2.2 优先级
在JS中函数是一等公民,在预解析时只解析函数
如:
fn(); //(2)按代码顺序执行,打印
var fn;
fn = 100; //将fn赋值为100
fn () ; //报错!!因为此时fn已经不是一个函数
function fn (){ //(1)最先执行,将fn解析为一个函数,然后再解析var fn
console.log("我是一个函数");
}
(建议:(1)变量尽量以名词命名,尽可能用到两三个单词;(2)函数名尽量以功能区分)
3. 作用域
用来限制变量的使用范围
3.1 全局作用域
全局可用,叫做window
3.2 局部作用域(也叫私有域)
函数体里面的作用域,只有该函数内可用
3.3 变量的三个机制
- 定义机制:只能在自己的作用域和子级作用域有效
- 使用机制: 越明确越优先,即先在自己的作用域找,找不到以次往f父作用域上找(全局也找到不到报错)
- 赋值机制:优先在自己作用域内查找,找不到就往父作用域上找还不到也不会报错 ,因为由于两种定义变量的方式存在(如定义变量可以 a = 10 这样定义) ,将会在全局作用域(windows)定义一个变量
3.4 作用域的预解析
- 全局下先预解析
- 局部的预解析只有在调用的时候才会预解析
(由于函数是单独进行预解析,因此是参数传递在前,预解析在后)
事件
常见的事件
click 点击事件
当用户点击了html元素得时候,会触发该事件
mouseover 鼠标覆盖事件
当鼠标移动到元素上面时
mouseout 鼠标离开事件
当鼠标从元素上离开时
focus 获得焦点事件
当获得焦点时触发
blur 失去焦点事件
失去焦点事件
load 加载事件
当元素被加载时触发, 如js中可用浏览器对象 window.onload
函数和元素结合:
- 函数还可以当作一个页面元素的事件处理函数
- 当页面的某个元素触发行为时,执行某个函数
- 语法:元素.onclick = 函数名或元素.onclick = function (){}
页面元素的简单操作
-
在一个页面里,标签的id名(只有id可以),可以直接当成一个变量来使用
-
这个元素就代表这个标签
<!DOCTYPE html> <!-- 函数还可以当作一个页面元素的事件处理函数 当页面的某个元素触发行为时,执行某个函数 页面元素的简单操作 在一个页面里,标签的id名(只有id可以),可以直接当成一个变量来使用 这个元素就代表这个标签 --> <html> <head> <meta charset="utf-8"> <title>test</title> </head> <body> <div id="box"> 点击试试 </div> <input id="frist"/> + <input id="second" /> <button id="but">=</button> <input id="res" disabled="disabled"/> </body> <script type="text/javascript"> console.log(box); box.onclick = function(){ console.log('我是一个事件处理函数'); } but.onclick = function(){ var resule; resule = (Number(frist.value)+Number(second.value)) ; //注意:从页面拿出来的都是字符串类型 console.log(resule) res.value = resule; } </script> </html>
6、引用数据类型详解
- 对象:承载一堆数据的盒子
- 函数:承载了一段代码的盒子
1 创建对象的方式
- 字面量创建
注: 成员以 key:value 的形式表示,并且多个成员用逗号隔开
var o1 = { //创建对象 o1
num:100, //成员 num 的值为 100
str:"字符串", //成员 str 的值为 "字符串"
function f1(){ console.log("我是对象o1的方法")}; //o1的一个方法
}
- 内置构造方法创建
var o = new Object();
区别:
(1)字面量创建可以直接在里面添加数据,数据以键值对key:value的形式出现,key表示数据名字,value表示值用(,)分隔
2.操作对象语法
增: 向对象添加成员
点语法格式:对象名.成员名 = 值
数组关联语法:对象名["成员名"] = 成员名] = 值
删:删除对象的成员
点语法格式:delete 对象名.成员名
数组关联语法:delete 对象名["成员名"]
改:修改对象的成员
点语法格式:对象名.成员名 = 值
数组关联语法:对象名["成员名"] = 成员名] = 值
查:获取对象的成员
点语法格式:对象名.成员名
数组关联语法:对象名["成员名"]
如果没有此成员,则为undefined
点语法和数组关联语法的区别
数组关联语法成员名可以使用变量和拼接字符串
点语法成员名不能使用变量和拼接字符串
注意:在控制台打印对象时*
->不展开时是当前的样子
->展开后是最终的样子
解决方案: (1)使用对象名.成员名直接获取 (2)使用console.table()的方式打印对象,就会得到当前的值
3. for in循环遍历对象的属性
类似java的增强for 即forearch
var o1 = {
num:100,
str:"字符串",
fn :function() { console.log("我是对象o1的方法")}
}
for(var key in o1){
// console.log(o1[key]); //遍历value
console.log(key); //默认为string类型
}
4. in关键字:判断一个成员判断是否在对象里
语法: "成员名" in 对象名
内置对象:Date
new Date()
Sun Nov 21 2021 00:30:16 GMT+0800 (中国标准时间)
new Date().getFullYear()
2021
//获得月份,注意,月份从0算起
new Date().getMonth()
10
//date代表日期
new Date().getDate()
21
//day代表星期几
new Date().getDay()
0
//获得时间戳, 全世界统一, 从1970年1月1日 00:00:00 开始到现在的毫秒数
new Date().getTime()
1637425919212
//获得本地时间
new Date().toLocaleString()
'2021/11/21 00:39:40'
7 . JSON
JSON 简介
早期,人们用xml传输
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
在javaScrip 一切皆为对象,任何js支持的类型,都可以用JSON来表示
JSON 格式
- 对象都用 {}
- 数组都用 []
- 都以键值对的形式表示, 即 key: value
JSON 与字符串之间的相互转换
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSON</title>
</head>
<body>
</body>
<script type="text/javascript">
//定义了一个对象
var user = {
name:'mm',
sex : '女' ,
age : 19,
} ;
//将对象转换成字符串
var user_text = JSON.stringify(user) ;
console.log(user) ;
console.log(user_text) ;
// 将字符串转换成对象
var user2_text = '{"name":"user2" ,"age":"20","sex":"男"}' ; //注意!解析的字符串对象名也必须要用引号
var user2 = JSON.parse(user2_text) ;
console.log(user2) ;
console.log(user2_text);
</script>
</html>
操作BOM对象(重点)
B: 浏览器 , BOM浏览器模型
浏览器(内核)介绍
- IE
- Chrome
- FireFox
- Safair
常用的BOM对象
window对象 代表浏览器窗口
screen 代表屏幕尺寸
location 代表当前页面的URL信息
host: "www.baidu.com"
href: "https://www.baidu.com/"
portocol: "https" //协议
reload:f reload() //刷新页面
location.assign("www.jd.com") //重定向
doucument 代表当前的页面,HTML,DOM文档树
document.title //获取当前页面的标题
document.cookie
history
history.back //回退
history.forward //前进
操作DOM对象(重点)
网页就是一个Dom树形结构!
获得dom节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>操作dom对象</title>
</head>
<body>
<div id="father">
<h1>标题1</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
</body>
<script type="text/javascript">
//对应CSS的选择器
var h1 = document.getElementsByTagName("h1"); //根据标签名
var p1 = document.getElementById("p1");
var p2 = document.getElementsByClassName("p2") ;
var father = document.getElementById("father") ;
//获取所有子节点
var childrens = father.children;
</script>
</html>
更新dom节点
<div id = "id1">
</div>
<script>
var id1 = document.getElementById("id1"); //首先获得节点
id1.innerText = “文本内容” ; // 修改文本的值,会把之前的文本内容清除,不可解析html标签
id1.innerHTML = “文本内容” ; // 修改文本的值,与上面的唯一区别是可以解析html标签
</script>
remove 删除节点
由于指针不能指向自己,所以要删除一个节点,必须要先获得父节点,再通过父结点来删除
注意:删除结点是动态的(即当删除第一个子节点的时候,原来的第二个子节点就变成了现在的第一个子结点)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>删除结点</title>
</head>
<body>
<div id="father1">
<h6 id="ch1">子结点</h6>
<h6 id="ch2">子结点</h6>
<h6 id="ch3">子结点</h6>
<h6 id="ch4">子结点</h6>
</div>
<!-- JS -->
<script type="text/javascript">
var f = document.getElementById("ch1").parentElement;
// 以下操作是错误的,动态删除
f.removeChild(f.children[0]) ;
f.removeChild(f.children[1]) ;
f.removeChild(f.children[2]) ;
</script>
</body>
</html>
append 追加结点
在document结点后面添加结点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</style>
</head>
<body>
<div id="father">
<h4 id ="java">java</h4>
<p id="se">javaSE</p>
<p id="ee">JavaEE</p>
<p id="me">javaME</p>
</div>
<!-- JS -->
<script type="text/javascript">
var new_p = document.createElement('p') ; //获得p标签结点
new_p.id = 'new_p'; //设置属性值
new_p.innerText = "hello java!";
father.append(new_p);
var body = document.getElementsByTagName("body") ;
var style = document.createElement("style") ;
//style.setAttribute("type","text/css") ; //设置属性值,其中参数 key,vaule,也可以用下面的方式
style.type = 'text/css'
style.innerHTML = 'body{background-color:pink }' ;
document.getElementsByTagName("head")[0].appendChild(style);
</script>
</body>
</html>
insert 插入结点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</style>
</head>
<body>
<div id="father">
<h4 id ="java">java</h4>
<p id="se">javaSE</p>
<p id="ee">JavaEE</p>
<p id="me">javaME</p>
<button type="button" onclick="apend_p">追加元素</button>
<button type="button" onclick="apend_style">追加样式</button>
<button type="button" onclick="insert_java">插入元素</button>
</div>
<!-- JS -->
<script type="text/javascript">
function apend_p(){// 追加p元素
alert("nihao!") ;
var new_p = document.createElement('p') ;
new_p.id = 'new_p';
new_p.innerText = "hello java!";
father.append(new_p);
}
function apend_style(){
//追击style元素
var body = document.getElementsByTagName("body") ;
var style = document.createElement("style") ;
//style.setAttribute("type","text/css") ; //设置属性值
style.type = 'text/css'
style.innerHTML = 'body{background-color:pink }' ;
document.getElementsByTagName("head")[0].appendChild(style);
}
function insert_java(){
// 插入p元素
var java = document.getElementById("java") ;
var js = document.createElement("p") ;
js.id = 'js' ;
js.innerText = "javaScript" ;
var father = document.getElementById("father") ;
father.insertBefore(js,java) ;
}
</script>
</body>
</html>
当拿到结点document结点(id也能直接进行操作)后,我们可以进行一下操作
操作文本
id1.innerText = “文本内容” ; 修改文本的值,会把之前的文本内容清除,不可解析html标签
id1.innerHTML = “文本内容” ; 修改文本的值,与上面的唯一区别是可以解析html标签
操作CSS(更改样式)
p1.style.color = "red" ; //修改颜色
p1.style.fontSize = 12em ; //修改字体大小
操作表单(验证表单)
注:可以通过添加 required 属性使文本框变为必填项,不填写就提交会有提示,表单里的input标签,一定要有name属性才能发送到后台
获得表单的值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS操作表单</title>
</head>
<body>
<form action="" method="post">
<!-->可以通过添加 required 属性使文本框变为必填项,不填写就提交会有提示<-->
用户名: <input type="text" id="uid" required/> <br>
密码: <input type="password" id="pwd" name="pwd" required/> <br>
<input type="radio" name="sex" id="sex_m" value="男" />男
<input type="radio" name="sex" id="sex_w" value="女" />女
<br>
<br>
<br>
<input type="submit" value="确定"/>
</form>
</body>
<script type="text/javascript">
var uid = document.getElementById("uid") ;
var pwd = document.getElementById("pwd") ;
var sex_m = document.getElementById("sex_m");
var sex_w = document.getElementById("sex_w") ;
//可通过 uid.value 获得文本框的值,同理也可以通过这种方式修改值
//单选框 可通过 sex_m.checked = true 则表示被选中,否则就是没选中来判断
</script>
</html>
表单数据加密(md5)以及提交验证
表单中的onsubmit 属性:用于提交验证,如果事件函数返回true,则提交,反之不提交,注意还要写一个return,并且默认为true
此外,在提交表单时容易被人抓包发现表单的数据,,因此我们需要对表单数据进行加密
如下代码对表单进行了加密
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>提交表单</title>
</head>
<body>
<!-- 引入md5.js 工具包 -->
<script src="MD5_js/md5.js" type="text/javascript" charset="utf-8"></script>
<!-- onsubmit 属性:表单提交验证,如果事件函数返回true,则提交,反之不提交,注意还要写一个return,并且默认为true -->
<form action="#" method="post" onsubmit="return ff2()">
<p>
用户名: <input type="text" id="username" name="username" value="" />
</p>
<p>
密码: <input type="password" id="pwd" name="password" />
</p>
<!-- 通过按钮绑定事件 -->
<!-- <button type="button" onclick="ff()">提交</button> -->
<input type="submit" value="提交" name="ok" />
</form>
<script type="text/javascript">
function ff(){
var uid = document.getElementById("username") ;
var pwd = document.getElementById("pwd") ;
console.log(uid.value);
console.log(pwd.value);
}
function ff2(){
alert("2")
var uid = document.getElementById("username") ;
var pwd = document.getElementById("pwd") ;
//md5加密
pwd.value = hex_md5(pwd.value) ;
return true ;
}
</script>
</body>
</html>
由于直接对密码框进行密文赋值,会导致密码框在提交的一瞬间变长,不能提升用户体验,所以我们可以采用一个隐藏密码框来进行赋值传输
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>提交表单</title>
</head>
<body>
<!-- 引入md5.js 工具包 -->
<script src="MD5_js/md5.js" type="text/javascript" charset="utf-8"></script>
<!-- onsubmit 属性:表单提交验证,如果事件函数返回true,则提交,反之不提交 -->
<form action="#" method="post" onsubmit="return ff2()">
<p>
用户名: <input type="text" id="username" name="username" value="" />
</p>
<p>
密码: <input type="password" id="input_pwd" name="input_pwd" />
</p>
<!-- 隐藏密码框 -->
<div id ="hidden_pwd" >
<input type="password" hidden="hidden" id="pwd" name="password"/>
</div>
<!-- 通过按钮绑定事件 -->
<!-- <button type="button" onclick="ff()">提交</button> -->
<input type="submit" value="提交" name="ok" />
</form>
<script type="text/javascript">
function ff(){
var uid = document.getElementById("username") ;
var pwd = document.getElementById("pwd") ;
console.log(uid.value);
console.log(pwd.value);
}
function ff2(){
alert("2")
var uid = document.getElementById("username") ;
// 明文密码框
var input_pwd = document.getElementById("input_pwd") ;
// 获得隐藏密码框结点
var pwd = document.getElementById("pwd") ;
//md5加密
pwd.value = hex_md5(input_pwd.value) ;
input_pwd.value = " " ;
return true ;
}
</script>
</body>
</html>