JavaScript
概念:一门客户端脚本语言。
脚本语言:不需要编译,浏览器可以直接解析执行。
功能:用来增强html的动态效果和交互过程,可以控制html元素。
组成:JavaScript=ECMAScript+DOM+BOM
基本语法
-
html如何导入脚本:
-
内部JS:将JavaScript代码放到<head>标签中的<script>标签之间。
-
外部JS:将JavaScript代码放到单独的.js文档中,通过<script>标签中的src属性将其引入到HTML文档中。
<script>可以放在<head>中,但最好是放在文档的最后,</body>标签之前,这样能使浏览器更快的加载页面。
注意外部文件中的JS语句不能放到<script>和</script>标签中,也不能使用任何HTML标签,只能是纯粹的JavaScript代码。alert("我是外部的JS文件,我不用包在script标签内")
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> HelloWorld<br/> <script src="JavaScript/a.js"></script> </body> </html>
-
-
注释:JS的注释和java一样,有单行注释和多多行注释
-
变量:
-
JavaScript允许直接对变量赋值而无需声明。如果程序员还未声明变量就直接对其赋值,赋值操作会自动声明它。
不过建议在使用变量前还是先声明,这是一种良好的编程习惯。a="hello";//直接使用变量,无需声明。
-
JavaScript是弱类型(weakly type)语言,声明变量时不需要指定类型,这也意味着程序员可以在任意阶段改变变量的类型。
声明变量使用var关键字。
注意:用var声明的变量是局部变量,不用var声明的变量是全局变量。var a; //JS是弱类型语言 a="hello"; a=3.14;//可以随意改变变量的类型
-
-
数据类型:
-
基本类型
- number:数字。整数/小数/NaN
- string:字符串。JS没有char类型,都是string类型。单双引号没有区别。
- boolean: 值是true/false
- null: 一个对象为空的占位符,代表此处不应该有值
- undefined: 未定义。如果个变量没有给初始化值,则会被默认赋值为undefined。代表此处有值但是没有赋值。
-
引用数据类型:对象
-
typeof运算符:因为JS是弱类型的语言,可以通过typeof获取变量的类型。
<script> var num1=123; var num2=2.34; var num3=NaN; var str1="hello"; var obj1; var obj2=undefined; var obj3=null; document.write(num1+"----"+typeof(num1)+"<br>") document.write(num2+"----"+typeof(num2)+"<br>") document.write(num3+"----"+typeof(num3)+"<br>") document.write(str1+"----"+typeof(str1)+"<br>") document.write(obj1+"----"+typeof(obj1)+"<br>") document.write(obj2+"----"+typeof(obj2)+"<br>") document.write(obj3+"----"+typeof(obj3)+"<br>") </script> /*结果为: 123----number 2.34----number NaN----number hello----string undefined----undefined undefined----undefined null----object */
-
-
运算符
-
一元运算符
++(自增),--,+(正号), -(负号) 。
注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换,将其他类型转为number。
string转number:按照字面值转换。如果字面值不是数字,则转为NaN
boolean转number:true转为1,false转为0var a = +"123" document.write(a);//123 document.write(typeof(a));//number a=+"hello" document.write(a);//NaN document.write(typeof(a));//number,说明NaN也是number
-
算数运算符:+ - * / % ...
-
赋值运算符:= += -+....
-
比较运算符: < >= <= == ===(全等于)
- 比较方式:
- 类型相同:直接比较
字符串:按照字典顺序,按位逐一比较,直到得出大小为止。 - 类型不同:转换成number,再比较
===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
- 类型相同:直接比较
- 比较方式:
-
逻辑运算符:&& || !
- 其他类型转boolean
- number:0或NaN为假,其他为真
- string:除了空字符串(""),其他都是true
- null&undefined:都是false
- 对象:所有对象都为true
- 其他类型转boolean
-
三元运算符:
? : 表达式
,用法和java一样
-
-
流程控制语句:
- if...else...
- switch:在java中,switch语句可以接受的数据类型:byte int shor char,枚举 ,String。
JavaScript可以接收所有的基本数据类型。 - while
- do while
- for
-
JS输出
window.alert()弹出警告框
document.write()将内容写到html文档
使用innerHTML写入到HTML元素
console.log()写入到控制台 -
练习:99乘法表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>99乘法表</title> <style> td{ border: 1px solid greenyellow; } </style> <script> var i; var j; document.write("<table>") for(i=1;i<=9;i++){ document.write("<tr>") for(j=1;j<=i;j++){ document.write("<td>") document.write(i+"*"+j+"="+(i*j)); document.write("</td>") } document.write("</tr>") } document.write("</table>") </script> </head> <body> </body> </html>
结果如下:
对象
-
Function:函数(方法)对象
-
创建:
function 方法名称(arguments){
方法体
}
var 方法名 = function(arguments){ 方法体
}
第二种写法等号右边的其实是一个匿名方法,我们用一个变量引用了这个方法,以后就可以重复使用了。 -
属性:length,代表形参的个数
-
特点:
- 因为JS是弱类型,所以方法的定义不用写返回值,不用写形参类型
- 在JS中,方法的调用只与方法的名称有关,和参数列表无关,没有重载,所以方法不要重名。
- 在方法中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数,相当于Java的可变参数
-
调用:
在超链接中调用:<a href="javascript:函数名"></a>
-
-
Array数组对象
-
创建:
- var arr = new Array(元素列表);
- var arr = new Array(默认长度);
- var arr = [元素列表];
-
属性:length,数组的长度
-
方法
- join(参数):将数组中的元素按照指定的分隔符拼接为字符串
- push():向数组的末尾添加一个或更多元素,并返回新的长度。
- pop():移除数组末尾的元素并返回这个元素
- shift():移除数组的第一个元素并返回这个元素
- unshift():向数组的开头添加元素,返回新的长度
- 复制数组:arr1 = [...arr2]。
...
是展开操作符 - includes(元素): 判断数组是否包含指定的元素
- reverse():反转数组
- sort():对数组排序
-
特点:JS中数组的长度可变,元素类型可变
-
-
Set
- 特点:元素唯一,存取顺序一致
- 成员
add():添加元素
size属性:获取集合长度
keys():获取迭代器对象
delete():删除指定的元素
-
Date:日期对象
- 创建:var date = new Date();
- 方法:
- oLocaleString():返回当前date对象对应的时间的字符串
- getTime():返回当前对象描述的时间到1970年1月1日零点的毫秒值差
-
Math:数学对象
- 特点:不用创建,直接使用。Math.method()
- 方法:
- random():返回 0 ~ 1 之间的随机数,含0不含1
- ceil(x):对数值进行上舍入
- floor(x):对数值进行下舍入。
- round(x):对数值四舍五入取整
- 属性:PI
-
自定义对象
//方式一,逐个定义成员变量和成员方法 var 对象名 = new Object(); 对象名.属性 = 值;//说明了JS的对象可以自由添加属性 对象名.方法名() = function(arguments){ statement } //方式二,花括号定义 var 对象名 = { 属性名 : 值, 属性名 : 值, 方法名: function(arguments){ statement} };
访问对象中的属性可以使用
.
或者[]
。详解:学习 Basic JavaScript: 通过变量访问对象属性 | freeCodeCamp.org删除对象属性
delete 对象名.属性名;
测试对象是否具有某属性:
对象名.hasOwnProperty(propName)
-
RegExp正则表达式:定义字符串的组成规则
-
正则表达式:定义字符串的组成规则。必须要包在
//
中间。-
字符集:[]
如: [a] [ab] [a-zA-Z_0-9].
:匹配除换行符 \n 之外的任何单字符
\d:单个数字字符 [0-9]
\w:单个单词字符(用的最多),相当于[a-zA-Z_0-9]
\W是\w的相反匹配模式
\s匹配空格,空格、回车符、制表符、换页符和换行符都行。相当于[ \r\t\f\n\v]
可以在字符集中插入^代表否定。如:/[^0-9]/
表示不匹配数字//想要匹配 bag、big 和 bug,但是不想匹配 bog /b[aiu]g/
-
量词符号:
?:表示出现0次或1次
*:匹配前面的子表达式0次或多次
+:匹配前面的子表达式一次或多次
{3}:出现3次
{m,n}:表示 m<= 数量 <= n
m如果缺省: {,n}:最多n次
n如果缺省:{m,} 最少m次 -
开始结束符号
^:开始
$:结束 -
忽略大小写标志
/hello/i -
匹配全局
默认情况下,只能提取或搜寻一次模式匹配。let testStr = "Repeat, Repeat, Repeat"; let ourRegex = /Repeat/; testStr.match(ourRegex);
在这里
match
将返回["Repeat"]
。若要多次搜寻或提取模式匹配,可以使用
g
标志。let repeatRegex = /Repeat/g; testStr.match(repeatRegex);
这里
match
返回值["Repeat", "Repeat", "Repeat"]
-
表达式分组
验证码有4位数字或6位数字两种,前面的匹配4位验证法,后面匹配6位验证码:/(^\d{4})$)|(^\d{6})$)/
-
贪婪和懒惰匹配
贪婪(greedy)匹配会匹配到符合正则表达式匹配模式的字符串的最长可能部分,并将其作为匹配项返回。 另一种方案称为懒惰(lazy)匹配,它会匹配到满足正则表达式的字符串的最小可能部分。
将正则表达式/t[a-z]*i/
应用于字符串"titanic"
。 这个正则表达式是一个以t
开始,以i
结束,并且中间有一些字母的匹配模式。正则表达式默认是贪婪匹配,因此匹配返回为["titani"]
。 它会匹配到适合该匹配模式的最大子字符串。
但是,你可以使用?
字符来将其变成懒惰匹配。 调整后的正则表达式/t[a-z]*?i/
匹配字符串"titanic"
返回["ti"]
。 -
完全匹配
/^\w{5,12}$/
-
-
方法
-
Regex.test(String str);
-
str.match(Regex);
上面两种方法的调用者和参数刚好相反
-
-
-
Global全局对象:这个Global中封装的方法不需要对象就可以直接调用。
encodeURI():url编码
decodeURI():url解码
encodeURIComponent():url编码,编码的字符更多
decodeURIComponent():url解码
parseInt():将字符串转为数字。可以指定进制
isNaN():判断一个值是否是NaN
ECMAScripts
1995年Netscape公司发布的Netscape Navigator 2.0中,发布了与Sun联合开发的JavaScript 1.0并且大获成功, 并且随后的3.0版本中发布了JavaScript1.1,恰巧这时微软进军浏览器市场,IE 3.0搭载了一个JavaScript的克隆版-JScript, 再加上Cenvi的ScriptEase(也是一种客户端脚本语言),导致了三种不同版本的客户端脚本语言同时存在。
为了建立语言的标准化,1997年JavaScript 1.1作为草案提交给欧洲计算机制造商协会(European Computer Manufacturers Association),第三十九技术委员会(TC39)被委派来“标准化一个通用的,跨平台的,中立于厂商的脚本语言的语法和语意标准”。最后在Netscape、Sun、微软、Borland等公司的参与下制订了ECMA-262,该标准定义了叫做ECMAScript的全新脚本语言。从此以后的Javascript,JScript,ActionScript等脚本语言都是基于ECMAScript标准实现的。
所以,ECMAScript实际上是一种脚本在语法和语义上的标准。实际上JavaScript是由ECMAScript,DOM和BOM三者组成的。 所以说,在JavaScript,JScript和ActionScript中声明变量,操作数组等语法完全一样,因为它们都是ECMAScript。但是在操作浏览器对象等方面又有各自独特的方法,这些都是各自语言的扩展。
ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
基本语法
let
基本用法
使用 var
关键字来声明变量,会出现重复声明导致变量被覆盖却不会报错的问题。
var camper = 'James';
var camper = 'David';
在上面的代码中,camper
变量的初始值为 James
,然后又被覆盖成了 David
。 在小型的应用中,你可能不会遇到这样的问题。但是当你的代码规模变得更加庞大的时候,就可能会在不经意间覆盖了之前定义的变量。 因为这样的情况不会报错,所以搜索和修复 bug 会变得非常困难。
在 ES6 中引入了新的关键字 let
来解决 var
关键字带来的潜在问题。 它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。如果你在上面的代码中使用 let
关键字来代替 var
关键字,结果会报错。
let camper = 'James';
let camper = 'David';
与 var
不同的是,当使用 let
的时候,在同一代码块中,同一名字的变量只能被声明一次。请注意 "use strict"
,这代表着开启了严格模式,用于检测常见的代码错误以及“不安全”的行为, 例如:
"use strict";
x = 3.14;
这将显示一个错误 x is not defined
。
不存在变量提升
let
不像var
那样会发生“变量提升”现象。所谓变量提升是指在JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。所以在JavaScript 中,变量可以先使用后声明。
console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError
var foo = 2;
let bar = 2;
上面代码中,变量foo
用var
命令声明,会发生变量提升,即脚本开始运行时,变量foo
已经存在了,但是没有值,所以会输出undefined
。变量bar
用let
命令声明,不会发生变量提升。这表示在声明它之前,变量bar
是不存在的,这时如果用到它,就会抛出一个错误。
暂时性死区
只要块级作用域内存在let
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
上面代码中,存在全局变量tmp
,但是块级作用域内let
又声明了一个局部变量tmp
,导致后者绑定这个块级作用域,所以在let
声明变量前,对tmp
赋值会报错。
ES6明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。
块级作用域
ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = "hello world";
}
}
f(); // undefined
上面代码中,函数f执行后,输出结果为undefined
,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
第二种场景,用来计数的循环变量泄露为全局变量。
for (var i = 0; i < 3; i++) {}
console.log(i);//显示3
上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
let
实际上为JavaScript新增了块级作用域。
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上面的函数有两个代码块,都声明了变量n
,运行后输出5。这表示外层代码块不受内层代码块的影响。如果使用var
定义变量n
,最后输出的值就是10。
const
const用来声明一个常量。但是对于引用类型,const
只是保证变量名指向的地址不变,并不保证该地址的数据不变
const s = [5, 6, 7];
s = [1, 2, 3];//报错
s[2] = 45;//这步操作没有问题
console.log(s);//[5,6,25]
为了确保数据不被改变,JavaScript 提供了一个函数 Object.freeze
。当一个对象被冻结的时候,你不能再对它的属性再进行增、删、改的操作。 任何试图改变对象的操作都会被阻止,却不会报错。
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);//变量被冻结了
obj.review = "bad";//不起作用
obj.newProp = "Test";//不起作用
console.log(obj); //{ name: "FreeCodeCamp", review: "Awesome" }。
箭头函数
箭头函数有点像lambda表达式,可以简化函数的编写。
const myFunc = function() {
const myVar = "value";
return myVar;
}
const myFunc = () => {
const myVar = "value";
return myVar;
}
const myFunc = () => "value";
上面三种写法都一样。
和一般的函数一样,你也可以给箭头函数传递参数。
const doubler = (item) => item * 2;
doubler(4);//8
如果箭头函数只有一个参数,则可以省略参数外面的括号。
const doubler = item => item * 2;
可以给箭头函数传递多个参数。
const multiplier = (item, multi) => item * multi;
multiplier(4, 2);//8
DOM
定义:Document Object 一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态的访问和修改文档的内容、结构和样式。
每次浏览器要加载和显示页面时,都需要解析构成页面的HTML源代码。在解析过程中,浏览器建立一个内部模型来表示文档里的内容,这个模型就是DOM。在浏览器渲染页面的可见内容时,就会引用这个模型。可以使用JavaScript来访问和编辑这个DOM的各个部分,从而改变页面的显示内容和用户交互的方式。
分类:早期,JavaScript只能对Web页面的某些部分进行最基本的访问,比如访问页面里的图像和表单。一个JavaScript程序所包含的语句,可以选择“页面上第二个表单”,或是“名称为registration的表单”。Web开发人员有时把这种情形称为0级DOM,以便与W3C的1级DOM向下兼容。0级DOM有时也称为BOM(浏览器对象模型)。从0级DOM开始,W3C逐渐扩展和改善了DOM规范。W3C更大的野心是不仅让DOM能够用于Web页面与JavaScript,也能用于任何编程语言和XML。
上图中,每个元素被称为一个节点,直接位于一个节点之下的节点被称为该节点的子节点(childNode),直接位于一个节点之上的节点被称为该节点的父节点(parentNode),具有相同父节点的两个节点称为兄弟节点(siblingNode)。
核心DOM
- Document:文档对象
- 方法
- 获取Element对象
getElementById()
getElementByTagName():根据标签获取对象。返回一个数组
getElementByClassName():根据class属性获取对象,返回一个数组
getElementByName():根据name属性获取对象,返回一个数组。 - 创建其他DOM对象
createAttribute(name)
createComment
createElement
createTextNode
- 获取Element对象
- Element:元素对象
- 方法
删除属性:removeAttribute(属性名)
设置属性:setAttribute(属性名, 属性值)
父元素.appendChild(子元素):将指定的子元素添加到父元素中
父元素.removeChild(子元素):删除父元素的指定子元素
replaceChild(新元素、旧元素):用新元素替换子元素
parentNode,返回元素的父元素 - 属性:
innerHTML,代表标签体中的内容,可以解析标签
innerText,代表标签体中的文本内容,不解析标签
style
className
- 方法
- Attribute:属性对象
- Text:文本对象
- Comment:注释对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 向body中添加子元素,显示:牛逼-->
<script>
// 要向body里添加子元素,必须先等body加载完了才行,但是js代码在body的前面会先于body加载
// 所以必须等body加载完了,通过window.onload来加载js代码。或者可以把js代码放到body的后面
window.onload = function(){
var object = document.createElement("div");//新建了一个div元素,字符串用不着写标签符号
object.innerHTML= "牛逼";
document.body.appendChild(object);//向body添加子元素,因为body经常用,所以变成了document的成员变量,不需要使用getElementbyTagName获取了
}
</script>
</head>
<body>
</body>
</html>
HTML DOM
-
标签体的获取和设置:innerHTML
-
使用html设置元素对象的属性
-
控制元素样式
-
使用元素的style属性来设置
div1.style.border = '1px solid red'; div1.style.fontSize = '20px'; //font-size -> fontSize
-
通过元素的className属性为其设置class属性,调用指定的css样式
-
BOM
Browser Object Model:将浏览器的各个组成部分封装成对象。
组成:
- Screen:显示器屏幕
- Navigator:浏览器对象
- Window:窗口对象
- History:历史记录对象
- Location:地址栏对象
Window:窗口对象
-
方法
-
window.onload()=function{}:花括号里的代码会等到页面加载完成之后再执行。有了这个方法就可以将JS代码放到 中。
-
弹出框方法
alert():显示带有一段消息和一个确认按钮的警告框。
confirm():显示带有一段消息以及确认按钮和取消按钮的对话框。如果用户点确认,返回ture;如果点取消,返回false。
prompt():显示可提示用户输入的对话框。用户输入的值是返回值。 -
打开关闭窗口的方法
open():打开一个新窗口。参数可以接收URL,返回值是打开的窗口。
close():关闭浏览器窗口。谁调用此方法就关闭谁。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" value="打开窗口" id="button1"> <input type="button" value="关闭窗口" id="button2"> <script> var button1 = document.getElementById("button1"); var baiduWindow; button1.onclick = function (){ baiduWindow = open("https://www.baidu.com");//必须是完整的url } var button2 = document.getElementById("button2"); button2.onclick = function (){ baiduWindow.close(); } </script> </body> </html>
-
定时器方法
- 设置一次性定时器:setTimeout(JS代码, 毫秒值):在指定的毫秒数后执行js代码。返回值是唯一的标识
- clearTimeout(标识):取消setTimeout()设置的定时器
- 设置循环定时器:setInterval(JS代码, 毫秒值):按照指定的毫秒循环执行js代码
- clearInterval(标识):取消setInterval()设置的定时器
-
-
属性:
-
获取其他BOM对象
history
location
Navigator
Screen
-
获取DOM对象
document
-
-
特点:window对象名可以省略,直接使用方法名、属性名就行。
Location:地址栏对象
-
方法
reload:刷新当前页面 -
属性
href:设置或返回完整的URL。改变此属性窗口将转到新的url。 -
设置5秒后自动跳转到新的页面
<body> <p> 注册成功!<span id="time">5</span>秒之后自动跳转到首页... </p> </body> <script> //1.定义方法。改变秒数,跳转页面 let num = 5; function showTime() { num--; if(num <= 0) { //跳转首页 location.href = "index.html"; } let span = document.getElementById("time"); span.innerHTML = num; } //2.设置循环定时器,每1秒钟执行showTime方法 setInterval("showTime()",1000); </script> </html>
History对象
- 方法
back() 加载 history 列表中的前一个 URL。
forward() 加载 history 列表中的下一个 URL。
go(参数) 加载 history 列表中的某个具体页面。参数为2,就前进2个历史记录。参数为-2,就后退两个历史记录 - 属性:length 返回当前窗口的历史记录列表中的url数量
事件
概念:为页面增加与用户的交互是JavaScript的基本功能之一。为此,我们需要一些机制来检测用户和程序在特定时间在做什么,比如鼠标在浏览器的什么位置,用户是否单击了鼠标或按了键盘按键,页面是否完整加载到浏览器,等等。我们将这些发生的事情称为事件(event)。
JavaScript用事件处理器(event handler)来处理事件,比如检测鼠标动作的3个:onClick、onMouseOver和onMouseOut。
添加事件(事件的注册)
- 静态注册:直接在HTML标签上,将事件名作为属性添加,属性值是js代码
- 动态注册:通过js获取标签的DOM对象,通过对象来指定事件
开灯关灯案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>开灯关灯</title>
</head>
<body>
<img src="images/off.gif" id="light">
<script>
var light = document.getElementById("light");
var flag=false;//代表灯泡的状态
light.onclick = function (){
if(flag){//如果灯开了
this.src="images/off.gif";
flag = false;
}else{
this.src='images/on.gif';
flag=true;
}
}
</script>
</body>
</html>
常见的事件
- 点击事件
- onclick:单击
- ondbclick:双击
- 焦点事件
- onblur:失去焦点
- onfocus:元素获得焦点
- 加载事件
- onload:一张页面或一幅图像完成加载
- 鼠标事件
- onmousedow 鼠标被按下
- onmouseup 鼠标被松开
- onmousemove 鼠标被移动
- onmouseover 鼠标移动某元素之上
- onmouseout 鼠标从某元素移开
- 键盘事件
- onkeydown 某个按键被按下
- onkeyup 某个按键被松开
- onkeypress 某个按键被按了一次
- 选择和改变
- onchange:域的内容被改变
- onselect:文本被选中
- 表单事件
- onsubmit:确认按钮被点击
返回true则提交,返回false则拒绝提交 - onreset:重置按钮被点击
- onsubmit:确认按钮被点击
JSON
JavaScript Object Notation:是一种轻量化的数据交换格式,本质就是字符串,易于编写和数据传输。很多项目已经使用JSON替代xml了。
JSON语法规则:
方法 | 说明 |
---|---|
stringify(对象) | 将指定的对象转换为JSON格式字符串 |
parse(JSON字符串) | 将指定的JSON字符串转换为对象 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON</title>
</head>
<body>
</body>
<script>
//定义天气对象
let weather = {
city : "北京",
date : "2088-08-08",
wendu : "10° ~ 23°",
shidu : "22%"
};
/*
也可以像对象一样创建JSON
let weather = {};
weather.city="北京";
weather.date="2088-08-08"
*/
//1.将天气对象转换为JSON格式的字符串
let str = JSON.stringify(weather);
document.write(str + "<br>");
//2.将JSON格式字符串解析成JS对象
let weatStr = "{\"城市\":\"上海\",\"日期\":\"2022-02-02\"}";
let weather2 = JSON.parse(weatStr);
document.write("城市:" + weather2.city + "<br>");
document.write("日期:" + weather2.date + "<br>");
</script>
</html>
一个JSON其实是一个数组,包含了多个对象,可以遍历访问:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let json =[
{"name": "李宁","age": 25,"department": "研发部"},
{"name": "马龙","age": 30,"department": "市场部","customers": [{"name": "张三"},{"name": "李四"},{"name": "王五"}]}
];
for(let i = 0; i < json.length; i ++){
let people = json[i];
document.write("<h1>name:"+people.name+", age:"+people.age+", department"+people.department+"</h1>");
if(people.customers != null){
for (let j = 0; j < people.customers.length; j++) {
document.write("<h2>customers:"+people.customers[j].name+"</h2>")
}
}
}
</script>
</body>
</html>
Java中使用JSON
要在java中使用JSON需要一些工具包,常用的有 FastJson、Gson等。FastJson由阿里开发,是国内最流行的json工具包,可以将JSON和JavaBean对象互相转化。需要去GitHub下载。
javabean:
package com.example.json;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
public class Student {
private String name;
private Integer age;
private String sex;
@JSONField(format = "yyyy/MM/dd hh:mm:ss")//格式化
private Date birthday;
public Student() {
}
public Student(String name, Integer age, String sex, Date birthday) {
this.name = name;
this.age = age;
this.sex = sex;
this.birthday = birthday;
}
//setter、getter 略
}
FastJSON测试类:
package com.example.json;
import com.alibaba.fastjson.JSON;
import java.util.Date;
public class StudentJsonTest1 {
public static void main(String[] args) {
Date birthday = new Date();
Student student = new Student("张三",20,"男",birthday);
//FastJSON 提供了 JSON 对象,可以将Java对象转换成JSON格式的字符串
String str = JSON.toJSONString(student);
System.out.println(str);
//parseObject() 可以把JSON转换为JavaBean对象,需要两个参数:JSON和需要转换的类
Student stu = JSON.parseObject(str, Student.class);
}
}
注解:@JSONField(serialize = false)表示不对此成员变量序列化
FastJSON操作数组
package com.example.json;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
//FastJSON对数组的操作
public class ArrayJsonTest2 {
public static void main(String[] args) {
//生成10个Student实例化对象,放入数组中
List<Student> studentList = new ArrayList<>();
for(int i = 1; i <= 10; i ++){
Student stu = new Student();
stu.setName("no"+i);
stu.setAge(i);
Date birthday = new Date(System.currentTimeMillis()+1000*i);
stu.setBirthday(birthday);
studentList.add(stu);
}
//JavaBean数组转换为JSON
String jsonString = JSON.toJSONString(studentList);
System.out.println(jsonString);
//JSON转为JavaBean对象数组
List<Student> students = JSON.parseArray(jsonString, Student.class);
}
}