对象

对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。

对象的分类

内建对象:由ES标准定义的对象,在任何ES的实现中都可以使用,比如Math、String、Number……
宿主对象:由JS运行环境提供的对象,主要指由浏览器提供的对象,比如BOM、DOM……
自定义对象:由开发人员自己创建的对象

创建一个对象:var obj = new Object();
向对象添加属性:obj.属性名 = 属性值;
读取对象的属性:obj.属性名;
删除对象的属性:delete obj.属性名;
如果读取对象中没有的属性,不会报错,而是会返回undefined。

属性名和属性值
  • 对象的属性名不强制要求遵守标识符的规范,但还是尽量按规范去做。如果要使用特殊的属性名,需要采用另一种方式:对象['属性名'] = 属性值;,读取时也要采用这种方式。
  • 使用[]去操作属性更加灵活,在[]中可以直接传递一个变量,这样,变量值是多少,就会读取那个属性。比如:
var obj = new Object();
obj["123"] = 789;
var n = "123";
console.log(obj[n]);
  • JS的属性值可以是任意的数据类型,可以是基本数据类型,可以是对象,可以是函数。
  • 检查一个对象中是否含有指定的属性:"属性名" in 对象,返回值 truefalse
基本数据类型和引用数据类型

JS中的变量都保存在栈内存中:

  • 基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响其他的变量;
  • 对于引用数据类型,变量保存的是对象的地址,对象保存在堆内存中,每创建一个新的对象,就会在堆内存中开辟出一个新的空间。如果两个变量保存的是同一个地址,那么修改一个变量之后,另一个会跟着改变。
对象字面量 {}
  • 使用对象字面量来创建一个对象:var obj = {};
  • 在创建时指定属性:var obj = { 属性名:属性值, 属性名:属性值, ……};

对象字面量的属性名可以加引号也可以不加,建议不加;如果要使用一些特殊的名字,则必须加引号。
属性名和属性值是一组一组的名值对结构,名和值之间用 : 连接,多个名值对之间用 , 隔开。

函数

函数也是一个对象,可以封装一些功能,在需要时执行这些功能。函数对象也可以有属性。

  • 创建一个函数对象:var func = new Function(); 此时 typeof func 返回值为 function。可以将要封装的代码以字符串的形式传递给构造函数,封装到函数中的代码不会立即执行,而是在函数调用的时候执行。
  • 调用函数:func(); 此时函数中封装的代码会按顺序执行。
  • 函数声明:
function 函数名([形参1, 形参2, ..., 形参N]){函数语句...
}
  • 函数表达式:创建一个匿名函数,再将这个匿名函数赋值给一个对象。
var 函数名 = function([形参1, 形参2, ..., 形参N]){语句...
}
参数

举例:

function sum(a,b){return a + b;
}

\qquad 调用函数时解析器不会检查实参的类型,所以要注意是否会接收到非法的参数,如果有可能,则需要对参数进行类型检查。
\qquad 调用函数时解析器也不会检查实参的数量,多余实参不会被赋值。如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
实参可以是任意的数据类型。
\qquad 如果return后面不跟任何值或者函数中不写return,都会返回一个undefined。

返回值

\qquad 返回值可以是任意数据类型,当然可以是一个对象,也可以是一个函数。

立即执行函数

\qquad 函数定义完后立即被调用,这种函数往往只会执行一次。举例:

(function(a,b){return a+b;})(123,456);
函数的方法 call() 和 apply()

\qquad 对于一个函数fun(),可以调用上述两个方法:fun.call(); fun.apply();
\qquad 调用时可以指定一个对象作为第一个参数,此时这个对象就会成为函数执行时的 this;后面传入的参数都会作为实参传递给函数fun(); 注意:call() 方法可以将实参在对象之后依次传递,apply()方法需要将实参封装到一个数组中统一传递。

arguments 参数列表

\qquad 在调用函数时,浏览器每次会传递进两个隐含的参数,第一个是函数的上下文对象this,第二个是封装实参的对象arguments。

  • arguments 是一个类数组对象,也可以通过索引来操作数据,可以获取长度;
  • 调用函数时,所有的实参都会在 arguments 中保存,arguments.length就是实参的数量;
  • 即使不定义形参,也可以通过arguments来使用实参;
  • 属性callee对应了当前正在执行的函数对象;

方法

\qquad 如果一个函数作为一个对象的属性保存,那么这个函数称为对象的方法,调用这个函数称为“调用对象的方法”。

枚举对象中的属性

语法:for(var 变量 in 对象){ 操作变量的语句 }
\qquad 对象中有几个属性,循环体就会执行几次;每次执行时,会将对象中的一个属性的名字赋值给变量,可以用obj[变量]取出该属性的值。

var obj = {name:"kirlant";age:18;gender:"female",address:"empire"};
for(var n in obj){console.log(obj[n]);
}

作用域

作用域指定一个变量的作用范围。
变量的声明提前 使用 var 关键字声明的变量会在所有代码执行之前被声明;如果不使用 var 关键字,就不会被声明提前。
函数的声明提前 使用函数声明形式 function 函数名(){} 创建的函数会在所有代码执行之前被创建,所以可以在函数声明之前调用函数;使用函数表达式创建的函数则不会被声明提前。

全局作用域

直接编写在script标签中的代码都在全局作用域中;
全局作用域在页面打开时创建,在页面关闭时销毁;
在全局作用域中,有一个全局对象window,代表浏览器的窗口,由浏览器创建,可以直接使用;
在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存;
全局作用域中的变量都是全局变量,在页面的任意部分都可以访问到。

函数作用域(局部作用域)

调用函数时创建函数作用域,函数执行完毕后作用域销毁;
每调用一次函数,就会创建一个新的函数作用域,它们之间是互相独立的;
函数作用域中可以访问到全局作用域的变量,而全局作用域中无法访问到函数作用域的变量;
当在函数作用域中操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,没有就向上一级作用域中寻找;如果直到全局作用域都没有找到,才会报错;
在函数中如果想访问全局变量,可以使用window对象;
在函数作用域中也有声明提前的特性,只是被提前声明,不会一起提前赋值;
函数声明也会在所有代码执行之前被声明;
在函数中,不使用var声明的变量都会成为全局变量;
定义形参就相当于在函数作用域中声明了变量,不传参就相当于变量是undefined。

this

浏览器在调用函数时,每次都会向函数内部传递一个隐含的参数this
this指向一个对象,称为函数执行的上下文对象,根据函数的调用方式不同,this会指向不同的对象

  • 以函数方式调用时,this永远指向window;
  • 以方法方式调用时,this指向调用方法的对象;
  • 以构造函数形式调用时,this指向新建的那个对象;
  • 使用call() 和 apply()调用时,this指向指定的那个对象。

使用工厂方法创建对象

定义一个方法,大批量创建对象:

  1. 创建一个新的对象;
  2. 向对象中添加属性和方法;
  3. 将新的对象返回;
function creatNewObject(name, age, gender, ads){var obj = new Object();obj.name = name;obj.age = age;obj.gender = gender;obj.address = ads;obj.sayName = function(){alert(this.name);}return obj;
}

使用的构造函数都是Object,所以创建的对象都是Object类型,不方便区分对象 ⟶\longrightarrow⟶ 创建一个构造函数,专门用来创建一类对象,函数首字母大写。

构造函数

构造函数要通过 new 关键字调用。执行流程:

  1. 立刻创建一个新的对象;
  2. 将新建的对象设为函数中的 this,在构造函数中用 this 来引用新建的对象;
  3. 逐行执行函数中的代码;
  4. 将新建的对象作为返回值返回;

使用同一个构造函数创建的对象称为一类对象,也将构造函数称为一个类。将通过一个构造函数创建的对象称为该构造函数(或者该类)的实例。

function Person(name, age, gender, ads){this.name = name;this.age = age;this.gender = gender;this.address = ads;this.sayName = function(){alert(this.name);}
}
var pers = new Person("kirlant", 16, "female", "empire");
console.log(typeof pers);
console.log(pers);
pers.sayName();

