前端三要素:
-
HTML(结构):超文本标记语言,Hyper Text Markup Language,决定网页的结构和内容。
-
CSS(表现):层叠样式表,Cascading Style Sheets,设定网页的表现样式。
- 针对CSS的编程语言:LESS、SASS
-
JavaScript(行为):是一种弱类型脚本语言,其源代码不需要经过编译,
而是由浏览器解释运行,用于控制网页的行为。
JQuery是一个库,Angular、React、Vue是三大框架。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1WI3nCfx-1647003759355)(…/AppData/Roaming/Typora/typora-user-images/image-20220301141447506.png)]
1. 什么是JavaScript
1.1 概述
JavaScript是一门世界上最流行的脚本语言
Java、JavaScript
一个合格的后端开发,必须精通JavaScript
1.2 历史
ECMAScript可以理解为是JavaScript的以这个标准
最新版本已经到6版本,但是大部分浏览器还只停留在支持es5代码上。
开发环境—线上环境,版本不一致。
2. 快速入门
2.1 引入
内部引入:script标签内
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--script标签内,写Javascript语言
可以放在head、也可以放在body-->
<script>
alert("hello world!")
</script>
</head>
<body>
</body>
</html>
外部引入:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--外部引用
注意点:script必须成对出现,闭合-->
<script src="js/qj.js"></script>
<!--不用显示定义type,也就是默认是javascript-->
<script type="text/javascript"></script>
</head>
<body>
</body>
</html>
2.2 基本入门
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--JavaScript严格区分大小写-->
<script>
//1.定义变量 变量类型 变量名=变量值
var name = "song";
var score = 82;
//2.条件控制
if (score >= 60 && score < 70) {
alert("合格")
} else if (score >= 70 && score < 80) {
alert("良好")
} else if (score >= 80) {
alert("优秀")
} else {
alert("其他")
}
//3.调试
//console.log(score)在浏览器的控制台打印变量
</script>
</head>
<body>
</body>
</html>
- Elements:html、css
- Console:js,控制台输出
- Sources:在源码打断点调试
- Network:网络抓包
- Application:Cookie缓存等
2.3 数据类型
数值、文本、图形、音频、视频…
变量
var 变量名 //不能以数字开头
number:数值(js不区分小数和整数)
123 //整数123
123.1 //浮点数
1.123e //科学计数法
-99 //负数
NaN //not a number
Infinity //表示无限大
字符串
'abc'
"abc"
布尔值
true
false
逻辑运算
&& //两个都为真,结果为真
|| //一个为真,结果为真
! //真即假,假即真
比较运算
= //赋值
== //等于(类型不一样,值一样,也会判断为true)
=== //绝对等于(类型一样结果一样,结果才为true)
//1=="1",true
//1==="1",false
这是一个JS缺陷,坚持使用===绝对等于判断!!不要使用==
须知:
- NaN===NaN,这个与所有的数值都不相等,包括自己
- 只能通过isNaN(NaN)来判断这个数是否是NaN
浮点数问题:
console.log((1/3)===(1-2/3)) //false
尽量避免使用浮点数进行比较,存在精度问题!
要对浮点数进行比较时,采用差的绝对值进行比较
console.log(Math.abs((1/3)-(1-2/3))<0.0000001) //true
null和undefined
null //空
undefined //未定义
数组
Java的数组是必须一系列相同类型的对象,JS不需要这样。
//保证代码可读性
var arr = [1,2,3,4,"hello",true,null]
取数组下标,如果越界,会显示 undefined
对象
数组是中括号,对象是大括号
//定义对象,每个属性之间用逗号隔开,最后一个不需要添加
var person = {
name: "song",
age: 3,
tags: ["java", "python", "php"]
}
//取对象的值
console.log(person,name)
2.4 严格检查格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
前提:IDEA需要设置支持ES6语法
'use strict';代表严格检查模式,预防JavaScript的随意性导致产生一些问题
使用要求:必须卸载JavaScript的第一行
局部变量建议都使用let定义
-->
<script>
'use strict';
//全局变量
i = 1;
//局部变量
var j = 2;
let k = 3;//ES6中支持的,只要是局部变量,更推荐使用let
</script>
</head>
<body>
</body>
</html>
3. 数据类型
3.1 字符串
1、正常字符串我们使用单引号或者双引号包裹;
2、注意转义字符\
\'
\n
\t
\u4e2d \u#### Unicode字符
\x41 Ascii字符
3、多行字符串编写
//tab键上边,Esc下面的键
var msg =`hello
world
Java`
4、模板字符串
let name = 'song';
let age = 3;
let msg = `你好呀,${name}`
console.log(msg)
5、字符串长度
str.length
6、字符串的可变性,不可变!
7、大小写转换
//注意,这里是方法,不是属性
student.toUpperCase()
student.toLowerCase()
8、获取指定元素的下标
console.log(student.indexOf('t'))
9、截取子串
//包含前面不包含后面
console.log(student.substring(1))//只有一个数字,从此处截取到最后
tudent
console.log(student.substring(1,3))//从1截取到3前(即2)[1,3)
tu
3.2 数组
Array数组可以包含任意的数据类型。
var array = [1, 2, 3, 4, 6, 'abc', null];//通过下标取值和赋值
array[1] = 8
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
1、长度
array.length
注意:如果给数字的长度array.length赋值,数组大小就会发生变化。如果赋值过小,元素会丢失。
2、获得下标索引
console.log(array.indexOf(1))
字符串的“1”和数字1是不同的。
3、截取数组的一部分,返回一个新数组,类似字符串中的substring
var array = [1, 2, 3, 4, 6, 'abc', null];
array.slice(1, 5)//[1,5)
4、push()、pop()尾部
array.push():将元素压入到尾部
array.pop():弹出尾部的一个元素
5、unshift()、shift()头部
array.unshift():将元素压入到透部
array.shift():弹出头部的一个元素
6、排序
array.sort()
7、元素反转reverse()
arr = ['A','b','m']
(3) ['A', 'b', 'm']
arr.reverse()
(3) ['m', 'b', 'A']
8、contact()
arr
(3) ['m', 'b', 'A']
arr.concat([1,2,3,4])
(7) ['m', 'b', 'A', 1, 2, 3, 4]
arr
(3) ['m', 'b', 'A']
注意:contact并没有修改原始数组,只是会返回一个新的数组
9、连接符join
打印拼接数组,使用特定的字符串连接
arr
(3) ['m', 'b', 'A']
arr.join('-')
'm-b-A'
arr.join('')
'mbA'
10、多维数组
arr=[[1,2,3],55,['2','acs',1]]
(3) [Array(3), 55, Array(3)]
arr[0][1]
2
arr[1]
55
arr[2][2]
1
数组:存储数据(如何存,如何取,其他方法可以自己实现)
3.3 对象
若干个键值对
var 对象名 = {
属性名: 属性值,
属性名: 属性值,
属性名: 属性值,
属性名: 属性值
}
//定义了一个person对象,它拥有四个属性
var person = {
name: "song",
age: 20,
score: 100,
school: 'CAS'
}
js中对象,{…}表示一个对象,键值对描述属性XXX:XXXX,多个属性之间使用逗号隔开,最后一个属性不加逗号。
JavaScript中对象的所有键都是字符串,值是任意对象。
1、对象赋值
person
{name: 'song', age: 20, score: 100, school: 'CAS'}
person.name="zhangsan"
'zhangsan'
person.name
'zhangsan'
2、使用一个不存在的对象属性,不会报错,undefined
person.hah
undefined
3、动态的删减属性,通过delete删除对象的属性
delete person.age
true
person
{name: 'zhangsan', score: 100, school: 'CAS'}
4、动态的添加,直接给新的属性添加值就行
person.hah=1
1
person
{name: 'zhangsan', score: 100, school: 'CAS', hah: 1}
5、判断属性是否在这个对象中 ‘XXX’ in xxx
'name' in person
true
//继承
'toString' in person
true
6、判断一个属性是否是这个对象自身拥有的
person.hasOwnProperty('toString')
false
person.hasOwnProperty('name')
true
3.4 流程控制
if 判断
let age = 3;
if (age < 3) {
alert("hahahahah");
} else if (age === 3) {
alert("mamammama")
} else {
alert("说话")
}
while 循环,避免程序死循环
let age = 3;
while (age < 20) {
age = age + 1;
console.log(age);
}
do{
age = age + 1;
console.log(age);
}while(age < 30)
for 循环
for (let i = 0; i < 60; i++) {
console.log(i)
}
for in ;for of数组循环
let age = [3, 2, 1, 4, 45, 6, 45, 6, 45, 34, 534, 543, 53, 11, 88]
//for(let index in object)
//for in获得的是数组索引
for (let num in age) {
console.log(age[num]);
}
//for(let value in object)
//获得的是数组的元素
for (let number of age) {
console.log(number)
}
forEach数组循环
ES5.1特性
age.forEach(function (value) {
console.log(value)
})
3.5 Map和Set
ES6的新特性
Map:类似字典,键值对的形式
//ES6才支持Map,类似python中的字典
//学生成绩、学生名字
// var names = ["tom", "jack", "song"];
// var score = [20, 80, 100];
//1.创建
var map = new Map([["tom", 20], ["jack", 80], ["song", 100]]);
//2.取值
var stu = map.get("tom");//通过key获得value
console.log(stu);
//3.赋值
map.set("admin", 88)
console.log(map)
//4.删除
map.delete("tom")
Set:不重复的集合
//ES6才支持Set,可以去重
var set = new Set([3,2,1,3,4,9]);
//1.添加
set.add(10)
//2.删除
set.delete(3)
//3.是否包含
console.log(set.has(2))
console.log(set)
3.6 iterator遍历迭代Map、Set
//使用forof遍历Set
var set = new Set([3, 2, 1, 3, 4, 9]);
for (var x of set) {
console.log(x)
}
//使用forof遍历Map
var map = new Map([["tom", 20], ["jack", 80], ["song", 100]]);
for (var m of map) {
console.log(m)
}
4. 函数
方法:存在在对象中,对象(属性、方法)
函数:函数放在对象中就是方法
4.1 定义函数
定义方式一:
绝对值函数
function abs(x) {
if (x >= 0)
return x;
else
return -x;
}
console.log(abs(-12))
一旦执行到return代表函数结束,返回结果!
如果没有执行return,函数执行完也会返回结果,结果就是undefined
定义方式二:
var abs = function (x) {
if (x >= 0)
return x;
else
return -x;
}
console.log(abs(-12));
function(x){…}是一个匿名函数(类似Java的匿名内部类),但是可以把结果赋值给abs,通过abs就可以调用。
方式一和方式二等价!
调用函数:
abs(10)//10
abs(-12)//12
参数问题:
javascript可以传递任意个参数,也可以不传递参数,都不会产生报错!
参数进来是否存在的问题?假设不存在参数,如何规避?–考虑手动抛出异常。
var abs = function (x) {
//手动抛出异常
if (typeof x != "number") {
throw "Not a number!"
}
if (x >= 0)
return x;
else
return -x;
}
console.log(abs('a'));
多个参数:
-
**
arguments
**是JS免费赠送的关键字; -
代表传递进来的所有参数,是一个数组
var abs = function (x) {
console.log("x--> " + x);
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
console.log(abs(12, 43, 23, -435, 88));
存在的问题:arguments包含所有的参数,有时候想要使用多余的参数(如上例中除了第一个参数x外的其他参数)来进行附加的操作,需要排除已有的参数,且已有参数个数未知。
传统解决方式:
var abs = function (a, b) {
console.log(a);
console.log(b);
if (arguments.length > 2) {
for (let i = 2; i < arguments.length ; i++) {
console.log(arguments[i]);
}
}
}
console.log(abs(12, 43, 23, -435,10));
新的解决方式:
reset
:获取除了已经定义了的其他参数- ES6引入的新特性
- rest接收的是可变参数,只能写在最后面,必须用…标识
var abs = function (a, b,...rest) {
console.log(a);
console.log(b);
for (let x of rest) {
console.log(x)
}
}
console.log(abs(12, 43, 23, -435,10));
4.2 变量作用域
作用域
以下报错说明,var定义变量实际是有作用域的。
假设在函数体中声明,则在函数体外不可以使用!(闭包)
function f(x) {
var a = 1;
var b = 2;
console.log(a * b * x);
}
console.log(a);//Uncaught ReferenceError: a is not defined
如果两个函数使用了相同的变量名,不影响
function f(x) {
var a = 1;
var b = 2;
console.log(a * b * x);
}
function g(x) {
var a = 10;
var b = 20;
console.log(a * b * x);
}
console.log(f(10));
console.log(g(10));
内部函数可以访问外部函数的变量,反之不可(外部不可以访问内部变量)
function f(x) {
var a = 1;
function g() {
var b = 10;
console.log("内部引用外部的:" + a);
}
g()
console.log("外部引用内部的:" + b);//Uncaught ReferenceError: b is not defined
}
假设内部函数变量名与外部函数变量名,重名
- 在JavaScript中函数查找变量名是从函数自身开始,由“内”向“外”查找
- 假设在函数外部存在重名的函数变量,则内部函数会屏蔽外部函数的同名变量
function f(x) {
var a = 1;
function g() {
var a = 10;
console.log("内部:" + a);//10
}
console.log("外部:" + a);//1
g()
}
提升变量的作用域:
说明:js执行引擎,自动提升了b的声明,但是不会提升变量b的赋值。
这是在js建立之初就存在特性,故要
养生规范:所有的变量定义都要放在函数头部,不要乱放,便于代码维护。
function f(x) {
var a = 1;
console.log(a + b);//NaN
var b = 10;
}
//上面等价于下面,即会自动把b的定义提前,但是赋值位置不会改变
function g(x) {
var b;
var a = 1;
console.log(a + b);//NaN
b = 10;
}
全局函数:
//全局变量
x = 1;
function g() {
console.log(x);
}
g();
全局对象window:
默认所有全局变量都会默认绑定在window
对象下。
//全局变量
x = 1;
alert(x);
//默认所有全局变量都会默认绑定在windows对象下。
alert(window.x);//与上面等价
alert()本身也是一个window的变量
//全局变量
x = 1111;
alert(x);
//默认所有全局变量都会默认绑定在windows对象下。
alert(window.x);//与上面等价
window.alert(x);
var old_alert = window.alert;
old_alert(x);
//自定义一个变量,覆盖了原始的alert变量
window.alert = function () {
};
window.alert(123);//发现alert失效
//恢复
window.alert = old_alert
window.alert(456)//可以弹出
说明JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,到window全局对象;如果在全局作用域都没找到,报错ReferenceError!
规范:
由于我们所有的全局变量都会绑定到window上,如果不同的js文件,使用了相同的全局变量,冲突->冲突—>如何减少冲突?
解决方式:把自己的代码全部放入自己定义的唯一命名空间中,降低全局命名冲突。
jQuery就是这样实现的。
//设置命名空间
var song = {};
//定义全局变量、函数等(无需var,直接通过自己创建命名空间)
song.a = 10;
song.b = 100;
song.add = function (a, b) {
return a + b;
}
局部作用域let:
原始var存在问题:
function f(){
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i+1);//发现的问题:i出了内部作用域,仍然可以使用
}
f()
ES6 let
关键字可以解决局部作用域冲突
function f(){
for (let i = 0; i < 10; i++) {
console.log(i);
}
console.log(i+1);//Uncaught ReferenceError: i is not defined
}
f()
建议都使用let去定义局部作用域的变量!
常量const
在ES6之前,如何定义常量:只有用全部大写字母命名的变量就是常量,建议不要修改这样的值。(只能是人为的遵守约定,但是可以修改)
var PI = 3.14;
console.log(PI);
PI = 10.894;//可以修改
console.log(PI);
ES6中引入了常量关键字 const
const PI = 3.14;//只读
console.log(PI);
PI = 10.894;//不可以修改,Uncaught TypeError: Assignment to constant variable.
4.3 方法
定义方法
方法就是把函数放在对象的里面,对象只有两个东西:属性和方法。
var stu = {
name: "zhangsna",
birth: 2020,
//方法
age: function () {
var now = new Date().getFullYear();
return now - this.birth;
}
}
console.log(stu.age())
//属性
stu.name
//方法,一定要带括号
stu.age()
this代表什么?对上面代码做拆分
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;//单独调用时,this指的是window,没有birth属性
}
var stu = {
name: "zhangsna",
birth: 2020,
//方法
age: getAge//内部只写函数名即可,代表方法名
}
console.log(stu.age())//2
console.log(getAge())//NaN
this是无法指向的,是默认指向调用它的那个对象。
apply:
在js中可以控制this指向
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var stu = {
name: "zhangsna",
birth: 2020,
//方法
age: getAge
}
//getAge.apply(stu,[]);//表明将this指向了stu,参数为空
console.log(stu.age())//2
console.log(getAge.apply(stu,[]))//2
5. 内部对象
标准对象:
typeof 123
'number'
typeof "abc"
'string'
typeof true
'boolean'
typeof NaN
'number'
typeof []
'object'
typeof {}
'object'
typeof Math.abs
'function'
typeof undefined
'undefined'
5.1 Date
基本使用:
var now = new Date();
console.log(now);//当前时间Sat Mar 05 2022 15:36:51 GMT+0800 (中国标准时间)
now.getFullYear();//年
now.getMonth();//月
now.getDate();//日
now.getDay();//星期几
now.getHours();//时
now.getMinutes();//分
now.getSeconds();//秒
now.getTime();//时间戳 全世界统一 1970.1.1 0:00:00开始的毫秒数
//时间戳转回本地时间
console.log(new Date(1646466049251));
console.log(now.toLocaleString());//转成本地时间的方法
5.2 JSON
早起所有数据传输都用XML文件。
json是什么?
- JSON(JavaScript Object Notation,JS对象简谱)是一种轻量级的数据交换格式。
- 简洁和清晰的层次结构使得JSON成为理想的数据交换语言。
- 易于阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JavaScript一切皆为对象,任何js支持的类型都可以用JSON来表示,包括数字、字符
格式:
- 对象都用{}
- 数组都用[]
- 所有键值对都用key:value
JSON字符串和JS对象的转化
var user = {
name: "song",
age: 23,
sex: "女"
}
//1.对象转成JSON字符串
var jsonuser = JSON.stringify(user);//'{"name":"song","age":23,"sex":"女"}'
//2.JSON字符串转成对象,参数为json字符串
var obj = JSON.parse('{"name":"song","age":23,"sex":"女"}');
结果:
user
{name: 'song', age: 23, sex: '女'}age: 23name: "song"sex: "女"[[Prototype]]: Object
jsonuser
'{"name":"song","age":23,"sex":"女"}'
obj
JSON个JS对象的区别:
//js对象
var obj = {a:"hello a",b:"hello b"};
//JSON,是一个字符串,里面用双引号,外面字符串就用单引号,要区分开
var json = '{"a":"hello a","b":"hello b"}';
5.3 Ajax
- 原生的js写法,xhr异步请求
- jQuery封装好的方法 $(#name"").ajax("")
- axios请求
6. 面向对象编程
6.1 原型对象
javascript、java、c#…都可以面向对象;但是javascript有一些区别。
- 类:模板(js中叫原型对象)
- 对象:具体的实例
在javascript这个需要大家换一下思维方式!
原型:
(类似指明继承的父类,指定原型后,可以继承其属性与方法)
var stu = {
name: "song",
age: 23,
sex: "女",
run: function () {
console.log(this.name + " is running!");
}
};
var zhangsan = {
name: "zhangsan"
};
//原型对象
//张三的原型是stu,可以继承其的方法属性
zhangsan.__proto__ = stu;
console.log(zhangsan.run());
console.log(zhangsan.age);
var Bird = {
fly: function () {
console.log("It is flying!");
}
};
//改变张三的原型是Bird,可以继承其的方法属性
zhangsan.__proto__ = Bird;
console.log(zhangsan.fly());
ES6之前定义一个类??
function Student(name) {
this.name = name;
}
//给Student新增一个hello方法,找到其原型再新增
Student.prototype.hello = function () {
alert("hello world!");
}
6.2 class对象
class继承:
class
关键字是在ES6引入的
1、定义一个类,属性、方法
//ES6之后
//定义一个学生的类
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('hello world!');
}
}
//定义一个学生对象
var stu1 = new Student("zhangsan");
stu1.hello();
2、继承
//ES6之后
//定义一个学生的类
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('hello world!');
}
}
//继承
class XiaoStudent extends Student {
constructor(name, grade) {
super(name);
this.grade = grade;
}
myGrade() {
alert(this.name+"的成绩是:" + this.grade);
}
}
//定义一个学生对象
var stu1 = new Student("zhangsan");
stu1.hello();
var stu2=new XiaoStudent("lisi",100);
var stu3=new XiaoStudent("wangwu",98);
stu2.myGrade();
stu3.myGrade();
本质:查看对象原型,还是利用的原型对象,但是更易理解。
6.3 原型链
7. 操作BOM对象(重点)
7.1 浏览器介绍
B:浏览器
BOM:浏览器对象模型
JavaScript和浏览器关系?
JavaScript诞生就是为了能让它再浏览器中运行!
浏览器内核:
- IE
- Chrome
- Safari
- FireFox:Linux
三方浏览器:(用的还是上面的内核)
- QQ浏览器
- 360浏览器
7.2 操作浏览器
window:
window代表浏览器窗口
window.innerHeight
2572
window.innerWidth
441
window.outerHeight
643
window.outerWidth
110
//可以调整浏览器窗口再试试
Navigator:
Navigator,封装了浏览器的信息
navigator.appName
'Netscape'
navigator.appVersion
'5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Mobile Safari/537.36 Edg/98.0.1108.62'
navigator.platform
'Win32'
navigator.userAgent
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Mobile Safari/537.36 Edg/98.0.1108.62'
大部分情况下不会使用navigator
对象,因为会被人为修改。不建议使用这些属性和判断来编写代码。
screen:
代表屏幕尺寸
screen.height
685
screen.width
650
location(重要):
location代表当前页面的URL信息
host: "localhost:63342"
hostname: "localhost"
href: "http://localhost:63342/JavaScript_Study/lesson01/js/5.%E5%87%BD%E6%95%B0.html?_ijt=d9eo45thisp1ihfd074mflom4a&_ij_reload=RELOAD_ON_SAVE"
origin: "http://localhost:63342"
pathname: "/JavaScript_Study/lesson01/js/5.%E5%87%BD%E6%95%B0.html"
port: "63342"
protocol: "http:"
reload: ƒ reload()//刷新网页
//设置新的地址:让当前网页跳转到指定地址
location.assign("https://www.taobao.com/")
document(内容):
document代表当前的页面,HTML、DOM文档树
document.title
'淘宝网 - 淘!我喜欢'
document.title="song"
'song'
document.title
'song'
能够获取具体的文档树节点
<dl id="app">
<dt class="title">Java</dt>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>
<script>
var dl = document.getElementById("app");
console.log(dl);
</script>
能够获取到网页cookie
document.cookie
''
劫持cookie原理:www.taobao.com
登录过程中的信息存储在cookie中;恶意获取cookie上传到它的服务器。
服务器端可以设置cookie:httpOmly来保证安全。
history:
history代表浏览器的历史记录
history.back()//后退网页
history.forward()//前进网页
8. 操作DOM对象(重点)
DOM:文档对象模型。
浏览器网页就是一个DOM树形结构!
- 更新:更新Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
要操作一个Dom节点,就必须先获得这个Dom节点。
获得Dom节点:
div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
//对应CSS选择器
var h1 = document.getElementsByTagName("h1");//通过标签获得
var p1 = document.getElementById("p1");//通过id获得
var p2 = document.getElementsByClassName("p2");//通过class获得
var father = document.getElementById("father");
var childrends = father.children;//获取父节点下的所有节点
var firstchild = father.firstChild;
var lastchild = father.lastChild;
</script>
这是原生代码,之后尽量使用jQuery()
更新节点:
- 操作文本
- 操作js
<div id="id1"></div>
<script>
//对应CSS选择器
var id1 = document.getElementById("id1");
//操作文本
id1.innerText = "123";//修改文本的值
id1.innerHTML = '<strong>789</strong>';//解析HTML文本标签
//操作js,注意属性值使用字符串包裹;属性名驼峰命名
id1.style.color = "red";//设置属性
id1.style.fontSize = "30px";
id1.style.padding = "2em";
</script>
删除节点:
删除节点的步骤:先获取父节点,再通过父节点删除自己。
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
//1.先获取要删除的节点
var p1 = document.getElementById("p1");
//2.通过要删除的节点获得其父节点
var father = p1.parentElement;
//3.通过父节点删除子节点
father.removeChild(p1);
//删除是一个动态的过程:删除多个节点的时候,children是在时刻变化的
father.removeChild(father.children[0]);//生效删除的是指定目标
father.removeChild(father.children[1]);//指定目标的位置已经改变
father.removeChild(father.children[2]);
</script>
注意:删除多个节点的时候,children是在时刻变化的!
插入节点:
我们获得了某个Dom节点,假设这个Dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是这个Dom就已经存在元素了,我们就不能这么干了!会产生覆盖。
追加已经存在的节点
<p id="js">JavaScript</p>
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>
<script>
var js = document.getElementById("js");
var list = document.getElementById("list");
list.appendChild(js);//追加到后面
</script>
效果:
创建新的节点,实现追加:
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>
<script>
//getElementById()返回的是一个唯一的指定元素
var js = document.getElementById("js");
var list = document.getElementById("list");
//通过JS创建一个新节点
var newP = document.createElement('p');//创建一个p标签
newP.id = "newP";//为新创建的元素设置属性
newP.setAttribute('id', 'newP');//等价与上面,是公用的写法
newP.innerText = "Hello World";
list.appendChild(newP);//追加到已有的父节点
//创建一个标签节点
var myScript = document.createElement("Script");//创建一个Script标签
//setAttribute()方法是设置属性的万能方式
myScript.setAttribute('type', 'text/javascript');//设置属性值
list.appendChild(myScript);
//getElementsByTagName()返回的是一个集合
var p = document.getElementsByTagName("p");//
var body = document.getElementsByTagName("body");//返回的是一个集合
body[0].style.background = "red";//对于唯一的body标签来说,他就是数组的第一个元素
</script>
效果:
创建新的节点,实现插入到前面:
<p id="js">JavaScript</p>
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>
<script>
var list = document.getElementById('list');
var ee = document.getElementById('ee');
var js = document.getElementById('js');
//要包含的节点.insertBefore(newNode,target)---把新节点插入到目标节点前面
list.insertBefore(js, ee);//通过父节点把js插入到ee前面
</script>
jQuery推荐的学习网站:
https://jquery.cuishifeng.cn/
9. 操作表单(验证)
表单是什么?
form 来自DOM树
- 文本框 text
- 下拉框 select
- 单选框 radio
- 多选框 checkbox
- 隐藏域 hidden
- 密码框 password
- …
表单的目的:提交信息
获得表单提交的信息:
<form action="post">
<p>
<span>用户名:</span>
<input type="text" id="username">
</p>
<!--单选框、多选框的值都是定义好的value-->
<p>
<span>性别:</span>
<input type="radio" name="sex" value="man" id="boy">男
<input type="radio" name="sex" value="woman" id="girl">女
</p>
</form>
<script>
var input_text = document.getElementById("username");
var boy = document.getElementById('boy');
var girl = document.getElementById('girl');
//得到输入框中的值
input_text.value
//修改输入框中的值
input_text.value = "123user";
//对于单选框、多选框等固定的值,.value只能取到固定赋予的值,与选中的值无关
boy.value;//man
girl.value;//woman
//获取单选框、多选框选中的值,只能根据是否选中来判断
boy.checked;//true false
girl.checked;//true false
//设定是否选中,赋值
boy.checked = true;
</script>
提交表单:
<!--1.表单级别的提交:onsubmit 方式 绑定一个函数-->
<form action="https://hao.360.com/" method="post" onsubmit="aaa()">
<!-- 必须要有name属性,提交的值才能抓取到 -->
<p>
<span>用户名:</span>
<input type="text" id="username" name="username">
</p>
<p>
<span>密码:</span>
<input type="password" id="password">
<!-- 必须要有name属性,提交的值才能抓取到 ,对于真实的密码不设置name属性,则post中就不会获取到-->
<input type="hidden" id="md5-password" name="password">
<!-- 抓取到的是加密后的密码 -->
</p>
<!--2.按钮级别的提交:按钮 绑定事件 onclick 被点击 -->
<!-- <button type="submit" οnclick="aaa()">提交</button>-->
<button type="submit">提交</button>
</form>
<script>
function aaa() {
var username = document.getElementById('username');
var password = document.getElementById('password');
var md5pwd = document.getElementById('md5-password');
//md5pwd.value=md5(password);//通过md5算法对真实密码进行加密,提交的是加密后的密码
md5pwd.value = "*****"
console.log(username.value);
console.log(password.value);
//可以校验表单内容,true就是通过提交;false就是阻止提交
return true;
}
</script>
10. jQuery
JavaScript
jQuery是一个库,里面存在大量JavaScript的函数(即封装了很多)
获取jQuery:在线的 or 下载的
https://jquery.com/download/
https://jquery.cuishifeng.cn/
https://www.jq22.com/cdn/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- cdn导入,在线的 -->
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<!-- 本地导入 -->
<script src="lib/jquery-3.6.0.min.js"></script>
</head>
<body>
</body>
</html>
jQuery的使用公式:
公式: $(selector选择器).action()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- cdn导入,在线的 -->
<!-- <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>-->
<!-- 本地导入 -->
<script src="lib/jquery-3.6.0.min.js"></script>
</head>
<body>
<!--公式: $(selector).action()-->
<a href="" id="test-jQuery">点我</a>
<a href="" id="test-jQuery2">点我2</a>
<script>
//方式一:原始的获取元素、使用方法等
var test = document.getElementById('test-jQuery2');
test.click()
//方式二:使用jQuery
//选择器就是css的选择器
$('#test-jQuery').click(function () {
alert("hello world!");
})
</script>
</body>
</html>
选择器selector:
//原生js,选择器少,麻烦不好记
//标签选择器
document.getElementsByTagName();
//id选择器
document.getElementById();
//类选择器
document.getElementsByClassName();
//jQuery css中的所有选择器都可以使用
$('p').click()//标签选择器
$('#id').click()//id选择器
$('.class').click()//class选择器
文档工具:
https://jquery.cuishifeng.cn/
事件action:
鼠标事件、键盘事件、其他事件
- mousedown() 鼠标按下
- mousemove() 鼠标移动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.6.0.js"></script>
<style>
#divMove {
width: 500px;
height: 500px;
border: 1px solid red;
}
</style>
</head>
<body>
<!--要求:获取鼠标当前的一个坐标-->
mouse: <span id="mouseMove"></span>
<div id="divMove">
在这里移动鼠标试试
</div>
<script>
//当网页元素加载完毕之后,响应事件
//$(document).ready(function (){});
//对以上加载事件的简化形式
$(function () {
$(`#divMove`).mousemove(function (e) {
//提示:获取选择器是一定要完全与CSS相同,不要忘记#id .class p等的符号
$('#mouseMove').text('x:' + e.pageX + '; y:' + e.pageY);
});
});
</script>
</body>
</html>
发现的问题:
jquery-3.6.0.min.js中不含有mousemove函数
jquery-3.6.0.js中有mousemove函数
操作DOM
节点文本操作:
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="python">Python</li>
</ul>
<script>
//原始直接通过js修改DOM的方式
/*var js = document.getElementsByClassName('js');
js[0].textContent = "js.....";*/
//通过jQuery修改DOM的方式
$('.sjs').text("JavaScript is good!");
$(`#test-ul li[name='python']`).text();//无参数获得值
$(`#test-ul li[name='python']`).text('python is good');//有参数设置值
$('#test-ul').html();//获得值
$('#test-ul').html('<span>123<span>');//设置值
</script>
CSS操作:
$(`#test-ul li[name='python']`).css({ "color": "#ff0011", "background": "blue" })//修改css样式,多个键值对
元素的显示隐藏:display:none;
$('.js').show();//显示
$('.js').hide();//隐藏
未来:ajax()
$('#form').ajax();
小技巧:
1、如何巩固JS?(看jQuery源码,看游戏源码!)
2、巩固HTML、CSS(扒网站,全部down下来,然后对应修改看效果)
Layer 弹窗组件
Element UI