【前端】【JavaScript】基础知识

文章目录

  • JavaScript 基础阶段
  • 一. 初识 JavaScript
    • (一) JavaScript 的作用
    • (二) HTML/CSS/JS 的关系
    • (三) 浏览器执行 JS 简介
    • (四) JS 的组成
    • (五) JS 书写位置
  • 二. JavaScript 输入输出语句
  • 三. 变量
    • (一) 变量的使用
    • (二) 变量语法扩展
    • (三) 变量命名规范
  • 四. 数据类型
    • (一) 简单数据类型
      • 1. isNaN()
      • 2. 字符串 String
      • 3. 获取检测变量的数据类型
      • 4. 数据类型转换
  • 五. 流程控制
    • (一) 分支结构
      • 1. if 语句
      • 2. 三元表达式
      • 3. switch 语句
    • (二) 循环结构
      • 1. for 循环
      • 2. while 循环
      • 3. do while 循环
      • 4. continue break
  • 六. 数组
  • 七. 冒泡排序
  • 八. 函数
    • (一) 声明函数
    • (二) 调用函数
    • (三) arguments 的使用
  • 九. 作用域
    • (一) 全局变量
    • (二) 局部变量
  • 十. JS 预解析
  • 十一. JS对象
    • (一) 创建对象
    • (二) 遍历对象
  • 十二. 内置对象
    • (一) 查文档
    • (二) Math 对象
    • (三) 日期对象
      • 1. Date() 方法
      • 2. 日期格式化
      • 3. 倒计时案例实现
    • (四) 数组对象
      • 1. 添加和删除数组元素
      • 2. 数组排序
      • 3. 数组索引方法
      • 4. 数组转换为字符串
    • (五) 字符串对象
      • 1. 根据字符返回位置
      • 2. 拼接以及截取字符串
      • 3. 替换字符串以及转换为数组
  • Web APIs
  • 十三. DOM 文档对象类型
    • (一) DOM 树
    • (二) 获取元素
      • 1. 根据 ID 获取
      • 2. 根据标签名获取
      • 3. 通过 HTML5 新增的方法获取(推荐)
      • 4. 特殊元素获取
    • (三) 事件基础
    • (四) 操作元素
      • 1. 操作元素内容
        • 1)element.innerText
        • 2)element.innerHTML (大量使用)
      • 2. 操作元素属性
      • 3. 操作表单元素属性
      • 4. css样式属性操作
        • 1)element.style(行内样式操作)
        • 2)element.className(类名样式操作)
      • 5. 鼠标经过变色案例
      • 6. 排他思想()算法设计换肤效果案例
      • 7. 自定义属性的操作
        • 1)获取属性值
        • 2)自定义属性
        • 3)设置属性值
        • 4)移除属性
    • (五) 节点操作
      • 1. 节点层级
        • 1)父级节点
        • 2)子节点
        • 3)兄弟节点
      • 2. 创建节点
      • 3. 添加节点
        • 1)appendChild
        • 2)insertBefore
      • 4. 删除节点
      • 5. 复制节点
      • 6. 动态创建元素
        • 1)document.write()(了解)
        • 2)element.innerHTML
        • 3)document.createElement()
    • (六) 事件高级
      • 1. 注册事件(绑定事件)
        • 1)传统注册方式
        • 2)方法监听注册方式
        • 3)addEventListener 事件监听处理
        • 4)attachEvent 事件监听方式(了解)
      • 2. 删除事件(解绑事件)
        • 1)传统注册方式
        • 2)方法监听注册方式
      • 3. DOM事件流
      • 4. 事件对象
        • 1)事件对象的常见属性和方法
      • 5. 事件委托(代理,委派)
      • 6. 常用的鼠标事件
        • 1) event 鼠标事件对象
        • 2) mouseenter 和 mouseover 的区别
      • 7. 常用的键盘事件
        • 1)键盘事件对象
  • 十四. BOM 浏览器对象类型
    • (一) BOM的构成
    • (二) window 对象的常见事件
      • 1. 窗口加载事件
      • 2. 调整窗口大小事件
    • (三) 定时器
      • 1. setTimeout() 定时器设置
      • 2. 停止 setTimeout() 定时器
      • 3. setInterval() 定时器设置
      • 4. 停止 setInterval() 定时器
      • 5. this 指向问题
    • (四) JS执行机制
      • 1. JS 是单线程
      • 2. 同步和异步
        • 1)同步
        • 2)异步
    • (五) location 对象
      • 1. URL
      • 2. location 对象的属性
      • 3. location 对象的方法
    • (六) navigator 对象
    • (七) history 对象
  • 十五. PC端网页特效
    • (一) 元素偏移量 offset 系列
      • 1. offset 与 style 区别
      • 2. 获取盒子中鼠标的坐标
    • (二) 元素可视区 client 系列
      • 1. 立即执行函数
      • 2. 淘宝 js 源码
    • (三) 元素滚动 scroll 系列
      • 1. 元素scroll系列属性
      • 2. 页面被卷去的头部
    • (四) 动画函数封装
      • 1. 动画实现原理
      • 2. 动画函数简单封装
      • 3. 给不同元素记录不同定时器
      • 4. 缓动效果原理
      • 5. 动画函数添加回调函数
    • (五) 常见网页特效案例
      • 1. 网页轮播图
  • 十六. 移动端网页特效
    • (一) 触屏事件
      • 1. 触摸事件对象(TouchEvent)
      • 2. 移动端拖动元素
    • (二) 移动端常见特效
      • 1. 自动播放功能-无缝滚动
      • 2. classList 属性
        • 1)添加类
        • 2)移除类
        • 1)切换类
      • 3. click 延时解决方案
    • (三) 移动端常用开发插件
      • 1. fastclick插件
      • 2. Swiper 插件的使用
      • 3. 移动端常用插件
      • 4. 插件的使用总结
    • (四) 移动端常用开发框架
      • 1. Bootstrap
  • 十七. 本地存储
    • (一) window.sessionStorage
    • (二) window.localStorage
  • 十八. jQuery
    • (一) JavaScript 库
    • (二) jQuery的概念
      • 1. jQuery 的下载
      • 2. jQuery的使用步骤
      • 3. jQuery 的入口函数
      • 4. jQuery 的顶级对象 $
      • 5. jQuery 对象和 DOM 对象
  • 十九. 数据可视化项目
    • (一) 什么是数据可视化
      • 1. 数据可视化
      • 2. 数据可视化的场景
      • 3. 常见的数据可视化库
    • (二) ECharts 简介
    • (三) ECharts 的基本使用
      • 1. ECharts 使用五步骤

JavaScript 基础阶段

目的是为了 JS 后面做铺垫

一. 初识 JavaScript

JavaScript是一种运行在客户端的脚本语言;
脚本语言:不需要编译,运行过程中由js解释器逐行来进行解释并执行;

(一) JavaScript 的作用

表单动态校验 (密码强度检测)
网页特效
服务端开发
桌面程序
APP
控制硬件-物联网
游戏开发


(二) HTML/CSS/JS 的关系

HTML决定网页结构和内容,相当于看到什么
CSS决定网页呈现给用户的模样,相当于给人穿衣服
JS 实现业务逻辑和页面控制,相当于人的各种动作


(三) 浏览器执行 JS 简介

浏览器分成两部分:渲染引擎和 JS 引擎
渲染引擎:用来解析HTML 与CSS,俗称内核;
JS 引擎:也称之为JS解释器。用来读取网页中的JavaScript 代码,对其处理后运行;
JS引擎执行代码时逐行解释每一句源码,然后由计算机去执行;


(四) JS 的组成

JavaScript由ECMAScript(JavaScript 语法),DOM(页面文档对象类型),BOM(浏览器对象类型)等三部分组成;
ECMAScript:规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。
DOM:通过DOM提供的接口可以对页面上的各种元素进行操作(大小,位置,颜色等)
BOM:是指浏览器对象模型,它提供了独立于内容的可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框,控制浏览器跳转,获取分辨率等。


(五) JS 书写位置

有3中书写位置,分别为行内,内嵌和外内部;

	
    <script>
        alert('沙漠骆驼')
    script>
    
    <script src="my.js">script>
    
head>
<body>
    
    <input type="button" value="唐伯虎" onclick="alert('秋香姐')">
body>


二. JavaScript 输入输出语句

为了方便信息的输入输出,JS中提供了一些输入输出语句,其常用的语句如下:

方法 说明
alert(msg) 浏览器弹出警示框
console.log(msg) 浏览器控制台打印输出信息
prompt(into) 浏览器弹出输入框,用户可以输入
prompt('请输入你的年龄')
alert('计算结果是')
console.log('我是程序员')

// 打印我们返回的元素对象,更好的查看里面的属性和方法
console.dir(time); 


三. 变量

本质:变量是程序在内存中申请的一块用来存放数据的空间。

(一) 变量的使用

变量在使用时分两步:1)声明变量;2)赋值

  1. 声明变量
    var age; // 声明一个名称为age的变量
    var 是一个JS关键字,用来声明变量。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管。
    age是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间。

  2. 赋值
    age = 18; // 给age 这个变量赋值为10

变量初始化
var age = 18; // 声明变量的同时赋值为18


(二) 变量语法扩展

同时声明多个变量时,只需要写一个var,多个变量名之间使用英文逗号隔开;
var age = 10, name = 'aili', sex = 2;


(三) 变量命名规范

有字母,数字,下划线,美元符号组成;
严格区分大小写;
不能以数字开头;
不能时关键字,保留字;
变量名必须有意义;
遵守驼峰命名法,首字母小写,后面的单词的首字母需要大写;



四. 数据类型

JavaScript 是-种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。
var age = 10; // 这是一个数字型
var areYourk = '是的'; // 这是一个字符串
在代码运行时,变量的数据类型是由JS引擎根据=右边变量值的数据类型来判断的,运行完毕之后.变量就确定了数据类型型。


JS把数据类型分为两类:

  1. 简单数据类型(Number, String, Boolean, Undefined, Null);
  2. 复杂数据类型(object);

(一) 简单数据类型

简单数据类型 说明 默认值
Number 数字型,包含整型,浮点型值,如21,0.21 0
Boolean 布尔值类型,如true,false,等价于1和0 false
String 字符串类型,如“张三”,注意在JS里面,字符串都带引号 “”
Undefined var a; 声明了变量a,但是没有给值,此时 a = undefined undefined
Null var a = null; 声明了变量a, 为空值 null

