概念:JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型的脚本语言。与HTML和CSS合称”前端三剑客“。
组成:ESMA Script + BOM + DOM
ESMA Script:主要是由ESMA(欧洲计算机制造商协会)制定的JS标准,即:JS的基础语法BOM:BOM(浏览器对象模型)是用于描述这种对象与对象之间层次关系的模型。BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。主要用于获取浏览器信息或 *** 作浏览器DOM:DOM(文档对象模型)是W3C组织推荐的处理可扩展置标语言的标准编程接口。主要用于 *** 作网页中的元素特点:
基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等 *** 作JavaScript都可直接对这些事件给出相应的响应交互性。JavaScript由于其动态性,让他具有良好的交互性,这也是它能被广泛应用于各大浏览器的原因之一简单易学。JavaScript是一种弱类型语言,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑跨平台性。JavaScript运行不依赖于 *** 作系统,同时它不需要服务器的支持,仅需要用户的浏览器支持,不同于服务端脚本语言,它是一种客户端脚本语言(相较而言,服务端脚本语言的安全性高于客户端脚本语言),而当今大部分浏览器都支持它作用:
嵌入动态文本于HTML页面。实现网页特效,包含广告代码、导航菜单代码、日历控件、飘浮特效、文字特效、色彩特效及图片特效等让网页和用户实现交互。对浏览器事件做出响应,比如实现d出窗口、元素的移动、窗口数据传递等在数据被提交到服务器之前验证数据。比如通过JS正则表达式验证表单中某数据域的数据类型或应满足的规则等基于Node.js技术进行服务器端编程。比如编写微信小程序JavaScript发展史:点击这里查看
ES各版本发布时间:(注意ES版本不等于JS版本)
ES1:1997ES2:1998ES3:1999ES4:ESMA预计在2008发布,但因兼容性成本太高,遭各大浏览器厂商抵制,未能如愿发布,详情ES5:2009ES5.1:2011ES6:2015ES7:2016ES8:2017ES9:2018ES10:2019ES11:2020ES12:2021
学习平台:菜鸟教程
二、JavaScript的引入方式
JavaScript的引入方式可以类比CSS的引入方式,共有三种:内联样式引入、内部样式引入、外部样式引入
这些样式的优先级:内联样式>内部样式||外部样式 后面两个的优先级遵循就近原则
内联样式引入:(也称标签级引入方式)直接在HTML标记属性值中直接写入JavaScript代码
DOCTYPE html>
<html lang="zn">
<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>引入方式测试1title>
head>
<body>
<button type="button" onclick="alert('Hello World!')"> 点我!button>
body>
html>
内部样式引入:(也称页面级引入方式)使用script标签进行引入Javascript代码
DOCTYPE html>
<html lang="zn">
<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>引入方式测试2title>
<script>
<!--
function hello() {
console.log("Hello World");//浏览器控制台输出
}
-->
/*
注意当浏览器能够识别script标签时,script中的不会被识别;当浏览器部能识别script标签时,会被识别, 因为所有的浏览器都能识别HTML的标签,但是不是所有的浏览器都能识别js代码,这样写的目的是防止js代码在不能识别js的浏览 器上报错。目的是提高容错(又学到一个小技巧)
*/
script>
head>
<body>
<script>hello();script>
body>
html>
外部样式引入:(也称项目级引入方式)将JS代码写在js文件中,html代码中使用script标签引入 (常用)
//js文件中的代码:
function hello() {
document.write("Hello World!");//网页输出
}
DOCTYPE html>
<html lang="zn">
<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>引入方式测试3title>
<script src="js代码部分.js">script>
head>
<body>
<script>
hello();
script>
body>
html>
三、JavaScript基础语法 1、变量
变量可分为:局部变量 和 全局变量
变量的命名规则:
变量名可以由数字0~9、字母A~Z或a~z、下划线 “_” 或美元符 “$”组成,但是不能以数字开始
例如:1a、d-c 都是非法的变量名
_1a、$bs、d_as、_、$ 都是合法变量名
注:
不能使用JavaScript中的关键字或保留字作为变量名。在JavaScript中定义了50多个关键字或保留字,它们是JavaScript内部使用的,不能作为变量的名称。如var、int、double、true等都不能作为变量的名称JavaScript的变量名区分大小写,如:str和Str分别代表两个不同的变量。最好进行 驼峰式命名,常量用大写字母JavaScript的变量名最好能够说明其代表的意思,譬如:定义两个字符串变量可用str1和str2,求和变量可用sum等变量的声明:
变量可以用var、let、const三种方式来定义,变量不需要指定某一种数据类型,被赋值后自动确定为相应的数据类型
var 变量名 = 值; //变量都是使用var关键字来声明
//例如:
var a = 123;
'use strict';//进入严格模式,可以防止一些不严谨而出现的bug(严格模式中变量的定义不能使用var来定义)
反正使用Java的规则取命名和声明肯定不会错
注:JavaScript是一种弱类型语言可以不进行声明直接使用,例如:a=123。不使用var声明时,浏览器在解析JavaScript代码时会将其解释为全局变量。在ES6中规定用let关键字来定义局部变量。
var和let的区别:(参考***)
let是块状作用域,而var是函数作用域(var定义的变量,内部函数可以访问外部函数的,反之不成立;而let定义的变量只能在一个{}代码块中有效,作用域为声明位置到该代码块结束位置)let不能在定义之前访问该变量,而var可以(因为var定义的变量会被预解析,输出的是undefined,而let就直接报错)let不允许变量在同一个作用域被重新定义,var允许let 和 const很相似,作用域相同,都是块状作用域、不能重复定义、不能在定义之前访问该变量,它们主要的区别是const定义的变量不允许被重新赋值,而let允许,通常用const去定义常量
所有的全局变量都绑定在window对象上,可以通过window.变量名来访问全局变量。
2、数据类型
js中的数据类型可分为两大类:基本数据类型(7种) 和 引用数据类型(……种)
2.1 基本数据类型2.1.1 Number基本数据类型共7种:Number、Boolean、String、Null、Undefined、Symbol、BigInt。其中前五种也叫作原始数据类型,是直接存储在栈中的简单数据段,占据空间小、大小固定,属于被频繁使用的数据。引用数据类型存储在堆内存中,占据空间大、大小不固定。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。
Number和BigInt范围的区别:
Number的范围:-9007199254740991 (-(2^53-1) ~ 9007199254740991(2^53-1) )
[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER]
BigInt的范围:5e-324 ~ 1.7976931348623157e+308
Number(数值型):表示所有类型的数值(js种把 整型和浮点型 都归为数值型)
//Number类型举例:
var a=123; //整数123
var b=1.23;//浮点数1.23
var c=1.2e3;//科学计数法1.2*10^3
NaN //非数字
Infinity //超出Number的最大表示范围,表示无穷大
2.1.2 Boolean Boolean(布尔型):true、false 2.1.3 String拓展:
NaN:
NaN虽然表示是一个非数字 , 但是一般是算术运算执行的结果, 因此NaN 仍然是 数值类型含NaN执行运算时 :如果是非加法运算,执行结果都是NaN;如果是加法运算 且 都是数值型的,结果为NaN,含有字符串型的,对数据进行拼接NaN 永远不会等于NaN。 NaN == NaN 执行结果是 false只能通过isNaN( )来判断一个数是否为NaNInfinity:JavaScript中数值的范围:5e-324 ~ 1.7976931348623157e+308
超过5e-324 的是负数的就是 -0,正数的就是 0。例如:-5e-325=-0,5e325=0超过1.7976931348623157e+308的是负数的就是-Infinity,是正数的就是Infinity。2e+308=Infinity,-2e308=-Infinity
String(字符串型): 表示字符串或单给字符(将Java中的String和char类型合并了)
//可以使用 '字符串' 或 “字符串” 或 `字符串` 包裹,特殊字符用转义字符表示
var str1 = "hi!";
var str2 = "ghp";
var str3 = `${str1}${str2}`;//EL表达式,必须在``中使用
alert(str3);//弹出hi!ghp
//字符串的常见操作
var str = "study";
//1.输出字符串的长度
alert(str.length());
//2.输出字符串的第1个字符(Java不能这样输出,Java只能输出字符串数组的某一个字符)
alert(str[0]);//注:不能单独使用str[]去改变字符串中的一个值
//3.字母大小写转换
str.toUpperCase();
str.toLowerCase();
//4.输出需要寻找字符第一次出现的索引位置
alert(str.indexOf('t'));//如果未找到返回-1
//5.输出字符串中[a,b)之间的字符串
alert(str.substring(1,3));//输出tu
2.1.4 Null
Null(空):表示一个空对象。当对象不存在时,输出时会返回NUll
2.1.5 Undefined
Undefined(未定义型):表示变量不含有任何值
2.1.6 Symbol常见返回是undefined的情况:
变量是未定义(未声明)的状态
变量没有进行手动赋值,编译器会默认赋值undefined(和Java不同,Java会给未赋值的变量自动赋相应初值)
获取对象中不存在的属性时默认为undefined
函数需要实参,但是调用时没有传值,形参是undefined
函数调用没有返回值或者return后没有数据,接受函数返回值的变量默认为undefined
使用Map中的set方法时未为key添加value时,value默认为undefined
Symbol(独一无二的值,ES6 新增):表示独一无二的值。Symbol 值通过 Symbol() 函数生成,其中Symbol()函数可以接收字符串参数,表示对 Symbol 实例的描述
2.1.7 BigInt好文!值得推荐 => 点这里1 点这里2
BigInt (大整数,能够表示超过 Number 类型大小限制的整数,ES11新增):可以用来更安全的表示Number范围外的数
拓展:
BigInt 类型不能用 Math 对象中的方法
不能和 Number 示例混合运。因为 JavaScript 在处理不同类型的运算时,会把他们先转换为同一类型,而 BigInt 类型变量在被隐式转换为 Number 类型时,可能会丢失精度,或者直接报错
BIgInt和Number能直接使用 “==”、“<”、“>” 进行比较
2.2 引用数据类型
Object(对象:是拥有属性和方法的数据) :在JavaScript中,除了基本数据类型其他的都是引用数据类型,相应的每种引用数据类型都有其相应的对象。JS中一切皆为对象,常见的有:Array、Function、Window、Documen、Date、RegExp……
对象的定义:
var person = { name : "ghp", age : 19, eamail : "12345678@qq.com" } var a = new person;//构造器创建对象
JavaScript中对象按定义可以分为:预定义对象和自定义对象。预定义对象是指系统提供的已经定义好的,可直接使用的对象,包含内置对象、文档对象和浏览器对象。按是否实例化可分为:实例化对象和普通对象。实例化对象,和Java中概念相同,抽象的类的对象不能被实例化。其实实例化有两个目的:一是为类创建了一个对象方便改变类中的属性值,二是一旦实例化,系统就会为该对象创建一个存储区域,该区域用来放你该对象属性
对象的操作:(和Java类似)
//1.对象的引用:(根Java类似) var a = person.name;//将对象person的name属性值赋给变量 //2.删减已有属性:delete 对象名.属性名; delete person.name; //3.添加新属性:对象名.属性名 = 属性值; person.sex = "男"; //4.判断属性是否在对对象中:属性值 in 对象名;(还可以用来判断对象父类中的属性) console.log("toString" in person);//输出true,toString是person的一个父类中的属性 //5.判断一个属性是否是这个对象自身拥有的:对象名.hasOwnProperty(); console.log(person.hasOwnProperty("toString"));//输出false //6.判断一个对象是否为另一个类的实例(还可以用于判断是否为另一个类的子类):对象名 instanceof 类名 var a = new Array(); console.log(a instanceof Array); //输出true console.log(a instanceof Object); /*输出true,Array是Object的子类(Object是所有对象的父类,也叫原型,在第四章会讲到)*/ console.log(a instanceof Function); //输出false //7.操作当前对象的属性和方法:this(java中是无法控制this的指向的,但是JS中可以通过apply控制this指向) var Person = { name : "ghp", birth : 2002, age : getAge } 1)当以普通函数的形式调用,this指向window对象 var getAge = fun(){ var now = new Date().getFullYear();//获取当前的年号 return this.age = now-this.birth; }; getAge();//this指向window,输出:NaN getAge.apply(Person,[])//输出:20。this指向Person,传入函数的参数为空 2)当以构造函数的形式调用,this指向新创建的对象 var a = new f(){ this.age = age; };//this指向a 3)当以方法的形式调用,this就指向当前调用的对象 console.log(Person.age);//this指向Person对象,输出:20 //8.批量操作指定对象的所有属性和方法:with(对象名) with(person){ var str = "姓名:" + name; var str = "年龄:" + age; var str = "性别:" + sex; }
2.2.1 Array
Array(数组):是预定义对象中的内置对象。用于在单个变量中存储多个值。(一给数组可以用来存多种类型的数据并且数组长度可变,和Java不同)
//数组的常规操作
var arr[1,2,3,4,5,6];
//1.可以使用arr[]改变索引处的字符
arr[2]=7;//将3改变成7,字符串.[]不能
//2. 可以使用arr.length改变数组长度(Java中不能改变数组长度,在Java中数组一经定义长度就确定了)
arr.length=2;//数组中第2个值以后的值都丢失,数组长度变为2
arr.length=8;//数组的第7,第8个为undefined
//3.输出需要寻找字符第一次出现的索引位置,未找到返回-1
console.log(arr.indexOf());//字符串的“1”和数字1不同
//4.截取数组的一部分,和操作字符串的substring()相似
console.log(arr.slice(1,3));//输出[2,3]
//5.push、pop
arr.push("7",8);//将"7"、8加入到arr的尾部,数组长度增加2,此时arr=[1,2,3,4,5,6,"7",8]
alert(arr.pop());//输出arr最后一个元素,数组长度减1,此时arr=[1,2,3,4,5]
//6.unshift(与push作用相反,添加元素在头部,数组长度增加)、shift(与pop作用相反,弹出头部的第一个元素,数组长度减1)
//7.对数组进行排序:arr.sort(),根据Unicode编码的字符大小来排序
//8.将数组中的元素反转:arr.reverse(),此时arr=[6,5,4,3,2,1]
//9.输出一个新数组,但是不改变原数组
console.log(arr.concat(7,"8"));//输出:[1,2,3,4,5,6,7,"8"],此时arr不变
//10.输出链接字符串,不改变元素组
console.log(arr.join("-"));//输出:1-2-3-4-5-6
//多维数组的定义:
var arrs[[1,2],[],[]];
2.2.2 Function
Function(函数):既有预定义对象,又有自定义对象。是由事件驱动的或者当它被调用时执行的可重复使用的代码块
和Java中的“函数”有很大区别,严格来讲Java中是没有“函数”这个概念的,Java中函数是必须写在类中的,是类的一个成员,需要类创建对象然后通过创建的对象来引用类中的方法(或者说直接在该函数同一个类中使用函数名来引用),它不属于一种数据类型,是属于类中的成员(或属性)。而在JS中是有函数这个概念的,函数可以自己创建对象来被调用,同时它属于引用数据类型。
Java中函数和JS中“函数”的比较:
Java中没有“函数概念”,只有“方法“概念。JS中函数和方法概念都有,JS中函数可以有相应的对象,可以直接调用也可以通过对象调用, 但是方法不能直接调用, 只能通过对象来调用,方法是一种特殊形式的函数(写在对象中或被对象属性调用的函数);Java中“方法”有重写和重载。JS中“函数”不能重构但能重写;Java中”方法“有分为普通方法和构造方法。JS中”函数“也分为普通函数和构造函数;java中的”方法“必须写在一个类中,是类的一个部分,通过类或类的实例化对象来调用。JS中”函数“是一种数据类型,可以单独写在外面,通过函数名调用或函数的实例化对象来调用;Java中”方法“的参数是强类型的,必须要传指定的数据类型、指定个数的数据。JS中函数的参数是弱类型参数,可以传任意个参数,也可以不传参数(参数默认为undefined),也可以传任意类型的参数。2.2.3 Window函数的定义:
//1.标准定义 function f([形参1],[形参2],……){ ……; return 数据;//需要返回值就写 } //2.匿名定义 var f = function ([形参1],[形参2],……){//和方法1等价 ……; return 数据;//需要返回值就写 } f();//无返回值函数的调用6 var a = f();//有返回值函数的调用 //构造函数的定义: var Person = function(name, age, gender) { this.age = age; this.name = name; this.gender = gender; } var p = new Person("ghp", 20, "男");
构造函数和普通函数的定义是差不多的,只是习惯上我们会将构造函数的函数名首字母大写。主要区别是调用方式不同,普通函数是直接调用,而构造函数必须使用new关键值创建新对象,通过对象来调用
解决传参问题:(函数的参数除了是基本数据类型和引用数据类型,还可以是HTML中的元素)
//手动抛出异常来判断传入的参数是否是指定数据类型 var abs = function(a) { if (typeof a !== "number") { throw "not a Number"; } if (a > 0) { return a; } else { return -a; } } //操作多余的参数:arguments(本质是用一个数组来接收所有参数) var f = function(a) {//假设调用f时多传了b、c两个参数 for(var i=0;i<arguments.length;i++){//遍历所有传进来的参数 console.log("第"+i+"参数:"+arguments[i]); } } //获取除了已定义的参数外的其他参数:...rest var f = function(a,...rest){//假设调用f时多传了2、3两个参数 console.log("已定义的参数:"+a); console.log("未定义的参数:"+rest);//输出:未定义的参数:2,3 }
函数中变量的作用域及其定义规范:
内部函数可以访问外部函数的成员,反之不成立
使用变量时,有一个由内而外的查找过程,当内部函数和外部函数变量重名时,内部函数会屏蔽外部函数的变量
var定义的变量作用域为函数式作用域,只要在函数内部(非内部函数)定义就能访问,但要访问变量的所赋的值需要先定义后使用,否则为undefined;let定义的变量作用域为块状域,一定要先声明后使用负责报错。所以一定要在函数的头部定义变量
JS中只有一个全局作用域,任何函数中的变量,假定没有在其函数的作用范围中找到,就会向外查找如果在全局变量中都没有找到,就会报错
Reference Error
由于所有的局部变量都会绑定在window对象上,在使用过程中很容易产生冲突。解决方法:自定义一个全局变量空间,将全局变量绑定在自定义的全局变量空间上
var SPACE = {};//写在文档的最开始位置 SPACE.PI = 3.1415926;//定义一个全局变量PI
Window:是预定义对象中的浏览器对象,代表当前的浏览器窗口(一个浏览器可以有多个窗口,代表浏览器可以用多个Window对象),是其他所有浏览器对象的父级,同时也是唯一一个引用不需要声明的对象
Window对象中常用的方法:
window.alter()window.innerHerght(); //获取浏览器窗口内部高度,窗口window.innerWidth();window.outerHeight(); //获取整个浏览器窗口的高度window.outerWidth();
window.screen.width(); //屏幕的宽、高window.screen.width();location.assign(‘url’); //实现网页跳转
2.2.4 DocumentWindow对象中常用对话提示框方法:
Open(URL,window name, window features):打开新窗口。
Close():关闭一个浏览器窗口。
alert(message):弹出一个警示对话框。
prompt(message,defaultmessage):弹出一个提示对话框。
confirm(message):弹出一个确认对话框。
setTimeout(expression,time):设置一定时间后自动执行一次expression代表的代码,使用time设置时间,以毫秒为单位。
setInterval(expression,time,[args]):设置一个时间间隔,使expression代表的代码可以周期性地被执行。使用time设置时间,以毫秒为单位。
备注:
prompt()方法不但可以像alert()方法和confirm()方法一样显示信息,而且还提供一个文本框要求用户从键盘输入自己的信息,同时它还包括“确定”和“取消”按钮。
其基本语法格式:prompt(“提示信息1”,“提示信息2”);
Document:document对象是浏览器对象,代表浏览器窗口中的文档,可以用来处理、访问文档中包含的HTML元素,如各种图像、超链接等。
write()方法,是document对象的最常用方法,他会自动解析HTML标签
document.write('待添加的文字'); //会在网页上输出h1标题类型的文字
document对象的属性有:
title:表示文档的标题。bgColor:表示文档的背景色。fgColor:表示文档的前景色。alinkColor:表示点击时超链接的颜色。linkColor:表示未访问过的超链接颜色。vlinkColor:表示已访问过的超链接颜色。URL:表示文档的地址。lastModified:表示文档的最后修改时间。
2.2.5 Date拓展:
document.cookie; //获取本地信息
一些黑客可以通过伪造cookie或者劫持cookie使用你的信息盗刷卡
一般服务器会使用cookie:httpOnly;进行加密
history必须要有历史记录
history.back(); 网页回退
history.forward(); 网页前进
history.go(n); //n去正数表示前进几个网页 ,负数表示后退几个页面
<body> <a href="https:baidu.com">点击跳转到百度a><br> <button onclick="advance()">点击前进button> <script type="text/javascript"> var a = document.querySelector('button'); function advance() { history.forward(); } script> body>
Date(日期):是JS中的预定义对象中的内置对象,其内部含有特有的方法,用于处理日期和时间
2.2.6 …常用操作:
var now = new Date(); now.getFullYear();//得到当前的年份,下面同理 now.getMoth();//月 now.getDate();//日 now.getDay();//星期 now.getHours();//小时 now.getMinutes();//分 now.getSeconds();//秒 now.getTime();//时间戳,全世界统一且唯一动态变化的,起始:1970.1.1.00:00:00 console.log(new Date(now.getTime())); //对时间戳进行解码,输出当前时间:Sat Apr 16 2022 23:16:56 GMT+0800 (中国标准时间) console.log(now.toLocaleString());//输出本地时间:2022/4/16 23:23:44 now.toGMTString();//格林威治标准时间,输出:Sat, 16 Apr 2022 15:28:12 GMT
时间戳(time-stamp)是一个经加密后形成的凭证文档,它包括三个部分:
需加时间戳的文件的摘要(digest)
DTS收到文件的日期和时间
DTS的数字签名
一般来说,时间戳产生的过程为:用户首先将需要加时间的文件用Hash编码加密形成摘要,然后将该摘要发送到DTS,DTS在加入了收到文件摘要的日期和时间信息后再对该文件加密(数字签名),然后送回用户。
时间戳的作用:客户端在向服务端接口进行请求,如果请求信息进行了加密处理,被第三方截取到请求包,可以使用该请求包进行重复请求操作。如果服务端不进行防重放攻击,就会服务器压力增大,而使用时间戳的方式可以解决这一问题
RegExp(正则表达式)……
拓展:
数据类型的判断:typeof 参靠文章 => 这里
用法:typeof(表达式) 。eg:
console.log(tyeof((1+2)));//输出:number console.log(tyeof((1+2+"a")));//输出:string console.log(tyeof(hello));//hello是函数名,输出:function(经测试发现匿名函数前的变量名类型是函数) consele.log(tyeof(person));//输出:object
JSON:
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。(早期都是使用 XML 数据交换格式的)
JSON的作用:
让数据的结构层次分明,简洁而清晰,易于人理解和阅读
易于机器解析和生成,并能够有效地提升网络传输效率
JSON和JS种对象的关系:JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的 var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
JSON和JS对象的转换:
//将JSON字符串转换成JS对象 var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'} //将JS对象转换成JSON字符串 var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
3、符号
JavaScript中符号可以分为:运算符 和 转义字符,以及一些特殊字符。
注释符和Java中一样
运算表达式=运算符+数据,实质是一个值
3.1.2 比较运算符”+“还可以用于字符串之间的连接,如:
var str1="123"; var str2="123"; var str3=str1+str2;//此时输出str3,会得到123123 //当一个表达式中有一个String类型,进行加法运算都会变成字符串的拼接
此外:”=“表示赋值
3.1.3 逻辑运算符除表中的以外,还有 **绝对等于 **:”===“,表示 数据类型相同 同时 值也相同(Java中没有)
运算符 | 功能描述 |
---|---|
&& | 逻辑与。同为真才为真,有一个为加,结果为假 |
|| | 逻辑或。同为假才为假,有一个为真,结果为假 |
! | 逻辑非。真为假,假为真 |
3.1.4 位运算符此外:“!!” 表示:将数据转成所对应的Boolean类型,例如:
var a = 123; var b = !!a; console.log(b);//输出:true。在js中+0(0)\-0转成Boolean型都是false,其他的数值都是true
运算符 | 功能描述 |
---|---|
& | 位与。同为1才为1,有一个为0,结果为0 |
| | 位或。同为0才为0,有一个为1,结果为1 |
^ | 异或。不同取1,相同取0 |
~ | 取反。1取0,0取1 |
>> | 右移。等价于除以2 |
<< | 左移。等价于乘以2 |
3.1.5 条件运算符此外:“~~” 表示:浮点数取整。例如:
var a = 3.1415926; var b = ~~a;//此时b=3
表达式1 ? 表达式2 : 表达式3 //当表达式1为真时,执行表达式2;为假时执行表达式3
3.2 转义字符
转义字符 | 功能描述 | |
---|---|---|
空格(\u0000) | \b | |
退格符(\u0008) | \t | |
水平制表符(\u0009) | \n | |
换行符(\u000A) | \v | |
垂直制表符(\u000B) | \f | |
换页符(\u000C) | \r | |
回车符(\u000D) | \" | |
双引号(\u0022) | \’ | |
单引号(\u0027) | \ | |
反斜杠(\u005c) | \xHH | |
由两位十六进制数组成数值表示latin1字符 | \XXX | |
由三位十六进制数组成的数值(000~377)表示Unicode编码 | \uHHHH | |
由四位十六进制组成的数值来表示表示Unicode编码 | if
退格符:用来删除前一个字符,对应键盘上的Backspace键
水平制表符:让字符串成4的倍数输出,不足的补空格
垂直制表符:让\v后面的数据换行同时接着与上面数据的末尾对齐输出 输出居然乱码了?
换行符:让光标往下一行(不一定到下一行行首,但通常是首行)
回车符:让光标重新回到本行开头
Unicode编码参考文章 => 点击查看
注意:在window操作系统中,Enter相当于 \r\n。参考文章 => 点击查看
4、流程控制 4.1 分支结构:
()表达式else……if……
()表达式else……if ()表达式else……//1.while循环:……
……无限套娃
4.2 循环结构:
while
()表达式;{
……}
do
;{
……}
while()表达式;//2.for循环:
for
([let] 变量赋值;;判断[]表达式)//[]中的内容可以省略{;
……}
for
(varin i ) arr//循环遍历数组时,i表示索引位置;循环遍历对象时;i表示一个属性,也能用person[i]表示和i是一样的效果{.
consolelog()i;//输出:0,1……}
//3.forEach循环:用于输出一个数组的所有值或对象属性的所有值
.
arrforEach(function(value).{
consolelog()value;//循环输出数组arr中的值}
);//4.分支语句switch
switch
( )表达式case{
value1 :1 语句块;case
value2 :2 语句块;case
value3 :3 语句块;...
default
:; 语句块n}
//6.关键字:break、continue和Java中一样
var
拓展:
Map:给对象设置若干对相关联的键(key)和键值(value)
= map new Map ([["a",92],["b",99],["c",95]]);//1.通过key获得value//输出:Map(3) {'a' => 92, 'b' => 99, 'c' => 95} var = i . mapget("a");//输出:92//2.向map中增加一对新的key和value . mapset("d",66);//3.删除键,以及对应的键值//输出:Map(4) {'a' => 92, 'b' => 99, 'c' => 95, 'd' => 66} . mapdelete("a");var//输出:Map(2) {'b' => 99, 'c' => 95}
Set:无序不重复的集合
= set new Set ([1,1,"1",2,3]);//set中只有一个1//1.向set中添加一个元素,在末尾 . setadd("ghp");//输出:Set(5) {1, '1', 2, 3, 'ghp'}//2.删除set中指定的一个元素 . setdelete(1);//输出:Set(3) {'1', 2, 3}//1.遍历数组
Iterator:迭代器 (ES6新增)
var = arr [ 1,2,3];for (letof i ) arr.{ consolelog()i;//输出:1 2 3。和for in 是不同的,i表示的是arr的值} //2.遍历map var = map new Map ([["a",92],["b",99],["c",95]]);for (letof i ) arr.{ consolelog()i;//输出:(2)["a",92] (2)["b",99] (2)["c",95]} var
原生具备 Iterator 接口的数据结构: (引自***)
Array、Map、Set、String、TypedArray、NodeList 对象、函数的 arguments 对象。
对于不具备Iterator接口的数据结构(主要是对象)都需要自己在Symbol.iterator属性上面部署,这样才会被for…of循环遍历。原因:对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。
四、面向对象编程
1、原型引言:
面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。
在JavaScript中有原型概念,和Java中的父类是相似的概念。原型的实现:
name Student{
:"qingjiang",age
:2,run
:function().{
consolelog(this.+name"run......");}
}
;var
= xiaoming name {
:"xiaoming"}
;.
xiaoming=_proto_ ; Student//小明的原型是Student函数对象,和Java中继承是类似的.
xiaomingrun();//控制台输出:小明run......class
2、继承
注:是在ES6引入的,使用关键字extend,和上面的原型是一样的效果,继承的本质就是原型
Student constructor{
(name)//constructor是定义构造器的关键字,和Java中的构造方法是一样的效果{this
.=name ; name}
hell
()alert{
("hello");}
}
var
= xiaoming new Student ("xiaoming");//实例化对象class
xiaoStudent extends Student constructor{
(,name)grade//重写父类的方法{super
()name;//调用父类的方法this
.=grade ; grade}
}
.
😆感觉在写Java
拓展:
原型链:每一个对象都会有一个原型对象Object,Object本身也是一个对象,它自己的原型是它本身,如此就形成了一个原型循环链
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。——摘自《javascript高级程序设计》
五、操作DOM对象
引言:
DOM对象就是文档对象(document)
DOM模型:整个网页就是一个DOM树,将HTML中的每个标签看作一个结点,每个结点都可以看作一个对象,它们的层次关系表示标签在网页中的嵌套关系,同一层结点的左右次序表示这些标签对象出现的先后顺序。
对DOM的操作,要操作先要获取一个DOM节点。(对DOM的操作预示着:可以只用JS实现一个网页)
增、删、改、查
5.1 获取DOM节点获取子节点:
documentquerySelector('#idname');//获取document节点中的拥有这个id名的节点 .
documentquerySelector('.classname');//获取document节点的第一个节点的拥有这个class类名的节点 .
documentquerySelector("TagName");//获取ducument节点中第一个标签的节点 .
documentquerySelectorAll()//获取所有类型的节点
eg:
DOCTYPEhtml <>
langhtml =""zn<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
<body>
iddiv =""fatherclass =""father<>
idp =""p1class =""p1>123<p>
idp =""p2class =""p1>456<p>
idp =""p3class =""p1>789p>
<div>
<script> !--HTMLjs代码要写在,代码下面--否则需要写一个函数在此处调用var>
= a . documentquerySelector("#p2");.
a=innerText '000' ;//将id="p2"的节点进行修改var
= b . documentquerySelector('.p1');.
b=innerText '999' ;//将document中的第一个的节点进行修改
script>
body>
1.html>
获取父级节点:
. documentgetElementById("idname").;parentElement2.
. documentgetElementById("idname").;parentNode.
documentgetElementById("idname").;offsetParent// 获取所有父节点,返回数据为数组类型 var
5.2 更新DOM节点 innerText和innerHTML
= a . documentgetElementById('diname');.
a=innerText '123' ;.
a=innerHTML ; '123<\strong>'//能够转义HTML标签 .
replaceChild可以通过获取的id操作相应的标签
例如:通过a.style.color= ‘red’; 更改css样式
nodereplaceChild( ,newnode)oldnode //只能使用父节点去操作替换下面的子节点 newnode
: oldnode 必需,用于替换 oldnode 的对象。
: 必需,被 newnode 替换的对象。
eg:
DOCTYPEHTML <>
<html>
<head>
http-equivmeta =""Content-Typecontent =""text/html; charset=utf-8<>
title>无标题文档title>
<head>
<body>
<div>
idspan =""oldnode>JavaScript是一个很常用的技术,为网页添加动态效果span>
<div>
hrefa =""javascript:replace()> 将加粗改为斜体<a>
typescript =""text/javascriptfunction>
replace ()var {
= oldnode . documentgetElementById('oldnode');var
= newnode . documentcreateElement("i");.
newnode=innerHTML . oldnode;innerHTML//将旧节点的内容赋给新节点.
oldnode.parentNodereplaceChild(,newnode) oldnode;//替换旧节点原来在网页(DOM数)中的位置}
script>
body>
<html>
5.3 删除节点
必须使用父节点删除子节点
object.removeChild();
<body>
idp =""p1>123<p>
idp =""p2>456<p>
idp =""p2>789 p>
//方法1:body>
var
= self . documentgetElementById('p1');var
= father . self;parentElement//获取p1的父节点 .
fatherremoveChild()self//删除p1,可以将self换成p1//方法2:
var
= self . documentgetElementById('p1');var
= father . self;parentElement//获取p1的父节点 .
fatherremoveChild(.father[children0])//注意删除节点的时候,是动态变化的.
fatherremoveChild(.father[children1])//此时删除的是第3个节点:789,因为当删除完第1个节点,第3个节点动态变化为第2个节点了
5.4 创建和插入节点
插入的节点是放在被插入节点的后面
创建节点:document.createElement()
插入节点:document.appendChild()
DOCTYPEhtml <>
langhtml =""zn<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
<body>
iddiv =""fatherclass =""father<>
idp =""p1class =""p1>123<p>
idp =""p2class =""p1>456<p>
idp =""p3class =""p1>789p>
<div>
varscript>
= a . documentgetElementById('father');var
= b . documentcreateElement('p');//创建一个新的节点,该节点为p标签.
b=innerText 'Hello World!' ;.
aappendChild()b;//此时在div的组后添加一个p标签,内容为:Hello World! 可以在浏览器中查看到该p标签
script>
body>
//插入css样式html>
var
= myStyle . documentcreateElement('style');//创建一个style节点.
myStyle=setAttribute ( 'type','text/css' );//设置文档类型,可以省略不写.
myStyle=innerHTML 'body{background-color:green;}' ;//设置css样式.
documentgetElementsByTagName('head')[0].appendChild()myStyle;//注意要指明第一个,不然浏览器无法选中//当然也可以直接使用document.querySelector('head').appendChild(myStyle);
拓展:
在JavaScript中,我们可以使用cloneNode()方法来实现复制节点。
语法:obj.cloneNode(bool)
说明:
参数obj表示被复制的节点,而参数bool是一个布尔值,取值如下:
(1)1或true:表示复制节点本身以及复制该节点下的所有子节点;
(2)0或false:表示仅仅复制节点本身,不复制该节点下的子节点;
使用这些方法去操作DOM节点太繁琐了,所以就诞生了JQuery
六、事件
6.1 注册事件在JavaScript中,事件往往是页面的一些动作引起的,例如当用户按下鼠标或者提交表单,甚至在页面移动鼠标时,事件都会出现
给元素添加事件,称为注册事件或者绑定事件
注册事件可分为:传统注册方式 和 方法监听注册方式
传统注册方式:通常是利用“on”开头的事件+函数进行实践注册
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classbutton =""btns>鼠标点击触发点击事件1<button>
classbutton =""btns>鼠标点击触发点击事件2<button>
varscript>
= x . documentquerySelectorAll('button');//获取所有button节点 [
x0].onclick= function ()//只对第一个button节点进行事件注册 { alert
("hi");}
script>
body>
传统注册方式注册事件具有唯一性,DOM对象只能绑定一个事件,后面绑定的事件会覆盖掉前面绑定的事件,和CSS样式的规则一样
html>
注:
方法监听注册方式:利用addEventListener()方法(IE9之前的IE浏览器不支持,可以用AttachEvent()代替)W3C新标准
eventTarget.addEventListener(type,listener[,useCapture])
eventTarget:目标对象type:事件类型,click、mouseover等,就是传统事件不带onlistener:事件处理函数useCapture:可选参数,false(默认) || ture
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classbutton =""btns>鼠标点击触发点击事件1<button>
classbutton =""btns>鼠标点击触发点击事件2<button>
varscript>
= x . documentquerySelectorAll('button');//获取所有button节点 [
x0].addEventListener('click',function ()alert {
('这是最新的事件注册方式');}
)
script>
body>
方法监听注册方式注册事件可以对DOM对象同时绑定多个不同类型的事件,不同事件按顺序执行,相同事件后面的覆盖前面的,和CSS样式的规则一样 html>
注:
6.2 删除事件
将注册的事件删除或解绑
传统删除事件
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
div>1<div>
div>2<div>
div>3<div>
varscript>
= x . documentquerySelectorAll('div');//获取所有button节点 [
x0]..style=border ( '1px solid black');//设置边框,更显眼 [
x0].onclick= function alert {
('hi');[
x0].=onclick null ;//删除事件}
script>
body>
html>
使用removeEventListener()方法删除事件(IE9之前的IE浏览器不支持,可以用detachEvent()代替)
eventTarget.removeEventListener(type,listener[,useCapture])
eventTarget:目标对象type:事件类型,click、mouseover等,就是传统事件不带onlistener:事件处理函数useCapture:可选参数,false(默认) || ture
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
div>1<div>
div>2<div>
div>3<div>
varscript>
= x . documentquerySelectorAll('div');//获取所有button节点 [
x0]..style=border ( '1px solid black');//设置边框,更显眼 [
x0].addEventListener('click',) f;//注:千万不要给函数加小括号function
f ()alert {
('hi');[
x0].removeEventListener('click',) f;}
script>
body>
html>
注:要删除事件时,不能使用匿名函数的写法,因为此时用匿名函数会导致无法写明删除的是哪一个事件。同时在不使用匿名函数的写法时,在注册使事件时,不需要给函数加小括号
6.3 DOM事件流 定义:事件发生时会在DOM节点上有一个特定的传递方向,我们将这一个过程称之为DOM事件流拓展:
不加小括号,直接使用函数名是传地址,这个可以用C语言测试,打印输出:printf(“%x\n”,f); ; 而使用小括号是代表调用函数,是传函数的返回值,如果这里加个小括号,就不需要点击事件函数会自动触发
主要有:捕获阶段、目标阶段、冒泡阶段 捕获阶段:网景最早提出,事件注册时从DOM最顶级节点向下传播,直至待处理事件的节点目标阶段:传播到待处理事件的节点时称之为目标阶段冒泡阶段:IE最早提出,事件从目标节点后,逐级向上传播直至DOM最顶级节点 示意图:假设给div节点绑定一个事件
DOM事件流阶段的执行
JS代码只能执行捕获阶段或冒泡阶段传统事件注册和attachEvent方法只能得到冒泡阶段addEventListener方法可以获取捕获阶段和冒泡阶段,当useCapture取值false时,执行冒泡阶段;取值true时执行捕获阶段代码测试:
//useCapture默认取值为false时执行冒泡阶段
//点击son时,会先弹出son,再弹出father
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classdiv =""fatherstyle ="height:; 100px"<>
classdiv =""sonstyle ="height:;20px ">div>
<div>
varscript>
= y . documentquerySelector('.son');.
y.style=border ( '1px solid black');//设置边框,更显眼 .
yaddEventListener('click',function ()alert {
('son');}
);var
= x . documentquerySelector('.father');.
x.style=border ( '1px solid black');//设置边框,更显眼 .
xaddEventListener('click',function ()alert {
('father');}
);
script>
body>
html>
//useCapture取值为true时执行捕获阶段
//点击son时,会先弹出father,再弹出son
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classdiv =""fatherstyle ="height:; 100px"<>
classdiv =""sonstyle ="height:;20px ">div>
<div>
varscript>
= y . documentquerySelector('.son');// .
y.style=border ( '1px solid black');//设置边框,更显眼 .
yaddEventListener('click',function ()alert {
('son');}
,true );var
= x . documentquerySelector('.father');.
x.style=border ( '1px solid black');//设置边框,更显眼 .
xaddEventListener('click',function ()alert {
('father');}
,true );
script>
body>
e = e | window.event
html>
6.4 事件对象
常用事件对象event,这是一个形参通常可以写成:e、evt。再IE6、7、8需要写成window.event,
兼容型写法:;同时它是浏览器给定的,它是一堆事件的集合
this和target方法的区别:
this指向我们绑定事件的对象;target指向触发事件的对象
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classdiv =""fatherstyle ="height:; 100px"<>
classdiv =""sonstyle ="height:;20px ">div>
<div>
varscript>
= x . documentquerySelector('.father');.
x.style=border ( '1px solid black');//设置边框,更显眼 .
xaddEventListener('click',function (e)// console.log(this);//无论点击son还是father都是输出father {
.
consolelog(.e)target//点击son就输出son的div,点击father就输出father的div}
);var
= y . documentquerySelector('.son');.
y.style=border ( '1px solid black');//设置边框,更显眼 // console.log(this);
//y.addEventListener('click', function(e) {
// console.log(e.target)
//});
script>
body>
.html>
阻止默认事件的发生:例如a标签的跳转
对于非IE主流浏览器:
nodeaddEventListerner('click',function(e).{
epreventDefault();}
).
对于IE6、7、8
nodeonclik= function (e).{
e;returnvalu}
.
对于传统的注册方式:使用return false;
nodeonclik= function (e)return{
false ;}
点击son时,会先弹出son,再弹出father
注:return后面的代码是无法继续执行的,但是兼容性很好
阻止事件冒泡:e.stopPropagation (同时可以取消事件捕获)
只弹出son
注:哪里需要阻止就往哪里加,因为加在son里面,它只是阻止son不能往上冒泡,如果点击事件发生在father上,且father的父级也绑定了事件,那么仍会冒泡
//useCapture默认取值为false时执行冒泡阶段
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
classdiv =""fatherstyle ="height:; 100px"<>
classdiv =""sonstyle ="height:;20px ">div>
<div>
varscript>
= y . documentquerySelector('.son');.
y.style=border ( '1px solid black');//设置边框,更显眼 .
yaddEventListener('click',function (e)alert {
('son');.
estopPropagation();}
);var
= x . documentquerySelector('.father');.
x.style=border ( '1px solid black');//设置边框,更显眼 .
xaddEventListener('click',function (e)alert {
('father');}
);
script>
body>
ifhtml>
拓展:
对于IE6、7、8的兼容性写法
(&&e . e)stopPropagation//如果浏览器认识e同时能够识别stopPropagation方法执行{. estiopPropagation();} else.{ window.event=cancelBubble true ;//IE6、7、8只认识cancelBubble方法}
事件委托:
事件委托:又称事件代理,在JQuery中称为事件委派。它是利用事件冒泡原理,通过父级节点来操作子节点,让程序做到只操作一次DOM节点就能操作多个DOM节点,能够有效提高程序的性能
//给父节点绑定事件,通过父节点的事件去改变字节点
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
<ul>
li>111<li>
li>222<li>
li>333li>
<ul>
varscript>
= ul . documentquerySelector('ul');.
uladdEventListener('click',function (e)//点哪个哪个就变色 {var
= x . e;target//获取点击的节点.
x.style=backgroundColor 'green' ;//改变点击节点的背景色// e.target.style.backgroundColor = 'green';
}
)
script>
body>
html>
鼠标事件:
//让图片随着鼠标移动而移动
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
srcimg =""./images/guajian.pngalt =""<>
<body>
varscript>
= img . documentquerySelector('img');.
documentaddEventListener('mousemove',function (e)var {
= x . e;pageXvar
= y . e;pageY.
img.style=position 'absolute' ;//加绝对定位,让图片移动不影响其他东西 .
img.style=left - x 160 + 'px' ;//一定要记得加单位,其中-160是为了让图片居中 .
img.style=top - y 160 + 'px' ;}
)
script>
body>
k
e
y
d
o
w
n
→
k
e
y
p
r
e
s
s
→
k
e
y
u
p
keydown\rightarrow{keypress}\rightarrow{keyup}
html>
键盘事件:
注:当使用最新的时间注册方式addEventListener()方法不需要写on。上面三个事件的执行顺序是:keydown→keypress→keyup
k
e
y
p
r
e
s
s
keypress
,其中keypress
k
e
y
u
p
keyup
不能识别功能键。同时keyup
k
e
y
d
o
w
keydow
和keydow
k
e
y
p
r
e
s
s
keypress
不区分大小写,但keypress//判断用户按下的键keyCode方法
document.addEventListener('keydown', function(e) {
alert(e.keyCode);//打印出来的是相应键位的ascii码值
})
区分
拓展:
//1.禁止鼠标右键弹出菜单 contextmenu DOCTYPEhtml <> <html> langhead =""en<> charsetmeta =""UTF-8<> title>Testtitle> <head> <body> p>dslfjlasjgflsdjgl;<p> varscript> = p . documentquerySelector('p');. paddEventListener('contextmenu',function (e). { epreventDefault();} ) script> body>
//2.禁止鼠标选中 selectstart var p = document.querySelector('p'); p.addEventListener('selectstart', function(e) { e.preventDefault(); })
html>//3. 获取鼠标焦点 node.focus();
使用mouseover时鼠标经过自身盒子或者经过子盒子时都会触发,而mouseenter时只会经过自身盒子时才被触发
mouseenter和mouseover的区别:
原因:mouseenter不会产生事件冒泡,而mouseover会产生事件冒泡
同样的mouseleave同样不会冒泡
6.5 BOM概述
BOM(Browser Oject Model)即浏览器对象模型,将整各浏览器看作是一个对象。它提供了独立于内容于浏览器窗口进行交互的对象,其核心对象是window,window中的方法是可以不需要使用 对象名.方法()来引用,同时它是所有浏览器对象的父级对象,并且它是由各浏览器厂商在各自的浏览器上自定义的,缺乏一个标准,所以兼容性较差。
JavaScript的标准是ECMA,DOM的标准的W3C,BOM最初是NEtscape浏览器的标准。需要注意的是:window包括document
window是浏览器窗口的一个接口它是一个全局对象,定义在全局作用域中的变量,函数都会绑定在window对象上,可以通过window.调用它们回顾:window 作用域
load事件和DOMContentLoaded事件的区别:
load:等页面内容全部(包括HTML标签、css、图片、音频、视频)加载完毕,在执行相应JS代码DOMContentLoaded:DOM(主要是HTML标签,不包括css、图片、音频、视频)加载完毕,执行相应JS代码risize事件:浏览器窗口发生变化就执行相应JS代码
setTimeout(function,time) 定时器
time单位是毫毛:1s 对应的是 1000,表示间隔多久调用前面的函数,然后就结束 注:只调用一次,前面调用的函数不要加()
或者写成这样setTimeout(function(){},time);
setInterval(funtion,time) 定时器 注:重复调用
使用方法和setTimeout方法相同,每隔time调用一次
clearInterval(setintervalName):
//设置一个开启和关闭定时器的按钮
DOCTYPEhtml <>
<html>
langhead =""en<>
charsetmeta =""UTF-8<>
title>Testtitle>
<head>
<body>
button>开启定时器<button>
button>关闭定时器<button>
varscript>
= btn . documentquerySelectorAll('button');var
= time null ;//一定要将函数的对象time定义成能被clearInterval()方法访问到,不然会报错 [
btn0].addEventListener('click',function ()= {
time setInterval (function(). {
consolelog("How are you?");}
,1000 );}
);[
btn1].addEventListener('click',function ()clearInterval {
()time;}
)
script>
body>
html>
七、三大常用方法 7.1 offset
相关属性:可以通过offset动态得到元素的位置、大小等
获取元素距离带有定位的父元素的位置(如果父级没有定位,以上一级有定位为主,都没有则以body为准)获取元素自身大小(宽度、高度)注:offset方法的返回值不带单位
offsetParent返回具有定位的父级标签(如果父级没有定位,以上一级有定位为主,都没有则以body为准),parentNode返回父级标签(无论是否具有定位);具体看代码
DOCTYPEhtml <>
langhtml =""en<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
.div1style>
position {
:; absolute}
<style>
<body>
classdiv =""div1<>
classdiv =""div2<>
classdiv3 =""div3>
div3>
div>
<div>
varscript>
= node . documentquerySelector('div3');.
consolelog(.node)offsetParent;//返回div1
script>
body>
html>
offset与style的区别 7.2 cilent动画原理:通过定时器setInterval()不断移动盒子的位置
cilent相关属性: 7.3 scroll scroll相关属性:通过使用cilent相关属性可以获取元素可视区的相关信息,动态得到元素的边框大小、元素大小
八、动画 8.1 动画实现的基本原理
动画的实现通常需要搭配定时器setInterval来实现。
实现步骤:
获取当前盒子的位置 (注:需要添加动画的元素一定要加定位relative | absolute | fixed)获取元素节点,使用style增加距离利用定时器不断重复上面的操作可以使用clearInterval清除定时器从而停止动画
DOCTYPEhtml <>
langhtml =""en<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
divstyle>
position {
:; absoluteleft
:; 0pxwidth
:; 100pxheight
:; 100pxbackground-color
:; pink}
<style>
<body>
div><div>
varscript>
= div . documentquerySelector("div");setInterval
(function(). {
div.style=left . div+offsetLeft 1 + "px" ;//只有元素添加了定位才能使用node.style.left}
,10 );//定时器设置10ms,设置间隔时间越少动画越流畅
script>
body>
html>
8.2 动画函数封装
使用一个动画函数对某一类动画进行封装,能够减少很多重复的代码。
一般的动画函数需要两个参数:目标对象obj,target移动的距离
速度:
relative>absolute|fixed
,暂且不知道原因
DOCTYPEhtml <>
langhtml =""en<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
.div1style>
position {
:; absoluteleft
:; 0pxwidth
:; 100pxheight
:; 100pxbackground-color
:; pink}
.div2
position {
:; relativetop
:; 100pxleft
:; 0pxwidth
:; 100pxheight
:; 100pxbackground-color
:rgb (,192, 255) 194;}
<style>
<body>
classdiv =""div1><div>
classdiv =""div2><div>
functionscript>
move (,obj) targetvar {
= timer setInterval (function()if {
( .obj)offsetLeft >= target//达到条件就停止动画 {clearInterval
()timer;}
.
obj.style=left . obj+offsetLeft 1 + "px" ;}
,50 );}
var
= a . documentquerySelector(".div1");var
= b . documentquerySelector(".div2");move
(,a100 );move
(,b300 );
script>
body>
move
html>
8.3 缓动动画优化代码:给不同元素添加不同的定时器
因为前面的简单封装在调用一次var timer =...
函数就会在系统中开辟一个空间,很浪费资源核心原理:利用JS的动态性的特点,动态给对象添加属性
即只要将:上面代码的
obj.timer =...
改为clearInterval(timer);
以及clearInterval(obj.timer);
改为button
完善代码:增加点击触发事件
因为在实践中大部分情况是通过一个点击事件来触发js动画效果的
在HTML代码中添加一个按钮
var bnt = document.querySelector("button")
在JS代码中获取button节点:
clearInterval(obj.timer);
然后绑定事件:btn.addEventListener(‘click’, function() {
move(a, 100);
});
但是会有一个bug,a会越点越快,因为每点击一次就会增加一个定时器。
需要在调用函数的最开始加一个清除定时器的代码: ( 目 标 值 − 现 在 的 位 置 ) / 10 (目标值-现在的位置)/10
前面的动画效果都是匀速运动,缓动动画就是让元素的运动速度有所变化,最常见的是减速运动
减速公式:(目标值−现在的位置)/10var (10是步长,步长越大减速效果更明显)
= step ( -target.obj)offsetLest/10//向左越来越慢移动 var
上面step存在小数问题,因为除法是直接舍去小数部分的,会导致实际移动距离小于目标移动距离
对于正方向的移动,采用向上取整,对于负方向的移动,采用向下取整
= step ( -target.obj)offsetLeft/10;=
step 0 step > ? . Mathceil()step: . Mathfloor()step;
8.4 给动画添加回调函数
回调函数是添加在动画结束的位置。动画结束后就执行回调函数。
DOCTYPEhtml <>
langhtml =""en<>
<head>
charsetmeta =""UTF-8<>
http-equivmeta =""X-UA-Compatiblecontent =""IE=edge<>
namemeta =""viewportcontent =""width=device-width, initial-scale=1.0<>
title>Testtitle>
<head>
.div1style>
position {
:; absoluteleft
:; 0pxwidth
:; 100pxheight
:; 100pxbackground-color
:; pink}
<style>
<body>
classdiv =""div1><div>
functionscript>
move (,obj, target) callback. {
obj=timer setInterval (function()if {
( .obj)offsetLeft > targetclearInterval {
(.obj)timer;if
()callback//判断回调函数是否传进来。可以不加判断,但是严谨一点加好{callback
();//当判定动画结束,就立刻执行该回调函数}
}
.
obj.style=left . obj+offsetLeft 2 + "px" ;}
,15 );}
function
f ()//定义回调函数 {alert
("动画已结束")}
var
= a . documentquerySelector(".div1");move
(,a1000 ,) f;
script>
body>
html>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)