JavaScript
JS概念和特点
概念:JS是一种具有函数优先的轻量级,解释型或即时编译型的高级编程语言,作为开发Web页面的脚本语言。JavaScript的标准是ECMAScript 。
特点:JavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。
- 是一种解释性脚本语言(代码不进行预编译)。
- 主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。
- 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
- 跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)。
- JavaScript脚本语言同其他语言一样,有它自身的基本数据类型,表达式和算术运算符及程序的基本程序框架。JavaScript提供了四种基本的数据类型和两种特殊数据类型用来处理数据和文字。而变量提供存放信息的地方,表达式则可以完成较复杂的信息处理。
- 可以实现web页面的人机交互。
组成部分
ECMAScript:描述了该语言的语法和基本对象,是一种由Ecma国际(前身为欧洲计算机制造商协会),定立ECMA-262标准化的脚本程序设计语言。规定了 JavaScript 脚本的核心语法,如 数据类型、关键字、保留字、运算符、对象和语句等。
文档对象模型(DOM):描述处理网页内容的方法和接口,定义了 JavaScript 操作浏览器的接口,提供了访问某些功能(如浏览器窗口大小、版本信息、浏览历史记录等)的途径以及操作方法。
浏览器对象模型(BOM):描述与浏览器进行交互的方法和接口, 定义了 JavaScript 操作 HTML 文档的接口,提供了访问 HTML 文档(如body、form、div、textarea等)的途径以及操作方法。
JS的引入方式
- 内部引入:可以不结合事件
<!--在head或body中,定义script标签,然后在script标签里面写js代码-->
<script>
alert("这是js的内部引入");
</script>
- 外部引入:可以不结合事件
<!--1.定义外部js文件(.js结尾的文件)-->
<!--2.在html中引入.js文件-->
<script type="text/javascript" src="index.js"></script>
<!--外部的JS文件,它具有维护性高、可缓存(加载一次,无需加载)、方便未来扩展、复用性高等特点-->
- 行内引入 :要结合事件来使用
<!--<开始标签 on+事件类型=“js代码”></结束标签>-->
<body>
<input type="button" οnclick="alert('行内引入')" value="button" name="button">
<button οnclick="alert(123)">点我</button>
</body>
注:
script标签一般定义在head或body中
Script标签一般单独使用,要么引入外部JS,要么定义内部JS,一般不混搭使用
如果哪一个script标签用于引入外部js文件了,那么浏览器会忽略掉该标签内部所有的js代码(如果有的话)
刚开始学习需要记住的测试方法
-
alert(exp) 弹出到警告框,(浏览器窗口弹出)
-
console.log(exp) 输出到控制台(浏览器中右击->检查->点击console)
-
document.write(exp) 输出到页面(body页面输出,会覆盖掉之前显示的内容)
注:exp代表表达式,如:a+b,1*1等。
标识符
变量,对象的属性以及函数的名字。
所有 JavaScript 变量必须以唯一的名称标识,这些唯一的名称称为标识符。
标识符可以是短名称(比如 x 和 y),或者更具描述性的名称(age、sum、totalVolume)
标识符可以是短名称(比如 x 和 y),或者更具描述性的名称(age、sum、totalVolume)
对大小写敏感
构造变量名称(唯一标识符)的通用规则是:
- 名称可包含字母、数字、下划线和美元符号($)
- 名称可以以字母,$ 和 _ 开头
- 名称对大小写敏感(y 和 Y 是不同的变量)
- 保留字(比如 JavaScript 的关键词)无法用作变量名称
变量:存储数据值的容器
// 声明了一个变量并且往里塞了一个值,
// var 变量名 = 值;
var a1 = 5;
// 声明了一个变量但不赋值,此时这个变量里面存的是空值(undefined)
//不带有值的变量,它的值将是 undefined
// var 变量名;
var a2;
a2 = 3;
//声明一个变量a3,a3存储的是8
var a3 = a1+a2;
//可以在一条语句中声明许多变量。以 var 作为语句的开头,并以逗号分隔变量
var b1 = 1,b2 = 2,b3 = 3;
//如果再次声明某个 JavaScript 变量,将不会丢它的值。在这两条语句执行后,变量 c1 的值仍然是 "c"
var c1 = "c"
var c1;
变量作用域
- 全局变量:在全局作用域下声明的变量就是全局变量,这种变量在任何地方都能被访问到.
- 局部变量:在函数体内部声明的变量,这种变量只能在该函数体内部使用,在函数体外无法被访问或操作。
在js中==没有块级作用域的概念,只有函数作用域==的概念,只有函数才是一个封闭的作用域,在函数体内部声明的变量在函数体外部无法访问。
局部变量和全局变量冲突:以局部变量为准。
如果想在函数体内部声明一个全局变量,那么只要去掉声明变量的var关键字即可
在局部作用域发生嵌套的时候,内层函数是可以访问到外层函数的局部变量的,反之则不行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// function fn(){
// var a = 5; //局部变量。
// }
// fn()
// console.log(a) //访问不到a,并且报错。
// 全局变量
// var a = 5;
// function fn(){
// // 在局部作用域中尝试访问全局变量
// console.log(a)
// }
// fn()
// var a = 5;
// function fn(){
// var a = 10;
// console.log(a) //局部变量和全局变量冲突:以局部变量为准。
// }
// fn()
// console.log(a) // 5
//在函数体内部声明了一个全局变量
//如果想在函数体内部声明一个全局变量,那么只要去掉声明变量的var关键字即可
// function fn(){
// a = 5;
// }
// fn()
// console.log(a)
// var a = 5;
// function fn(){
// a = 10;
// console.log(a)
// }
// fn()
// console.log(a)
// 在局部作用域发生嵌套的时候,内层函数是可以访问到外层函数的局部变量的,反之则不行
function wrap(){
var a = 5;
(function (){
console.log(a)
b = 10;
})()
console.log(b)
}
wrap()
console.log(b)
</script>
</body>
</html>
变量提升:
- 是JS解释器的一种机制,当我们执行某一个函数的时候,JS解释器会从上到下把函数中的局部变量提取出来放到函数体的顶端先声明但不赋值,此时该变量里面存储的值就为undefined。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// var a
// a
// function fn(){
// console.log(a)
// a = 5;
// }
// fn()
//不会报错,控制台输出undefined
</script>
</body>
</html>
常量:值本身
表达式
表达式指一段具有返回值(计算结果)的语句。任何拥有返回值的语句都是表达式,任何表达式都是有返回值的。
表达式的副作用:如果某个表达式它的存在与否对我们整个js执行环境上下文有不同的运算结果时,我们称这个表达式是含有副作用的表达式。比如最常见的变量声明语句,这就是一个含有副作用的表达式。
运算符:将简单表达式组合成复杂表达式的方法
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
** | 幂(ES2016) |
/ | 除法 |
% | 系数 |
++ | 递增 |
– | 递减 |
在算术运算中,数被称为操作数,(两个操作数之间执行的)运算由运算符定义。
逻辑与和逻辑或(&& 和 ||)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 1.逻辑与和逻辑或整个表达式的返回值一定会返回左端或者是右端操作数的某一个
// 2.返回哪一个操作数取决于运算符左端操作数强制转换为Boolean值的结果和运算符是哪个。
// 死记硬背:
// && 如果左端运算符强制转换为布尔值类型之后返回值为false,则直接返回左端操作数本身。
// || 如果左端运算符强制转换为布尔值类型之后返回值为true,则直接返回左端操作数本身。
// console.log(0 && 3)
// console.log(1 && 3)
// console.log("王大伟" || 3)
// console.log(0 || 3)
</script>
</body>
</html>
三元运算符(num1?num2:num3)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
//操作数1?操作数2:操作数3
//三元运算符一定会在操作数2和操作数3中选取一个返回
// 如果一号操作数的返回值是true或强制转换为Boolean类型之后为true则整个表达式的返回值是2号操作数的返回值。反之则是3号操作数的返回值。
console.log(1?2:3)
console.log(0?2:3)
</script>
</body>
</html>
数据类型
值类型(基本类型):
- 字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
number:1,2,3,4,5,6,-1,-2,-3,3.14,NaN(非数字),Infinity,-Infinity
==判断一个值是否为NaN:==isNaN(exp) 如果exp的返回值是NaN则返回true
string(字符串):“a”,“1”,“字符串”,“abcd”,"-12.33",“1a”,""
boolean(布尔值):true,false
undefined(未定义):undefined
null(空对象)
undefined和null的区别:Undefined 这个值表示变量不含有值。可以通过将变量的值设置为 null 来清空变量。
**注:**Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。
JavaScript 变量均为对象。当声明一个变量时,就创建了一个新的对象。
引用数据类型:
- 对象(Object)、数组(Array)、函数(Function)。
- Object(对象)
- null(空对象)
- function(函数)
//创建数组方法一
var cars=new array();
cars[0]="aaa";
cars[1]="111";
cars[2]="true";
//方法二
var cars=new Array("aaa","111","true");
//方法三
var cars=["aaa","111","true"];
//创建对象
//对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔
var person={firstname:"yan", lastname:"ma", id:1122};
//对象属性有两种寻址方式
var name;
name=person.lastname;
name=person["lastname"];
基本类型和引用类型区别:
在将引用类型的变量(a)赋值给另外的一个变量(b)时,b本身存储的只是一个对a的引用,也可以理解为是一个快捷方式,所以无论修改的是a还是b都会对另外的一个变量产生影响。而基本类型,在将一个变量赋值给另外的一个变量时,执行的是值的拷贝,此时有两个相同的值,所以无论修改了哪一个都不会对另外的一个变量产生影响。
JavaScript拥有动态类型:意味着相同的变量可用作不同的类型
var a; // a 为 undefined
var a = 5; // 现在 a 为数字
var a = "John"; // 现在 a 为字符串
声明变量类型:
- 声明新变量时,可以使用关键词 “new” 来声明其类型
var carname=new String;
var x= new Number;
var y= new Boolean;
var cars= new Array;
var person= new Object;
数值的操作方法:
- parseInt(Number) 取整,没有副作用,只截取整数部分
- parseFloat(Number) 强制转换为数字,没有副作用
- Number.toFixed(保留的位数) 保留几位小数;注意:这个返回结果不再是Number类型而是字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
// parseInt(Number) 取整,没有副作用
// Number.toFixed(保留的位数) 保留几位小数
var n = 3.141592653;
// 取整,没有副作用
parseInt(n)
// 保留几位小数,没有副作用;注意:这个返回结果不再是Number类型而是字符串。
console.log(n.toFixed(3))
</script>
</head>
<body>
</body>
</html>
数据类型的强制转换规则
- 强制转换数据类型的方法
Number(exp) 将表达式的返回值强制转换为数字类型。
String(exp) 将表达式的返回值强制转换为字符串类型。
Boolean(exp)将表达式的返回值强制转换为布尔类型。
- 转换规则
- 转String:所有类型转换为字符串类型就以字面量的形式进行转换。
- 转Boolean:
- number:除了0和NaN以外全部返回true。
- String:除了空字符串以外其他情况全为true。
- undefined: undefined是false。
- null:null是false。
- 转Number
- String:纯数字转换结果是字面量的形式转换,其他所有情况均为NaN。
- Boolean: true为1,false为0。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// * 转Number
// - String:纯数字转换结果是字面量的形式转换,其他所有情况均为NaN。
// - Boolean: true为1,false为0。
// console.log(Number("123"))
// console.log(Number("123.456"))
// console.log(Number(“字符串”))
// console.log(Number("123中文"))
// console.log(Number(true))
// console.log(Number(false))
// console.log(Number(undefined))
// 转String:所有类型转换为字符串类型就以字面量的形式进行转换。
// console.log(String(123))
// console.log(String(123.456))
// console.log(String(NaN))
// console.log(String(true))
// console.log(String(false))
//转Boolean
//- Number:除了0和NaN以外全部返回true。
//- String:除了空字符串以外其他情况全为true。
//- undefined:undefined是false。
//- null:null是false。
// console.log(Boolean(1))
// console.log(Boolean(2))
// console.log(Boolean(-1))
// console.log(Boolean(0))
// console.log(Boolean(NaN))
console.log(Boolean("字符串"))
console.log(Boolean("123"))
console.log(Boolean("true"))
console.log(Boolean("false"))
console.log(Boolean("0"))
console.log(Boolean("NaN"))
console.log(Boolean(""))
</script>
</body>
</html>
为元素绑定事件的简易方法
// 想为一个元素绑定事件的流程:
// 1.要让触发事件的那个元素持有一个id
// 2.在js代码中写入如下代码
// 元素id名.onclick = function(){
// 当用户点了这个元素之后才执行的代码段
// }
btn.onclick = function(){
// 事件句柄
console.log(1)
console.log(2)
}
简单获取一个input文本框中填写的内容
- 给input标签添加一个id属性
- id名.value 的返回值就是input框中目前所输入的内容(返回值为String类型)
判断相等的总结:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 1.数字和Boolean进行比较1==true为true,2==true为false.
// 2.NaN == NaN 返回false
// 3.undefined == null 返回true
// console.log(1 == 1)
// console.log(1 == "1")
// console.log(0 == false)
// console.log(1 == true)
// console.log(2 == true)
// console.log("字符串" == true)
// console.log("true" == 1)
// console.log(NaN == NaN)
// console.log(undefined == null)
</script>
</body>
</html>
1.数字和Boolean进行比较 1 == true 为true,2 == true 为false.
2.NaN == NaN 返回false。
3.undefined == null 返回true。
进行判断的具体流程
- 有NAN,一律返回false
- 有布尔类型,布尔类型转换成数字比较。
- null和undefined不会相互转换,相等。
- 有数字类型,和对象相比,对象用valueof转换成原始值进行比较。
- 其他情况,一律返回false。
- 有String类型,两种情况:
- 对象,对象用toString方法转换成string相比。
- 数字,string类型转换成数字进行比较。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// * 转Number
// - String:纯数字转换结果是字面量的形式转换,其他所有情况均为NaN。
// - Boolean: true为1,false为0。
// console.log(Number("123"))
// console.log(Number("123.456"))
// console.log(Number("王大伟"))
// console.log(Number("123王大伟"))
// console.log(Number(true))
// console.log(Number(false))
// console.log(Number(undefined))
// 转String:所有类型转换为字符串类型就以字面量的形式进行转换。
// console.log(String(123))
// console.log(String(123.456))
// console.log(String(NaN))
// console.log(String(true))
// console.log(String(false))
// console.log(Boolean(1))
// console.log(Boolean(2))
// console.log(Boolean(-1))
// console.log(Boolean(0))
// console.log(Boolean(NaN))
console.log(Boolean("王大伟"))
console.log(Boolean("123"))
console.log(Boolean("true"))
console.log(Boolean("false"))
console.log(Boolean("0"))
console.log(Boolean("NaN"))
console.log(Boolean(""))
</script>
</body>
</html>
语句
条件语句(分支语句,逻辑语句)
- if语句
- switch语句
if(exp){
语句块
...
}
// if else语句
if(exp){
分支1
}
else{
分支2
}
switch(变量){
case 常量:{
分支1;
break;
}
case 常量2:{
分支2;
break;
}
case 常量3:{
分支3;
break;
}
default:{
默认分支;
break;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// if(2 == "2"){
// console.log(1)
// console.log(2)
// }
// console.log(3)
if(false){
console.log(1)
}
else{
console.log(2)
}
console.log(3)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var n = 0;
switch(n){
case 1:{
alert("这里是1");
break;
}
case 2:{
alert("这里是2");
break;
}
case 0:{
alert("这里是0");
break;
}
case 3:{
alert("这里是3");
break;
}
case 100:{
alert("这里是100");
break;
}
default:{
alert("这里是default")
break;
}
}
</script>
</body>
</html>
循环语句
- for语句
for(var i = 0;i < 100;i++){
// 循环体
console.log(i)
}
- while语句
while(exp){
//循环体
}
- do while语句
// 至少执行一次版本的while语句
do{
//循环体
}
while(exp)
break和continue:
只能出现在循环语句内部,当循环体内部执行到break关键字时,整个程序会跳出(结束)最近的循环。当循环体内部执行到continue关键字时,程序会结束本一次循环进入到下一次循环。
函数:
- 一段可以被高度复用的代码段。
// 匿名函数:不常见,就是一个没有名字的函数。
function(){
// 函数体
}
// 声明函数
//function 函数名(形参1,形参2,形参3...){
//函数体
//....
//}
// 调用函数
// 函数名(实参1,实参2,实参3...)
<script>
// 声明函数:做计划
function f1(){
console.log(1)
console.log(2)
console.log(3)
}
// 调用函数:开始实施,执行。
f1()
f1()
f1()
</script>
函数的参数
- 形参:在函数体内声明的变量,只声明不赋值。
- 实参:在调用函数时传入的参数,这里相当于是为形参赋值。
// function add(n){
// console.log(n+2)
// }
// add(2)
// add(22)
// add(222)
// 计算并输出两个任意数字之和
// function add(n,m){
// console.log(n+m)
// }
// add(10,5)
// add(100,500)
// 计算并输出两个任意之间较大的那个
// function max(num1,num2){
// if(num1 > num2){
// console.log(num1)
// }
// else{
// console.log(num2)
// }
// }
// max(10,5)
// max(100,200)
参数对象:
- 参数对象的使用场景只是在调用函数时传入实参的数量不确定的情况下,那么我们就会把形参去掉用参数对象
arguments
来代替。参数对象的本质是一个类数组,拥有数组下标的特性和.length特性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 声明一个函数
// 该函数接收两个number类型的参数
// 该函数会返回两个参数相加之和
// function add(num1,num2){
// return num1 + num2;
// }
// console.log(add(5,10))
// 声明一个函数
// 该函数接收若干个number类型的参数
// 该函数会返回所有实参相加之和
// 该函数会过滤掉所有非Number的实参
function add(){
var total = 0;
// 数组的枚举/数组的循环/数组的遍历
for(var i = 0; i < arguments.length;i++){
if(typeof arguments[i] !== "number"){
continue;
}
total = total + arguments[i];
}
return total;
}
// console.log(add(1,5,6,3,4))
// console.log(add(1,5))
// console.log(add(1,5,6,3,4,1,2,5))
console.log(add(1,5,6,3,"字符串",4,1,2,5))
</script>
</body>
</html>
执行一个函数的表达式
1.副作用是把函数体内部的所有代码从上到下执行一遍。
2.返回值:如果调用的那个函数体内部没有return语句,则一律返回undefined。如果调用的函数体内有return语句,则返回值是return语句后面的表达式的返回值。
return的作用:只能出现在函数体内部
- 控制调用函数表达式的返回值。如果调用的那个函数体内部没有return语句,则一律返回undefined。如果调用的函数体内有return语句,则返回值是return语句后面的表达式的返回值。
- 做流程控制,如果调用函数时执行到return语句了,那么程序会认为此次执行函数的任务就已经执行完了,就会忽略掉return语句以下的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// function add(num1,num2){
// console.log(num1+num2)
// }
// add(5,10)
// add(10,20)
// function add(num1,num2){
// return num1+num2;
// }
// 执行一个函数的表达式
// 1.副作用是把函数体内部的所有代码从上到下执行一遍。
// 2.返回值:如果调用的那个函数体内部没有return语句,则一律返回undefined。如果调用的函数体内有return语句,则返回值是return语句后面的表达式的返回值。
// alert(add(5,10))
// console.log(add(10,20))
// var result = add(1,5)
//fn(5)函数的返回值是1;console.log("abc")不执行,原因参考return的作用。
function fn(num1){
return 1;
console.log("abc");
}
fn(5)
</script>
</body>
</html>
函数的引用:
- 也就是函数的本身,引用的方法就是函数名(如:fn)不加括号,返回值是函数本身。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function fn(){
alert(1)
alert(2)
}
// 调用函数:函数名()
// fn()
// 函数的引用
// console.log(fn)
// 在函数的引用(本身)后面加一对小括号就代表调用该函数
</script>
</body>
</html>
IIFE自调用函数
var a = (function(n,m){
return(n+m)
})(10,5)
console.log(a)
// 以下两种写法完全等价
// 普通声明函数
// function fn(n,m){
// return n + m;
// }
// 匿名函数声明并赋值给另外一个变量
// var fn = function(n,m){return n + m;}
// console.log(fn)函数引用
// console.log(fn(5,10))
// IIFE自调用函数
var a = (function(n,m){
console.log(n+m)
})(10,5)
//函数引用
console.log(a)
JS数组
- 若干个值的有序集合。拥有下标的特性,可以使用
数组[下标]
的形式从一个数组集合中提取出来某一个元素;拥有.length特性,可以使用数组.length
返回数组中成员的数量(数组的长度)
//创建数组方法一
var arr=new array();
cars[0]="aaa";
cars[1]=;
cars[2]="true";
//方法二
var arr=new Array("aaa","111","true");
//方法三
var arr=["aaa","111","true"];
//!!如何枚举(遍历,循环)一个数组
for(var i = 0; i < arr.length;i++){
arr[i]
}
数组的全局方法:Array.方法()
- push(exp) 向后插
- pop() 删除最后一个
- unshift(exp) 向前插
- shift() 删除第一个
- splice(index,howmany,repalcement) 添加/删除/替换
- splice(要插入位置的下标,0,要插入的元素) 往数组中某一个位置塞一个元素进去
- splice(要删除元素的下标,1) 从数组中删除掉某一个元素
- concat(array) 数组拼接
- join() 将数组转换为字符串,参数作为分隔符。
- reverse() 颠倒数组中元素的顺序
- slice(start,end) 从数组中截取一部分,end作为结束下标在结果集中并不包含该元素。
- sort() 默认以字符编码顺序进行排序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 声明一个空数组
var arr = [];
// 声明一个有内容的数组
var arr2 = [1,5,6,3,4,1,2,5];
// 利用数组下标(从0开始计数的)的特性来从数组中提取某一位成员
// console.log(arr2[1])
// 利用数组.length返回这个数组中一共有多少位成员
// console.log(arr2.length)
// 修改/添加数组成员
// arr2[0] = "new"; // 这种话是含有副作用的
// arr2[9] = "hello"; // 这是做添加,因为原本下标9的位置没有值。
// arr2[11] = "aaa" // 不会这么写代码的,因为中间有断层。
// console.log(arr2)
// console.log(arr2[15]) // 试图去访问一个不存在的数组中的下标,程序并不会报错,会返回undefined。
// 在不知道数组长度到底是多少的情况,往数组尾端插入一个新元素的写法。
// arr2[arr2.length] = "newbee";
// arr2[arr2.length] = "new";
// arr2.push("newBee")
// console.log(arr2)
// 开头插
// arr2.unshift("newBee");
// console.log(arr2)
// 删除掉数组中第一个元素
// arr2.shift()
// 删除掉数组中最后一个元素
// arr2.pop()
// 往数组下标为2的地方塞一个"aaa"进去
// arr2.splice(2,0,"aaa")
// 在数组中删除掉下标为2的元素
arr2.splice(2,1)
console.log(arr2)
</script>
</body>
</html>
// sort方法在不传入参数的情况下,默认以字符编码顺序进行排序,而非数学大小关系进行排序。
// 使用sort进行按照数学大小关系进行排序。
arr.sort(function(num1,num2){
return num1-num2;
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// var arr1 = ["a","b","c","d","e","f"];
// var arr2 = ["d","e","f"];
// arr1 = arr1.concat(arr2,['m',"mmm"])
// console.log(arr1)
// console.log(arr1.join("www"))
// arr1.reverse()
// console.log(arr1)
// 从第二位截取到第五位(不包含)
// console.log(arr1.slice(2,5))
// 从倒数第三位截取到第五位(不包含)
// console.log(arr1.slice(-3,5))
// 从第二位截取到最后
// console.log(arr1.slice(2))
// var arr1 = ["a","b","c","d","e","f"];
// 替换
// arr1.splice(1,3,"www")
// 删除
// arr1.splice(1,3)
// 删除
// arr1.splice(2,1)
// 添加
// arr1.splice(1,0,"www","mm")
// console.log(arr1)
//
// console.log(arr1.join("|"))
var arr = [1,5,6,11,3,4,2];
arr.sort(function(num1,num2){
return num1-num2;
})
console.log(arr)
</script>
</body>
</html>
ES5下的Array的全局方法
- forEach(function(item,index,array){})
// forEach:在循环数组的时候可以使用
var arr = [1,5,6,4];
arr.forEach(function(item,index,array){
// 本次循环出来的成员
console.log(item)
// 本次循环的下标
console.log(index)
// 被循环数组本身
console.log(array)
})
- map(function(item,index,array){})
// map 修改原数组中成员并返回一个新的数组
var arr = [1,5,6,4];
var newArr = arr.map(function(item,index,array){
//修改原成员
return item+1;
})
- filter(function(item.index,array){})
// filter过滤某一个数组中的成员,并返回一个新数组。
// 从一个结果集中过滤掉某一些元素并返回新元素
var arr = [1,5,6,3,4,1,2,5];
console.log(arr.filter(function(item){
return !!(item % 2)
}))
- reduce(function(temp,temp2){})
// reduce返回一个结果(不一定是数组),循环次数是整个数组长度-1,第一个参数第一次循环时代表数组的第0位,以后每一次都代表的是上一次循环的return语句的返回值;第二个参数第一次循环代表的是下标为1的那位元素,以后为下标为2,下标为3....。如果我们希望将某一个数组中的所有成员进行累计计算的话,此时是最适合reduce方法的使用的。
var arr = [1,5,6,3,4,1,2,5];
console.log(arr.reduce(function(temp,temp2){
console.log(temp)
return temp + temp2;
}))
- indexof(value,start) 从数组中检测某一个元素出现的位置,如果没找到将返回-1。
JS对象:
- 值的无序集合,一个key:value这种键值对的数据结构,对象也可以被看作成是若干个属性的无序集合。
// 声明一个空对象
var o = {}
// 声明一个不空的对象
var o = {
name:"yan",
age:18,
sex:"famale",
married:false,
// 方法:如果对象中哪一条属性的属性值是一个函数,那么我们就不太愿意把它叫成属性,而愿意叫做方法。
sayHello:function(){
alert("我叫yan~O(∩_∩)O")
return 1;
}
}
// !!对象的查询的两种写法:
//Object.属性名 在Object对象中直接查找某个属性名的所对应的属性值
//Object["属性名"] 与上面等价
//Object[属性名] 把属性名看做成一个变量,首先从js执行环境上下文中获取该变量存放的值(如:"a"),然后再从Object对象中查找变量中存放的值所对应的属性的属性值(a属性的属性值)
// 对象的修改/添加
//Object.属性名 = 新值
//Object["属性名"] = 新值
// 删除掉对象中的某一条属性
//delete Object.属性名
// 检测一个属性在另外一个对象中是否存在
//"属性名" in Object
// 枚举对象
for(var i in Object){
// 循环体执行次数取决于Object属性的个数
// 每一次进入循环体的时候i依次代表了对象的属性名
// 对象的属性名
// console.log(i)
// 对象的属性值
// console.log(Object[i])
}
对象的查询的两种写法:
- Object.属性名 在Object对象中直接查找某个属性名的所对应的属性值
- Object[“属性名”] 与上面等价
- Object[属性名] 把属性名看做成一个变量,首先从js执行环境上下文中获取该变量存放的值(如:“a”),然后再从Object对象中查找变量中存放的值所对应的属性的属性值(a属性的属性值)
检测一个属性在另外一个对象中是否存在
- “属性名” in Object
枚举对象
for(var i in Object){
// 循环体执行次数取决于Object属性的个数
// 每一次进入循环体的时候i依次代表了对象的属性名
// 对象的属性名
// console.log(i)
// 对象的属性值
// console.log(Object[i])
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var o = {
name:"yyyy",
age:18,
sex:"famale",
married:false
}
// var age = "sex";
// 此时name是常量
// console.log(o.name)
// 此时age当做是一个变量
// console.log(o[age])
// 对象的修改/添加
// o.age = 19;
// o.height = 187;
// 对象属性的删除
// delete o.age
// 对象的检测
// console.log("age1" in o)
var arr = [1,5,6,3]
var o = {
name:"yyyy",
age:18,
sex:"famale",
married:false,
// 方法:如果对象中哪一条属性的属性值是一个函数,那么我们就不太愿意把它叫成属性,而愿意叫做方法。
sayHello:function(){
alert("哈喽~O(∩_∩)O")
return 1;
}
}
// for语句不能循环对象
// for in语句枚举对象
// for(var i in o){
// 对象的属性名
// console.log(i)
// 对象的属性值
// console.log(o[i])
// }
// console.log(o.sayHello())
</script>
</body>
</html>
JS字符串
字符串.length属性和下标的特性
var str = "aabbccddee";
// 返回字符串的长度:一共有多少个字符
console.log(str.length)
// 字符串的下标特性
console.log(str[2])
// 字符串的下标特性只能获取 不能修改
str[2] = "m"; // 此操作无效
String对象的全局方法
参考文档:https://www.w3school.com.cn/jsref/jsref_obj_string.asp
方法 | 作用 |
---|---|
charAt() | 返回在指定位置的字符 |
concat() | 连接字符串 |
indexOf() | 检索字符串 |
lastIndexOf() | 从后向前搜索字符串 |
replace() | 替换与正则表达式匹配的子串 |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分。 |
substring() | 提取字符串中两个指定的索引号之间的字符。 |
substr() | 从起始索引号提取字符串中指定数目的字符。 |
split() | 把字符串分割为字符串数组。 |
Math对象
方法 | 作用 |
---|---|
abs() | 返回绝对值 |
ceil() | 向上取整 |
floor() | 向下取整,类似于parseInt() |
round() | 四舍五入 |
max() | 返回最大值 |
min() | 返回最小值 |
random() | 返回0-1之间的伪随机数(不可能等于1,有可能等于0) |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// console.log(Math.random())
// 0-99之间的随机整数
console.log(parseInt(Math.random() * 100))
// 10-99之间的随机整数
parseInt((Math.random() + 0.1) * 90)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 自定义对象:自己声明的
// var o = {
// name:"yyyy",
// age:18,
// sayHello:function(){
// alert("哈喽~")
// }
// }
// console.log(o)
//内置对象,宿主对象
//返回圆周率
//console.log(Math.PI)
// 返回绝对值 //console.log(Math.abs(-2))
// 向上取整
//console.log(Math.ceil(3.0000000001))
// 向下取整:类似于parseInt() //console.log(Math.floor(3.999999999))
// 四舍五入
//console.log(Math.round(3.5))
// 返回最大值或最小值
// console.log(Math.max(10,5,300))
// console.log(Math.min(10,5,300))
// 返回0-1之间的伪随机数(不可能等于1,有可能等于0)
// Math.random()
</script>
</body>
</html>
Date对象
- 如果想要使用Date对象首先先得实例化
var date = new Date()
方法 | 作用 |
---|---|
getFullYear() | 返回年份 |
getMonth() | 返回月份(从0开始计数) |
getDate() | 返回日期 |
getHours() | 返回小时数 |
getMinutes() | 返回分钟数 |
getSeconds() | 返回秒数 |
getDay() | 返回星期(周日返回的是0) |
getTime() | 获取时间戳(从1970年1月1日00:00:00到现在一共经过了多少毫秒) |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
//获取当前时间,在控制台中输出
// 实例化一个Date对象
var date = new Date();
console.log(date.getFullYear())
console.log(date.getMonth() + 1)
console.log(date.getDate())
console.log(date.getHours())
console.log(date.getMinutes())
console.log(date.getSeconds())
console.log(date.getDay())
console.log(date.getTime())
</script>
</body>
</html>
获取非当前时间的日期对象
var date = new Date("YYYY-MM-DD HH:MM:SS")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
// 获取此时此刻的日期对象
var date = new Date();
// 获取了一个非当前时间
var d = new Date("1993-08-07 07:00:00");
console.log(d.getFullYear())
console.log(d.getHours())
console.log(d.getDay())
</script>
</body>
</html>
计算两个日期对象之间的差值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h2 id="times"></h2>
<script>
// 此时距离过年还有多少天零多少小时零多少分零多少秒
// 春节的日期对象
var target = new Date("2021-02-12 00:00:00");
// 当前的日期对象
var now = new Date();
// 相差的一共有多少秒
var totals = Math.floor((target.getTime() - now.getTime()) / 1000)
var day = Math.floor(totals / 86400)
var hours = Math.floor(totals % 86400 / 3600);
var minute = Math.floor(totals % 3600 / 60)
var second = totals % 60;
console.log(day);
console.log(hours);
console.log(minute);
console.log(second);
times.innerHTML = `距离春节还有${day}天${hours}小时${minute}分钟${second}秒`
</script>
</body>
</html>
计时器
setInterval(function(){
},time)
BOM
- Broswer Object Model 浏览器对象模型
window对象
常用的属性和方法
三个弹出框:
- 特点:阻塞代码执行。
- alert(“内容”) 弹出框
- confirm(“提示信息”) 确认框 确定返回true ,取消返回false
- prompt(“提示信息”,“默认值”) 输入框 返回数值为字符串
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
//弹出框且打印数据
//alert("heihei");
//console.log("xixi");
//注意:弹出框是具有阻塞行为的
//从页面接收数据
//prompt([描述信息],[默认值]);
//var x = prompt("请输入价格",666);
//console.log(+x+1);
//返回boolean值
//confirm([描述信息]);
var flag;
flag = confirm("确定要转账嘛");
console.log(flag);
</script>
</body>
</html>
两个定时器:
setInterval(function(){
执行任务
},间隔时间) 连续执行定时
setTimeout(function(){
执行任务
},间隔时间) 只执行一次,延时执行定时
停止计时器
- 停止连续执行定时:clearInterval();
- 停止延时执行定时:clearTimeout();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
height: 100px;
width: 100px;
background-color: greenyellow;
}
</style>
</head>
<body>
<button type="button" id="begin">开始</button>
<button type="button" id="end">停止</button>
<div id="box">
</div>
</body>
</html>
<script>
//setInterval(执行任务,间隔时间): 连续执行定时器
//clearInterval()
// var count = 0;
//定时器的返回值:可以理解为是关闭定时器的钥匙
// var time = setInterval(function(){
// console.log(count++);
// if(count == 5){
// clearInterval(time);
// }
// },1000);
//setTimeout(执行任务,间隔时间): 用法同上 只执行一次 延时性 clearTimeout() 停止定时器(一般用的不太多)
// setTimeout(function(){
// console.log("heihei");
// },5000);
// clearTimeout()
var oBox = document.getElementById("box");
var oBtnBegin = document.getElementById("begin");
var oBtnEnd = document.getElementById("end");
var time = null;
oBtnBegin.onclick = function(){
time = setTimeout(function(){
oBox.style.display = "none";
},3000);
//oBox.style.backgroundColor = "red";
}
oBtnEnd.onclick = function(){
clearTimeout(time);
}
</script>
两个事件:
onload事件:
onload事件会在页面或图像加载完成后立即发生。延迟加载,等整个页面全部执行完之后,在去执行onload里面的方法
window.onload = function(){
console.log("页面加载完成");
}
console.log("页面正在加载");
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
var d = document.getElementById("t");
d.innerHTML = "666";
</script>
</head>
<body>
<p id="t"></p>
</body>
</html>
JS代码在head标签内部时,程序运行时会报错Cannot set property ‘innerHTML’ of null。因为代码是从上到下执行的,在执行JS时下面的部分代码未被加载到,会产生错误。
解决方法有两种:
- 给js代码中添加onload事件。
window.onload = function(){
var d = document.getElementById("t");
d.innerHTML = "666";
}
- 将js代码添加在html标签后。
window.onload = function(){
var d = document.getElementById("t");
d.innerHTML = "666";
}
onscroll事件
-
滚动条事件
-
兼容问题 获取滚动条移动的垂直距离
var _top = document.body.scrollTop || document.documentElement.scrollTop;
-
回到顶部
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
body{
height: 1000px;
}
#btn{
position: absolute;
top:1000px;
}
</style>
</head>
<body>
<button type="button" id="btn">返回顶端</button>
</body>
</html>
<script>
//滚动条事件
window.onscroll = function(){
//console.log("heihei");
//兼容问题 获取滚动条移动的垂直距离
var _top = document.body.scrollTop || document.documentElement.scrollTop;
console.log(_top);
}
var oBtn = document.querySelector("button");
oBtn.onclick = function(){
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
</script>
window对象的属性和方法都可以省略window, 直接使用的所有全局变量都是window对象的属性 所有全局函数都是window对象的方法。
location地址对象
页面跳转:location.href 可读写
//当前页面地址 读
document.write(location.href);
//页面在三秒后跳到外网
setTimeout(function(){
location.href = "http://www.baidu.com";
},3000);
//location.replace("index.html");
location.replace("http://www.baidu.com"); 覆盖原先网页 没有浏览痕迹
页面覆盖:location.replace(“url”)
//覆盖原先网页 没有浏览痕迹
//location.replace("index.html");
location.replace("http://www.baidu.com");
页面刷新:location.reload();
<input type="text">
<button onclick="fun()">刷新</button>
<script>
function fun(){
location.reload();
}
</script>
document 文档对象
- 每个载入浏览器的 HTML 文档都会成为 Document 对象。
- Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问
- Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问
- 作用:获取对象
document的方法:
- write() 打印到页面
- getElementById(“ID名”) 通过ID获取元素 ,返回单个对象-> Node
- getElementsByTagName(“标签名”) 通过标签名获取元素 ,返回数组-> NodeList
- getElementsByClassName(“class名”) 通过类名获取元素,返回数组 -> NodeList
- getElementsByName;通过name属性获取元素,返回数组;
- querySelector()通过id名,类名,标签名等获取单个元素
- querySelectorAll()批量获取类和标签,返回数组。
//找对象
//document.getElementById(); 返回单个对象
//document.getElementsByTagName(); 返回数组
//document.getElementsByClassName(); 返回数组
//document.getElementsByName(); 返回数组
// var oTexts = document.getElementsByName("txt");
// for(var i=0; i<oTexts.length; i++){
// console.log(oTexts[i].value);
// }
//document.querySelector(); 获取单个的ID,类,标签元素
// var oP = document.querySelector("p");
// console.log(oP.innerHTML);
// var oP1 = document.querySelector("#_p");
// console.log(oP1.innerHTML);
// var oP2 = document.querySelector("._p");
// console.log(oP2.innerHTML);
//document.querySelectorAll();批量获取 类 和 标签 返回数组
//var oTexts = document.querySelectorAll("input");
var oTexts = document.querySelectorAll(".test");
for(var i=0; i<oTexts.length; i++){
console.log(oTexts[i].value);
}
- document.write()特点:
- 自带字符串解析
- 如果该方法与事件连用,会直接覆盖原网页
//document
//a. document.write()
//1.自带字符串解析
//document.write("sdfsdf" + "<br/>" + "heihei");
//document.write("<font color='yellow'>"+666+"</font>");
//2.如果该方法与事件连用,会直接覆盖原网页
var oBtn = document.getElementById("btn");
oBtn.onclick = function(){
document.write("heihei");
}
Node节点:
- Object数据类型,对应的是页面中的某一个元素。
节点对应的属性和方法
属性/方法 | 作用 |
---|---|
innerHTML | 设置/获取该元素开始标签与结束标签之间的内容。 |
className | 设置/获取该元素class属性的属性值。 |
setAttribute(“key”,“value”) | 设置该元素的某一个行内属性的属性值。 |
getAttribute(“key”) | 获取该元素的某一个行内属性的属性值 |
style | 设置/获取元素的行内样式 |
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="heihei">
</div>
</body>
</html>
<script>
//1通过.进行读写
var oBox = document.querySelector("#heihei");
//写
//oBox.id = "haha";
//读
//console.log(oBox.id);
//------------------------------
//2.getAttribute/setAttribute
//写
//oBox.setAttribute("id","xixi");
//读
//console.log(oBox.getAttribute("id"));
</script>
outerHTML/innerText/innerHTML
outerHTML,innerText和innerHTML的不同之处在于:
- innerHTML:将元素中所有的内容都获取到 包括HTML标签 但是不包括自身标签
- innerText:将元素的内容获取出来不包括HTML标签
- outerHTML:将自身以及子元素所有的内容都获取出来 包括HTML标签 包括自身标签
//var oD = document.querySelector("#d");
//innerHTML 该元素的所有内容 最常用的
//console.log(oD.innerHTML);
//innerText 该元素文本内容
//console.log(oD.innerText);
//outerHTML 包含元素自身标签的所有内容
//console.log(oD.outerHTML);
//通过字符串进行页面拼接
var oUl = document.querySelector("ul");
// oUl.innerHTML = "<li>" + 666 + "</li>";
// oUl.innerHTML += "<li>" + 777 + "</li>";
for(var i=0; i<10; i++){
oUl.innerHTML += "<li>" + i + "</li>";
}
获取非行内样式(兼容问题)
getComputedStyle(元素,false)["attr"];
-
行内样式:行内样式就是写在标签体内的样式:如,
<div style="color:red"></div>
-
非行内样式:非行内样式就是指不是写在标签体内的style属性的样式。如内的定义的样式或用link引入的外部css文件都是非行内样式。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#box{
color: blue;
font-size: 22px;
}
</style>
</head>
<body>
<!-- 行内样式 -->
<!-- <div style="color:red"></div> -->
<!-- --------------------------------- -->
<div id="box">
</div>
</body>
</html>
<script>
//行内样式
//var oBox = document.querySelector("div");
//写
//oBox.style.color = "yellow";
//读
//console.log(oBox.style.color);
//--------------------------------------------------------------------
//获取非行内样式(兼容问题)
var oBox = document.querySelector("#box");
//读必须通过官方的方法
//getComputedStyle(元素,false)["attr"];
console.log(getComputedStyle(oBox,false)["color"]);
oBox.style.fontSize = "60px";
console.log(getComputedStyle(oBox,false)["fontSize"]);
</script>
NodeList(节点列表,节点集合)
- 类数组,拥有数组下标的特性和.length的特性。
- 由若干个Node节点构成的类数组,如果我们通过数组下标的特性提取出某一个成员,那么该成员就是Node节点。
Node和NodeList
- Node与NodeList是完全独立的两个存在,它们之间的方法或属性都不互通
偏移量
- offsetWidth/offsetHeight/offsetLeft/offsetTop
offsetHeight和offsetWidth监测盒子的宽高
- 包括内容、padding、border, 不包括margin
offsetLeft和offsetTop监测距离父盒子有定位的左/上的距离
- 返回上级盒子(有定位的)左边的位置,如果先辈没有定位则以body为基准
- offsetLeft从先辈有定位的padding开始计算(border不算
- offsetLeft = style.left(没有px)
offsetLeft与style.left区别
- 最大区别在于offsetLeft可以返回没有定位盒子的距离左侧的位置(若父辈没有定位,offsetLeft以body为准;style.left则返回空字符串)
- offsetLeft 返回的是数字,style.left返回的是字符串,除了数字以外带有单位px
- offsetLeft 只读,style.left可读写,(只读是获取值,可读写是赋值)
- 如果没有给HTML元素指定top样式,则style.left返回空字符串
- style.left必须要事先定义,否则值为空
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
#father{
width: 300px;
height: 300px;
border: 1px solid red;
}
#son{
width: 120px;
height: 100px;
border: 1px solid red;
position: absolute;
left: 78px;
top:55px;
}
</style>
</head>
<body>
<div id="father">
<div id="son">
</div>
</div>
</body>
</html>
<script>
var oSon = document.querySelector("#son");
//读 : 读出的结果是纯数字
console.log(oSon.offsetLeft);
console.log(oSon.offsetTop);
console.log(oSon.offsetWidth);
console.log(typeof oSon.offsetHeight);
//写 : 需要加px的字符串
//oSon.offsetLeft = 99; //X
oSon.style.left = "166px";
oSon.style.top = "166px";
oSon.style.width = "166px";
oSon.style.height = "166"+"px";
</script>
DOM
- document object model 文档对象模型
节点间的关系
根据节点间的层次关系访问节点:(包括文本和元素)
parentNode 返回节点的父节点
childNodes 返回子节点集合,childNodes[i]
firstChild 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点
lastChild 返回节点的最后一个子节点
nextSibling 下一个节点
previousSibling 上一个节点
通过层级关系访问元素节点
firstElementChild 返回节点的第一个子节点,最普遍的用法是访问该元素的文本节点
var str = a.firstElementChild.innerHTML;
lastElementChild 返回节点的最后一个子节点
nextElementSibling 下一个节点
previousElementSibling 上一个节点
children返回父元素的子元素,以数组形式返回
节点类型:通过nodeType属性来判断节点类型
1代表元素节点
3代表文本节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>你好!</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<p id = "_p">123</p>
</body>
</html>
<script>
//document.body直接代表body的js形式
//var oBody = document.body;
//注意区分文本节点和元素节点
//var str = oBody.firstChild.nextSibling.innerHTML;
//console.log(str);
//var str = oBody.firstElementChild.nextElementSibling.firstElementChild.nextElementSibling.innerHTML; 超级复杂,一般没人这样干
//console.log(str);
var oP = document.querySelector("#_p");
//nodeType判断节点类型
//1 元素节点
console.log(oP.nodeType);
//3 文本节点
console.log(oP.firstChild.nodeType);
</script>
节点的操作
document.createElement(HTML标签名) //创建一个元素节点
node.appendChild(newChild) //newChild 被添加到孩子列表中的末端。
node.insertBefore(newChild, referenceNode) // 将 newChild 节点插入到 referenceNode 之前。
node.remove() //删除node子节点。
node.replaceChild(newChild, oldChild) //用newChild节点替换oldChild节点
insertBefore:添加到一个节点前面
- 父节点.insertBefore(要添加的子节点,参照节点);
- 参照节点如果为null 那就和appendChild()一样
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ul>
<input type="text"/>
<button type="button">增加</button>
</body>
</html>
<script>
var oText = document.querySelector("input");
var oBtn = document.querySelector("button");
var oUl = document.querySelector("ul");
oBtn.onclick = function(){
var oLi = document.createElement("li");
oLi.innerHTML = oText.value;
//父节点.insertBefore(目标节点,参照节点):将目标节点插人至参照节点之前
//oUl.appendChild(oLi);
//oUl.insertBefore(oLi,oUl.children[1]);
oUl.insertBefore(oLi,null);
}
</script>
动态增加节点
- 创建节点
- 追加节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- <h2>姓名</h2>
<p>yyyy</p> -->
</body>
</html>
<script>
//增
//1.创建节点
//createElement("标签名");
var oH = document.createElement("h2");
oH.innerHTML = "姓名";
//2.追加
//父节点.appendChild("子节点");
document.body.appendChild(oH);
var oP = document.createElement("p");
oP.innerHTML = "yyyy";
document.body.appendChild(oP);
//流程 : 先创建,后追加
</script>
动态删除节点:节点.remove(无参) 直接删除
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>MySql</li>
<li>PHP</li>
</ul>
<button type="button">删除</button>
</body>
</html>
<script>
//删除的方法 元素.remove();
var oBtn = document.querySelector("button");
var oUl = document.querySelector("ul");
//var arrLis = oUl.childNodes;
var arrLis = oUl.children;//返回父元素的子元素,以数组形式返回
oBtn.onclick = function(){
arrLis[2].remove();
}
</script>
表格的动态创建和删除
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
</html>
<script>
var oTb = document.createElement("table");
oTb.border = "1px";
var count = 0;
for(var i=0; i<3; i++){
var oTr = document.createElement("tr");
for(var j=0; j<3; j++){
var oTd = document.createElement("td");
oTd.innerHTML = ++count;
oTr.appendChild(oTd);
}
var oDelTd = document.createElement("td");
oDelTd.innerHTML = "删除";
oTr.appendChild(oDelTd);
//this:一定出现在函数体内
//与事件连用时,代表触发该事件的元素本身
oDelTd.onclick = function(){
//oDelTd.parentNode.remove();//x
this.parentNode.remove();
}
oTb.appendChild(oTr);
}
document.body.appendChild(oTb);
</script>
事件
- 事件源:触发事件的元素
- 事件类型: 例如 click 点击事件
- 事件对象(函数):事件触发后要执行的代码(函数形式),事件处理函数
事件对象:event
- 事件:对某个元素的某种操作
- 事件对象:当某个事件触发时产生的对象,就是事件对象。
- event使用前提,必须有事件,不同的事件产生的事件对象不同。
- 事件对象的兼容:var e = evt || event;
- 事件对象拥有该事件相关的属性和方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script type="text/javascript">
//事件对象 event
//onkeyup 键盘按下弹起事件,
document.onkeyup = function(evt){
//事件对象的兼容
var e = evt || event;
alert(e);
}
</script>
</body>
</html>
小老虎跳一跳案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#tiger{
height: 100px;
width: 100px;
background-image: url(img/3.jpg);
background-size: 100px 100px;
position: absolute;
left: 200px;
top:500px;
}
</style>
</head>
<body>
<div id="tiger">
</div>
</body>
</html>
<script>
var oBox = document.querySelector("#tiger");
document.onclick = function(){
oBox.style.top = oBox.offsetTop - 100 + "px";
setTimeout(function(){
oBox.style.top = "500px";
},2000);
}
</script>
鼠标事件
坐标属性:
- pageX / pageY 相对于整个文档顶部和左侧的坐标
- clientX / clientY 相对于局部窗口(视口)的左侧和顶部的坐标
- offsetX / offsetY 相对于内部元素的距离左侧和顶部的坐标 常用于拖拽。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
height: 1000px;
}
#box{
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
left: 200px;
top:200px;
}
</style>
</head>
<body>
<div id="box">
</div>
</body>
</html>
<script>
document.onclick = function(evt){
var e = evt ||event;
console.log("page:" + e.pageX + "," + e.pageY); //常用
//console.log("client:" + e.clientX + "," + e.clientY); //比较少用
console.log("offset:" + e.offsetX + "," + e.offsetY); //用于拖拽
}
</script>
图片随鼠标移动案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#tiger{
height: 100px;
width: 100px;
background-image: url(img/3.jpg);
background-size: 100px 100px;
position: absolute;
left: 200px;
top:500px;
}
</style>
</head>
<body>
<div id="tiger">
</div>
</body>
</html>
<script>
var oTiger = document.querySelector("#tiger");
document.onmousemove = function(evt){
var e = evt || event;
oTiger.style.left = e.pageX - oTiger.offsetWidth/2 + "px";
oTiger.style.top = e.pageY - oTiger.offsetHeight/2 + "px";
}
</script>
键盘事件
- onkeyup:用户按下弹起(释放)某一个按键时发生。
- onkeydown:用户按下按键时发生,任何一个按键即可发生事件。
- onkeypress:用户按下按键,并且产生一个字符时发生。(意思是按ctrl这样的按键是没有效果的)
//键盘事件源都是document
//键盘抬起的时间点触发
document.onkeyup = function(){
console.log("heihei");
}
//键盘落下的时间点触发
document.onkeydown = function(){
console.log("heihei");
}
//生成一个字符串触发
document.onkeypress = function(){
console.log("heihei");
}
事件对象属性:
keyCode:获取键盘按键值,字母对应其ASCII值识别。
A :65 a:97 字符0:48 回车:13
注意:keyPress的ctrl+回车返回值为10
document.onkeypress = function(evt){
var e = evt || event;
if(e.keyCode == 13 || e.keyCode == 10 && e.ctrlKey){
alert("send");
}
}
ctrlKey:返回当事件被触发时,"ctrl"是否被按下,返回值为true or false。
键盘检测兼容写方法:
var key = e.keyCode || e.which || e.charCode;
//事件对象
document.onkeypress = function(evt){
var e = evt || event;
//65 97 48字符0 32空格 13回车
//keyCode:获取按下字符的ASC码值
//兼容写法
var key = e.keyCode || e.which || e.charCode;
console.log(key);
//ctrl + 回车 10
if(key == 10 && e.ctrlKey){
console.log("发送");
}
//判断ctrl是否被按下
console.log(e.ctrlKey);
// console.log(e.keyCode);
// console.log(e.which);
// console.log(e.charCode);
}
//console.log(String.fromCharCode(98));
height: 100px;
border: 1px solid red;
position: absolute;
left: 200px;
top:200px;
}
</style>
</head>
<body>
<div id="box">
</div>
</body>
```
图片随鼠标移动案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#tiger{
height: 100px;
width: 100px;
background-image: url(img/3.jpg);
background-size: 100px 100px;
position: absolute;
left: 200px;
top:500px;
}
</style>
</head>
<body>
<div id="tiger">
</div>
</body>
</html>
<script>
var oTiger = document.querySelector("#tiger");
document.onmousemove = function(evt){
var e = evt || event;
oTiger.style.left = e.pageX - oTiger.offsetWidth/2 + "px";
oTiger.style.top = e.pageY - oTiger.offsetHeight/2 + "px";
}
</script>
键盘事件
- onkeyup:用户按下弹起(释放)某一个按键时发生。
- onkeydown:用户按下按键时发生,任何一个按键即可发生事件。
- onkeypress:用户按下按键,并且产生一个字符时发生。(意思是按ctrl这样的按键是没有效果的)
//键盘事件源都是document
//键盘抬起的时间点触发
document.onkeyup = function(){
console.log("heihei");
}
//键盘落下的时间点触发
document.onkeydown = function(){
console.log("heihei");
}
//生成一个字符串触发
document.onkeypress = function(){
console.log("heihei");
}
事件对象属性:
keyCode:获取键盘按键值,字母对应其ASCII值识别。
A :65 a:97 字符0:48 回车:13
注意:keyPress的ctrl+回车返回值为10
document.onkeypress = function(evt){
var e = evt || event;
if(e.keyCode == 13 || e.keyCode == 10 && e.ctrlKey){
alert("send");
}
}
ctrlKey:返回当事件被触发时,"ctrl"是否被按下,返回值为true or false。
键盘检测兼容写方法:
var key = e.keyCode || e.which || e.charCode;
//事件对象
document.onkeypress = function(evt){
var e = evt || event;
//65 97 48字符0 32空格 13回车
//keyCode:获取按下字符的ASC码值
//兼容写法
var key = e.keyCode || e.which || e.charCode;
console.log(key);
//ctrl + 回车 10
if(key == 10 && e.ctrlKey){
console.log("发送");
}
//判断ctrl是否被按下
console.log(e.ctrlKey);
// console.log(e.keyCode);
// console.log(e.which);
// console.log(e.charCode);
}
//console.log(String.fromCharCode(98));