运行结果:

object
Person {name: 'kirlant',age: 16,gender: 'female',address: 'empire',sayName: [Function (anonymous)]
}
kirlant

检查一个对象是否是一个类的实例:对象 instanceof 构造函数;返回值为 truefalse
所有的对象都是Object的后代,所有任何对象进行 instanceof Object 时,返回的都是 true

原型对象 prototype

将函数定义在全局作用域中会污染全局作用域的命名空间,而且不安全。
自行创建的每一个函数中,都会被解析器添加一个属性 prototype,对应着一个对象,即原型对象。prototype保存了原型对象的地址,是唯一的。当函数作为普通函数调用prototype时,没有任何作用;当函数以构造函数形式调用时,它创建的对象中都会有一个属性prototype,指向该构造函数的原型对象,可以通过__proto__来访问该属性。
原型对象相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,因此,可以将所有对象中共有的内容统一设置到原型对象中
当我们访问一个对象的一个属性或方法时,先在对象自身中查找,如果有就直接使用,如果没有就去原型对象中寻找,找到了就直接使用。

function Person(name, age, gender, ads){this.name = name;this.age = age;this.gender = gender;this.address = ads;
}
//向原型中添加公共方法
Person.prototype.sayName = function(){console.log(this.name);
}
var pers = new Person("kirlant", 16, "female", "empire");
console.log(typeof pers);
console.log(pers);
pers.sayName();

运行结果:

object
Person {name: 'kirlant',age: 16,gender: 'female',address: 'empire'
}
kirlant

检查对象自身(而不是原型对象)中是否含有某个属性:对象.hasOwnProperty(属性);返回值为 truefalse
原型对象也是对象,所以原型对象中也有__proto__ ⟶\longrightarrow⟶ 调用一个对象的属性或方法时,先在自身中寻找,找不到就去原型对象中寻找,再找不到则去原型对象的原型对象中寻找,直到找到Object对象的原型。Object对象的原型没有原型,其__proto__属性值对应的是null,Object对象的原型中依然找不到就返回undefined。

toString()

console.log(pers.toString());

运行结果:

[object Object]

可以根据需要重写该函数。

垃圾回收

程序运行过程中会产生垃圾,垃圾积攒过多会导致程序运行时间变慢 ⟶\longrightarrow⟶ 需要一个垃圾回收机制处理程序运行过程中产生的垃圾。
当一个对象没有任何变量或属性对它进行引用,它就变成了垃圾,这种对象过多会占用大量内存导致程序运行变慢,所以需要对它进行清理。JS中有自动的垃圾回收机制,会自动将它们从内存中销毁,我们不需要也不能进行垃圾回收的操作。我们需要做的只是将不再使用的对象设置为null

内建对象

数组 Array

创建数组对象:var arr = new Array();可以在创建时指定数组元素var arr = new Array(1, 2, 3);
添加元素:数组[索引] = 值;
读取元素:数组[索引];如果读取不存在的索引,不会报错而会返回一个undefined。
获取数组长度:数组.length;可以修改数组的长度数组.length = 值;如果修改的长度大于原来的长度,那么多余部分会空出来;如果小于原来的长度,那么多余部分会被删除。向数组的最后一个位置添加元素:arr[arr.length] = 值;
使用字面量创建数组:var arr = [];可以在创建时指定数组元素var arr = [1, 2, 3];
数组中的元素可以是任意数据类型,可以是对象,可以是函数。

数组的常用方法:

  • push() 向数组末尾添加一个或多个元素,并返回数组新的长度;
  • pop() 删除并返回数组的最后一个元素;
  • unshift() 向数组开头添加一个或多个元素,并返回数组新的长度;
  • shift() 删除并返回数组的第一个元素;
  • slice() 从数组中提取指定位置的元素,切片:var get = arr.slice(0,2);索引前闭后开;如果第二个参数不写,那么会截取从start索引开始往后的全部元素;索引如果传递一个负值,则从后往前计算;
  • splice() 删除指定位置的元素,并将被删除的元素作为返回值返回:var del = arr.slice(startIdx, delNums, [addElement1, addElement2, ...]);从startIdx开始,删除delNums个元素,然后在startIdx前插入addElement1, addElement2,…;
  • concat() 连接两个或多个数组,并将新的数组返回;
  • join() 将数组转换为一个字符串,不会对原数组产生影响,而是将转换后的字符串作为结果返回;可以指定一个字符串作为数组中元素的连接符:var result = arr.join(mystr);默认用","连接;
  • reverse() 反转数组,直接修改原数组;
  • sort() 对数组中的元素进行排序,直接修改原数组;默认按照Unicode编码进行排序,因此对数字排序可能得到错误的结果;⟶\longrightarrow⟶ 添加回调函数指定排序规则:arr.sort( function(a,b){return a-b;} );注意:数组中,a要在b之前;浏览器根据回调函数的返回值决定元素的顺序,如果返回值小于等于0,那么不交换元素位置,如果返回值大于0,那么交换元素位置;

遍历数组
方法一:for

for(var i=0; i<arr.length; i++){console.log(arr[i]);
}

方法二:forEach()
\qquad forEach()方法需要一个函数作为参数,该函数由我们创建但不由我们调用,称为回调函数。数组中有几个元素函数就会执行几次,每次都将遍历到的元素以实参的形式传入函数中,因此可以定义形参来读取这些内容。
\qquad 浏览器会向回调函数中传入三个参数:当前遍历到的元素,当前元素的索引,当前正在遍历的数组。

// IE8及以下的浏览器均不支持该方法
arr.forEach(function(value, index, obj){console.log(value);console.log(index);console.log(obj);
});

日期 Date

JS中使用Date对象来表示一个时间。
创建对象:var d = new Date(); 此时默认值为当前代码执行的时间;
创建指定时间对象:var d = new Date("12/03/2016 11:10:30"); 字符串格式:月/日/年 时:分:秒
获取当前日期对象的时间戳:getTime(),从格林威治标准时间1970.01.01 00:00:00 到当前日期花费的毫秒数;计算机底层保存时间时使用的都是时间戳;
获取当前的时间戳:Date.now();

Math

工具类,封装了数学运算相关的属性和方法。
向上取整:Math.ceil()
向下取整:Math.floor()
四舍五入:Math.round()
生成一个0~1之间的随机数:Math.random(),不包括0和1
计算x的y次幂:Math.pow(x,y)

包装类

包装类将基本数据类型转换为对象:String、Number、Boolean。当对一些基本数据类型调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后调用对象的属性和方法,调用完以后,再将其转换回基本数据类型。

字符串 String

字符串在底层以字符数组的形式保存,因此操作方法和操作数组类似。
属性:length,用来获取字符串的长度;
方法:charAt() 返回字符串中指定位置的字符;
\qquad \, charCodeAt() 获取指定位置字符的Unicode编码;
\qquad \, String.fromCharCode() 根据字符编码获取字符;
\qquad \, indexOf() 检索字符串中是否含有指定内容,返回值为该内容第一次出现的索引,没有则返回-1;可以指定第二个参数为开始查找的位置;
\qquad \, lastIndexOf() 从后向前检索字符串中是否含有指定内容;
\qquad \, slice(startIdx, endIdx) 截取指定位置字符串的内容(前闭后开),返回截取的内容,不影响原字符串;endIdx可省略,此时截取从startIdx开始的所有内容;索引若为负数,则从后向前数;
\qquad \, substring(startIdx, endIdx) 和slice()类似;参数不能传负数,如果传入了负值则默认使用0;会自动调整参数的位置,如果startIdx>endIdx,会自动交换两个参数;
\qquad \, substr(startIdx, nums) 从startIdx开始截取nums个字符;
\qquad \, split(str) 以str为拆分位置,拆分字符串为字符串数组;如果传入空串,则会将每个字符都拆分开;
\qquad \, toUpperCase() 将字符串转换为大写并返回;
\qquad \, toLowerCase() 将字符串转换为小写并返回;

正则表达式