在JS中八进制前面加0, 十六进制前面加0x;
var num1 = 07; // 对应十进制的7
var num2 = 0xA; // 对应十进制的10

1. isNaN()

用来判断一个变量是否为非数字的类型;是数字返回false;
var ss = isNaN('age');

2. 字符串 String

字符串型可以是引号中的任意文本,其语法为双引号""单引号''


通过字符串的length属性可以获取整个字符串的长度。
var number = '123456789';
alter(number.length; // 显示 11


多个字符串之间用 + 进行拼接,字符串 + 任何类型 = 拼接后的新字符串数字相加,字符相连
alert('老师今年' + age + '岁');

3. 获取检测变量的数据类型

typeof 可用来获取检测变量的数据类型;
alert(typeof 12); // number

4. 数据类型转换

转换为字符串

方式 说明 案例
toString() 转成字符串 var num = 1;
alert(num.toString());
String()强制转换 转成字符串 var num = 1;
alert(String(num));
加号拼接字符串 和字符串拼接的结果都是字符串 var num = 1;
alert(num + "我是字符串");

转换为数字型

方式 说明 案例
parseInt(string) 函数 将 string 类型转换成整数数值型 parseInt('78')
parseFloat(string) 函数 将 string 类型转换成浮点数数值型 parseFloat('78.3')
Number() 强制转换函数 将 stirng 类型转换为数值型 Number('12')
js 隐式转换(- * /) 利用算数运算,隐式转换为数值型 '12'-0

转换为布尔型

方式 说明 案例
Boolean() 函数 其他类型转换成布尔值 Boolean('true')

代表空、否定的值会被转换为false , 如"、0、 NaN、null. undefined

console. log (Boolean('')); // false
console. log (Boolean(0)); // false
console. log (Boolean(NaN)); // false
console. log (Boolean (null)); // false
console. log (Boolean (unde fined)); // false
conso1e. log (Boolean('小白)); // true
console. log (Boolean(12)); // true


五. 流程控制

流程控制主要有三种结构,分别是顺序结构分支结构循环结构,这三种结构代表三种代码执行的顺序。
顺序结构程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
分支结构执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程) , 从而得到不同的结果。

(一) 分支结构

1. if 语句

if(条件表达式1) {
	语句1} else if(条件表达式2) {
	语句2}else {
	// 上述条件都不成立,执行此处代码
} 

2. 三元表达式

条件表达式 ? 表达式1 : 表达式2
如果条件表达式结果为真,则返回表达式1的值;如果条件表达式结果为假,则返回表达式2的值;

3. switch 语句

switch(表达式) {
	case value1:
		// 表达式 等于 value1 时要执行的代码
		break;\
	case value2:
		// 表达式 等于 value2 时要执行的代码
		break;
	default:
		// 表达式 不等于任何一个 value 时要执行
}

(二) 循环结构

1. for 循环

for(初始化变量; 条件表达式; 操作表达式) {
	// 循环体
}

初始化变量就是用var声明的一个普通变量,通常用于 作为计数器使用
条件表达式就是用来决定每一次循环是 否继续执行就是终止的条件
操作表达式是每次循环最后执行的代码经常用于我们计数器变量进行更新(递增或者递减)

2. while 循环

while(条件表达式) {
	// 循环体代码
}

执行思路:

  1. 先执行条件表达式,如果为true,则执行循环体代码;如果为false,则退出循环,执行后面的代码;
  2. 执行循环体代码;
  3. 循环体代码执行完毕后,程序会继续判断执行条件表达式,如果条件仍为true,则会继续执行循环体,直到循环条件为false时,整个循环过程才会结束。

3. do while 循环

do {
	// 循环体代码
} while(条件表达式);

执行思路:

  1. 先执行一次循环体代码;
  2. 再执行条件表达式,如果结果为true ,则继续执行循环体代码;如果为false,则退出循环,继续执行后面代码。
    注意:先再执行循环体,再判断,我们会发现d…while循环语句至少会执行一次循环体代码。

4. continue break

continue关键字用于立即跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)
break关键字用于立即跳出整个循环(循环结束)。



六. 数组

利用 new 创建数组

var 数组名 = new Array();
var arr = new Array();

利用数组字面量创建数组

// 1. 使用数组字面方式创建空的数组
var 数组名 = [];
var arr = [];
// 2. 使用数组字面量方式创建带初始值的数组
var 数组名 = ['小白''小黑', '大黄'];
var arr = [1, 2, 3, 4];

数组中可以存放任意类型的数据,例如字符串,数字,布尔值等;
arr.length动态检测数组元素的个数;
可以通过修改数组索引追加数组元素。



七. 冒泡排序

冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示。

var arr = [5, 7, 2, 9, 1, 4];
for(var i = 0; i < arr.length-1; i++) {
	for (var j = 0; j < arr.length-i-1; j++) {
		if (arr[j] > arr[j+1]) {
			var som = arr[j];
			arr[j] = arr[j+1];
			arr[j+1] = som;
		}
	}
}


八. 函数

函数在使用时分为两步:声明函数,调用函数;

(一) 声明函数

// 1. 利用函数关键字自定义函数(命名函数)
function 函数名(形参1, 形参2) {
	// 函数体代码
	return 需要返回的结果;
}

function cook(aru) {
	console.log(aru);
	return 666;
}

// 2. 函数表达式(匿名函数)
// var 变量名 = function() {}
var fun  = function(aru) {
	console.log(aru);
}
fun('pink老师');
// fun 是变量名,不是函数名

function是声明函数的关键字,必须小写;


(二) 调用函数

// 调用函数
函数名(实参1, 实参2); // 通过调用函数名来执行函数体代码

cook('酸辣土豆丝');
var ss = cook('酸辣土豆丝'); // 获取返回值结果

我们的函数如果有return,则返回的是return 后面的值;如果函数没有return ,则返回undef ined。


(三) arguments 的使用

当我们不确定有多少个参数传递的时候,可以使用 arguments 来获取实参的值;
只有函数才有 arguments 对象,而且每个函数都内置好了arguments 对象,arguments 对象中存储了传递的所有实参

function cook() {
	console.log(arguments); // 里面存储了所有传递过来的实参 arguments = [1, 2, 3]
	console.log(arguments.length); // 3
	console.log(arguments[1]); // 2

	// 我们可以按照数组的方式遍历 arguments
	for (let i = 0; i < arguments.length; i++) {
		console.log(arguments[i]);
	}
}
cook(1, 2, 3);

伪数组,并不是真正意义上的数组;

  1. 具有数组的 length 属性
  2. 按照索引的方式进行存储的;
  3. 他没有真正数组的一些方法,pop() push() 等;


九. 作用域

JS作用域:就是代码名字(变量) 在某个范围内起作用和效果;
目的是为了提高程序的可靠性,更重要的是减少命名冲突;
全局作用域:整个 script标签或者是一个单独的js文件。
局部作用域:在函数内部就是局部作用域,这个代码的名字只是在函数内部起到效 果和作用。

(一) 全局变量

在全局作用域下声明的变量叫做全局变量 (在函数外部定义的变量);

  1. 全局变量在代码的任何位置都可以使用;
  2. 在全局作用域下 var 声明的变量,是全局变量;
  3. 特殊情况下,在函数内不适用 var 声明的变量也是全局变量 (不建议使用) ;

(二) 局部变量

在局部作用域下声明的变量叫做局部变量 (在函数内部定义的变量);

  1. 局部变量只能在该函数内部使用;
  2. 在函数内部 var 声明的变量,是局部变量;
  3. 函数的形参实际上就是局部变量;


十. JS 预解析

JS引擎运行 js 分两步:预解析 代码运行

  1. 预解析:JS引擎会把 js 里面所有的 var ,还有 function 提升到当前作用域的最前面;
  2. 代码执行:按照代码书写顺序从上往下执行
    预解析分为:变量解析(变量提升) 和 函数预解析(函数提升);
  3. 变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作;
  4. 函数提升:就是把所有的函数声明提升到当前作用域最前面,不调用函数;


十一. JS对象

(一) 创建对象

1. 利用对象字面量创建对象

// var obj = {} // 创建了一个空对象
var obj = {
	uname:'张三丰',
	age: 18,
	sex: '男',
	seyHi:function() {
		console.log('hi~');
	}
}

里面的属性或者方法我们采取键值对的形式 键 属性名:值 属性值;
多个属性或者方法中间用逗号隔开的;
方法冒号后面跟的是一个匿名函数;
使用对象:

// 调用对象属性
// 1.  对象.属性名
console.log(obj.uname);
// 2. 对象名['属性名']
console.log(obj['age']);

// 调用对象方法
// 对象名.方法名()
obj.sayHi();

2. 利用 new Object 创建对象

var obj = new Object(); // 创建了一个空对象
obj.uname = '张三丰';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function() {
	console.log('hi~');
}
// 调用对象
console.log(obj.uname);
console.log(obj['age']);
obj.sayHi();

3. 利用构造函数创建对象

// 声明构造函数
function 构造函数名() {
	this.属性 =;
	this.方法 = function() {}
}
function Star(uname, age, sex) {
	this.name = uname;
	this.age = age;
	this.sex = sex;
}

// 使用构造函数
new 构造函数名();
var ldh = new Star('刘德华', 19, '男');
console.log(ldh.name);

(二) 遍历对象

// for in 遍历对象
// for(变量 in 对象) {}
for(var k in obj) {
	console.log(k); // 属性名
	console.log(obj[k]); // 属性值
}


十二. 内置对象

(一) 查文档

学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN来查询。
MDN:https://developer.mozilla.org/zh-CN/

如何学习对象中的方法

  1. 查询该方法的功能
  2. 查看里面参数的意义和类型
  3. 查看返回值的意义和类型
  4. 通过demo进行测试

(二) Math 对象

Math 数学对象:不是构造函数,所以不需要new 来调用,直接使用里面的属性和方法即可;

方法/属性 说明
Math.PI 圆周率值
Math.max(i, j) 取最大值
Math.max(12, 23) // 23
Math.min(i, j) 取最小值
Math.min(12, 23) // 12
Math.abs(i) 绝对值
Math.abs(-12) // 12
Math.round(i) 四舍五入, 就近取值
Math.round(1.5) // 2
Math.floor(i) 向下取整
Math.floor(3.4) // 3
Math.ceil(i) 向上取整
Math.ceil(3.4) // 4
Math.random() 随机数
Math.floor(Math.random()*10 // 取0~9内的一个随机数
// 随机获取学生姓名
function getRandom(min, max) {
	return Math.floor(Math.random() * (max-min+1))+min;
}
var arr = ['张三', '艾莉', '艾琳', '古丽'];
alert(arr[getRandom(0, arr.length-1)]);

(三) 日期对象

Date 对象是一个构造函数,所以需要实例化后才能使用;
Date 实例用来处理日期和时间;

1. Date() 方法

1)获取当前时间必须实例化

var now = new Date();
alert(now); // Tue Nov 22 2022 16:49:21 GMT+0800 (中国标准时间)

2)Date() 构造函数的参数

