Javascript快速入门
1 JavaScript
-
JavaScript 和 Java 是完全不同的语言。相似的只有那四个字母。
-
语法相较于Java 很随意。
-
解释型或即时编译型的 编程语言。
-
支持面向对象。
2 数据类型
2.1 数据类型(概览)
2.1.1 定义变量
//var 定义的是局部变量,作用域为整个函数
var num = 1; //定义什么都可以var
var s = 'hello, world'; // 可以不写分号
//let 定义的也是局部变量,作用域为一个块
let num = 1;
let s = 'hello, world';
//默认为全局变量,不推荐这样写
num = 1;
s = 'hello, world';
2.1.2 数字:
666 //数字都知道
NaN //not a number
Infinity //无限大
2.1.3 字符串:
// 单引号括起来,双引号也可以
'hello';
'abc';
2.1.4 布尔值
// true, false
2.1.5 数组
var arr = [1, 2, 3, 'hello', true, null];
//不必同类型
var array = new Array(1, 2, 3, 'hello', true, null);
//打印数组
console.log(arr);
console.log(array);
//打印某个元素arr[index]即可
2.1.6 对象
//数组用中括号,对象用大括号
var Person = {
name: 'hello',
age: 18
}
console.log(Person.name); //输出 hello
2.1.7 null 和 undefined
// null 是空
// undefined 未定义
2.1.8 逻辑运算
&& //都为真为真
|| //一个为真即为真
! //真即假, 假即真
2.1.9 比较运算符
= //赋值
== //等于(类型不一样,值一样则为true)
=== //绝对等于(类型一样,值一样才为true)
-
NaN与所有数值都不相等,包括自己。
-
判断是否为NaN 则用isNaN()
-
浮点数会有精度损失。
判断两个浮点数是否相等
思路:相减绝对值小于一个很小的数。
console.log((Math.abs((1 / 3) - (1 - (2 / 3))) < 0.000000001)); //输出true
2.2 严格语法检查
//在js代码第一行加上一句use strict
'use strict'
i = 1; //此时这句会报错,以及其他不严谨的语法也会报错
//ES6标准
2.3 数据类型
2.3.1 字符串
- 正常字符串,使用 单引号 或 双引号 包裹
- 转义字符如同其他语言一样 ‘\’ + 对应的码
- 长字符串用反引号 " ` " 包裹
- 模板字符串 ‘ $ ‘
var s1 = 'hello, world'; //正常字符串
var s2 = '\x41'; // ASCII码 \x**表示 16进制 \*** 表示八进制
var s3 = `hello
world
666`; //长字符串输出包含其中的换行和]\t
// 模板字符串
var name = 'abc';
var s4 = `iam ${name}`; //会输出iam abc
字符串长度
-
字符串会有个length属性记录字符串长度。
-
字符串可以像数组一样通过下标取对应的字符。
-
字符串不可变
字符串常用方法
- toUpperCase()、toLowercase()
- indexOf()、charAt()
- substring();
<script>
'use strict'
let s = 'teacher';
s.toUpperCase();
console.log(s); // 仍然输出teacher,字符串不可变
console.log(s.toUpperCase()); // 输出TEACHER
console.log(s.indexOf('c')); // 3
console.log(s.charAt(3)); // c
console.log(s.substring(1)); // eacher
console.log(s.substring(1,3)); // ea
</script>
2.3.2 数组
数组常用方法
- Array可以包含任意的数据类型。
- Array有length属性,这个length是可以改变的。
- indexOf(), 通过元素获得下标索引。
- slice(), 和字符串的substring()相似,slice()可以截取数组的一部分, 返回一个新数组。
- push(), pop(), 在数组的末尾 压入、弹出数据。如同数据结构中的栈。 返回值为数组的长度。
- unshift(), shift(), 在数组的头部添加、删除元素。返回值为数组的长度。
- concat(), 数组连接,没有修改数组,返回值为连接好的数组。
- join(), 使用特定的字符连接数组。
var arr = [1, 2, 3, 'hello', null, true, NaN, undefined, Infinity]; //可以包含任何元素
//arr.length = 20; //多出来的长度里面为undefined
//arr.length = 2; //赋值过小 那么会导致2后面的元素都会丢失
arr.indexOf(null); // 4
arr.indexOf(undefined); // 7
arr.indexOf(Infinity); // 8
arr.indexOf(NaN); // -1
arr.slice(2); // [3, 'hello', null, true, NaN, undefined, Infinity]
arr.slice(3, 5); // ['hello', null]
arr.push('abc'); // [1, 2, 3, 'hello', null, true, NaN, undefined, Infinity, 'abc']
arr.unshift('666'); // ['666', 1, 2, 3, 'hello', null, true, NaN, undefined, Infinity, 'abc']
arr.pop(); // ['666', 1, 2, 3, 'hello', null, true, NaN, undefined, Infinity]
arr.shift(); // [1, 2, 3, 'hello', null, true, NaN, undefined, Infinity]
var array = [1, 2, 3];
arr.concat(array); // [1, 2, 3, 'hello', null, true, NaN, undefined, Infinity, 1, 2, 3]
arr.join('-'); // 1-2-3-hello--true-NaN--Infinity
多维数组
JavaScript中不像java那样
int[][] arr = new int[3][3];
就定义了一个二维数组。
JavaScript中是这样定义的:
var arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
/* [1, 2, 3]
[4, 5, 6]
[7, 8, 9] */
arr[1][1]; // 5
2.3.3 对象
- 对象的属性是若干个键值对
var 对象名 = {
属性名 : 属性值,
属性名 : 属性值,
属性名 : 属性值,
}
// 定义了一个有四个属性的Person对象
var Person = {
name : 'a',
age : 3,
email : '877602782@qq.com',
score : 0
}
//属性赋值
Person.name = 'abc';
//使用一个不存在的属性
console.log(Person.uuu); // undefined
- JavaScript中,数组用中括号,对象用大括号,键值对描述属性,每个属性用逗号隔开,最后一个不加逗号。
- 动态的删除添加属性
delete Person.name; //true
//添加
Person.uuu = '123';
- 判断属性是否在对象中
'age' in Person; // true
Person['age']; // 3
- 对象中所有的键都是字符串, 值是任意类型
- 同样的JavaScript中也有继承, 若是要判断是否为自己独有的属性,则调用hasOwnProperty()方法。
'toString' in Person; // true
Person.hasOwnProperty('toString'); // false
Person.hasOwnProperty('age'); // true
3 流程控制
拥有其他语言的基础,这部分是一样的。
3.1 分支
if判断
var num = 5;
if (num < 5) {
console.log('num 小于 5');
} else if (num > 5) {
console.log('num 大于 5');
} else {
console.log('num 等于 5');
}
// 输出 num 等于 5
没什么好说的,遇到复杂的判断需要注意的就是 else 永远与它前面最近的 if 配对
3.2 循环
1. while循环
var num = 0;
while (num < 100) {
num++; // num = num + 1
}
console.log(num); // 100
2. do-while循环
var num = 0;
do {
num++;
} while (num < 100);
console.log(num); // 100
和while不同的是, 无论是否为true,都要执行一次循环体。
3. for循环
var num = 0;
for (num = 0; num < 100; num++) {
;
}
console.log(num); // 100
for 和 while 可以相互转换。
for里面有个注意的点,若是要遍历
for (let i = 0; i < 100; i++);
// for 运行完后, i就不在了
for 运行完后, i就不在了,如同java中的
for (int i = 0; i < 100; i++);
同样,JavaScript中也有 for-each 循环, 有三种:
var arr = [1, 2, 3, 4, 5, 6];
arr.forEach(function (num) {
console.log(num); // 会将arr里的元素逐个输出
})
// 第二种更像java中的for-each
var arr = [1, 2, 3, 4, 5, 6];
for (let num in arr) {
console.log(arr[num]); // 会将arr里的元素逐个输出
}
// 第三种只能说一模一样(ES6新特性)
var arr = [1, 2, 3, 4, 5, 6];
for (let num of arr) {
console.log(num); // 会将arr里的元素逐个输出
}
4 集合
- Map 和 Set ES6支持
4.1 Map
和java一样 就是 一堆 键值对 key = value 的形式
// 创建方式一:
var map = new Map([
[1, '一元'],
[2, '二元'],
[5, '五元']
]);
//创建方式二:
var map = new Map();
map.set(1, '一元');
map.set(2, '二元');
map.set(5, '五元');
console.log(map); // Map(3) {1 => '一元', 2 => '二元', 5 => '五元'}
// 通过key得到对应的value
map.get(5); // 五元
// 得到键值对迭代器
map.entries(); .// MapIterator {1 => '一元', 2 => '二元', 5 => '五元'}
// 得到key迭代器
map.keys(); // MapIterator {1, 2, 5}
// 得到value迭代器
map.values(); // MapIterator {'一元', '二元', '五元'}
// Map有size属性
map.size; // 3
4.2 Set
特点:像Java里的Set一样, 无序, 不重复 。
这里的无序指的是没有下标,和java不太一样,JavaScript中的Set虽然没有下标,但是是有序的,顺序为插入的顺序。
可以把Set看作是没有value的Map,因为Map中key不能重复,所以Set中元素不能重复。
// 创建方式一:
var set = new Set([3, 1, 2, 1, 2]); // 元素不能重复,实际上为 Set(3) {3, 1, 2}
// 创建方式二:
var set = new Set();
set.add(3);
set.add(1);
set.add(2);
// 删除某个元素
set.delete(3); // true 集合为 Set(2) {1, 2}
// 判断某个元素在不在集合中
set.has(3); // false
set.has(2); // true
4.3 Iterator
使用for-of遍历 Array、Map、Set
var arr = [3, 1, 2, 1, 2];
for (let num of arr) {
console.log(num); // 输出 3 1 2 1 2
}
var map = new Map([[3, 4], [1, 2], [2, 3]]);
for (let item of map) {
console.log(item); // 输出 [3, 4] [1, 2] [2, 3]
}
var set = new Set([3, 1, 2, 1, 2]);
for (let item of set) {
console.log(item); // 输出 3 1 2
}
5 函数
- 和其他语言的函数没有多大区别
5.1 定义与调用
5.1.1 定义
方式一:
function 函数名(形参) {
函数体
}
//和Java不一样的是,不需要写返回值类型。如果需要返回值,直接return
// 无返回值
function myF() {
console.log('my first function');
}
// 有返回值
function myF2() {
return 'my first function';
}
// 遇到return表示函数结束,返回值为undefined
function myF3() {
return;
}
方式二:
var 函数名 = function(形参) {
函数体
}
// 就是形式变了一下,换汤不换药
// 无返回值
var myF = function() {
console.log('my first function');
}
// 有返回值
var myF2 = function() {
return 'my first function';
}
// 遇到return表示函数结束,返回值为undefined
var myF3 = function() {
return;
}
5.1.2 调用
-
调用和Java没什么两样
myF(); //输出 my first function console.log(myF2()); //输出 my first function console.log(myF3); //输出 undefined
5.2 传参问题
5.2.1 没有参数和多个参数
JavaScript很自由
function printX(x) {
console.log(x);
}
//以下调用都是不报错的
printX(); // undefined
printX(55, 66); // 55
printX(NaN); // NaN
printX('hello', 1, 2, 3, 4); // hello
可以看到,不传参数为undefined 多个参数只取需要的前n个。
但是可以手动 ‘报错’, 和Java的抛出异常很像
function printX(x) {
if (x === undefined)
throw 'nothing';
console.log(x);
}
printX(); // 报错
5.2.2 arguments
-
是JavaScript中的关键字,代表的是传进来的所有参数。
function printX(x) { console.log(arguments); } printX(1, 2, 3, 4, 5); //输出 Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ] //还可以像数组一样通过下标取值 function printX2() { console.log(arguments[2]); } printX2(1, 2, 3, 4, 5); //输出 3
5.2.3 可变参数 rest
- ES6新特性, 只能写在最后面。
function printX(x, ...rest) {
console.log(rest);
}
printX(1, 2, 3, 4, 5); // 输出 [2, 3, 4, 5]
5.3 变量作用域
5.3.1 var
-
var 定义的变量,是局部变量
function myF() { var x = 1; } x += 2; // 报错, x 未定义
-
JavaScript中函数可以嵌套定义,并且内部函数可以访问外部的var,外部无法访问内部的var,说明了var定义的变量的作用域是整个函数。
function myF() { var x = 1; function myY() { var y = x + 1; console.log(y); } myY(); } myF(); //输出 2 // 但这样会报错 function myF() { var x = 1; function myY() { var y = x + 1; console.log(y); } myY(); var z = y + 1; } myF(); //输出 2 并报错 y is not defined
-
若内部函数变量和函数中变量重名,则由内向外查找。
function myF() { var x = 1; function myY() { var x = 2; console.log(x); // 2 } myY(); console.log(x); // 1 } myF();
5.3.2 全局变量
-
如果一个变量什么声明都没有,那么它是全局变量,不过不建议这样写,如果用严格语法检查,这样会报错
'use strict' i = 1; // 报错
解决方法是 var 一个变量 写在最上面
-
所有全局的东西都在 window 下
var i = 1; console.log(i); // 1 console.log(window.i); // 1 alert(i); //等价于 window.alert(i);
难受的是,JavaScript只有一个全局 window,如果引入多个JavaScript文件,就可能会出现冲突。解决方法为,定义一个自己的全局。
// 定义一个我的全局
var myJS = {};
// 定义全局变量
myJS.i = 1;
myJS.s = 'hello';
myJS.f = function() {
return this.i + this.s;
}
把自己的代码放入自己定义的唯一空间名字中,降低全局命名冲突的问题。
5.3.3 let
-
ES6 新特性
-
let定义的变量作用域为一个块,也就是一个大括号,常用在for中,解决局部命名冲突的问题
for (var i = 0; i < 10; i++) { ; } console.log(i); // 输出 10 for (let i = 0; i < 10; i++) { ; } console.log(i); // undefined
5.3.4 常量
ES6之前,定义常量只是将变量名大写。
ES6 引入关键字 const
//ES6 之前
var PI = 3.1415926;
//ES6
const PI = 3.1415926;
5.4 方法
函数在对象里面就是方法。
5.4.1 定义与调用
// 定义方法
var XiaoMing = {
name: 'xiaoming',
birth: 2001,
age: function() {
var now = new Date().getFullYear(); // 2022
return now - this.birth;
}
}
// 调用方法
console.log(XiaoMing.age()); // 21
5.4.2 this 关键字
用起来和Java的感觉差不多,表示当前对象的一个引用。
比如上一段代码的第八行,this.birth 就表示的是当前对象中的birth。
5.4.2 apply()方法
通过apply()方法,可以改变 this 的指向。
方式一:
// 定义方法
var XiaoMing = {
name: 'xiaoming',
birth: 2001,
age: function() {
var now = new Date().getFullYear(); // 2022
return now - this.birth;
}
}
var XiaoHong = {
birth: 2000
}
// 调用方法
console.log(XiaoMing.age()); // 21
console.log(XiaoMing.age.apply(XiaoHong)); // 22
方式二:
// 定义方法
var age = function() {
var now = new Date().getFullYear(); // 2022
return now - this.birth;
}
var XiaoMing = {
name: 'xiaoming',
birth: 2001,
}
var XiaoHong = {
birth: 2000
}
// 调用方法
console.log(age.apply(XiaoMing, [])); // 21
console.log(age.apply(XiaoHong, [])); // 22
6 标准内置对象
JS中一切都是对象
typeof 123 'number' typeof '123' 'string' typeof [12, 23] 'object' typeof undefined 'undefined' typeof NaN 'number' typeof {} 'object' typeof Math.abs() 'number' typeof null 'object' typeof true 'boolean'
6.1 Date
Date对象可以帮助我们获取时间。
// 创建对象
var date = new Date(); // 创建对象
console.log(date); // Sat Mar 19 2022 16:29:14 GMT+0800 (中国标准时间)
// 年
date.getFullYear(); // 2022
// 月
date.getMonth(); // 2 (这里是0~11,真实月份需要再加上1)
// 日
date.getDate(); // 19
// 周几
date.getDay(); // 6
// 时
date.getHours(); // 16
// 分
date.getMinutes(); // 29
// 秒
date.getSeconds(); // 14
// 时间戳
date.getTime(); // 1647678554475 获取时间戳 1970.1.1 00:00 到现在的毫秒数
new Date(1647678554475); // Sat Mar 19 2022 16:29:14 GMT+0800 (中国标准时间)
date.toDateString(); // Sat Mar 19 2022
//转换成其他时区
date.toGMTString(); // Sat, 19 Mar 2022 08:29:14 GMT
7 JSON
JSON?
JavaScript Object Notation
是一种轻量级的数据交换格式
7.1 JSON语法规则
- 数据在 key/value 对中
- 数据由逗号分隔
- 大括号 { } 保存对象
- 中括号 [ ] 保存数组
7.2 JSON 和 JS对象 转换
var Person = {
name: "abc",
age: 30,
sex: "man"
}
// 对象转换为JSON字符串
var json = JSON.stringify(Person);
console.log(Person); // {name: 'abc', age: 30, sex: 'man'}
console.log(json); // {"name":"abc","age":30,"sex":"man"}
// JSON字符串转化为对象
var p = JSON.parse('{"name":"abc","age":30,"sex":"man"}');
8 面向对象编程
JavaScript中万物皆为对象
JavaScript中的面向对象编程和Java略有不同
JavaScript是一种基于对象(object-based)的语言
8.1 原型继承
Java、C# 中的面向对象:
- 类:模板
- 对象:实例
JavaScript不太一样,JavaScript中有个东西叫 原型。
每个对象都可以有一个原型
原型有继承中的父类那么点意思,先来看一段代码:
var Student = {
name: 'who',
age: 3,
run: function() {
console.log(this.name + ' run run...');
}
}
var XiaoMing = {
name: 'XiaoMing'
}
XiaoMing.__proto__ = Student;
XiaoMing.run(); // 输出 XiaoMing run run...
console.log(XiaoMing.age); // 输出 3
这段代码表示 XiaoMing的原型是Student,继承 了Student的run()方法,还继承了Student的其他属性。
8.2 class
class
关键字是ES6新特性,写法更为规范,更容易后端人员理解。
8.2.1 构造方法
和Java像又不像
ES6之前是这样的:
function Student(name) {
this.name = name;
}
// 若要新增属性/方法,需要把新增的属性添加到原型上
Student.prototype.run = function() {
alert(this.name + ' run run');
}
var s = new Student('XiaoMing');
console.log(s.name); // XiaoMing
s.run(); // 弹出 XiaoMing run run
这个时候是通过函数来创建对象,只有new了,这个函数才叫做构造方法,不然就只是个普通函数。 当作普通函数时,name就成了全局变量,不太好。
ES6之后对后端人员就又好了许多:
class Student {
constructor(name) {
this.name = name;
}
run() {
alert(this .name + ' run run');
}
}
var s = new Student('XiaoMing');
console.log(s.name); // XiaoMing
s.run(); // 弹出 XiaoMing run run
效果不能说毫不相干,只能说是一模一样,还规范了许多,后端人员的福音。
8.2.2 继承
class继承的写法和Java很像。
// 接着上面的代码
class BigStudent extends Student {
constructor(name, age) {
super(name);
this.age = age;
}
myAge() {
alert('i am ' + this.age + ' years old');
}
}
var bs = new BigStudent('XiaoHong', 30);
bs.myAge(); // 输出 i am 30 years old
bs.run(); //输出 XiaoHong run run
本质上也是原型继承,通过输出bs发现,bs的prototype是Student。
9 浏览器
BOM(Browser Object Model):浏览器对象模型
DOM (Document Object Model):文档对象模型
9.1 浏览器
摘自廖雪峰:
由于JavaScript的出现就是为了能在浏览器中运行,所以,浏览器自然是JavaScript开发者必须要关注的。
目前主流的浏览器分这么几种:
- IE 6~11:国内用得最多的IE浏览器,历来对W3C标准支持差。从IE10开始支持ES6标准;
- Chrome:Google出品的基于Webkit内核浏览器,内置了非常强悍的JavaScript引擎——V8。由于Chrome一经安装就时刻保持自升级,所以不用管它的版本,最新版早就支持ES6了;
- Safari:Apple的Mac系统自带的基于Webkit内核的浏览器,从OS X 10.7 Lion自带的6.1版本开始支持ES6,目前最新的OS X 10.11 El Capitan自带的Safari版本是9.x,早已支持ES6;
- Firefox:Mozilla自己研制的Gecko内核和JavaScript引擎OdinMonkey。早期的Firefox按版本发布,后来终于聪明地学习Chrome的做法进行自升级,时刻保持最新;
- 移动设备上目前iOS和Android两大阵营分别主要使用Apple的Safari和Google的Chrome,由于两者都是Webkit核心,结果HTML5首先在手机上全面普及(桌面绝对是Microsoft拖了后腿),对JavaScript的标准支持也很好,最新版本均支持ES6。
其他浏览器如Opera等由于市场份额太小就被自动忽略了。
另外还要注意识别各种国产浏览器,如某某安全浏览器,某某旋风浏览器,它们只是做了一个壳,其核心调用的是IE,也有号称同时支持IE和Webkit的“双核”浏览器。
不同的浏览器对JavaScript支持的差异主要是,有些API的接口不一样,比如AJAX,File接口。对于ES6标准,不同的浏览器对各个特性支持也不一样。
在编写JavaScript的时候,就要充分考虑到浏览器的差异,尽量让同一份JavaScript代码能运行在不同的浏览器中。
9.2 BOM
9.2.1 window
- window对象代表浏览器窗口
- 充当全局作用域
可通过window获取一些浏览器的属性:
window.innerWidth // 获取文档显示区的宽度
window.innerHeight // 获取文档显示区的高度
window.outerWidth // 获取一个窗口的外部宽度,包括所有的界面元素
window.outerHeight // 获取一个窗口的外部高度,包括所有的界面元素
9.2.2 navigator
- navigator对象表示浏览器的信息
- 不要对navigator的一些属性进行判断,因为可以被修改
navigator.appName // 浏览器名
navigator.appVersion // 浏览器版本
navigator.language // 浏览器设置的语言
navigator.platform // 操作系统类型
navigator.userAgent // UA头
9.2.3 screen
- screen对象表示屏幕信息
screen.availHeight // 返回不含windows任务栏的屏幕高度
screen.height // 返回屏幕高度
screen.colorDepth // 返回目标设备或缓冲器上的调色板的比特深度
9.2.4 location
- location 对象表示当前页面的URL信息
在百度页面下打印location,几个重要属性:
/*
host: "www.baidu.com"
protocol: "https:"
port: ""
*/
还有几个重要的方法:
//在一个页面中设置
location.assign('url') // 会跳转到目标页面
location.reload(); // 会重新加载当前页面
9.2.5 document
- document对象表示当前页面HTML DOM文档树的根节点。
- 要查找DOM树的某个节点,常用document的getElementById()和getElementsByTagName()方法,DOM中细说。
document.title = '666' // 那么,该网页的标题就变成了666
9.2.6 history
- history对象保存的浏览器的历史记录
history.back(); // 相当于点了后退
history.forward(); // 相当于点了前进
- 因为Ajax的大量使用,history已过时。
9.3 DOM
操作DOM便是JavaScript控制网页行为的核心
9.3.1 操作DOM
- HTML被浏览器解析为一颗DOM树,通过JavaScript对树的节点进行操作来控制网页的行为。
- 因为是树形结构,所以就那么几个操作:增、删、改、查。
9.3.2 获取DOM节点
-
利用document对象获取DOM节点,常用的方法有document.getElementById()、document.getElementsByTagName() 以及 document.getElementsByClassName()。
-
id在HTML文档中是唯一的,document.getElementById()可找到指定的标签。
-
document.getElementsByTagName() 、document.getElementsByClassName()返回的是一组标签。
-
为了精确查找,可以先定位父节点,再查找子节点。
例:
<!-- 有这么个网页 -->
<div id="test-div">
<div class="c-red">
<p id="test-p">JavaScript</p>
<p>Java</p>
</div>
<div class="c-red c-green">
<p>Python</p>
<p>Ruby</p>
<p>Swift</p>
</div>
<div class="c-green">
<p>Scheme</p>
<p>Haskell</p>
</div>
</div>
定位一些元素:
// 选择<p>JavaScript</p>:
var js = document.getElementById('test-p');
// 选择<p>Python</p>,<p>Ruby</p>,<p>Swift</p>:
var arr = document.getElementsByClassName('c-red')[1].children;
// 选择<p>Haskell</p>:
var haskell = document.getElementsByClassName('c-green')[1].lastElementChild;
可以看到几个操作:
- document.getElementsByClassName(‘c-red’)、document.getElementsByClassName(‘c-green’)返回的是数组,所以要加上索引才能精确定位。
- children 获取所有直属子节点
- firstElementchild、lastElementChild 获取第一个、最后一个子节点
9.3.3 更新DOM
- 获取标签后,可以修改标签的一些属性。
有几种常用的更新DOM的方法:
- innerHTML 不仅可以修改文本,还可以添加标签。
- innerText 和 textContent 只能添加文本,不能添加标签,‘<’、‘>’这些符号会被自动编码。
- item.style.xxx 的形式修改样式、要注意的是 类似与font-weight这种命名在JavaScript中要换成小驼峰写法 fontWeight。
现在有一个页面
<div id="test-div">
<p id="test-js">666/p>
<p>javascript</p>
</div>
//1. innerHTML
var js = document.getElementById('test-js');
js.innerHTML = '<h1> 798 </h1>';
/* 那么上面的HTML标签就会变成:
<div id="test-div">
<h1 id="test-js"> 798 </h1>
<p>javascript</p>
</div> */
//2. innerText
js.innerText = '<p> 666 </p>'; //或 js.textContent = '<p> 666 </p>';
/* 那么上面的HTML标签就会变成:
<div id="test-div">
<h1 id="test-js"> <p> 666 </p> </h1>
<p>javascript</p>
</div> */
//3. style.xxx
js.style.color = 'red';
/* 那么上面的HTML标签就会变成:
<div id="test-div">
<h1 id="test-js" style="color: red;"> <p> 666 </p> </h1>
<p>javascript</p>
</div> */
-
可用setAttribute()方法修改属性值
element.Attribut('属性名', '值');
9.3.4 插入DOM
当获取某个DOM节点后,我们就可以对其进行操作。
- 插入节点也有几个方法
<script>
// 若有一组空标签,<div></div>,那么就可以使用innerHTML来替换掉它。
// 如果不是空,则需要使用插入方法
var list = document.getElementById('list');
list.append('666');
/* <p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
666
</div> */
var js = document.getElementById('js');
list.appendChild(js);
/* <div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
666
<p id="js">JavaScript</p>
</div> */
</script>
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
-
一般是创造一个新节点再插入进去。
var tag = document.createElement('p'); tag.id = 'abc'; tag.innerText = 'new tag'; list.appendChild(tag); /* <div id="list"> <p id="java">Java</p> <p id="python">Python</p> <p id="scheme">Scheme</p> 666 <p id="js">JavaScript</p> <p id="abc">new tag</p> </div> */
这些都是插入到末尾的,有没有一种方式能够插入到指定位置呢**?**
- insertBefore
parentElement.insertBefore(newElement, referenceElement); 会把新的节点插入到referenceElement之前。
假如现在要插入一个新的节点到python之前:
var newTag = document.createElement('a');
newTag.href = 'http://www.baidu.com';
newTag.innerText = '百度';
var py = document.getElementById('python');
list.insertBefore(newTag, py);
// 效果如下:
/* <div id="list">
<p id="java">Java</p>
<a href="http://www.baidu.com">百度</a>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
666
<p id="js">JavaScript</p>
<p id="abc">new tag</p>
</div> */
9.3.5 删除DOM
删除比插入容易的多
-
要删除一个节点,首先要获取它的父节点和它本身,再调用父节点的removeChild()方法。
/* <div id="list"> <p id="java">Java</p> <a href="http://www.baidu.com">百度</a> <p id="python">Python</p> <p id="scheme">Scheme</p> 666 <p id="js">JavaScript</p> <p id="abc">new tag</p> </div> */ // 若要删除最后一个p标签 var list = document.getElementById('list'); var removed = document.getElementById('abc'); list.removeChild(removed); // 也可以根据位置来删除 list.removeChild(list.children[1]); //删除第二个子节点 a标签 删除了过后 children的长度也会减一
10 JQuery
10.1 JQuery是什么?
jQuery 是一个 JavaScript 库。
jQuery 极大地简化了 JavaScript 编程。
10.2 JQuery怎么用?
10.2.1 引入jQuery
使用JQuery库的两种方法:
一、到官网下载,导入到项目中
二、用CDN,如:
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
10.2.2 选择器
-
$ 是JQuery的别名,JQuery把所有功能都封装再一个全局变量jQuery中。
-
jQuery使用方便:
<div id="list"> <p id="java">Java</p> <a href="http://www.baidu.com">百度</a> <p id="python">Python</p> <p id="scheme">Scheme</p> 666 <p id="js">JavaScript</p> <p id="abc">new tag</p> </div> <script> // 若是要删除python $('#python').remove(); </script>
太简洁了
jQuery选择器和css写法差不多,比js原生代码简洁太多。
最常用的:
-
标签选择器:
<!-- 若都选择p标签 --> <!-- css --> <style> p { } </style> <!-- jQuery --> <script src = "jQuery url"> $('p'); </script>
-
id选择器
<!-- 若都选择id为abc的标签 --> <!-- css --> <style> #abc { } </style> <!-- jQuery --> <script src = "jQuery url"> $('#abc'); </script>
-
类选择器
<!-- 若都选择class为abc的标签 --> <!-- css --> <style> .abc { } </style> <!-- jQuery --> <script src = "jQuery url"> $('.abc'); </script>
10.3 jQuery事件
-
常用鼠标事件
- mousedown() 按下鼠标
- mousemove() 移动鼠标
- mouseover() 鼠标悬停
<!-- 这段代码将会显示鼠标的坐标 --> <div id="ab"> </div> <div id="cd"> </div> <script> $(function () { let x = $('div')[1], y = $('div')[0]; x.style.height = `${window.innerHeight - 200}px`; x.style.width = `${window.innerWidth - 200}px`; x.style.border = '5px solid pink'; y.style.height = '60px' $('#cd').mousemove(function(e) { $('#ab').text('x:' + e.pageX + ' y:' + e.pageY); }) }) </script>
10.4 操作DOM
jQuery 获取DOM很简单,拿来操作DOM很方便
10.4.1 节点文本操作
-
text()方法和html()方法就像innerText和innerHTML,但比后者强大
<ul id="test-ul"> <li class="js">JavaScript</li> <li name="book">Java & JavaScript</li> </ul> <script> $(function () { $('#test-ul li[name=book]').text(); // 没有参数时 获取文本 Java & JavaScript $('#test-ul li[name=book]').text('<p>abc</p>'); //有参数时,修改文本 <p>abc</p>。 $('#test-ul li[name=book]').html(); // 没有参数时 获取文本 Java & JavaScript $('#test-ul li[name=book]').html('<p>abc</p>'); //有参数时,修改标签 abc。 }) </script>
10.4.2 CSS的操作
-
js可以批量操作css,且修改css相当方便,还支持链式编程。
-
可以操作标签的属性 attr()、prop()、removeAttr().
-
可以为标签增加类名 addClass()。
<div id="list"> <p id="java">Java</p> <a href="http://www.baidu.com">百度</a> <p id="python">Python</p> <p id="scheme">Scheme</p> 666 <p id="js">JavaScript</p> <p id="abc">new tag</p> </div> <script> // div背景颜色变成红色,里面所有文字变成蓝色。 $(function() { $('#list').css('background-color', 'red').css('color', 'blue'); }) </script>
10.4.3 元素的显示和隐藏
-
jQuery里正好有show()和hide()方法
<div id="list"> <p id="java">Java</p> <a href="http://www.baidu.com">百度</a> <p id="python">Python</p> <p id="scheme">Scheme</p> 666 <p id="js">JavaScript</p> <p id="abc">new tag</p> </div> <script> $('a').hide(); // 第3行的a标签就不见了 </script>
10.4.4 操作表单
-
使用jQuery操作表单是很明智的,输入框取值赋值的问题,一个val()方法就够了。
//摘自廖雪峰 /* <input id="test-input" name="email" value="test"> <select id="test-select" name="city"> <option value="BJ" selected>Beijing</option> <option value="SH">Shanghai</option> <option value="SZ">Shenzhen</option> </select> <textarea id="test-textarea">Hello</textarea> */ var input = $('#test-input'), select = $('#test-select'), textarea = $('#test-textarea'); input.val(); // 'test' input.val('abc@example.com'); // 文本框的内容已变为abc@example.com select.val(); // 'BJ' select.val('SH'); // 选择框已变为Shanghai textarea.val(); // 'Hello' textarea.val('Hi'); // 文本区域已更新为'Hi'
val()修改的就是value属性的值。
10.5 中文文档
https://jquery.cuishifeng.cn/