\qquad正则表达式定义了一些字符串的规则,计算机根据正则表达式来检查一个字符串是否符合规则,或提取字符串中符合规则的内容。
创建正则表达式对象:var reg = new RegExp("正则表达式", "匹配模式");使用typeof检查正则对象会返回object;匹配模式有两种:i 忽略大小写,g 全局匹配模式;
使用字面量创建正则表达式:var reg = /正则表达式/匹配模式;
举例:

var reg = new RegExp("a", "i");
var reg = /a/i;

正则表达式中的一些逻辑符:
| [] 或;
[a-z] 任意小写字母;
[A-Z] 任意大写字母;
[A-z] 任意字母;
[^ ] 除了括号里的xxx;
[0-9] 任意数字;
[^0-9] 除了数字;
方法:reg.test(str) 检查字符串str是否符合正则表达式reg的规则,返回truefalse
字符串和正则表达式
var str = "1a2b3c4d5e";
方法:str.split();将一个字符串拆分为数组,可以传递一个正则表达式作为参数,方法就会根据正则表达式拆分字符串;不需要设置全局匹配也会全部拆分;
\qquad \, str.search();搜索字符串中是否含有指定内容,如果找到了就返回第一次出现的位置,如果没有返回-1;可以接收正则表达式;即使设置了全局匹配也只搜索第一个;
\qquad \, str.match();根据正则表达式将字符串中符合条件内容提取出来;默认情况下只找第一个符合条件的内容,可以设置正则表达式为全局匹配,就能找到所有内容;可以设置多个匹配模式,顺序无所谓;匹配到的内容被封装到一个数组中返回;
\qquad \, str.replace(被替换内容(可以用正则表达式),新内容); 将字符串中的指定内容替换为新的内容;默认只替换第一个;
正则表达式的语法
量词: 设置一个内容出现的次数
\qquad \, {n}花括号前的内容恰好出现n次,只对它前面的一个内容起作用;
\qquad \, {n1,n2}出现n1~n2次;
\qquad \, {n1, }出现n1次以上;
\qquad \, (){n}小括号中的内容恰好出现n次;
\qquad \, + 前面的内容出现至少一次;
\qquad \, * 前面的内容出现0次或多次,等同于{0, }
\qquad \, ? 前面的内容出现0次或1次,等同于{0, 1}
\qquad \, ^ 开头;
\qquad \, $ 结尾;
如果在正则表达式中同时使用^$,则要求字符串必须完全符合正则表达式。

元字符: 具有特殊意义的字符
\qquad \, . 任意字符
\qquad \, \ 转义字符;使用构造函数时,由于它的参数是字符串,而\是一个转义字符,因此在字符串中使用\转义其他字符时需要写\\
\qquad \, \w 任意字母、数字、_;等同于[A-z0-9_]
\qquad \, \W 除了字母、数字、_;等同于[^A-z0-9_]
\qquad \, \d 任意数字;等同于[0-9]
\qquad \, \D 除了数字;等同于[^0-9]
\qquad \, \s 空格;
\qquad \, \S 除了空格;
\qquad \, \b 单词边界;
\qquad \, \B 除了单词边界;
单词边界举例:检查是否含有某个单词时,在这个单词前后加上 \b,就不会查到以这个单词为组成部分的更长的单词。即两个\b中间是一个独立的单词。

var reg = /\bchild\b/g;
var find = "hello child";
console.log(reg.test(find)); // true
find = "hello children";
console.log(reg.test(find)); // false

练习:
创建一个正则表达式,检查字符串是否是手机号

// 以1开头,第二位数字只能是3~9,然后跟着9位任意数字,结束
var reg = /^1[3-9][0-9]{9}$/g;
var phone = "18763370911";
console.log(reg.test(phone));

接收一个用户的输入:

var userName = prompt("请输入用户名:");
console.log(userName);

去除字符串前后的空格:
\qquad \, 使用空串替换空格,注意中间位置的空格不应该去掉。
\qquad \, 思路:全局匹配开头的一个或多个空格,或结尾的一个或多个空格,都用空串替换。

var userName = "       Garcia Kirlant       ";
userName = userName.replace(/^\s*|\s*$/g,"");
console.log(userName); // Garcia Kirlant

邮件的正则:
\qquad \, 以任意字母、数字、下划线开头(^),5位以上;
\qquad \, 一个@
\qquad \, 网站名称,一次以上的数字或字母;
\qquad \, 一到两次域名(.com, .cn什么的);每个域名长度为2~5,包括一个.和后面的字母;
\qquad \, 一个结束符$;