如果构造函数括号里面有时间,就返回参数里面的时间。
var now = new Date('2022-11-12 / 2022/11/12');
// Sat Nov 12 2022 08:00:00 GMT+0800 (中国标准时间)

2. 日期格式化

对象.方法

方法 说明
obj.getFullYear() 获取当年
obj.getMonth() 获取当月(0~11)
实际应用时,加一
obj.getDate() 获取当天日期
obj.getDay() 获取星期几(周日:0 ~ 周六:6)
obj.getHours() 获取当前小时
obj.getMinutes() 获取当前分钟
obj.getSeconds() 获取当前秒钟

获取总的毫秒数:Date.now();

3. 倒计时案例实现

【前端】【JavaScript】基础知识_第1张图片

function conutDown(time) {
	var nowTIme = +new Date(); // 返回的时当前时间总的毫秒数
	var inputTime = +new Date(time); // 返回的是用户输入时间总的毫秒数
	var times = (inputTime - nowTIme) / 1000; // time 是剩余时间总的毫秒数
	var d = parseInt(times / 60 / 60 / 24); // 天
	d = d < 10 ? '0' + d : d;
	var h = parseInt(times / 60 / 60 % 24); // 时
	h = h < 10 ? '0' + h : h;
	var m = parseInt(times / 60 % 60); // 分
	m = m < 10 ? '0' + m : m;
	var s = parseInt(times % 60); // 当前的秒
	s = s < 10 ? '0' + s : s;
	return d + '天' + h + '时' + m + '分' + s + '秒';
}
alert(conutDown('2022-11-22 18:47:00'));

(四) 数组对象

// 利用 new Array() 创建数组
// var arr1 = new Array(); // 创建了一个空的数组
// var arr1 = new Array(2); // 这个2 表示:里面有2个空的数组元素
var arr1 = new Array(2, 3); // 等价于[2, 3] 这样写表示:里面有两个数组元素,是2和3

1. 添加和删除数组元素

方法 说明
Array.isArray(arr) 判断是否是一个数组
arr.push(i) 数组末尾添加元素
arr.unshift(i) 数组开头添加元素
arr.pop() 删除数组最后一个元素
arr.shift() 删除数组第一个元素
var arr = new Array();
Array.isArray(arr); // 判断是否为数组
arr.push(2, 1, 'pink'); // 在数组末尾,添加一个或多个数组元素
arr.unshift(3, 'lov'); // 在数组开头,添加一个或多个数组元素
arr.pop(); // 删除数组的最后一个元素,并返回删除的元素值
arr.shift(); // 删除数组的第一个元素,并返回删除的元素值

2. 数组排序

方法 说明
arr.reverse() 颠倒数组中元素的顺序
arr.sort() 对数组中元素进行排序
var arr = new Array(2, 16, 4, 7, 1);
arr.reverse(); // [1,7,4,6,2] 颠倒数组中元素的顺序
arr.sort(); // [1,2,4,6,7]  对数组中元素进行排序(0~9比较好使)
arr.sort(function(a, b) { // 对所有的数字都好使
   return a - b; // 升序排序
   // return b - a; // 降序排序
});

3. 数组索引方法

方法 说明
arr.indexOf(i) 查找指定素第一个索引号
arr.lastIndexOf(i) 查找指定 元素最后一个索引号
var arr = new Array(2, 16, 4, 4, 7, 1);
var ss = arr.indexOf(4); // 数组中查找给定元素的第一个索引,返回索引号,不存在返回-1
var s = arr.lastIndexOf(4); // 数组中的最后一个索引,返回索引号,不存在返回-1

4. 数组转换为字符串

方法 说明
arr.toString() 数组转换成字符串,用逗号分割
arr.join(‘/’) 数组转换成字符串,用户自定义分割字符
var arr = new Array(2, 16, 4, 4, 7, 1);
var ss = arr.toString(); // 把数组转换成字符串,逗号分隔每一项
       var s = arr.join(' '); // 方法用于把数组中的所有元素转换为一个字符串

(五) 字符串对象

1. 根据字符返回位置

方法 说明
indexOf(‘要查找的字符’, 开始的位置) 从前往后找,找不到返回-1
lastIndexOf(‘要查找的字符’, 开始的位置) 从后往前找,找不到返回-1
var arr = 'angla boby';
var i = arr.indexOf('a', 0); // 从前往后找
var j = arr.lastIndexOf('m', 1); // 从后往前找```

2. 拼接以及截取字符串

var arr = 'angla boby';
var ar = '12';
var arr1 = arr.concat(ar); // 拼接多个字符串
var i = arr.substr(2, 5); // 从索引为2的位置开始,取5个数
var ss = arr.slice(1, 6); // 从1位置开始,截取到6位置,6位置的值取不到
var s = arr.substring(1, 5); // 从1位置开始,截取到5位置,5位置的值取不到, 不接受负值

3. 替换字符串以及转换为数组

var arr = 'angl abo by';
var s = arr.replace('a', 'q'); // 替换第一个a为q
var ss = arr.split(' '); // 按照分割符,转换为数组


Web APIs

Web APIs 是 JS 所独有的部分;
主要学习页面交互功能;


Web API 主要是针对于浏览器提供的接口,主要针对于浏览器做互动效果;
Web PAI 一般都有输入输出(函数的传参和返回值),Web API 很多都是方法;

十三. DOM 文档对象类型

【前端】【JavaScript】基础知识_第2张图片

文档对象模型
DOM 就是把「文档」 当作一个「对象」来看待;
DOM的顶级对象是document
DOM主要学习的是操作页面元素
DOM是W3C标准规范
W3C 已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式;

(一) DOM 树

【前端】【JavaScript】基础知识_第3张图片

文档:一个页面就是一个文档,DOM中使用 document 表示;
元素:页面中的所有标签都是元素,DOM中使用 element 表示;
节点:网页中的所有内容都是节点(标签,属性,文本,注释等),DOM中使用 node 表示;
DOM把以上内容都看做是对象;


(二) 获取元素

因为我们文档页面从上往下加载,所以先得有标签,所以我们script写到标签的下面。

1. 根据 ID 获取

语法
var element = document.getElementById(id);
参数

  1. 如果当前文档中拥有特定ID的元素不存在,返回null;
  2. id是大小写敏感的字符串,代表了所要查找的元素的唯一ID;

返回值:返回一个匹配到ID的 element 对象。若在当前 document 下没有找到,则返回 null;
document——文档

2. 根据标签名获取

使用 getElementsByTagName() 方法,可以返回带有指定标签名的对象集合。
语法
document.getElementsByTagName('标签名');

var ul = document.getElementsByTagName('ul');

还可以获取某个元素(父元素) 内部所有指定标签名的子元素;
语法

var ul = document.getElementsByTagName('ul');
console.log(ul[0].getElementsByTagName('li'));

3. 通过 HTML5 新增的方法获取(推荐)

根据类名返回元素对象集合
document.getElementsByClassName('类名');

var scrip = document.getElementsByClassName('ss');
// 输出结果: [li.ss, li.ss, li.ss, li.ss, li.ss]