var reg = /^\w{5,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
console.log(reg.test("2427369255@qq.com")); // true
console.log(reg.test("2427369255@qq.com.3")); // false

文档对象模型 Document Object Model ( DOM )

JS中通过DOM来对HTML文档进行操作。
文档:整个的HTML网页文档;
对象:将网页中的每个部分都转换为了一个对象;之后就可以以面向对象的形式操作网页;
模型:使用模型来表示对象之间的关系,方便我们获取对象;

节点 Node

\quad \; \;节点是构成HTML文档最基本的单元,网页中的每一个部分都可以称为是一个节点,比如:html标签、属性、文本、注释、整个文档……都是节点。
\quad \; \;节点的具体类型是不同的:标签-元素节点属性-属性节点文本-文本节点文档-文档节点
\quad \; \;节点的类型不同,其属性和方法也不同。

节点的属性:
  • 文档节点:
    nodeName#document
    nodeType: 9
    nodeValue: null
  • 元素节点:
    nodeName: 标签名
    nodeType: 1
    nodeValue: null
  • 属性节点:
    nodeName: 属性名
    nodeType: 2
    nodeValue: 属性值
  • 文本节点:
    nodeName#text
    nodeType: 3
    nodeValue: 文本内容

\quad \; \;浏览器已经提供了文档节点对象document,这个对象是window属性,可以在页面中直接使用;文档节点代表的是整个网页。

事件

\quad \; \;事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,也就是用户和浏览器之间的交互行为,比如鼠标移动、点击按钮、关闭窗口等。
\quad \; \;JavaScript 与 HTML 的交互是通过事件产生的,事件发生后需要有一个行为来处理事件。可以在事件对应的属性中设置一些js代码,当事件被触发时执行这些代码,但这种方式导致行为和结构耦合,不推荐使用。最好为事件绑定处理函数来响应事件,事件被触发时调用该响应函数。

文档的加载

浏览器在加载页面时,是按照自上而下的顺序加载的,读取一行运行一行,因此如果将script标签写在页面上部,在代码执行时,页面还没有加载,DOM对象也没有加载,就会导致无法获取DOM对象,事件就不能触发 ⟶\longrightarrow⟶ onload事件在整个页面加载完成后才触发,可以为 window 对象绑定一个 onload 事件,该事件对应的响应函数将会在页面加载完成之后才执行,就能确保在代码执行时所有的DOM对象都加载完毕。
在body的结束标签前一行引入外部.js文件。

window.onload = function(){自定义的所有的响应函数
}

innerHTML属性用于获取标签内部的HTML代码,对于自结束标签没有意义。

DOM 增 删 查 改

1. 查询
  • 获取元素节点:通过 document 对象调用
    getElementById() 通过 id 属性获取一个元素节点对象,一定是唯一的;
    getElementsByTagName() 通过标签名获取一组元素节点对象,返回值是一个数组;
    getElementsByName() 通过 name 属性获取一组元素节点对象;
  • 获取元素节点的子节点:通过具体的元素节点调用
    getElementsByTagName() 获取当前标签节点的指定标签名的后代节点;
    childNodes 属性,当前节点的所有子节点,返回值是一个数组;会获取包括文本节点在内的所有节点,在IE8以上的浏览器中,标签之间的空白区域也会被算成一个节点,注意兼容性
    children 属性,获取当前元素的所有子元素
    firstChild 属性,获取当前节点的第一个子节点(包括空白文本节点);
    firstElementChild 属性,获取当前元素的第一个子元素(不支持IE8及以下的浏览器);
    lastChild 属性,获取当前节点的最后一个子节点(包括空白文本节点);
    lastElementChild 属性,获取当前元素的最后一个子元素(不支持IE8及以下的浏览器);
  • 获取父节点兄弟节点:通过具体节点调用
    parentNode 属性,获取当前节点的父节点;
    previousSibling 属性,当前节点的前一个兄弟节点;
    nextSibling 属性,当前节点的后一个兄弟节点;
  • 获取 body 标签document.body
  • 获取 html 根标签document.documentElement
  • 获取所有元素:document.all
  • 根据元素的 class 属性查询一组节点对象:document.getElementByClassName()
  • 根据 CSS 选择器来查询元素节点document.querySelector(),传入参数为 CSS 选择器,比如".box1 div"选择了第一个class=box1的元素下面的第一个divdocument.querySelectorAll()则选择所有符合条件的元素,以数组形式返回
2. 增加
  • appendChild()添加子节点(父节点调用)
  • insertBefore(newNode, chooseNode) 在指定子节点前插入新节点(父节点调用)
  • replaceChild(newNode, chooseNode) 用新节点替换指定子节点(父节点调用)
3. 删除(父节点调用)
  • removeChild(delNode) 删除子节点(父节点调用)
4. 修改(父节点调用)

-利用 innerHTML 属性进行修改

父节点常用 当前节点.parentNode 属性来获取

操作样式

  • 修改样式
    元素.style.样式名 = 样式值(字符串);
    \quad 如果CSS的样式名中含有’-‘需要将其改成驼峰命名法:去掉’-',将后面的第一个字母变成大写。
    \quad 通过style修改的样式都是内联样式,有较高的优先级,修改后会立刻生效。CSS样式中写了!important的属性除外。
  • 读取样式 (只读)
    元素.style.样式名
    \quad 通过style读取的样式都是内联样式,无法读取样式表中的样式。
  • 读取元素当前显示的样式 (只读)
    IE(8及以下)浏览器:元素.currentStyle.样式名
    其他浏览器:getComputedStyle(元素, null) 返回一个对象,该对象封装了元素的所有样式,读取时用 对象.样式名 来获取具体样式,如果获取的样式没有设置,那么会获取到具体的而不是默认的auto
    兼容:自己封装一个函数(呵呵)
//  根据浏览器中有无 getComputedStyle()方法来选择获取方式
//  obj: 要获取样式的元素
//  name: 要获取的样式名
function getStyle(obj, name){// getComputedStyle()方法在 IE8 及以下的浏览器中没有 ->// getComputedStyle是一个变量,局部和全局都找不到时会报错;// window.getComputedStyle是一个属性,局部和全局都找不到时会返回 undefined,转换为布尔值后就是 false。if(window.getComputedStyle){return getComputedStyle(obj, null)[name];}else{return obj.currentStyle[name];}
}
  • 其他相关属性 element.属性名
    \quad clientWidth、clientheight 获取元素的可见宽度、高度(包括内容区和内边距),返回值是数字,可以直接进行计算;属性只读,不能修改;
    \quad offsetWidth、offsetHeight 获取元素的整个宽度和高度,包括内容区、内边距和边框;
    \quad offsetParent 获取元素的定位父元素,也就是离当前元素最近的开启了定位的祖先元素;如果所有的祖先元素都没有开启定位,则返回body;
    \quad offsetLeft、offsetTop 当前元素相对于其定位父元素的水平、垂直偏移量;
    \quad scrollWidth、scrollHeight 获取元素整个滚动区域的宽度和高度;
    \quad scrollLeft、scrollTop 获取水平、垂直滚动条滚动的距离;chorm浏览器认为body的滚动条属于body,可以用document.body.scrollTop获取垂直距离;firefox、ie等浏览器认为body的滚动条属于html,要用document.documentElement.scrollTop。垂直距离同理;
    \quad 当满足 scrollHeight - scrollTop == clientheight 时,说明垂直滚动条滚动到底;水平滚动条同理。 用户注册界面常常有不看完协议就不让单击表单项的情况,这是因为在HTML中创建表单项时,disabled 属性为 disabled="disabled"; 表单项不可用;滚动条滚动的时候触发事件 onscroll,判断协议是否被拉到底,拉到底之后设置 disabled=false;令表单项可用。
    其他相关属性

事件对象

\quad 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数。在事件对象中封装了当前事件的一切相关信息,比如鼠标的坐标、键盘上被按下的键、鼠标滚轮的滚动方向……
\quad 注意:IE8 及以下的浏览器中,事件对象被作为 window 对象的属性 保存。
\quad HTML DOM 事件

  • onmousemove 事件,鼠标在元素中移动时触发;
  • clientX、clientY 事件的属性,获取鼠标相对于可见窗口的坐标;
  • pageX、pageY 事件的属性,获取鼠标相对于整个页面的坐标;

// 获取各个元素
var divMove = document.getElementById("move");
var divShow = document.getElementById("show");
// 获取div
// 绑定事件
divMove.onmousemove = function(event){event = event || window.event; // 兼容性var x = event.clientX;var y = event.clientY;divShow.innerHTML = "x = "+ x + ", y = "+ y;
};
<div class="outer" id="outer"><div class="move" id="move"></div><div class="show" id="show"></div>
</div>
// less代码
@fontSize:20px;
@margins:20px;
body{width: 600px;margin: @margins auto;display: flex;justify-content: center;.outer{width: 100%;.move{width: 100%;height: 400px;margin-bottom: @margins;border: 1px solid rgb(127, 26, 222);}.show{width: 100%;height: 40px;line-height: @fontSize;border: 1px solid rgb(127, 26, 222);}}
}
事件的冒泡 bubble

\quad 事件的冒泡指事件的向上传导,当后代元素上的事件被触发时,祖先元素的相同事件也会被触发。在开发中,大部分情况下冒泡都是有用的。如果不希望事件冒泡,可以通过事件对象取消冒泡event.cancelBubble=true;

<body id="body"><div class="outer" id="outer"><div class="inner" id="inner"></div></div>
</body>
// 获取各个元素
var theBody  = document.getElementById("body");
var divOut = document.getElementById("outer");
var divIn = document.getElementById("inner");
// 绑定事件
theBody.onclick = function(event){alert("body");
};
divOut.onclick = function(event){alert("outer");
};
divIn.onclick = function(event){event.cancelBubble=true;alert("inner");
};
@length:100px;
body{width: @length*3;height: @length*3;border: 1px solid rgb(127, 26, 222);margin: 20px auto;display: flex;justify-content: center;.outer{width: @length*2;height: @length*2;background-color: rgb(200, 235, 255);margin: auto;display: flex;justify-content: center;.inner{width: @length;height: @length;margin: auto;background-color: azure;}}
}
事件的委派

\quad 只绑定一次事件,即可应用到多个元素上,即使元素是后来添加的。因此可以考虑将事件绑定给这些元素共同的祖先元素上,这样,当后代元素上的事件触发时,会一直冒泡到祖先元素上,从而通过祖先元素的响应函数来处理事件。需要判断触发事件的元素是不是期望的元素。
\quad 通过委派可以减少事件绑定的次数。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body id="body"><ul id="list"><li><a class="link" href="javascript:;">一方通行</a></li><li><a class="link" href="javascript:;">垣根帝督</a></li><li><a class="link" href="javascript:;">御坂美琴</a></li><li><a class="link" href="javascript:;">麦野沈利</a></li><li><a class="link" href="javascript:;">食蜂操祈</a></li><li><a class="link" href="javascript:;">蓝花悦</a></li><li><a class="link" href="javascript:;">削板军霸</a></li></ul><div class="divBtn"><input id="btnAdd" type="button" value="添加"><input id="btnBind" type="button" value="绑定"></div><script type="text/javascript" src="./learn.js"></script></body>
</html>
// 获取各个元素
var lines  = document.getElementsByTagName("a");
var list = document.getElementById("list");
var btnBind = document.getElementById("btnBind");
var btnAdd = document.getElementById("btnAdd");
// 绑定事件
list.onclick = function(event){event = event || window.event;if(event.target.className == "link"){alert("alert list");}
}
// 点击按钮添加超链接
btnAdd.onclick = function(event){var newLi = document.createElement("li");newLi.innerHTML = "<a class='link' href='javascript:;'>第八人</a>";list.appendChild(newLi);
}
@length: 100px;
@fontsize: 25px;
body{width: @length*4;height: @length*3;font-size: @fontsize;border: 1px solid rgb(127, 26, 222);margin: 20px auto;display: flex;flex-wrap: wrap;justify-content: center; ul{width: 100%;background-color: rgb(223, 202, 255);margin: auto;text-align: center;display: flex;justify-content: center;li{line-height: @fontsize;margin: 10px;}}.divBtn{margin: 0 auto;input{font-size: 20px;line-height: 26px;text-align: center;color: white;background-color: rgb(121, 38, 194);border: solid 2px rgb(84, 28, 134);}}
}
事件的绑定

\quad 使用对象.事件 = 函数的形式只能同时为一个元素的一个事件绑定一个响应函数,如果绑定了多个函数,则后面的会覆盖前面的函数 ⟶\longrightarrow⟶ 使用 addEventListener()(不支持IE8及以下)或 attachEvent()(只支持IE8及以下)。

  • addEventListener()先绑定先执行
    参数:
    \quad 事件的字符串,去掉‘on’
    \quad 回调函数,事件触发时调用该函数;
    \quad 是否在捕获阶段触发事件,一般设为false
    this 指向绑定事件的对象;
  • attachEvent()后绑定先执行
    参数:
    \quad 事件的字符串,需要‘on’
    \quad 回调函数,事件触发时调用该函数;
    this 指向window;
// 为一个按钮绑定多个单击响应函数
/* 为一个按钮绑定多个单击响应函数obj:要绑定事件的对象eventStr:事件名称,不加'on'callback:要绑定的回调函数
*/
function bind(obj, eventStr, callback){if(obj.addEventListener){// 大部分浏览器兼容的方式obj.addEventListener(eventStr, callback, false);}else{/* this 指向谁由调用方式决定 IE8及以下浏览器中,让浏览器调用匿名函数,在匿名函数中让obj调用回调函数,就能保证不管是什么浏览器,调用 callback 的都是 obj*/// IE8及以下浏览器obj.attachEvent("on"+eventStr, function(){callback.call(obj);});}
}
bind(btnBind, "click", function(){ alert("first"); });
bind(btnBind, "click", function(){ alert("second"); });
bind(btnBind, "click", function(){ alert("third"); });
事件的传播

微软 事件应该从内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后向祖先元素传播,也就是事件应该在冒泡阶段执行。
网景 事件应该从外向内传播,先触发当前元素最外层的祖先元素事件,再向内传播给后代元素,也就是事件应该在捕获阶段执行。
W3C 综合两个方案,将事件的传播分成三个阶段:
\quad 捕获阶段:从最外层的祖先元素向目标元素进行事件的捕获,默认此时不会触发事件;
\quad 目标阶段:事件捕获到目标元素,捕获结束后开始在目标元素上触发事件;
\quad 冒泡阶段:事件从目标元素向祖先元素传递,依次触发祖先元素上的事件。

\quad 如果希望在捕获阶段触发事件,可以将 addEventListener() 的第三个参数设置为 true,一般不希望在捕获阶段触发事件,所以一般都设为 false。IE8及以下浏览器没有捕获阶段。

滚轮事件

元素.onwheel = function(){},但是在火狐浏览器中需要用addEventListener()绑定DOMMouseScroll事件。
获取滚轮滚动方向:
\quad event.wheelDelta属性,大于0时向上滚动,小于0时向下滚动;
\quad event.detail属性,小于0时向上滚动,大于0时向下滚动;火狐专用
当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动。这是浏览器的默认行为,如果不希望发生这个行为,可以令函数返回值为false火狐需要用event.preventDefault()取消默认行为;IE8会报错,因此需要加一个判断。

<div id="box1"></div>
body{height: 2000px;div{width: 100px;height: 100px;position: absolute;}#box1{min-height: 100px;max-height: 1000px;background-color: rgb(194, 223, 247);}
}
// 获取各个元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
/*鼠标滚轮向下滚动时,box1变长;向上滚动时,box1变短
*/
box1.onwheel = function(event){// 向上滚动 180if(event.wheelDelta > 0 || event.detail < 0){box1.style.height = box1.clientHeight - 10 + "px";}// 向下滚动 -180else{box1.style.height = box1.clientHeight + 10 + "px";}event.preventDefault && event.preventDefault();return false;
};
键盘事件

键盘事件一般绑定给 可以获取到焦点的对象 或者 document。

  • 某个按键被按下:onkeydown
    \quad 如果按着一个键不松手,它会连续触发。当连续触发时,第一次和第二次之间间隔稍长,其他的间隔则很短,这是为了防止误操作。
  • 某个按键被松开:onkeyup
    \quad 不会连续触发。
  • event 的属性
    \quad key 返回键值,比如按下’y’,返回"y";
    \quad code 返回一个奇怪的东西,比如按下’y’,返回"KeyY";
    \quad shiftKey、ctrlKey、altKey 返回是否按下了这三个键,按下为 true
document.onkeydown = function(event){event = event || window.event;// 判断y是否被按下// if(event.key === "y"){//     alert("press a y");// }// 判断 Y 是否被按下(y和Shift同时被按下)if(event.shiftKey && (event.key === "Y")){alert("press shiftKey and y");}
};

对于输入文本框,输入内容属于 onkeydown 的默认行为,如果取消了默认行为,那么内容不会出现在文本框中。

<input type="text" />
var input = document.getElementsByTagName("input")[0];
var reg = /^[0-9]/i;
input.onkeydown = function(event){event = event || window.event;// 不让输入数字if(reg.test(event.key)){return false;}
};

浏览器对象模型 Browser Object Model ( BOM )

\quad 提供一组对象,用来完成对浏览器的操作。这些对象在浏览器中都是作为 window 对象的属性保存的,可以通过 window 对象调用,也可以直接使用。

  • Window 整个浏览器的窗口,网页的全局对象;
  • Navigator 当前浏览器的信息,通过该对象来识别不同浏览器;
  • Location 当前浏览器的地址栏信息(最上面显示网址的那个小框框),用来获取地址栏信息或者操作浏览器跳转页面;
  • History 浏览器的历史记录;由于隐私原因,该对象不能获取具体历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效;
  • Screen 用户的屏幕信息,可以获取用户的显示器的相关信息(移动端会用,PC端不常用);

Navigator

\quad 历史原因,大部分属性都没什么用了,只剩一个userAgent来判断浏览器信息了。userAgent是一个字符串,用来描述浏览器。
\quad IE11中和IE相关的标识都去除了,所以不能通过userAgent识别IE浏览器了(卧槽)。Edge浏览器已经变成Chrome内核了:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53

var ua = window.navigator.userAgent;
if(/msie/i.test(ua)){alert("Oh No IE");
}else if(/chrome/i.test(ua)){alert("Chorme");
}else if(/firefox/i.test(ua)){alert("Firefox");
}

还可以通过一些浏览器中特有的对象来判断浏览器信息,比如ActiveXObject只存在于IE里(哦豁,找到你了)。

if("ActiveXObject" in window){alert("ohoo~ IE, I find you");
}

History

操作浏览器向前或向后翻页。

  • length 获取到当前访问的连接数量;
  • back() 回退到上一个页面,和浏览器的后退按钮作用一样;
  • forward() 跳转到下一个页面,和浏览器的前进按钮一样;
  • go() 跳转到指定页面,需要一个整数n做参数,n是跳转页面的个数;n>0时向前跳转,n<0时向后跳转;
<div id="box1"><a href="https://www.bilibili.com">哔哩哔哩</a><br><a href="https://www.baidu.com"> 百度 </a><br><a href="https://mp.csdn.net/mp_blog/manage/article">咦?</a><br>
</div>
var btnBack = document.getElementById("back");
var btnFoward = document.getElementById("foward");
btnBack.onclick = function(){history.back();console.log(history.length);
};
btnFoward.onclick = function(){history.forward();history.back();console.log(history.length);
}
body{position: absolute;div{width: 100px;height: 100px;display: flex;flex-wrap: wrap;justify-content: center;align-content: center;}#box1{background-color: rgb(194, 223, 247);a{width: 100%;font-size: 20px;line-height: 20px;vertical-align: middle;text-align: center;margin: 4px auto; }}#btns{background-color: rgb(194, 247, 233);input{height: 25px;font-size: 20px;line-height: 20px;text-align: center;border-radius: 7px;border: solid 1px rgb(105, 105, 105);padding: 0 10px;margin: 2px auto;}}
}

Location

\quad 如果直接打印location,则可以获取到浏览器的地址栏信息(当前页的完整路径);如果直接将其修改为一个完整的路径或相对路径,则页面会自动跳转到该路径,并生成相应的历史记录;

  • location.assign()用来跳转到其他页面,作用和直接修改location一样;
  • location.reload() 用于重新加载当前页面,作用和刷新按钮一样;如果传入true作为参数,则会强制清空缓存,刷新页面;
  • location.replace() 用一个新的页面替换当前页面,调用完毕会跳转页面,不会生成历史记录,不能用回退按钮;

Window

  • 如果希望一段程序每间隔一段时间调用一次,可以使用定时调用setInterval( function(){}, times)
    参数:回调函数;每次调用的间隔时间,整数,单位是mm;
    返回值:一个Number型的整数timer,用来作为定时器的唯一标识,传入clearInterval()来关闭该定时器;
  • 延时调用 setTimeout()函数不马上执行,而是隔一段时间以后再执行,而且只执行一次。参数与定时调用相同。
    延时调用和定时调用是可以互相代替的。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body id="body"><div class="line start"></div><div class="mid"><div class="btn"><div class="btn1"><button id="btn1Right">向右移动嗷</button><button id="btn1Left">向左移动嗷</button></div><div class="btn2"><button id="btn2Right">向右移动嗷</button><button id="btn2Left">向左移动嗷</button></div></div><div class="box" id="box1"></div><div class="box" id="box2"></div></div><div class="line end"></div><script type="text/javascript" src="./learn.js"></script></body>
</html>
// 获取各个元素
var btn1Right = document.getElementById("btn1Right");
var btn1Left = document.getElementById("btn1Left");
var btn2Right = document.getElementById("btn2Right");
var btn2Left = document.getElementById("btn2Left");
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
//  根据浏览器中有无 getComputedStyle()方法来选择获取方式
//  obj: 要获取样式的元素
//  name: 要获取的样式名
function getStyle(obj, name){// getComputedStyle()方法在 IE8 及以下的浏览器中没有 ->// getComputedStyle是一个变量,局部和全局都找不到时会报错;// window.getComputedStyle是一个属性,局部和全局都找不到时会返回 undefined,转换为布尔值后就是 false。if(window.getComputedStyle){return getComputedStyle(obj, null)[name];}else{return obj.currentStyle[name];}
};
/*尝试创建一个移动 div 的函数obj:要移动的对象speed:移动速度target:移动的目标位置dir:移动方向, "left" 或 "top" (height 或者 width 会变得奇怪起来)t:移动的间隔时间,mmcallback:一个函数,动画执行完毕后执行*/
function move(obj, speed, target, dir, t, callback=function(){}){clearInterval(obj.timer);// 开启一个定时器来控制div移动方向obj.timer = setInterval(function(){var oldPos = parseInt(getStyle(obj, dir));var useSpeed;if(target < oldPos){useSpeed = -speed;}else{useSpeed = speed;}var newPos = oldPos + useSpeed;if((useSpeed > 0 && newPos > target)||(useSpeed < 0 && newPos < target)){newPos = target; }obj.style[dir] = newPos+"px";if(newPos == target){clearInterval(obj.timer);callback();}},t);
};
btn1Right.onclick = function(){ move(box1, 20, 900, "left", 20);
};
btn1Left.onclick = function(){move(box1, 20, 0, "left", 20);
};
btn2Right.onclick = function(){ move(box2, 40, 900, "left", 20);
};
btn2Left.onclick = function(){move(box2, 40, 0, "left", 20);
};
body{display: flex;justify-content: center;.line{width: 5px;height: 500px;background-color: black;margin: 10px 0;}.mid{width: 1000px;margin: 10px 0;position: relative;.btn{width: 100%;height: 32px;margin-bottom: 10px;position: absolute;display: flex;flex-wrap: nowrap;justify-content: center;div{margin: 0 5px;}button{height: 32px;font-size: 20px;line-height: 20px;text-align: center;padding: 5px 7px;margin: 0 3px;}.btn1 button{color: rgb(22, 74, 126);border: 1px solid rgb(22, 74, 126);background-color: rgb(197, 223, 248);}.btn2 button{color: rgb(22, 88, 13);border: 1px solid rgb(22, 88, 13);background-color: rgb(232, 255, 212);}}.box{width: 100px;height: 100px;}#box1{margin-top: 70px;background-color: rgb(197, 223, 248);}#box2{margin-top: 20px;background-color: rgb(232, 255, 212);}}
}

类的操作

修改元素样式

\quad 通过style属性来修改元素样式时,每修改一个样式,浏览器就要重新渲染一次页面,这样执行性比较差,而且当需要修改多个样式时很不方便。
⟶\longrightarrow⟶ 一行代码修改多个样式:通过修改元素的className属性来简介修改样式。此时浏览器只需要重新渲染页面一次,性能比较好,并且可以使表现和行为进一步分离。

<button id="btn01">点击按钮,修改box样式</button>
<div id="box" class="b1"></div>
body {#btn01{width: 200px;font-size: 16px;margin: 10px;}.b1{width: 100px;height: 100px;background-color: #296ea3;margin: 10px;}.b2{width: 200px;height: 200px;background-color: #8da8bd;margin: 10px;}
}
var btn01 = document.getElementById("btn01");
var box = document.getElementById("box");
btn01.onclick = function(){// 修改box的样式? No,修改box指向的类box.className = "b2";
}

有时候只想在前一个样式的基础上修改几个属性,可以使用:

.b2{width: 200px;background-color: #8da8bd;}
box.className += " b2";

封装成函数

<button id="btn01">点击按钮,添加box样式</button>
<button id="btn02">点击按钮,删除box样式</button>
<button id="btn03">点击按钮,切换box样式</button>
<div id="box" class="b1"></div>
body {button{width: 200px;font-size: 16px;margin: 10px;}.b1{width: 100px;height: 100px;background-color: #296ea3;margin: 10px;}.b2{width: 200px;background-color: #8da8bd;}
}
var btn01 = document.getElementById("btn01");
var btn02 = document.getElementById("btn02");
var btn03 = document.getElementById("btn03");
var box = document.getElementById("box");
btn01.onclick = function(){// 修改box的样式? No,修改box指向的类if(!hasClass(box, "b2")){addClass(box,"b2");}
}
btn02.onclick = function(){removeClass(box,"b2");
}
btn03.onclick = function(){toggleClass(box,"b2");
}
// 定义一个函数,用来向元素中添加指定的class属性值
function addClass(obj, cn){obj.className += " "+cn;
}
// 判断一个元素中是否含有指定的class属性值
function hasClass(obj, cn){var reg = new RegExp("\\b"+cn+"\\b");if(reg.test(obj.className)){return true;}else{return false;}
}
// 删除元素中指定的class属性
function removeClass(obj, cn){var reg = new RegExp("\\b"+cn+"\\b");obj.className = obj.className.replace(reg, "");
}
// 切换一个类
// 如果元素中具有该类,则删除;如果元素中没有该类,则添加
function toggleClass(obj, cn){if(hasClass(obj, cn)){removeClass(obj, cn);}else{addClass(obj, cn);}
}

JS对象表示法 JavaScript Object Notation(JSON)

JSON就是一个特殊格式的字符串,可以被任何语言识别,并转换为任何语言中的对象。JSON主要用来进行不同语言之间数据的交互。
JSON和JS对象的格式一样,只是属性名必须加双引号,其他的和JS语法一致。
JSON分类:对象 { };数组 [ ]
JSON中允许的值:字符串、数值、布尔值、null、对象、数组;不能传函数嗷

  • JSON工具类
    将JSON字符串转换为JS对象:JSON.parse();
    将JS对象转换为JSON字符串:JSON.stringify();

练习

1. 图片切换

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body><div class="image"><img src="./imgs/bf_3.jpg" /><button id="last">last</button><button id="next">next</button></div><script type="text/javascript" src="./learn.js"></script></body>
</html>
var paths = ["./imgs/bf_3.jpg","./imgs/ssm_3.jpg","./imgs/xh_3.jpg"];
var idx = 0;
var nums = paths.length;
// 获取两个按钮
var btnLast = document.getElementById("last");
var btnNext = document.getElementById("next");
// 为两个按钮绑定单击响应函数
btnLast.onclick = function(){var change = document.getElementsByTagName("img")[0];idx = (idx+nums-1)%nums;change.src = paths[idx];
};btnNext.onclick = function(){var change = document.getElementsByTagName("img")[0];idx = (idx+1)%nums;change.src = paths[idx];
};
body {width: 500px;height: 500px;margin: 0 auto;display: flex;justify-content: center;
}
.image {width: 300px;margin: 100px 100px;display: flex;flex-wrap: wrap;justify-content: center;
}
.image img {width: 90%;margin: 20px 5%;
}
.image button {width: 20%;color: #353535;font-size: 20px;line-height: 20px;text-align: center;border-radius: 7px;border: solid 1px #696969;background-color: #c4c4c4;margin: 0 7%;
}
2. 选择

@fontSize:20px;
body{// width: 600px;height: 500px;margin: 0 auto;display: flex;justify-content: center;
}
.test{// width: 100%;margin: 100px 100px;font-size: @fontSize;display: flex;flex-wrap: wrap;justify-content: center;align-content: center;.first,#f2,#f3{width: 80%;height: @fontSize;margin: 10px;display: flex;flex-wrap: wrap;justify-content: center;align-content: center;div{margin: 0 10px;}.btn{height: 30px;color: rgb(53, 53, 53);font-size: @fontSize;line-height: @fontSize;text-align: center;border-radius: 7px;border: solid 1px rgb(105, 105, 105);padding: 0 10px;margin: 0 10px;}}
}
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body><div class="test"><div class="first">你爱好的运动是?<form id="f1" action="" method="post"><input id="choose" type="checkbox" name="choose" value="allOrNone" />全选/全不选</form></div><form id="f2" action="" method="post"><div name="ins"><input type="checkbox" name="sports" value="basketball" />篮球</div> <div name="ins"><input type="checkbox" name="sports" value="football" />足球</div><div name="ins"><input type="checkbox" name="sports" value="badminton" />羽毛球</div><div name="ins"><input type="checkbox" name="sports" value="pingpang" />乒乓球</div></form><form id="f3" action="" method="post"><input class="btn" id="all" type="button" value="all"><input class="btn" id="none" type="button" value="none"><input class="btn" id="reverse" type="button" value="reverse"><input class="btn" id="submit" type="button" value="submit"><input class="btn" id="add" type="button" value="add"><input class="btn" id="replace" type="button" value="replace"></form></div><script type="text/javascript" src="./learn.js"></script></body>
</html>
body {height: 500px;margin: 0 auto;display: flex;justify-content: center;
}
.test {margin: 100px 100px;font-size: 20px;display: flex;flex-wrap: wrap;justify-content: center;align-content: center;
}
.test .first,
.test #f2,
.test #f3 {width: 80%;height: 20px;margin: 10px;display: flex;flex-wrap: wrap;justify-content: center;align-content: center;
}
.test .first div,
.test #f2 div,
.test #f3 div {margin: 0 10px;
}
.test .first .btn,
.test #f2 .btn,
.test #f3 .btn {height: 30px;color: #353535;font-size: 20px;line-height: 20px;text-align: center;border-radius: 7px;border: solid 1px #696969;padding: 0 10px;margin: 0 10px;
}
/*# sourceMappingURL=./learn.css.map */
// 获取按钮
var btnAll = document.getElementById("all");
var btnNone = document.getElementById("none");
var btnRev = document.getElementById("reverse");
var btnSub = document.getElementById("submit");
var btnAdd = document.getElementById("add");
var btnRep = document.getElementById("replace");
var choose = document.getElementById("choose");
var items = document.getElementsByName("sports");
var f2form = document.getElementById("f2");
var inserts = document.getElementsByName("ins");
var str = [];
// 为按钮绑定单击响应函数
btnAll.onclick = function(){for(var i=0; i<items.length; ++i){items[i].checked = true;}choose.checked = true;
};btnNone.onclick = function(){for(var i=0; i<items.length; ++i){items[i].checked = false;}choose.checked = false;
};
btnRev.onclick = function(){for(var i=0; i<items.length; ++i){items[i].checked = !items[i].checked;}
};btnSub.onclick = function(){  for(var i=0; i<items.length; ++i){if(items[i].checked){str.push(items[i].value);}}if(str.length==0){str.push("choose nothing");}alert(str);str = [];
};
btnAdd.onclick = function(){var addStr = prompt("请输入待添加节点名及其value,以\" \"隔开(如 游泳 swimming):");var sportName = addStr.split(' ');// 创建"游泳"节点,添加到 id="f2" 的 form下// <div><input type="checkbox" name="sports" value="basketball" />篮球</div>// 1.创建div元素节点var swim = document.createElement("div");swim.name = "ins";// 2.创建 input 节点var inp = document.createElement("input");inp.type = "checkbox";inp.name = "sports";inp.value = sportName[1];// 3.创建文本节点var txt = document.createTextNode(sportName[0]);// 4.建立父子节点关系swim.appendChild(inp);swim.appendChild(txt);// 5.选择插入位置var addIdx = prompt("请输入插入位置(第几个,如 1):");f2form.insertBefore(swim,inserts[addIdx-1]);// 6. 更新节点inserts = document.getElementsByName("ins");
};
btnRep.onclick = function(){var addStr = prompt("请输入待添加节点名及其value,以\" \"隔开(如 游泳 swimming):");var sportName = addStr.split(' ');// 创建"游泳"节点,添加到 id="f2" 的 form下// <div><input type="checkbox" name="sports" value="basketball" />篮球</div>// 1.创建div元素节点var swim = document.createElement("div");swim.name = "ins";// 2.创建 input 节点var inp = document.createElement("input");inp.type = "checkbox";inp.name = "sports";inp.value = sportName[1];// 3.创建文本节点var txt = document.createTextNode(sportName[0]);// 4.建立父子节点关系swim.appendChild(inp);swim.appendChild(txt);// 5.选择替换位置var addIdx = prompt("请输入要替换的节点位置(第几个,如 1):");f2form.replaceChild(swim,inserts[addIdx-1]);// 6. 更新节点inserts = document.getElementsByName("ins");
};
// 获取单选框
choose.onclick = function(){for(var i=0; i<items.length; ++i){items[i].checked = this.checked;}
};
// 为每一个多选框都判断一次是否进行了全选
for(var i=0; i<items.length; ++i){items[i].onclick = function adjust(){var nums = 0;var items = document.getElementsByName("sports");for(var i=0; i<items.length; ++i){if(items[i].checked){++nums;}}if(nums==items.length){choose.checked = true;}else{choose.checked = false;}};
}
3. 拖拽
<div id="box1"></div>
<div id="box2"></div>
body{div{width: 100px;height: 100px;position: absolute;}#box1{background-color: rgb(194, 223, 247);}#box2{background-color: rgb(218, 255, 223);}
}
// 获取各个元素
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
/* 拖拽 box 元素1. 鼠标按下时,开始拖拽2. 鼠标移动时,元素跟随鼠标移动3. 鼠标松开时,元素停在该位置
*/
box1.onmousedown = function(event){event = event || window.event;// 偏移量 = 鼠标当前位置 - 元素当前位置var diffX = event.clientX - box1.offsetLeft;var diffY = event.clientY - box1.offsetTop;// 鼠标移动时,修改元素位置,绑定给 box 的父元素document.onmousemove = function(event){event = event || window.event;// 计算元素应该去的位置var mouseX = event.clientX - diffX;var mouseY = event.clientY - diffY;box1.style.left = mouseX + "px";box1.style.top = mouseY + "px";}// 鼠标松开时,元素停止移动,固定在当前位置,也就是取消移动事件,同时取消松开事件document.onmouseup = function(){document.onmousemove = null;document.onmouseup = null;}return false;
}
box2.onmousedown = function(event){event = event || window.event;// 偏移量 = 鼠标当前位置 - 元素当前位置var diffX = event.clientX - box2.offsetLeft;var diffY = event.clientY - box2.offsetTop;// 鼠标移动时,修改元素位置,绑定给 box 的父元素document.onmousemove = function(event){event = event || window.event;// 计算元素应该去的位置var mouseX = event.clientX - diffX;var mouseY = event.clientY - diffY;box2.style.left = mouseX + "px";box2.style.top = mouseY + "px";}// 鼠标松开时,元素停止移动,固定在当前位置,也就是取消移动事件,同时取消松开事件document.onmouseup = function(){document.onmousemove = null;document.onmouseup = null;}return false;
}

当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖拽功能异常。如果不希望发生这个行为,可以通过 return false; 来取消这个行为(IE8有毒吧???)。

4. 键盘移动小方块
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body id="body"><div id="box1"></div><script type="text/javascript" src="./learn.js"></script></body>
</html>
body {position: absolute;
}
body div {width: 100px;height: 100px;position: relative;background-color: #c2dff7;
}
// 获取各个元素
var box = document.getElementById("box1");
var speed = 10;
var dir = "nomove";
// 开启一个定时器来控制div移动方向
setInterval(function(){switch(dir){case "ArrowUp":box.style.top = box.offsetTop - speed + "px";break;case "ArrowDown":box.style.top = box.offsetTop + speed + "px";break;case "ArrowLeft":box.style.left = box.offsetLeft - speed + "px";break;case "ArrowRight":box.style.left = box.offsetLeft + speed + "px";break;}
},200);
document.onkeydown = function(event){event = event || window.event;    if(event.ctrlKey){speed  = 50;}else{speed = 10;}dir = event.key;
};
document.onkeyup = function(){dir = "nomove";
};
5. 图片定时自动切换

开启一个定时器,实现图片的自动切换。
每点击一次按钮就会开启一个定时器,这样开启多个定时器之后,图片切换的速度会非常快;而且即使按了停止按钮,也只能关掉最后的那个定时器,前面打开的无法再关闭 ⟶\longrightarrow⟶ 在开启定时器之前,需要将当前元素上的其他定时器关闭。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 令视口为完美视口 --><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>大秦帝国</title><link rel="shortcut icon" href="./imgs/kirlant.ico"><link rel="stylesheet" href="./baseCSS/reset.css"><link rel="stylesheet" href="./css/all.css"><link rel="stylesheet" href="./learn.css"></head><body><div class="image"><img id="imgs" src="./imgs/bf_3.jpg" /><button id="start">start</button><button id="stop">stop</button></div><script type="text/javascript" src="./learn.js"></script></body>
</html>

css代码同练习一。

var img = document.getElementById("imgs");
var btnStart = document.getElementById("start");
var btnStop = document.getElementById("stop");
var paths = ["./imgs/bf_3.jpg","./imgs/ssm_3.jpg","./imgs/xh_3.jpg"];
var nums = paths.length;
var idx = 0;
var times = 0;
btnStart.onclick = function(){clearInterval(times);times = setInterval(function(){++idx;idx %= nums;img["src"] = paths[idx];},1000);
};
btnStop.onclick = function(){clearInterval(times);
};

【JavaWeb学习】JavaScript(基础)相关推荐

  1. javaweb(02) JavaScript基础知识

    javaweb(02): JavaScript基础知识 JavaScript简介 为什么出现JavaScript Javascript是什么 JavaScript和Java的关系? 就像卡巴斯基和巴基 ...

  2. (四)javaweb 学习--javascript篇基础

    文章目录 javascript (数据类型,方法) javascrip使用 javascrip使用进阶 HTML代码 CSS代码 javascript代码 javascrip使用进阶2 HTML代码 ...

  3. 一步步学习javascript基础篇(8):细说事件

    终于学到事件了,不知道为何听到"事件"就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有 ...

  4. JavaWeb -03 JavaScript基础

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.JavaScript介绍 1.1 JavaScript简介 1.2 JavaScript发展史 1.3 JavaScri ...

  5. 前端学习-JavaScript基础(ES6)

    简介: ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并 ...

  6. 前端学习-JavaScript基础

    一.初识JavaScript 官网: https://www.w3.org/standards/webdesign/script 说明: JavaScript语法规范是ECMAScript,ECMAS ...

  7. JavaWeb学习 JavaScript语法快速学习

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

  8. JavaScript学习---JavaScript基础知识

    JavaScript的引入方式 JavaScript的引入方式: 1.直接在script里面写: 2.使用<script src="JS的文件位置"> {#1 直接编写 ...

  9. 前端学习-JavaScript基础(正则表达式)

    正则表达式 正则表达式在很多程序设计语言都有,大同小异,尤其是在Python爬虫的使用很多,我也就跟他们学习爬爬图片,小视频啥的,咳咳都是学习资料.在JavaScript中,使用比较多的是表单验证,字 ...

  10. 学习JavaScript基础入门(0基础JavaScript,)

    一.介绍JavaScript 1.编程语言 编程让计算机为解决某个问题而使用某种程序设计语言编写代码,并最终得到结果的过程 2.计算机基础 就是计算机所执行的一系列的指令集合,而程序全部都是我们所掌握 ...

最新文章

  1. 一种新的验证码(改进版)
  2. 跟我学雨林木风系统制作——2.涉及的技术及用到的工具介绍
  3. final 140字评论II
  4. 通过特殊字符查询所在表 或 存储过程
  5. linux python代码编辑器,Linux上的Python编辑器
  6. Elasticsearch 常见的 8 种错误及最佳实践
  7. Spring 框架用到的 9 个设计模式汇总!
  8. 用Unity盖房子(一):《勇者斗恶龙:建造者2》游戏功能的猜想
  9. 软考安全工程师历年真题汇总
  10. 驱动框架5——基于驱动框架写led驱动
  11. PPP认证原理和实验
  12. 吐血推荐 | 5+1款源代码管理笔记本(全平台)
  13. Jetson Nano 入坑之路 ----(9)C++调用SYN6288语音播报模块
  14. PointRCNN 车辆 行人 自行车识别
  15. LeetCode-618. 学生地理信息报告(困难)行转列
  16. 火灾探测和监测系统的最新进展回顾
  17. 制作u盘winpe启动盘_干货| 如何制作U盘启动盘安装操作系统
  18. Unity发布VR项目到Android
  19. 微信小程序用canvas画图并分享
  20. 抖音快手短视频如何用python程序高效的自动化剪辑?

热门文章

  1. matlab 动态邻域粒子群,求解TSP问题的动态邻域粒子群优化算法
  2. Jira - JIRA-Bootstrap ERROR
  3. matlab 字符串标量和字符向量
  4. 10项支持措施!武汉东湖新技术开发区打造中部地区风投创投中心奖励补贴政策解读
  5. 科研快报 | 三代测序技术-海水微生物态,助力海水微生态及微生物基因组研究
  6. 服务器硬盘故障数据恢复流程介绍
  7. 情人节程序员用HTML网页表白【情人节表白网页】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
  8. DOA估计 基于稀疏贝叶斯的离格DOA估计
  9. 用开源中国(oschina)Git管理代码(整合IntelliJ 13.1.5)
  10. 外汇天眼:多位支持加息放缓!美元走弱黄金上涨