根据指定选择器(.box/#box)返回第一个元素对象
document.querySelector('选择器');

var scrip = document.querySelector('.ss');
// 输出结果:
  • 1
  • 根据指定选择器返回元素对象集合
    document.querySelectorAll('选择器');

    var scrip = document.querySelector('.ss');
    // 输出结果:[li.ss, li.ss, li.ss, li.ss, li.ss]
    

    4. 特殊元素获取

    获取body元素:
    document.body // 返回body元素对象
    获取html元素:
    document.documentElement // 返回html元素对象

    var body = document.body;
    // 输出结果:body
    var html= document.documentElement;
    // 输出结果:html
    

    (三) 事件基础

    事件是可以被JS侦测到的行为;触发——响应机制
    事件是有三部分组成:

    1. 事件源:事件被触发的对象(按钮)
    2. 事件类型:如何触发(鼠标点击/鼠标经过/键盘按下)
    3. 事件处理程序:通过一个函数赋值的方式完成

    执行事件步骤:

    1. 获取事件源
    2. 注册事件(绑定事件)
    3. 添加事件处理程序(采取函数赋值形式)
    
    <button id="btn">唐伯虎button>
    
    <script>
    	// 获取事件源
    	var btn = document.getElementById('btn');
    	// 绑定事件
    	// btn.onclick
    	// 添加事件处理程序
    	btn.onclick = function() {
    		alert('点击按钮,弹出对话框!');
    	}
    script>
    

    (四) 操作元素

    利用DOM操作元素来改变元素里面的内容,属性等。

    1. 操作元素内容

    这两个属性是可读写的,可以获取元素里面的内容,也可以改变元素内容。

    内容
    修改“内容”的值

    1)element.innerText

    var btn1 = document.getElementById('btn');
    btn1.innerText = '你好,我是按钮'; // 修改内容
    alert(btn1.innerText); // 获取内容
    

    该属性不识别html标签,同时空格和换行也会换掉;

    2)element.innerHTML (大量使用)

    var btn1 = document.getElementById('btn');
    btn1.innerHTML= '你好,我是按钮';
    alert(btn1.innerHTML); // 获取内容
    

    包括html标签,同时保留空格和换行;

    2. 操作元素属性

    通过修改元素的属性(src, href, title),进行操作。

    
    <button id="btn">刘德华button>
    <button id="btn1">张学友button><br>
    <img src="btn.gif" alt="">
    <script>
    	var btn = document.getElementById('btn');
    	var btn1 = document.getElementById('btn1');
    	var imgs = document.querySelector('img');
    	btn1.onclick = function() {
    		imgs.src = 'btn1.gif';
    		imgs.title = '张学友';
    	}
    	btn.onclick = function() {
    		imgs.src = 'btn.gif';
    		imgs.title = '刘德华';
    	} 
    script>
    

    【前端】【JavaScript】基础知识_第4张图片【前端】【JavaScript】基础知识_第5张图片

    3. 操作表单元素属性

    利用DOM可以操作表单元素的属性。
    type value checked selected disabled


    element.value.length:表单元素值的长度

    <button>按钮button>
    <input type="text" value="请输入内容">
    <script>
    	var btn = document.querySelector('button');
    	var input = document.querySelector('input');
    	btn.onclick = function() {
    		// 修改value的值
    		input.value = '被点击了';
    		// btn.disabled = true;
    		this.disabled = true;
    		// this 指向的是事件函数的调用者  btn
    	}
    script>
    

    4. css样式属性操作

    通过JS修改元素的大小,颜色,位置等样式。

    1. element.style 行内样式操作
      如果样式比较少或者功能简单的情况下使用
    2. element.className 类名样式操作
      如果样式修改较多的情况下使用
      className会直接更改元素的类名,会覆盖原先的类名

    1)element.style(行内样式操作)

    
    <style>
    	.box {
    		width: 200px;
    		height: 200px;
    		background-color: pink;
    	}
    style>
    <div class="box">div>
    <script>
    	var box = document.querySelector('div');
    	box.onclick = function() {
    		// 改变颜色,宽 css样式
    		this.style.backgroundColor = 'yellow';
    		this.style.width = '250px';
    	}
    script>
    

    2)element.className(类名样式操作)

    <style>
    	div {
    		background: pink;
    		width: 150px;
    		height: 150px;
    	}
    	.change {
    		background: purple;
    		color: #fff;
    		font-size: 25px;
    		margin-top: 100px;
    	}
    style>
    <div>文本div>
    <script>
    	var div = document.querySelector('div');
    	div.onclick = function() {
    		this.className = 'change';
    	}
    script>
    

    5. 鼠标经过变色案例

    1. 普通设计

    
    <input type="button" value="开关灯" id="1">
    <input type="button" value="开关灯" id="2">
    <input type="button" value="开关灯" id="3">
    <input type="button" value="开关灯" id="4">
    <input type="button" value="开关灯" id="5">
    <script>
    	var button = document.getElementsByTagName('input');
    	for(var i = 0; i < button.length; i++) {
    		button[i].onmouseover = function() {
    			this.style.backgroundColor = 'pink';
    		}
    		button[i].onmouseout = function() {
    			this.style.backgroundColor = '#efefef';
    		}
    	}
    script>
    

    排他思想(算法)进行设计

    <script>
    	// 1. 获取所有的按钮元素
    	var button = document.getElementsByTagName('input');
    	// 2. button 得到的是伪数组
    	for(var i = 0; i < button.length; i++) {
    		button[i].onmouseover = function() {
    			// 1) 先把所有的按钮背景颜色去掉  干掉所有人
    			for(var i = 0; i < button.length; i++) {
    				button[i].style.backgroundColor = '';
    			}
    			// 2) 然后让当前的元素颜色为pink  留下我自己
    			this.style.backgroundColor = 'pink';
    		}
    	}
    script>
    

    在这里插入图片描述在这里插入图片描述

    6. 排他思想()算法设计换肤效果案例

    <style>
    	img {
    		position: relative;
    		width: 100px;
    		height: 100px;
    		margin: auto;
    		left: 20%;
    		margin-top: 50px;
    	}
    style>
    <img src="/Picture/静态合集/大背景.gif" alt="">
    <img src="/黑背景.gif" alt="">
    <img src="/Picture/动图合集/雨滴.gif" alt="">
    <img src="/Picture/动图合集/1.gif" alt="">
    <script>
    	// 1. 获取元素
    	var imgs = document.getElementsByTagName('img');
    	var body = document.body;
    	// 2. 循环注册事件
    	for(var i = 0; i < imgs.length; i++) {
    		imgs[i].onclick = function() {
    			// 1) 先把所有的背景去掉  干掉所有人
    			for(var i = 0; i < imgs.length; i++) {
    				body.style.backgroundImage = '';
    			}
    			// 2) 然后让当前点击元素的url为body的url  留下我自己
    			body.style.background = 'url('+this.src+')';
    		}
    	}
    script>
    

    7. 自定义属性的操作

    1)获取属性值

    element.属性:获取属性值;
    img.url // 获取img标签的url属性
    element.getAttribute('属性');
    区别:

    1. element.属性获取内置属性值(元素本身自属性
    2. element.getAttribute('属性');主要获取程序员自定义的属性

    2)自定义属性

    index = "1"
    程序员自己添加的属性。
    H5规定自定义属性data开头做为属性名并且赋值。
    比如

    var li = document.querySelector('.ss'); li.setAttribute('data-index', 12); // 结果:
  • 1
  • 3)设置属性值

    element.属性 = '值':设置内置属性值;
    img.url // 获取img标签的url属性
    element.setAttribute('属性', '值');
    区别:

    1. element.属性设置内置属性值
    2. element.setAttribute('属性');主要设置自定义的属性

    4)移除属性

    element.removeAttribute('属性')


    (五) 节点操作

    获取元素通常使用两种方式:

    1. 利用DOM提供的方法获取元素
      逻辑性不强,繁琐。
    2. 利用节点层级关系获取元素
      利用父子兄节点关系获取元素
      逻辑性强,但是兼容性稍差。

    网页中的所有内容都是节点(标签,注释,文本,属性等),在DOM中,节点用nodel来表示。
    DOM树中的所有的节点均可通过JS进行访问,所有节点均可被修改,也可以创建或删除。


    节点至少拥有nodeType(节点类型)nodeName(节点名称)nodeValue(节点值)这三个基本属性。

    1. 元素节点nodeType 为 1
    2. 属性节点nodeType 为 2
    3. 文本节点nodeType 为 3(文本节点包含文字,空格,换行)

    在实际开发中,节点操作主要操作的是元素节点。

    1. 节点层级

    利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系

    1)父级节点

    语法:node.parentNode
    parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
    如果指定的节点没有父节点,则返回null

    <div class="demo">
    	<div class="box">
    		<div class="erweima">Xdiv>
    	div>
    div>
    <script>
    	// 利用DOM提供的方法获取父节点
    	var erweima = document.querySelector('.erweima');
    	var box = document.querySelector('.box');
    
    	// 利用父子节点关系获取父节点
    	var erweima = document.querySelector('.erweima');
    	var box = erweima.parentNode;
    	var demo = box.parentNode; // 获取demo节点
    script>
    

    2)子节点

    获取子节点

    语法:parentNode.childNodes
    parentNode. childNodes 返回包含指定节点的子节点的集合.该集合为即时更新的集合。
    返回值里面包含所有的子节点,包括元素节点,文本节点等。


    语法:parentNode.children
    parentNode. children是一个只读属性,返回所有的子元素节点它只返回子元素节点,其余节点不返回

    <ul>
    	<li>我是lili>
    	<li>我是lili>
    	<li>我是lili>
    	<li>我是lili>
    ul>
    <script>
    	// 利用DOM提供的方法获取所有的子节点
    	var ul = document.querySelector('ul');
    	var li = ul.querySelector('li');
    
    	// 利用父子节点关系获取所有的子节点
    	var ul = document.querySelector('ul');
    	var li = ul.childNodes; // [text, li, text, li, text, li, text, li, text]
    	var li1 = ul.children; //  [li, li, li, li]
    script>
    

    获取第一个和最后一个子节点

    语法:parentNode.firstChild
    firstChild返回第一个子节点,找不到则返回null.同样,也是包含所有的节点
    语法:parentNode.lastChild
    lastChild返回最后一个子节点,找不到则返回null.同样,也是包含所有的节点
    不足之处:返回值里面包含所有节点


    语法:parentNode.firstElementChild
    firstElementChild返回第一个子元素节点,找不到则返回null。
    语法:parentNode.lastElementChild
    lastElementChild返回最后一个子元素节点,找不到则返回null。
    不足之处:这两个方法有兼容性问题,IE9以上才支持


    如果想要一个子元素节点,可以使用parentNode.children[0]
    parentNode.children[0]

    <ul>
    	<li>我是lili>
    	<li>我是lili>
    	<li>我是lili>
    	<li>我是lili>
    ul>
    <script>
    	var ul = document.querySelector('ul');
    	// 1. firstChild 第一个子节点不管是文本节点还是元素节点
    	var som1 = ul.firstChild; // #text
    	var som2 = ul.lastChild; // #text
    	// 2. firstElementChild 返回第一个子元素节点
    	var som3 = ul.firstElementChild; // li
    	var som4 = ul.lastElementChild; // li
    script>
    

    3)兄弟节点

    获取兄弟节点

    语法:node.nextSibling
    nextsibling返回当前元素的下一个兄弟节点。找不到则返回null。同样,也是包含所有的节点。
    语法:node.previousSibling
    previoussibling返回当前元素上一个兄弟节点。找不到则返回null.同样,也是包含所有的节点。

    获取兄弟元素节点

    语法:node.nextElementSibling
    nextElementsibling返回当前元素下一个兄弟元素节点。找不到则返回null.
    语法:node.previousElementSibling
    previousElementsibling返回当前元素上一个兄弟节点。找不到则返回null,
    注意:这两个方法有兼容性问题,IE9以上才支持。
    自己封装一个兼容性的函数

    function getNextElementSibling(element) {
    	var el = element;
    	while(el = el.nextSibling) {
    		if(el.nodeType == 1) {
    			return el;
    		}
    	}
    	return null;
    }
    

    2. 创建节点

    语法:document.createElement('tagName')
    document. createElement()方法创建由tagName指定的HTMIL 元素。因为这些元素原先不存在是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
    实例:var a = document.createElement('a');

    3. 添加节点

    1)appendChild

    语法:node.appendChild(child)
    node . appendChild()方法将一个节点添加到指定父节点的子节点列表末尾,类似于css里面的after伪元素。
    实例: create.appendChild(a);

    2)insertBefore

    语法:node.insertBefore(child, 指定元素)
    node . insertBefore ()方法将一个节点添加到父节点的指定子节点前面。 类似于css里面的before伪元素。
    实例:ul.insertBefore(li, ul.children[0]);

    <ul >你好ul>
    <script>
    	// 1. 创建节点元素节点
    	var li = document.createElement('li');
    	// 2. 添加节点,node.appendChild(child) node 父级 child 子级
    	var ul = document.querySelector('ul'); // 获取父节点
    	ul.appendChild(li); // 添加节点
    	// 3. 添加节点node. insertBefore(child,指定元素);
    	var lili = docment.createElement('li');
    	ul.insertBefore(lili, ul.children[0]);
    script>
    

    4. 删除节点

    语法:node.removeChild(child)
    node . removeChild()方法从DOM中删除一个子节点 ,返回删除的节点。

    // 1,. 获取元素
    var ul = document.querySelector('ul');
    // 2. 删除元素
    ul.removeChild(ul.children[0]);
    

    5. 复制节点

    语法:node.cloneNode()
    node . cl oneNode()方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点

    var ul = document.querySelector('ul');
    // 1. node.cloneNode(); 括号为空或者里面是false,只复制标签
    // 2. node.cloneNode(true); 括号为true,复制标签,也复制里面的内容
    var li = ul.children[0].cloneNode(true);
    ul.appendChild(li);
    

    注意:

    1. 如果括号参数为空或者为false , 则是浅拷贝,即只克隆复制节点本身,不克降里面的子节点。
    2. 如果括号参数为true。则是深度拷贝,会复制节点本身以及里面所有的子节点。

    6. 动态创建元素

    1)document.write()(了解)

    docoment .write是直接将内容写入页面的内容流。但是文档执行完毕,则它会导教页面全部重绘

    <ul>
    	<li>你好li>
    	<li>我号li>
    ul>
    <button>按钮button>
    <script>
    	// document.write('
  • 大家好
  • ');
    var btn = document.querySelector('button'); // 页面加载完毕以后才能点击按钮,这时会发生页面重绘 btn.onclick = function() { document.write('
  • 大家好
  • '
    ); }
    script>

    2)element.innerHTML

    innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘
    innerHIML创建多个元素效率更高(不要拼接字符串.采取数组形式拼接),结构稍微复杂;

    <div class="inner">div>
    <script>
    	var inner = document.querySelector('.inner');
    	 // 拼接字符串方式创建
    	for (let i = 0; i < 100; i++) {
    		inner.innerHTML += '百度';
    	}
    	
    	// 数组形式拼接创建
    	var array = [];
    	for (let i = 0; i < 100; i++) {
    		array.push('百度');
    	}
    	inner.innerHTML = array.join('');
    script>
    

    不同浏览器下,innerHTML效率要比creatElement 高

    3)document.createElement()

    createElement() 创建多个元索效率稍低一点点 ,但是结构更清晰;

    <div class="create">div>
    <script>
    	var create = document.querySelector('.create');
    	for (let i = 0; i < 100; i++) {
    		// 创建元素
    		var a = document.createElement('a'); 
    		// 添加元素
    		create.appendChild(a);
    	}
    script>
    

    (六) 事件高级

    1. 注册事件(绑定事件)

    给元素添加事件,称之为注册事件
    注册事件有两种方式:传统方式方法监听注册方式

    1)传统注册方式

    利用on开头的事件onclick

    btn.onclick = function() {}
    特点:注册事件的唯一性
    同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。

    2)方法监听注册方式

    w3c 标准 推荐方式
    addEventListener它是一个方法
    IE9 之前的IE不支持此方法,可使用 attachEvent()代替
    特点:同一个元素同一个事件可以注册多个监听器
    按注册顺序依次执行

    3)addEventListener 事件监听处理

    eventTarget.addEventListener() 方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定事件时,就会执行事件处理函数。
    语法:
    eventTarget.addEventListener(type, listener[, useCapture])
    参数:

    1. type:事件类型字符串,比如click, mouseover, 注意这里不要带on
    2. listener:事件处理函数,事件发生时,会调用该监听函数
    3. useCapture:可选参数,是一个布尔值,默认是false
    var li = document.querySelector('.ss');
    li.addEventListener('click', function() {
    	alert(22);
    })
    li.addEventListener('click', function() {
    	alert(33);
    })
    

    4)attachEvent 事件监听方式(了解)

    eventTarget.attachEvent() 方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定事件时,指定的回调函数就会被执行。
    语法:eventTarget.attachEvent(eventNameWithOn, callback)
    参数:

    1. eventNameWithOn:事件类型字符串,比如onclick, onmouseover, 这里要带on
    2. callback:事件处理函数,当目标触发事件时回调函数被调用
    var li = document.querySelector('.ss');
    li.attachEvent('click', function() {
    	alert(22);
    })
    

    2. 删除事件(解绑事件)

    1)传统注册方式

    eventTarget.onclick = null;

    2)方法监听注册方式

    eventTarget.removeEventListener(type, listener{, useCapture]);
    下面的方法与 attachEvent 事件监听方法一起用:
    eventTarget.detachEVent(eventNameWithOn, callback);

    var li = document.querySelectorAll('.ss');
    li[0].onclick = function() {
    	alert(11);
    	// 1. 传统方式删除事件
    	li[0].onclick = null;
    }
    
    li[1].addEventListener('click', fn);
    function fn() {
    	alert(22);
    	// 2. removeEventListener 删除事件
    	li[1].removeEventListener('click', fn);
    }
            
    li[2].attachEvent('onclick', fn1);
    function fn1() {
    	alert(33);
    	// 3. detachEVent 删除事件
    	li[2].detachEVent('onclick', fn1);
    }
    

    3. DOM事件流

    事件流描述的是从页面中接受事件的顺序。
    事件发生时会发生在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
    DOM事件流分为3个阶段:

    1. 捕获阶段
    2. 当前目标阶段
    3. 冒泡阶段

    【前端】【JavaScript】基础知识_第6张图片
    注意:

    1. JS 中只能执行捕获或者冒泡其中的一个阶段。
    2. onclick 和 attachEvent 只能得到冒泡阶段。
    3. addEventListener(type, listener[, useCapture])第三个参数如果是true表示在事件捕获阶段调用事件处理程序;如果是false表示在事件冒泡阶段调用事件处理程序
    4. 实际开发中,很少用事件捕获,更关注冒泡阶段。
    5. 有些事件是没有冒泡的,比如onblur, onfocus, onmouseover, onmouseleave.
    6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。
    var li = document.querySelector('.ss');
    li.addEventListener('click', function() {
    	alert(22);
    }, ture);
    

    4. 事件对象

    var li = document.querySelectorAll('.ss');
    li[0].onclick = function(event) {
    	// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
    }
    li[0].addEventListener('click', function(event) {
    	// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
    })  
    

    这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
    当我们注册事件时,event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。

    1)事件对象的常见属性和方法

    事件对象属性方法 说明
    e.target 返回触发事件的对象 标准
    e.srcElement 返回触发事件的对象 非标准 ie6-8使用
    e.type 返回事件的类型
    比如:click mouseover 不带on
    e.preventDefault() 该方法阻止默认事件(默认行为) 标准
    比如:不链接跳转
    e.returnValue 该属性阻止默认事件(默认行为) 非标准
    e.stopPropagation() 阻止冒泡 标准
    e.cancelBubble 该属性阻止冒泡 非标准 ie6-8使用

    1. e.target返回触发事件的对象

    e. target返回的是触发事件的对象(元素)
    this返回的是绑定事件的对象(元素)

    var ul = document.querySelector('ul');
    ul.addEventListener('click', function(e) {
    	// 我们给 ul 绑定了事件  那么 this 就指向 ul
    	console.log(this); // 结果:ul
    	// e.target 指向我们点击的那个对象 谁触发了这个事件 
    	// 我们点击的是 li e.target 指向的就是 li
    	console.log(e.target); // 结果:li
    });
    

    ie6-8使用e.srcElement返回触发事件的对象,用法同上。

    2. e.type返回事件类型

    返回 click mouseover 等, 不带on

    var div = document.querySelector('div');
    div.addEventListener('click', function(e) {
    	console.log(e.type); // click
    });
    

    3. e.preventDefault()阻止默认行为

    让链接不跳转或者让提交按钮不提交等;

    var a = document.querySelector('a');
    a.addEventListener('click', function(e) {
    	// 标准写法
    	e.preventDefault();
    	// 低版本浏览器
    	e.returnValue;
    	// 可以利用return false 也能阻止默认行为 没有兼容性问题
    	return false;
    });
    

    **4. e.stopPropagation() **:阻止事件冒泡

    阻止冒泡

    var som = document.querySelector('.som');
    som.addEventListener('click', function(e) {
    	alert('som');
    	if(e&&e.stopPropagation) {
    		// stop 停止 Propagation 传播
    	} else {
    		// 非标准 cancel 取消 bubble 泡泡
    		window.event.cancelBubble = true;
    	}
    }, false);
    

    5. 事件委托(代理,委派)

    事件委托的原理不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。

    var ul = document.querySelector('ul');
    ul.addEventListener('click', function(e) {
    	alert('知否知否,点我应有弹框在手!');
    	e.target.style.backgroundColor = 'pink';
    });
    

    6. 常用的鼠标事件

    使用传统的注册方式:加on
    使用addEventListener:不加on

    鼠标事件 触发条件
    onclick 鼠标点击左键触发
    onmouseover 鼠标经过触发
    onmouseout 鼠标离开触发
    onfocus 获得鼠标焦点触发
    onblur 失去鼠标焦点触发
    onmousemove 鼠标移动触发
    onmouseup 鼠标弹起触发
    onmousedown 鼠标按下触发

    禁止鼠标右键菜单

    contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

    var ul = document.querySelector('ul');
    	ul.addEventListener('contextmenu', function(e) {
    	e.preventDefault();
    });
    

    禁止鼠标选中(selectstart 开始选中)

    禁止鼠标选中文字等。

    var ul = document.querySelector('ul');
    	ul.addEventListener('selectstart', function(e) {
    	e.preventDefault();
    });
    

    1) event 鼠标事件对象

    鼠标事件对象 说明
    e.clientX 返回鼠标相对于浏览器窗口可视区域的X坐标
    e.clientY 返回鼠标相对于浏览器窗口可视区域的Y坐标
    e.pageX 返回鼠标相对于文档页面的X坐标 IE9+ 支持
    e.pageY 返回鼠标相对于文档页面的Y坐标 IE9+ 支持
    e.screenX 返回鼠标相对于电脑屏幕的X坐标
    e.screenY 返回鼠标相对于电脑屏幕的Y坐标

    2) mouseenter 和 mouseover 的区别

    当鼠标移动到元素上时就会触发mouseenter 事件
    类似于mouseover,他们两者之间的差别是

    1. mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发,mouseenter 只会经过自身盒子触发
    2. 之所以这样,就是因为mouseenter不会冒泡
    3. 跟mouseenter 搭配鼠标离开mouseleave 同样不会冒泡

    7. 常用的键盘事件

    使用传统的注册方式:加on
    使用addEventListener:不加on

    键盘事件 触发条件
    onkeyup 某个键盘按键被松开时触发
    onkeydown 某个键盘按键按下时触发
    onkeypress 某个键盘按键按下时触发
    不识别 ctrl shift 箭头 等功能键

    1)键盘事件对象

    键盘事件对象 属性 说明
    keyCode 返回该的ASCLL值

    注意:onkeydownonkeyup不区分区分字母大写onkeypress区分字母大小写
    在我们实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)。



    十四. BOM 浏览器对象类型

    浏览器对象模型
    把「浏览器」当做一个「对象」来看待
    BOM的顶级对象是window
    BOM学习的是浏览器窗口交互的一些对象
    BOM是浏览器厂商在各自浏览器上定义的,兼容性较差

    (一) BOM的构成

    【前端】【JavaScript】基础知识_第7张图片

    window 对象是浏览器的顶级对象,它具有双重角色。

    1. 它是JS访问浏览器窗口的一个接口。
    2. 它是一个全局对象。定义在全局作用域中的变量,函数都会变成window对象的属性和方法

    在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert(), prompt()等。
    注意:window 下的一个特殊属性 window.name,自带的


    BOM 比 DOM 更大,它包含 DOM。
    【前端】【JavaScript】基础知识_第8张图片

    (二) window 对象的常见事件

    1. 窗口加载事件

    1. onload

    window.onload 是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像脚本文件、CSS文件等),就调用的处理函数
    语法:

    window.onload = function(){}
    window.addEventListener('load', function(){});
    

    注意:

    1. 有了 window.onload 就可以把JS代码写到页面元素的上方,因为 onload 是等页面内容加载完毕,再去执行处理函数。
    2. window.onload 传统注册方式只能写一次,如果有多个,会以最后一个为准。
    3. 如果使用 addEventListener 则没有限制。

    2. DOMContentLoaded

    DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表, 图片. flash等等。
    语法:

    window.addEventListener('DOMContentLoaded', function() {});
    

    如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间交互效果就不能实现,必然影响用户的体验.此时用DOMContentLoaded事件比较合适。

    2. 调整窗口大小事件

    window. onresize调整窗口大小加载事件,当触发时就调用的处理函数。
    语法:

    window.onresize = function(){}
    window.addEventListener('resize', function(){});
    

    只要窗口大小发生像素变化,就会触发这个事件
    我们经常利用这个事件完成应式布局。
    window.innerWidth 当前屏幕的宽度


    (三) 定时器

    1. setTimeout() 定时器设置

    setTimeout() 方法用于设置一个定时器,该定时器在定时器到期后执行调用函数
    语法:

    window.setTimeout(调用函数, [延迟的毫秒数]);
    var timer1 = setTimeout(function(){}, 2000);
    

    window 可以省略。
    这个调用函数可以直接写函数,或者写函数名。
    延迟的毫秒数省略默认是0,如果写,必须是毫秒。
    因为定时器可能有很多,所以我们经常给定时器赋值一个标识符

    2. 停止 setTimeout() 定时器

    clearTimeout ()方法取消了先前通过调用setTimeout ()建立的定时器
    window 可以省略

    window.clearTimeout(timeout ID);
    
    var div = document.querySelector('div');
    // 设置定时器
    var timer1 = setTimeout(function(){
    	div.style.display = 'none';
    }, 2000);
    var btn = document.querySelector('button');
    btn.addEventListener('click', function() {
    	// 停止定时器
    	clearTimeout(timer1);
    });
    

    3. setInterval() 定时器设置

    setTimeout() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数
    语法:

    window.setInterval(回调函数, [间隔的毫秒数]);
    var timer1 = setInterval(function(){}, 2000);
    

    window 可以省略。
    这个调用函数可以直接写函数,或者写函数名。
    延迟的毫秒数省略默认是0,如果写,必须是毫秒。
    因为定时器可能有很多,所以我们经常给定时器赋值一个标识符

    4. 停止 setInterval() 定时器

    clearInterval()方法取消了先前通过调用setInterval()建立的定时器
    window 可以省略
    里面的参数就是定时器的标识符

    window.clearInterval(timeout ID);
    
    var div = document.querySelector('div');
    // 设置定时器
    var timer1 = setInterval(function(){
    	div.style.display = 'none';
    }, 2000);
    var btn = document.querySelector('button');
    btn.addEventListener('click', function() {
    	// 停止定时器
    	clearInterval(timer1);
    });
    

    5. this 指向问题

    一般情况下,this 最终指向的是那个调用它的对象。
    全局作用域或者普通函数中,this 指向全局对象 window (注意定时器里面的 this 指向 window)。
    方法调用中,谁调用,this 指向谁。
    构造函数中,this 指向构造函数的实例。

    (四) JS执行机制

    1. JS 是单线程

    JS 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 JS 这门脚本语言诞生的使命所致——JS 是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。
    单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。 这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

    2. 同步和异步

    为了解决上面提到的问题。利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JS脚本创建多个线程。于是,IS中出现了同步和异步。
    异步和同步的本质区别:这条流水线上各个流程的执行顺序不同。

    1)同步

    前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后) ,再去切菜,炒菜。

    2)异步

    你在做一件事情时,因为这件事情会花费很长时间。在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜,

    (五) location 对象

    【前端】【JavaScript】基础知识_第9张图片

    window对象给我们提供了一个location属性,用于获取或设窗体的URL。并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。

    1. URL

    统一资源定位符(URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
    URL 一般语法格式为:
    > protocol://host[:port]/path/[?query]#fragment
    > http://www.baidu.itcast.cn/index.html?name=andy&age=18#link

    组成 说明
    protocol 通信协议 常用http, ftp, maito等
    host 主机(域名)www.itheima.com
    port 端口号 可选,省略时使用方案的默认端口 如http的默认端口为80
    path 路径 由零或多个’/‘符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
    query 参数 以键值对的形式,通过&符号分隔开来
    fragment 片段 #后面内容 常见于链接 锚点

    2. location 对象的属性

    对象属性 返回值
    location.href* 获取或者设置 整个URL
    location.host 返回主机(域名)www.itheima.com
    location.port 返回端口号 如果未返回 空字符串
    location.pathname 返回路径
    location.search* 返回参数
    location.hash 返回片段 #后面内容 常见于链接 锚点

    3. location 对象的方法

    location 对象方法 返回值
    location.assign() 跟href一样,可以跳转页面(也称之为重定向页面)
    location.replace() 替换当前页面,因为不记录历史,所以不能后退页面
    location.reload() 重新加载页面,相当于刷新按钮或者 f5 ,如果参数为true 强制刷新 ctrl+f5

    (六) navigator 对象

    navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent ,该属性可以返回由客户机发送服务器的user-agent头部的值。
    判断用户用哪个终端打开页面,实现跳转:

    if(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPed|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
    	window.location.href = "";  // 手机
    } else {
    	window.location.href = "";  // 电脑
    }
    

    (七) history 对象

    【前端】【JavaScript】基础知识_第10张图片

    window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL

    history 对象方法 作用
    back() 后退功能
    forward() 前进功能
    go(参数) 前进后退功能
    参数如果时 1 ,前进一个页面
    如果是 -1 ,后退一个页面
    var btn = document.querySelector('input');
    btn.addEventListener('click', function() {
    	history.back();     // 后退
    	history.forward();  // 前进
    	history.go(1);      // 前进一个页面
    	history.go(-1);     // 后退一个页面
    });
    


    十五. PC端网页特效

    (一) 元素偏移量 offset 系列

    offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等
    获得元素距离带有定位父元素的位置
    获得元素自身的大小 (宽度高度)
    注意返回的数值都不带单位

    offset 系列常用属性 作用
    element.offsetParent 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
    element.offsetTop 返回元素相对带有定位父元素上方的偏移
    element.offsetLeft 返回元素相对带有定位父元素左边框的偏移
    element.offsetWidth 返回自身包括padding,边框,内容区的宽度,返回数值不带单位
    element.offsetHeight 返回自身包括padding,边框,内容区的高度,返回数值不带单位
    var btn = document.querySelector('input');
    // 返回带有定位的父级元素
    var parent = btn.offsetParent; 
    // 返回上方偏移量
    var top = btn.offsetTop;
    // 返回左边框偏移量
    var left = btn.offsetLeft;
    // 返回padding,边框,内容区的宽度
    var width = btn.offsetWidth;
    // 返回padding,边框,内容区的高度
    var height = btn.offsetHeight;
    

    1. offset 与 style 区别

    offset

    1. offset 可以得到任意样式表中的样式值
    2. offset 系列获得的数值是没有单位的
    3. offsetWidth 包含 padding+border+width
    4. offsetWidth 等属性是只读属性,只能获取不能赋值
    5. 所以我们想要获取元素大小位置,用offset 更合适

    style

    1. style 只能得到行内样式表中的样式值
    2. style.width 获得的是带有单位的字符串
    3. style.width 获得不包含 padding 和 border 的值
    4. style.width 是可读写属性,可以获取也可以赋值
    5. 所以,我们想要给元素更改值,则需要用style改变

    2. 获取盒子中鼠标的坐标

    鼠标移动,获取坐标

    var som = document.querySelector('div');
    som.addEventListener('mousemove', function(e) {
    	// 鼠标在盒子中的坐标 = 鼠标在页面中的坐标(e.pageX, e.pageY) - 盒子在页面中的距离(this.offsetLift, this.offsetTop)
    	var x = e.pageX - this.offsetLeft;
    	var y = e.pageY - this.offsetTop;
    	this.innerHTML = 'x坐标是' + x + 'y坐标是' + y;
    });
    

    【拖动模块框,放大镜效果】实例


    offset 系列经常用于获得元素位置offsetLeft offsetTop


    (二) 元素可视区 client 系列

    client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

    client 系列属性 作用
    element.clientTop 返回元素上边框的大小
    element.clientLeft 返回元素左边框的大小
    element.clientWidth 返回自身包括padding,内容区的宽度,不含边框,返回数值不带单位
    element.clientHeight 返回自身包括padding,内容区的高度,不含边框,返回数值不带单位
    var div = document.querySelector('div');
    var top = div.clientTop; // 元素上边框大小
    var left = div.clientLeft; // 元素左边框大小
    var width = div.clientWidth; // 返回自身宽度
    var height = div.clientHeight; // 返回自身高度
    

    1. 立即执行函数

    立即执行函数(function() {})()或者(function(){}())
    主要作用:创建一个独立的作用域。避兔了命名冲突问题

    // 写法 可以传递参数进来
    // 1. (function() {})();   或者   2. (function(){}());
    (function(a, b) {
    	console.log(a + b);
    	var num = 10;
    })(1, 2); // 第二个括号可以看作是调用函数
    
    (function sum(a, b) {
    	console.log(a + b);
    	var num = 10; // 局部变量
    }(2, 3));
    

    2. 淘宝 js 源码

    (function flexible(window, document) {
    	// 获取html的根元素
    	var docEl = document.documentElement;
    	// dpr 物理像素比
    	var dpr = window.devicePixelRatio || 1;
    
    	// 设置body 的字体大小
    	function setBodyFontSize() {
    		// 如果页面中有body 这个元素 就设置body 的字体大小
    		if(document.body) {
    			document.body.style.fontsize = (12 * dpr) + 'px';
    		} else {
    			// 如果没有body 这个元素,则等页面主要的DOM元素加载完毕再去设置body的字体大小
    			document.addEventListener('DOMContentLoaded', setBodyFontSize);
    		}
    	}
    	setBodyFontSize();
    
    	// 设置html 元素的文字大小
    	function setRemUnit() {
    		var rem  = docEl.clientWidth;
    		docEl.style.fontsize = rem + 'px';
    	}
    	setRemUnit();
    
    	// 当页面尺寸发生变化的时候,要重新设置以下rem 的大小
    	window.addEventListener('resize', setRemUnit);
    	// pageshow 是我们重新加载页面触发的事件
    	window.addEventListener('pageshow', function(e) {
    		// e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也从新计算一下rem 的大小
    		if(e.persisted) {
    			setRemUnit();
    		}
    	});
    
    	// 有些移动端浏览器不支持 0.5 像素的写法
    	if(dpr >= 2) {
    		var fakeBody = document.createElement('body');
    		var testElement = document.createElement('div');
    		testElement.style.border = '.5px solid transparent';
    		fakeBody.appendChild(testElement);
    		docEl.appendChild(fakeBody);
    		if(testElement.offsetHeight === 1) {
    			docEl.classList.add('hairlines');
    		}
    		docEl.removeChild(fakeBody);
    	}
    })(window, document);
    

    client 系列经常用于获取元素大小clientWidth clientHeight


    (三) 元素滚动 scroll 系列

    1. 元素scroll系列属性

    scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等

    scroll 系列属性 作用
    element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
    element.scrollLeft 返回被卷去的左侧距离,返回数值不带单位
    element.scrollWidth 返回自身实际的宽度,不含边框,返回值不带单位
    element.scrollHeight 返回自身实际的高度,不含边框,返回值不带单位

    2. 页面被卷去的头部

    如果浏览器的高(宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,称之为页面被卷去的头部。滚动条在滚动时会触发onscroll事件。
    注意:元素卷去的头部是element.scroltTop,如果是页面被卷去的头部则是window.pageYOffset


    scroll 系列经常用于获取滚动距离scrollTop scrollLeft


    (四) 动画函数封装

    1. 动画实现原理

    核心原理通过定时器setInterval() 不断移动盒子位置。
    实现步骤:

    1. 获得盒子当前位置
    2. 让盒子在当前位置加上一个移动距离
    3. 利用定时器不断重复这个操作
    4. 加一个结束定时器的条件
    5. 注意此元素需要添加定位,才能使用element.style.left

    2. 动画函数简单封装

    注意函数需要传递两个参数,动画对象移动距离

    // 简单动画函数封装
    function animate(obj, target) {
    	var timer1 = setInterval(function() {
    		if(obj.offsetLeft >= target) {
    			clearInterval(timer1);
    		}
    		obj.style.left = obj.offsetLeft+5+'px';
    	}, 50);
    }
    
    var div = document.querySelector('div');
    // 调用函数
    animate(div, 350);
    

    3. 给不同元素记录不同定时器

    // 简单动画函数封装
    // 给不同的元素指定了不同的定时器  obj.timer
    function animate(obj, target) {
    	// 先清除以前的定时器,只保留当前的一个定时器执行 
    	clearInterval(obj.timer);
    	obj.timer = setInterval(function() {
    		if(obj.offsetLeft >= target) {
    			clearInterval(obj.timer);
    		}
    		obj.style.left = obj.offsetLeft+5+'px';
    	}, 50);
    }
    
    var div = document.querySelector('div');
    // 调用函数
    animate(div, 350);
    

    4. 缓动效果原理

    缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。

    1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
    2. 核心算法:(目标值 - 现在的位置) / 10 做为每次移动的距离步长
    3. 停下来的条件是:让盒子位置等于目标位置就停止定时器
    4. 注意步长值需要取整
      往前: Math.ceil(8.1) -> 9
      往后:Math.floor(-8.1)-> -9
    // 简单动画函数封装
    // 给不同的元素指定了不同的定时器  obj.timer
    function animate(obj, target) {
    	// 先清除以前的定时器,只保留当前的一个定时器执行 
    	clearInterval(obj.timer);
    	obj.timer = setInterval(function() {
    		var step = (target - obj.offsetLeft) / 10;
    		// 判断是正着走还是负着走
    		step > 0 ? Math.ceil(step) : Math.floor(step);
    		if(obj.offsetLeft == target) {
    			clearInterval(obj.timer);
    		}
    		obj.style.left = obj.offsetLeft+step+'px';
    	}, 15);
    }
    // 匀速动画 就是 盒子是当前的位置 + 固定的值 10
    // 缓动动画 就是 盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10
    
    var div = document.querySelector('div');
    // 调用函数
    animate(div, 350);
    

    5. 动画函数添加回调函数

    回调函数原理函数可以作为一个参数。将这个函数作为参数传到另一个函数里面,当那个函数执行完毕后,再执行传进去的这个函数,这个过程就叫做回调。

    // 简单动画函数封装
    function animate(obj, target, callback) {
    	// 先清除以前的定时器,只保留当前的一个定时器执行 
    	clearInterval(obj.timer);
    	obj.timer = setInterval(function() {
    		var step = (target - obj.offsetLeft) / 10;
    		// 判断是正着走还是负着走
    		step > 0 ? Math.ceil(step) : Math.floor(step);
    		if(obj.offsetLeft == target) {
    			// 定时器结束
    			clearInterval(obj.timer);
    			if(callback) {
    				// 调用函数
    				callback();
    			}
    		}
    		obj.style.left = obj.offsetLeft+step+'px';
    	}, 15);
    }
    // 匀速动画 就是 盒子是当前的位置 + 固定的值 10
    // 缓动动画 就是 盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10
    
    var div = document.querySelector('div');
    // 调用函数
    animate(div, 350, function() {});
    

    (五) 常见网页特效案例

    1. 网页轮播图

    防止轮播图按钮连续点击造成播放过快。
    节流阀的目的当上一个函数动画执行完毕,再去执行下一个函数动画,让事件无法连续触发。
    核心实现思路利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

    1. 开始设置一个变量var flag = true;
    2. if(flag) { flag = false; do something} 关闭水龙头
    3. 利用回调函数 动画执行完毕,flag = ture 打开水龙头
    // flag 节流阀
    // 设置变量
    var flag = true;
    // 判断节流阀是否打开
    if(flag) {
    	flag = false; // 关闭节流阀
    	// 执行动画函数
    	// 动画函数执行完毕后,回调函数内打开节流阀,继续执行下一个动画函数
    	animate(ul, -num * focusWidth, function() {
    		flag = true; // 打开节流阀
    	});
    }
    

    【轮播图】实例



    十六. 移动端网页特效

    (一) 触屏事件

    移动端浏览器兼容性比较好,不需要考虑兼容性问题,可以放心的使用原生JS书写效果。
    触屏事件 touch (也称触摸事件)。
    touch对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触摸事件可响应用户手指对屏幕或者触控板操作。
    常见的触屏事件如下:

    触屏touch事件 说明
    touchstart 手指触摸到一个DOM元素时触发(手指按下)
    touchmove 手指在一个DOM元素上滑动时触发(手指按住滑动)
    touchend 手指从一个DOM元素上移开时触发(手指离开)

    1. 触摸事件对象(TouchEvent)

    TouchEvent是一类描述手指在触摸屏面(如屏幕,触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少等。
    touchstart 等事件都会各自有事件对象。
    三个常见触摸事件对象列表:

    触摸列表 说明
    touches 正在触摸屏幕的所有手指的一个列表
    targetTouches 正在触摸当前DOM元素上的手指的一个列表
    changedTouches 手指状态发生改变的列表,从无到有,从有到无变化

    因为平时我们都是给元素注册触摸事件,所以重点记住 targetTouches

    var span = document.querySelector('span');
    span.addEventListener('touchstart', function(e) {
    	// touches  正在触屏的所有手指的列表
    	// targetTouches  正在触摸当前DOM元素的手指列表
    	// changedTouches  手指状态发生了改变的列表
    	
    	// 得到正在触摸DOM元素的第一个手指的相关信息  比如 手指的坐标等
    	console.log(e.targetTouches[0]);
    })
    

    2. 移动端拖动元素

    1. touchstart, touchmove, touchend 可以实现拖动元素
    2. 但是拖动元素需要当前手指的坐标值,我们可以使用targetTouches[0] 里面的 pageX 和 pageY
    3. 移动端拖动原理:手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离
    4. 手指移动的距离: 手指滑动中的位置 - 手指刚开始触摸的位置

    拖动元素三部曲:
    1)触摸元素tuochstart:获取手指初始坐标,同时获得盒子原来的位置
    2)移动手指touchmove:计算手指的滑动距离,并且移动盒子
    3)离开手指touchend

    注意:手指移动也会触发滚动屏幕,所以这里要阻止默认的屏幕滚动 e.preventDefault();

    // 获取元素
    var div = document.querySelector('div');
    // 获取手指初始坐标
    var startX = 0;
    var startY = 0;
    // 获取盒子原来的位置
    var x = 0;
    var y = 0;
    // 1. 触摸元素
    div.addEventListener('touchstart', function(e) {
    	// 获取手指的初始坐标
    	startX = e.targetTouches[0].pageX;
    	startY = e.targetTouches[0].pageY;
    	// 获取盒子原来的位置
    	x = this.offsetLeft;
    	y = this.offsetTop;
    })
    // 2. 移动手指
    div.addEventListener('touchmove', function(e) {
    	// 计算手指移动的距离 移动后的位置 - 初始位置
    	var moveX = e.targetTouches[0].pageX - startX;
    	var moveY = e.targetTouches[0].pageY - startY;
    	// 移动盒子
    	this.style.left = x+moveX+'px';
    	this.style.top = y+moveY+'px';
    	e.preventDefault(); // 组织屏幕滚动
    })
    

    (二) 移动端常见特效

    1. 自动播放功能-无缝滚动

    注意,我们判断条件是要等到图片滚动完毕再去判断,就是过渡完成后判断
    此时需要添加检测过渡完成事件 transitionend

    2. classList 属性

    classList 属性是HTML5新增的一个属性,返回元素的类名。但是ie10以上版本支持。
    该属性用于在元素中添加,移除及切换CSS类

    1)添加类

    element.classList.add("类名");
    例:div.classList.add('current');
    在后面追加类名,不会覆盖以前的类名,前面不需要加.

    2)移除类

    element.classList.remove("类名");
    例:div.classList.remove('current');

    1)切换类

    element.classList.toggle("类名");
    例:div.classList.toggle('current');

    3. click 延时解决方案

    移动端click事件会有300ms的延时,原因是移动端屏幕双击会缩放(double tap to zoom)页面。
    解决方案:

    1. 禁用缩放。浏览器禁用默认的双击缩放行为并且去掉300 ms 的点击延迟。
    2. 利用touch事件自己封装这个事件解决延迟。
    3. 使用插件。fastclick 插件解决 300 ms 延迟。

    (三) 移动端常用开发插件

    移动端要求的是快速开发,所以我们经常会借助于些插件来帮我完成操作。
    JS插件是=js文件,它遵循定规范编写,方便程序展示效果,拥有特定功能且方便调用。如轮播图和瀑布流插件。
    特点:它般是为了解决某个问题而专门存在,其功能单一, 并且比较小。
    我们以前写的animate.js也算一个最简单的插件。

    1. fastclick插件

    fastclick 插件解决 300 ms 延迟。使用延时
    GitHub 官网地址:https://github.com/ftlabs/fastclick

    2. Swiper 插件的使用

    中文官网地址:https://www.swiper.com.cn/

    1. 引入插件相关文件;
    2. 按照规定语法使用。

    3. 移动端常用插件

    superslide:http://www.superslide2.com/
    iscroll:http://github.com/cubiq/iscroll

    4. 插件的使用总结

    1. 确认插件实现的功能
    2. 去官网查看使用说明
    3. 下载插件
    4. 打开demo实例文件,查看需要引入的相关文件,并且引入
    5. 复制demo实例文件中的结构html,样式css以及js代码

    (四) 移动端常用开发框架

    框架,就是一套架构,它会基于自身的特点向用户提供一套较为完整的解决方案。框架的控制权在框架本身,使用者要按照框架所规定的某种规范进行开发。
    前端常用的框架有Bootstrap, Vue, Angular, React等。既能开发PC端,也能开发移动端。

    1. Bootstrap

    Bootstrap 是一个简洁,直观,强悍的前端开发框架,它让 web 开发更迅速,简单。
    它能开发PC端,也能开发移动端
    Bootstrap JS 插件使用步骤:

    1. 引入相关js文件
    2. 复制HTML结构
    3. 修改对应样式
    4. 修改相应JS参数


    十七. 本地存储

    随着互联网的快速发展,基于网页的应用越来越普遍,同时也便的越来越复杂, 为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5 规范提出了相关解决方案。
    本地存储特性:

    1. 数据存储在用户浏览器中
    2. 设置,读取方便,甚至页面刷新不丢失数据
    3. 容量较大,sessionStorage 约 5M,localStorage 约 20M
    4. 只能存储字符串,可以将对象JSON.stringify() 编码后存储

    (一) window.sessionStorage

    1. 生命周期为关闭浏览器窗口
    2. 在同一个窗口(页面)下数据可以共享
    3. 以键值对的形式存储使用

    存储数据:
    sessionStorage.setItem(key, value);
    获取数据:
    sessionStorage.getItem(key);
    删除数据:
    sessionStorage.removeItem(key);
    删除所有数据:
    sessionStorage.clear();


    (二) window.localStorage

    1. 生命周期永久生效,除非手动删除,否则关闭页面也会存在
    2. 在多窗口(页面)共享(同一浏览器可以共享)
    3. 以键值对的形式存储使用

    存储数据:
    localStorage.setItem(key, value);
    获取数据:
    localStorage.getItem(key);
    删除数据:
    localStorage.removeItem(key);
    删除所有数据:
    localStorage.clear();



    十八. jQuery

    (一) JavaScript 库

    仓库可以把很多东西放到这个仓库里面。找东西只需要到仓库里面查找就可以了
    JavaScript库:即library,是一个封装好的特定的集合(方法和函数)。从封装一大堆函数的角度理解库,就是在这个库中,封装了很多预先定义好的函数在里面,比如动画animate, hide, show,比如获取元素等。
    就是一个js文件,里面对我们原生js代码进行了封装,存放到里面。这样我们可以快速高效的使用这些封装好的功能了。
    》比如jQuery,就是为了快速方便的操作DOM,里面基本都是函数(方法)。
    常见的JS库:

    1. jQuery
    2. Prototype
    3. YUI
    4. Dojo
    5. Ext JS
    6. 移动端的zepto

    这些库都是对原生JS的封装,内部都是用JS实现的,我们主要学习的是jQuery。


    (二) jQuery的概念

    jQuery 是一个快速,简洁的JS库,倡导写更少的代码,做更多的事情。
    j 就是JS;Query 查询;意思是查询js,把js中的DOM操作进行了封装,我们可以快速的查询使用里面的功能。
    jQuery封装了JS常用的功能代码,优化了DOM操作。事件处理。动画设计和Ajax交互。
    学习jQuery本质:就是学习调用这些函数(方法)
    jQuery出现的目的就是加快前端开发人员的开发速度,我们可以非常方便的调用和使用它,从而提高开发效率。
    优点:

    1. 轻量级,不会影响页面加载速度
    2. 跨浏览器兼容。基本兼容现主流的浏览器
    3. 链式编程,隐式迭代
    4. 对事件,样式,动画支持,大大简化了DOM操作
    5. 支持插件扩展开发。有着丰富的第三方的插件,例如:树形菜单,日期控件,轮播图等
    6. 免费,开源

    1. jQuery 的下载

    官网地址:https://jquery.com/
    版本:
    1x:兼容IE678等低版本浏览器,官网不再更新
    2x:不兼容IE678等低版本浏览器,官网不再更新
    3x:不兼容IE678等低版本浏览器,是官网主要更新维护的版本
    各个版本的下载:https://code.jquery.com/

    2. jQuery的使用步骤

    1. 引入jQuery文件
    2. 使用即可

    3. jQuery 的入口函数

    1. 
    $(function() {
    	... // 此处是页面DOM加载完成的入口
    	$('div').hide(); // 隐藏
    })
    2. 
    $(document).ready(function() {
    	... // 此处是页面DOM加载完成的入口
    })
    
    1. 等着DOM结构渲染完毕即可执行内部代码,不必等到所有外部代码资源加载完成,jQuery帮我们完成了封装。
    2. 相当于原生JS中的DOMContentLoaded。
    3. 不同于原生JS中的load事件是等页面文档,外部的JS文件,css文件,图片加载完毕才执行内部代码。
    4. 更推荐使用第一种方式。

    4. jQuery 的顶级对象 $

    1. $ 是jQuery的别称,在代码中可以使用jQuery代替$,但一般为了方便,通常都直接使用$
    2. $是jQuery的顶级对象,相当于原生JS中的window。把元素利用$包装成jQuery对象,就可以调用jQuery的方法。

    5. jQuery 对象和 DOM 对象

    1. 用原生JS来获取的对象就是DOM对象;
      var div = document.querySelector('div');
    2. jQuery方法获取的元素就是jQuery对象;
      $('div');
    3. jQuery对象的本质:利用$对DOM对象包装后生成的对象(伪数组形式存储);

    DOM 对象与jQuery对象之间是可以转换的。
    因为原生JS比jQuery更大,原生的一些属性和方法jQuery没有给我们封装,要想使用这些属性和方法需要把jQuery对象转换为DOM对象才能使用。

    1. DOM对象转换为jQuery对象:$(DOM对象)
      $('div')
    2. jQuery对象转换为DOM对象:(两种方式)
      $('div')[index] index是索引号
      $('div').get(index) index是索引号


    十九. 数据可视化项目

    (一) 什么是数据可视化

    1. 数据可视化

    数据可视化主要目的借助于图形化手段,清晰有效地传达与沟通信息。
    数据可视化可以把数据从冰冷的数字转换成图形,揭示蕴含在数据中的规律和道理。

    2. 数据可视化的场景

    目前互联网公司常有这么几大类的可视化需求:

    1. 通用报表
    2. 移动端图标
    3. 大屏可视化
    4. 图编辑&图分析
    5. 地理可视化

    3. 常见的数据可视化库

    D3.js:目前Web端评价最高的JS可视化工具库(入手难)
    ECharts.js:百度出品的一个开源JS数据可视化库
    Highcharts.js:国外的前端数据可视化库,非商用免费,被许多国外大公司所使用
    AntV:蚂蚁金服全新一代数据可视化解决方案


    (二) ECharts 简介

    ECharts 是一个使用JS实现的开源可视化库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器,底层依赖矢量图形库ZRender,提供直观,交互丰富,可高度个性化的数据可视化图表。
    官网地址:https://echarts.apache.org/zh/index.html


    (三) ECharts 的基本使用

    1. ECharts 使用五步骤

    步骤1:下载并引入 echarts.js 文件 ----> 图表依赖这个js库
    步骤2:准备一个具备大小的DOM容器 ----> 生成的图表会放入这个容器内
    步骤3:初始化 echarts 实例对象 ----> 实例化echarts对象
    步骤4:指定配置项和数据(option) ----> 根据具体需求修改配置选项
    步骤5:将配置项设置给 echarts 实例对象 ----> 让echarts对象根据修改好的配置生效

    你可能感兴趣的:(前端,javascript,前端,开发语言)