JavaScript

JavaScript

也是为HTML服务的 存储数据 计算 请求
从三个方向来讲

  • ECMAScript — 包含JS的基本语法
  • BOM – 浏览器对象模型 是跟浏览器进行交互的
    Browser Object Model
  • DOM — 文档对象模型 跟文档进行交互的
    Document Object Model

补充

CSS
响应式布局: 根据不同的屏幕设置不同的布局

/* 最小屏幕宽 720px样式 */
@media screen and (min-width:720px) {
	#footer p{
		color: #008B8B;
	}
}
/* 最小屏幕宽 960px样式 */
@media screen and (min-width:960px) {
	#footer p{
		color: palevioletred;
	}
}
/* 最小屏幕宽 1200px样式 */
@media screen and (min-width:1200px) {
	#footer p{
		color: rgb(138,138,138);
	}
}

引入JS的方式

内部引入

在head 或者 body 中添加script标签 标签之间就是JS的代码

<script>
	// 行注释
	
	/*
	块注释 -- 块注释不能相互嵌套
	*/
	
	// 打招呼 弹框型
	// alert("Hello world")
	
	// 与文档交互型 通过文档对象document操作对象
	// 文档上可以显示标签  跟文档操作 所以也可以写标签
	// +完成字符串的拼接
	document.write("hello world" + "<br/>")
	document.write("<img src='../img/cat.jpg' width='100px' />")
	
	// 在控制台显示
	console.log("Hello world")
</script>

外部引入

前提有一个JS文件
在head 或者 body 中添加script标签 通过属性src引入JS文件

<script src="../js/main.js"></script>

<script src="../js/main.js">
	console.log("你们看不见我")
</script> -->

内部引用和外部引用不能合并在一起
标签之间的内容时不会识别的
以后写的话内部就是内部 外部就是外部

ECMAScript的基本语法

变量的声明

JS是动态语言, 变量的类型是有赋予的值来决定的 与Python这一点是一样的

  • 声明变量的格式:
    var 变量名 = 值;
    语句结束之后 写分号可以 不写也可以 建议写
  • 声明多个变量
    var 变量名 = 值, 变量名1 = 值, …

数据类型

  • 数字类型 Number

  • 字符串类型 String 使用引号包含的数据, 单双引号都可以

  • 布尔类型 Boolean 值只有两个 true 和 false

  • 对象类型 Object ===> Python 中的字典

  • 特殊的数据类型

    • Null 等价于Python中的NoneType
      值只有一个 null ===> None 空对象
    • Undefined 只有一个值 undefined, 当声明变量的时候 没有对其进行初始化,就直接使用了该变量, 该变量的值就是undefined
  • 检验变量类型的方法
    typeof 变量名

<script>
	var num = 10;
	console.log(typeof num);//number
	num = 14.5;
	console.log(typeof num);//number
	
	var value = "how are you";
	console.log(typeof value);//string
	
	value = true;
	console.log(typeof value);//boolean
	
	var a;
	console.log(typeof a); //undefined
	
	// JS中的对象声明格式 类似于 Python中的字典
	var obj = {
		name:"测测",
		age:18
	};
	console.log(typeof obj);//object
	
	var b = null;
	console.log(typeof b);//object
	
	var num1 = 10, num2 = 20
	console.log(num1)//10
	console.log(num2)//20
	
	// JS中无效
	num1, num2 = 30, 40
	console.log(num1)//10
	console.log(num2)//30
</script>

Boolean类型详解

其他类型转化为布尔类型的规则

  • 数值类型 — 非零即为true
  • 字符串类型 — 空字符序列为false 非空为true
  • 对象类型中 — Object的数据 —> Python中的字典的
  • 非null即为true
  • undefined 也是false

转换的格式
Boolean(数据)

var b = true;
console.log(typeof b)//boolean

console.log(Boolean(10))//true
console.log(Boolean(0))//false
console.log(Boolean(3.14))//true

console.log(Boolean(""))//false
console.log(Boolean(" "))//true

console.log(Boolean(null))//false
console.log(Boolean(undefined))//false
console.log(Boolean({}))//true

number类型详解

在小数数据存储的时候, 小数点后没有数据 或者是小数点后只有一个0
解释器解释 计算器在存储的时候会把该数据存储为整型 (节省内存)

浮点数据的存储占用的内存要比整型数据大很多 几乎为两倍

var num = 10;
console.log(typeof num);//number

var value = 10.0
console.log(value)//10

// 声明浮点数据的时候的格式
value = .8  // 不建议使用这种格式
console.log(value)//0.8

value = 1.8
console.log(value)//1.8

// 数值类型的最大值和最小值
console.log(Number.MAX_VALUE) // 1.7976931348623157e+308
console.log(Number.MIN_VALUE) //5e-324
// 数据过大或者过小的时候 会转化为科学计数法表示的


// 数值相除的时候 分母是不能为0的
console.log(0 / 0) // NaN -- Not a Number
// 如果数据超过上面的范围就会出现 正无穷和负无穷的情况
console.log(1 / 0) // Infinity 正无穷
console.log(-1 / 0) // -Infinity 负无穷

// 验证数据 是否 不是一个数值   isNaN(数据)
// 不是数值尾部true  是数值为false
console.log(isNaN("123abc"))//true
console.log(isNaN(123))//false

// 将字符串类型数据或者浮点类型数取整
var res = parseInt(3.14);
console.log(res)//3

// 字符串: 只要字符串开头的数据满足整数的格式 就能提取出来数据
console.log(parseInt("+125613fghjdklasjjhfds"))//125613
console.log(parseInt("a+125613fghjdklasjjhfds"))//NaN

// 将字符串的数据转化为浮点型
// 只要字符串开头的数据满足整数或者小数的格式
console.log(parseFloat("1.34abdf"))//1.34

字符串类型详解

1.声明字符串的格式
  • var s = “abc”;
  • s = new String(“abc”)
  • s = String(“abc”)
    new 可以省略
2.获取字符串的长度

var len = s.length

3.获取指定索引位置的字符
  • var ch = s[0]
  • ch = s.charAt(0)
4.获取子串从指定位置开始第一次出现的位置

s = “how are you how old are you”

  • 默认是从头开始找的
    var index = s.indexOf(“are”)
    console.log(index)//4
  • 从指定位置开始
    index = s.indexOf(“are”, 5)
    console.log(index)//20
5.获取子串到指定位置中最后一次出现的位置

index = s.lastIndexOf(“are”)
console.log(index)//20

  • 指定位置结束
    index = s.lastIndexOf(“are”, 19)
    console.log(index)//4
  • 找不到返回-1
    index = s.indexOf(“meet”)
    console.log(index)//-1
6.拼接字符串
  • 使用运算符 + 号拼接 可以与任意类型的数据进行拼接 结果都是字符串类型
s = "abcdef"
var new_s = s + "-" + "hello"
console.log(new_s)//abcdef-hello

new_s = new_s + 10
console.log(new_s)//abcdef-hello10
console.log(typeof new_s)//string

new_s = new_s + true
console.log(new_s)//abcdef-hello10true
console.log(typeof new_s)//string

s = "hello" + 5 * 5
console.log(s)//hello25

s = 5 + 5 + "hello"
console.log(s)//10hello
  • 拼接方法2 可以一次性拼接多个 每个之间使用逗号隔开即可
    new_s = “hello”.concat(10,true,“nice”)
    console.log(new_s)
7.提取子串

s = “goodgoodstudydaydayup”

开始索引和结束索引
[开始,结束)

  • 什么都不传递 默认是从头到尾的
    var substr = s.substring()
    console.log(substr)//goodgoodstudydaydayup
  • 从指定起始位置到结束
    substr = s.substring(4)
    console.log(substr)//goodstudydaydayup
  • 指定范围
    substr = s.substring(1,4)
    console.log(substr)//ood
  • 从指定位置开始提取指定长度的子串
    substr = s.substr(1,4)
    console.log(substr)//oodg
  • 类似于第一种 指定起始和结束的
    substr = s.slice(1, 4)
    console.log(substr)//ood
8.将字符串中的字母转化为大写字母

var upper_str = s.toUpperCase()
console.log(upper_str)//GOODGOODSTUDYDAYDAYUP

9.将字符串中的字母转化为小写字母

var lower_str = upper_str.toLowerCase()
console.log(lower_str)//goodgoodstudydaydayup

10.切割字符串
  • 切割为单词
    s = “good good study day day up”
    var sub_arr = s.split(" ")
    console.log(sub_arr)// [“good”, “good”, “study”, “day”, “day”, “up”]
  • 指定切割后获取的前n个子串
    var sub_arr = s.split(" ", 1)
    console.log(sub_arr)//[“good”]
  • 切割符可以直接用正则表达式
    /正则表达式/
    s = “i13love14you520hahaha”
    sub_arr = s.split(/\d+/)
    console.log(sub_arr)//[“i”, “love”, “you”, “hahaha”]
11.替换字符串 — 只能替换查找到的第一个

var replace_s = s.replace(“o”, “OO”)
console.log(replace_s)//i13lOOve14you520hahaha

函数

封装重复使用的代码 简化代码 降低代码的重复率
格式:

function 函数名(形参列表){
	函数体
	return 返回值
}

解读

  1. function 声明函数的关键字
  2. 函数名 遵守标识符规范 使用小驼峰的命名规则
    第一个单词首字母小写 之后每个单词首字母都是大写的
    getMaxValue
  3. ()是固定的
  4. 形参列表
    形参变量 有多个的话每个之间使用逗号隔开即可
    如果没有的话就不用设定了
    声明形参变量时 不用使用var来修饰了
    形参的个数是由 参与功能的未知项的个数决定的
  5. 在JS中没有什么缩进规则
  6. return 结束函数的标志 并将返回值返回到调用位置处
    如果没有返回值 return可以省略的
  • Python中是有可变参数的
    *args **kwargs
    JS中函数本身就是可变参数的
    在函数体中 有一个数组(Python中的列表)的属性叫arguments存放着传递给函数的所有实参
  • 函数呢也就是一个数据, 一个值 类似于10等 是可以被进行传递的
// 计算两个数的和
function add(x, y){
	console.log(arguments)
	// 想获取其中的数据的话 可以通过遍历来获取
	for (i in arguments){
		console.log(i)
		console.log(arguments[i])
	}
	return x + y
}
console.log(typeof add)
// 函数的调用
var res = add(10, 20)
console.log(res)
res = add(10, 20, 30, 40, 50)
console.log(res)

匿名函数

* function(形参列表){
	函数体
	return 返回值
}

一次性函数

在内存中执行完成会被立即释放的

res = (function(a, b){
	return a + b
})(13, 24)
console.log(res)

函数也是一个数据 可以被赋予给变量的

f = function(a, b){
	return a + b
}

res = f(17, 19)
console.log(res)

f1 = add
res = f1(19, 19)
console.log(res)

使用var 标记变量和不标记变量的区别

函数有自己独立的作用域
在函数内部声明的变量 不用var标记 – 是一个全局变量
在函数的外部可以使用
使用var声明 就是一个局部变量 只能在函数中使用

function display(){
	var max_value = 100
	min_value = 10
}
display()

console.log(min_value)//10
console.log(max_value)//Uncaught ReferenceError: max_value is not defined

函数嵌套

function outer(){
	console.log("外部函数")
	function inner(){
		console.log("内部函数")
	}
	inner()
}
outer()

想让inner的作用范围广一些 闭包
函数嵌套, 外层函数的返回值是一个函数

function outer1(){
	console.log("外部函数1")
	function inner1(){
		console.log("内部函数1")
	}
	return inner1
}
res = outer1()
res()

运算符

算术运算符

+ - * / %

console.log(1 + 2)
console.log(1 - 2)
console.log(1 * 2)
console.log(1 / 2)
console.log(1 % 2)

一元运算符

+(正号) -(符号) ++(自加) --(自减)
单独的一条语句 a++ 和 ++a是没有区别的
都是在原来的基础上对变量进行自加1
在参与运算的时候
a++ 先将变量的值参与运算 再对变量进行自加1
++a 先对变量进行自加1 再将变量的值参与运算

var m = 10
n = m++
console.log(n) //10
console.log(m) //11
n = ++m
console.log(n) //12
console.log(m) //12

复合运算符

+= -= *= /= %=

比较运算符

> >= < <= == != ===(恒等)
==和===的区别

  • ===才表示的是恒等: 数据和类型都是一致的 结果才为true
  • == 数据内容一致 类型不一致结果也可以为true
var res = (123 == "123" ? "成立" : "不成立")
console.log(res)//成立

res = (123 === "123" ? "成立" : "不成立")
console.log(res)//不成立

res = (123 === 123 ? "成立" : "不成立")
console.log(res)//成立

逻辑运算符

逻辑与 && (and) 逻辑或 || (or) 逻辑非 ! (not)
在Python中and和or是具有短路原则的

  • && 逻辑与
    并且的关系 两边表达式同时成立 结果才能成立
    换句话说 一假则全假 有一个不成立 结果就判定为假
    左边表达式判定为假 右边表达式则没有必要判断真假 也就意味
    执行到此结束了。 如果后面有逻辑或的表达式 直接执行逻辑或表达式的右边
  • 逻辑或
    或者的意思 必须两边表达式都不成立 结果才不成立
    换句话说 一真则全真
    左边表达式判断为真了, 右边表达式就没有必要判断真假了
var x = 10, y = 11
res = (x < y && --y >= x++)
// res  x  y  分别等于什么???
console.log(res)
console.log(x)
console.log(y)
// true 11 10

var x = 10, y = 11
res = (x >= 10 && y-- > ++x || y++ > 10)
// res   x   y
console.log(res)
console.log(x)
console.log(y)
// false 11 11

三元运算符

条件表达式 ? 表达式1 : 表达式2
条件成立执行表达式1 否则执行表达式2

var res = (123 == "123" ? "成立" : "不成立")
console.log(res)//成立

res = (123 === "123" ? "成立" : "不成立")
console.log(res)//不成立

res = (123 === 123 ? "成立" : "不成立")
console.log(res)//成立

流程控制语句

  • 顺序语句 — 代码是从上到下执行的
  • 分支语句

判断结构 — if语句

if(条件表达式){
	条件成立时执行的语句	
}else{
	条件不成立时执行的语句	
}

if(条件表达式1){
	条件1成立时执行的语句
}else if(条件表达式2){
	条件2成立时执行的语句
}...
else{
	以上条件均不成立执行的语句
}

选择结构

case后跟随的是固定的数据 是一个明确的值
是根据switch后面的表达式的结果可能出现的情况列出的选项
如果其中一个选项满足 整个选择语句结构 通过break就结束
default是case中列出的选项都不成立 执行default
default的执行时机与其书写的位置没有关系

switch(表达式){
	case 值1:
		执行语句
		break
	case 值2:
		执行语句2
		break
	...
	default:
		执行语句
		break
}

循环语句

while循环
while(条件表达式){
	循环语句
}
do-while循环

do-while至少会执行一次循环操作

do{
	循环操作
}while(条件表达式)
for循环

小括号中放的是三条语句, 因为语句结束的标记是分号 有两个分号
初始化条件有多个 使用逗号分隔

for(循环初始化语句;循环条件判断语句;循环后初始化条件变化的语句){

}
// 死循环
for(;;){}
for-in循环

变量获取的是序列的索引

for(变量 in 序列){

}

数组Array

类比成 Python中的列表
在JS中的数组没有脚标越界一说

1. 数组的定义方式

  • 只是一个整数 创建出来一个长度为10 的数组 但是数组中没有元素
    var arr = new Array(10)
    console.log(arr)
  • 超过一个的数据 创建的是一个数组长度为数据个数的 元素内容为数据的数组
    arr = new Array(10, 20)
    console.log(arr)
  • 字面量 直接列出
    arr = [12, 30, 40, 60]
    console.log(arr)

2.获取数组的长度

  • 这个属性可读可写
    var len = arr.length
    console.log(len)
  • 重新设置 数据或根据你设置的长度重新变化数组中的数据
    arr.length = 0 // 清空元素
    console.log(arr)
    arr.length = 10
    console.log(arr)

3. 获取数组中指定索引位置的元素

没有指定位置 不会报错的 只是返回undefined
var value = arr[11]
console.log(value)

4. 遍历数组

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

5.常见的操作

添加元素
  • 在末尾追加元素 — 可以添加多个
    arr.push(true, “hello”)
    console.log(arr)
  • 在开头添加
    arr.unshift(“head”,false)
    console.log(arr)
  • 在指定位置添加
    arr.splice(6, 0 ,66)
    console.log(arr)
移除元素
  • 移除尾部 只能移除一个
    arr.pop()
    console.log(arr)
  • 移除头部 只能移除1个
    arr.shift()
    console.log(arr)
  • 移除指定位置
    arr.splice(7, 1)
    console.log(arr)
  • 修改指定位置的元素
    arr[6] = 77
    console.log(arr)
    或者是
    arr.splice(7,1,88)
    console.log(arr)
splice的参数
  • 起始索引
  • 删除元素的个数 添加(删除个数为0) 替换() 删除指定位置的元素(删除个数为1)
  • 新增元素的内容 可以有多个元素 每个元素之间使用逗号隔开即可
以指定拼接符拼接数组中的元素 结果是一个字符串

var join_str = arr.join("-")
console.log(join_str)

翻转数据中的数据

arr.reverse()
console.log(arr)

对数组中的元素进行排序
  • 默认是升序排序的 按照数据的相同位置的元素对比 进行排序的 类似于字符串的比较
    arr = [17, 21, 19, 38, 29, 128]
    arr.sort()
    console.log(arr) //[128, 17, 19, 21, 29, 38]
  • 数值升序
    函数需要两个形参
    函数需要返回值的
    返回的是交换元素的状态
    这个函数给定的是交换数据的标准
arr.sort(function(ele1, ele2){
	return ele1 - ele2
	// ele1 > ele2  结果是大于零的会交换元素
	// 否则不交换
})
console.log(arr)

Object对象

Object的数据结构是类似于Python的字典的键值对的形式呈现出来的

  • 声明一个对象
    var person = new Object()
  • 添加属性: 通过点语法的形式添加
    person.name = “李泽”
    person.age = 20
  • 行为 — 方法
    在Python中self 接受的被描述的对象的地址 可以通过
    self来获取对象的属性和行为
    在JS中这个字段 this 接受的就是被描述对象的地址
person.study = function(){
	console.log(this.age +"岁的"+this.name + "在学习")
}
  • 获取对象的属性

    • 通过点语法的行为来获取
      console.log("姓名: " + person.name)
    • 可以通过字典中根据键获取值的格式 获取属性值
      console.log(“年龄:” + person[“age”])
  • 删除对象的属性
    delete person.name

  • 调用行为
    person.study()

  • 常用创建对象的形式

var student = {
	name:"测测",
	age: 18,
	sleep:function(){
		console.log(this.name + "在睡觉")
	}
}

student.sleep()

时间类

  • 获取当前时间
    var date = new Date()
    console.log(date)

  • 自定义时间
    月份 0-11 表示1到12
    date = new Date(2020, 12, 25)
    console.log(date)
    date = new Date(2020, 0, 25, 12, 30, 25)
    console.log(date)

  • 将指定的时间字符串格式转化为时间
    年月日: “年-月-日” 或者 “年/月/日”
    date = new Date(“2021-12-25 12:30:30”)
    console.log(date)

  • 以特定的格式显示星期 年月日
    console.log(date.toDateString())

  • 以特定的格式显示时分秒和时区
    console.log(date.toTimeString())

  • 以本地时间格式显示年月日
    console.log(date.toLocaleDateString())

  • 以本地时间格式显示时分秒
    console.log(date.toLocaleTimeString())

  • 获取指定时间对应的时间戳
    时间戳:指定时间到1970年1月1日凌晨经历的秒数
    var time_code = date.getTime()
    console.log(time_code)

  • 将时间戳转化为指定的时间
    date = new Date(time_code)
    console.log(date)

  • 获取指定字符串时间对应的时间戳
    time_code = Date.parse(“2019-12-25 23:15:14”)
    console.log(time_code)
    date = new Date(time_code)
    console.log(date)

  • 获取时间中指定字段的值get/重置指定字段的值set

    • 获取年
      var year = date.getFullYear()
      console.log(year)
    • 重设
      date.setFullYear(2020)
      console.log(date)
    • 获取月
      var month = date.getMonth()
      console.log(month)
    • 重设
      date.setMonth(11)
      console.log(date)
    • 获取日
      var day = date.getDate()
      console.log(day)
    • 重设
      date.setDate(18)
      console.log(date)
    • 获取时
      var hour = date.getHours()
      console.log(hour)
    • 重设
      date.setHours(10)
      console.log(date)
    • 获取分
      var minute = date.getMinutes()
      console.log(minute)
    • 重设
      date.setMinutes(10)
      console.log(date)
    • 获取秒
      var second = date.getSeconds()
      console.log(second)
    • 重设
      date.setSeconds(56)
      console.log(date)
    • 获取星期
      var week = date.getDay()
      console.log(week)

数学类

console.log(“圆周率:”+Math.PI)
console.log(“产生的是0到1之间的随机数 不包含1:”+Math.random())
console.log(“两个数中的最大值:”+Math.max(18, 21))
console.log(“两个数中的最小值:”+Math.min(18, 21))
console.log(“绝对值:”+Math.abs(-10))
console.log(“求幂数:”+Math.pow(2, 5)) // 2的5次方
console.log(“开平方:”+Math.sqrt(8))
console.log(“四舍五入:”+Math.round(3.78))
console.log(“向上求整:”+Math.ceil(18.01))
console.log(“向下求整:”+Math.floor(18.99))

BOM - Browser Object Model浏览器对象模型

窗口对象 window
提供的是与浏览器进行交互的属性和方法
window对象常用的属性和行为
属性:

  • document — 文档对象
  • history – 历史记录对象
  • location – 网址信息对象

行为:

  • alert 弹框
  • prompt 包含输入框的弹框
  • confirm 包含确认取消按钮的弹框
    点击确定取消的话会返回对应的结果
    确定 — true
    取消 — false
  • 打开并创建一个新的窗口 open
    窗口中显示的网址
    自定义名字
    设置新窗口的属性:width height left top
  • 定时器
  • 延时器

在JS中声明的变量和行为 如果没有标记属于哪个对象,那么它就属于window对象的

var person = {
	name:"珂珂"
}
console.log(person.name)

var value = 100
console.log(value) // window对象是可以省略的
console.log(window.value)

alert("弹窗")
window.alert("弹窗2")

// 为了适配所有的浏览器
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight

console.log("屏幕宽度:" + width + " 屏幕高度:" + height)

document

<p class="dou">红豆生南国,春来发几枝。愿君多采撷,此物最相思。</p>
<script>
	// 怎么获取p元素
	// 根据选择器获取 --- 在文档上获取信息就得使用文档对象
	var p_node = document.querySelector(".dou")
	// 获取标签上的文本 // 重新设置
	var text = p_node.innerText
	console.log(text)
	
	// 重置文本  在原来的基础上进行修改
	//p_node.innerText += "这是一首相思诗"
	//p_node.innerText = "相思"
	
	// 设置样式  style属性的值
	p_node.style.color = "red"
	p_node.style.border = "solid 1px blue"
</script>

常用方法

<button type="button" class="btn">隐藏图片</button>
<div><img class="cat" src="../img/cat.jpg" width="200px" alt=""></div>
<a href="https://www.w3school.com.cn" target="baidu">验证新窗口的名字</a>
<script>
	var btn_node = document.querySelector(".btn")
	var img_node = document.querySelector(".cat")
	// 点击按钮  --- 执行行为
	// 事件的绑定  ---- 当你点击了按钮 就是触发了这个事件 会自动执行的
	btn_node.onclick = function(){
		var res = confirm("确认要隐藏吗???")
		if(res){
			// 点击了确认键
			img_node.style.display = "none"
		}
	}
	var new_win = open("https://www.baidu.com", "baidu","width=300, height=500, left=100, top=150")
</script>

定时器

每隔多长时间执行什么行为就是定时器
要执行的行为
时间间隔 单位是毫秒
定时器生成的时候 会有一个定时器id的产生 根据这个id去移除定时器

var i = 1
var timeid = setInterval(function(){
	console.log("执行了该定时器" + i + "次")
	i++
	if(i > 20){
		// 停止定时器
		clearInterval(timeid)
	}
}, 1000)

延时器

延时指定时间之后 才会执行某些行为
只会执行一次
在延时期间 关闭这个行为 延时器生成的时候也是有延时器id的

<button class="btn">取消延时对应的操作</button>
<script>
	var timerid =  setTimeout(function(){
		console.log("延时器执行的行为")
	}, 5000)
	var btn = document.querySelector(".btn")
	btn.onclick = function(){
		// 取消延时器
		clearTimeout(timerid)
	}
</script>

history历史记录

first

<p>第一页</p>
<img src="../../img/cat.jpg" width="100px" />
<div>
	<a href="second.html">2页码</a>
</div>
<button class="next_btn">下一页</button>
<button class="third_btn">第三页</button>
<script>
	var next_btn = document.querySelector(".next_btn")
	next_btn.onclick = function(){
		// 前进一页
		history.forward()
	}
	
	var third_btn = document.querySelector(".third_btn")
	third_btn.onclick = function(){
		// 前进两页
		history.go(2)
	}
</script>

second

<p>第二页</p>
<a href="third.html">3页</a>
</body>
<ul>
	<li>苹果</li>
	<li>香蕉</li>
	<li>草莓</li>
	<li>西瓜</li>
</ul>
<button class="prev_btn">上一页</button>
<button class="next_btn">下一页</button>

<script>
	var prev_btn = document.querySelector(".prev_btn")
	var next_btn = document.querySelector(".next_btn")
	
	prev_btn.onclick = function(){
		// 回退一页
		history.back()
	}
	next_btn.onclick = function(){
		// 前进一个  正数 前进几页就是正几
		history.go(1)
	}
</script>

third

<p>第三页</p>
<table border="1" cellspacing="0" width="200px">
	<tr>
		<td>1-1</td>
		<td>1-2</td>
		<td>1-3</td>
	</tr>
	<tr>
		<td>2-1</td>
		<td>2-2</td>
		<td>2-3</td>
	</tr>
	<tr>
		<td>3-1</td>
		<td>3-2</td>
		<td>3-3</td>
	</tr>
</table>

<button class="prev_btn">上一页</button>
<button class="first_btn">第一页</button>

<script>
	// 查看历史记录的页码
	console.log(history.length)
	
	var prev_btn = document.querySelector(".prev_btn")
	var first_btn = document.querySelector(".first_btn")
	
	prev_btn.onclick = function(){
		// 回退一页
		history.back()
	}
	
	first_btn.onclick = function(){
		// 回退几页  回退的话是负数 退几页就是负几
		history.go(-2)
	}
</script>

location页面网址信息

<form action="" method="get">
	<p>用户名: <input type="text" name="uname"></p>
	<p>密码:<input type="text" name="upsw"></p>
	<p><input type="submit" value="登陆"></p>
</form>

<button class="href">重定向</button>
<button class="reload">重新加载</button>
<script>
	// 除了获取页面网址的操作外 还可以重新设置页面的网址信息(重定向)
	console.log("当前页面的整个网址:" + location.href)
	console.log("获取ip地址(域名)和端口号:" + location.host)
	console.log("获取ip地址(域名):" + location.hostname)
	console.log("获取端口号:" + location.port)
	console.log("协议:" + location.protocol)
	console.log("获取请求资源存放的路径:" + location.pathname)
	
	// 从服务器角度获取提交的数据  location.search
	if(location.search){
		console.log("获取的提交后?后对应的数据:" + location.search)// ?uname=xiaomu&upsw=123456
		var data_str = location.search
		data_str = data_str.substring(1) //uname=xiaomu&upsw=123456
		// 以&为切割符进行切割
		var data_arr = data_str.split("&")
		console.log(data_arr) //["uname=xiaomu", "upsw=123456"]
		
		// 使用对象来接受键值对
		var data_obj = {}
		// 遍历数组 获取每一对数据
		for(var i = 0; i < data_arr.length; i++){
			console.log(data_arr[i]) //uname=xiaomu
			// 按照等号切割
			key_value_arr = data_arr[i].split("=")
			console.log(key_value_arr)//["uname", "xiaomu"]
			data_obj[key_value_arr[0]] = key_value_arr[1]
		}
		console.log(data_obj)//Object {uname: "xiaomu", upsw: "23456"}
	}
	
	var href_btn = document.querySelector(".href")
	href_btn.onclick = function(){
		// 重定向
		location.href = "http://www.baidu.com"
	}
	
	var reload_btn = document.querySelector(".reload")
	reload_btn.onclick = function(){
		// 重新加载
		location.reload()
	}
	
</script>

编码

var s = "你好 byebye,.12345"
var encode = encodeURIComponent(s)
console.log(encode)//%E4%BD%A0%E5%A5%BD%20byebye%2C.12345

var decode = decodeURIComponent(encode)
console.log(decode)//你好 byebye,.12345

DOM — Document Object Model

文档对象模型

在文档对象模型中 它是以节点的形式来操作文档的
常用的节点的分类:

  • 元素节点 — 标签
  • 属性节点 — 标签的属性
  • 文本节点 — 文本节点

文本是嵌套在标签之间的 文本节点 是元素节点的子节点
属性是跟标签是平级的

DOM + 事件

DOM中获取元素节点的操作

在head中获取文档中的内容时 要等页面加载完成之后才可以操作
因为代码是从上向下执行的 在进行JS操作的时候 文档上的元素还没有加载 所以是获取不到的
想要获取的话 等页面加载完成的时候 才能获取
onload — 页面加载完成的时候触发这个事件

<head>
	<meta charset="utf-8">
	<title></title>
	<script>
		window.onload = function(){
			// 根据元素名称 获取元素节点集
			var p_nodes = document.getElementsByTagName("p")
			console.log(p_nodes)
			// 在节点集中根据索引获取其中的节点
			var p_node = p_nodes[0]
			console.log(p_node.innerText)
			
			// 根据id名称获取对应的元素节点
			var p_id_node = document.getElementById("tree")
			// 设置该节点的样式
			p_id_node.style.color = "palevioletred"
			
			// 根据类名获取对应的元素节点集
			var p_class_nodes = document.getElementsByClassName("spring")
			// 集合的长度
			console.log(p_class_nodes.length)//2
			p_class_nodes[1].style.backgroundColor = "plum"
			
			// 根据选择器 获取 满足选择器条件的第一个元素节点
			var p_selector_node = document.querySelector(".spring")
			p_selector_node.style.border = "dotted 2px blue"
			
			// 根据选择器 获取 满足选择器的所有节点 --- 节点集
			var p_selector_nodes = document.querySelectorAll(".spring")
			console.log(p_selector_nodes.length)
		}
	</script>
</head>
<body>
	<p class="spring">
		小草偷偷地从土里钻出来,嫩嫩的,绿绿的。园子里,田野里,瞧去,一大片一大片满是的。坐着,躺着,打两个滚,踢几脚球,赛几趟跑,捉几回迷藏。风轻悄悄的,草软绵绵的。
	</p>
	<p id="tree">桃树、杏树、梨树,你不让我,我不让你,都开满了花赶趟儿。红的像火,粉的像霞,白的像雪。花里带着甜味儿;闭了眼,树上仿佛已经满是桃儿、杏儿、梨儿。花下成千成百的蜜蜂嗡嗡地闹着,大小的蝴蝶飞来飞去。野花遍地是:杂样儿,有名字的,没名字的,散在草丛里,像眼睛,像星星,还眨呀眨的。</p>
	<p class="spring">
		“吹面不寒杨柳风”,不错的,像母亲的手抚摸着你。风里带来些新翻的泥土的气息,混着青草味儿,还有各种花的香,都在微微润湿的空气里酝酿。鸟儿将窠巢安在繁花嫩叶当中 [2]  ,高兴起来了,呼朋引伴地卖弄清脆的喉咙,唱出宛转的曲子,与轻风流水应和着。牛背上牧童的短笛,这时候也成天嘹亮地响着。
	</p>
</body>

操作文本

获取/设置元素节点中的内容
在设置的时候是有区别的

  • innerHTML — 识别内容中标签
  • innerText — 不识别标签 会把标签当做纯文本显示在文档上
<p class="page">天上风筝渐渐多了,地上孩子也多了。城里乡下,家家户户,老老小小,也赶趟儿似的,一个个都出来了。舒活舒活筋骨,抖擞抖擞精神,各做各的一份事去。<span>“一年之计在于春”</span>,刚起头儿,有的是工夫,有的是希望。</p>
<script>
	// 根据类选择器获取元素节点
	var page_node = document.querySelector(".page")
	
	// 获取内容
	var content = page_node.innerHTML
	console.log(content)
	
	content = page_node.innerText
	console.log(content)
	
	// 设置内容
	page_node.innerHTML += "<b>摘抄自朱自清的春</b>"
	page_node.innerText += "<b>摘抄自朱自清的春</b>"
</script>

操作属性

设置属性

  • 元素节点.属性名 = 属性值
    这种形式不能设置自定义属性
    类 特殊 — className 设置类
  • setAtttribute(属性名, 属性值)

获取属性值

  • 元素节点.属性名
    获取不到自定义属性
  • getAttribute(属性名)
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		#article{
			color: red;
		}
		.page {
			background-color: palegoldenrod;
		}
	</style>
</head>
<body>
	<p title="spring">春天像小姑娘,花枝招展的,笑着,走着。</p>
	<script>
		// 根据元素选择器获取
		var p_node = document.querySelector("p")
		//设置
		p_node.id = "article"
		p_node.className = "page"
		p_node.setAttribute("name", "zhuziqing")
		
		// 对于自定义属性名的区别
		//p_node.index = 0
		p_node.setAttribute("index", 0)
		
		//获取
		var value = p_node.title
		console.log(value)//spring
		
		value = p_node.className
		console.log(value)//page
		
		// 在原来的基础上添加类 一定要注意空格
		p_node.className += " back"
		value = p_node.className
		console.log(value)//page back
		
		value = p_node.getAttribute("name")
		console.log(value)//zhuziqing
		
		// 自定义属性的获取
		//console.log(p_node.index)
		value = p_node.getAttribute("index")
		console.log(value)//0
	</script>
</body>

建议使用 setAttribute设置属性
建议使用 getAttribute设置属性

关于样式的操作

  • 设置样式
    调用style属性就行了
    元素节点.style.样式名 = 样式值
    样式值赋予的是字符串格式的
  • 获取样式
    元素节点.style.样式名
    只能获取行内样式 不能获取内部或者外部样式
  • 获取内部样式
    • 元素节点.currentStyle [这个不兼容谷歌]
      获取的是元素节点当前对应的样式对象 – 以字典的形式存在
    • 获取其中的某个样式
      元素节点.currentStyle[样式名]
    • getComputedStyle(元素节点) [IE不兼容]
      获取的是元素节点当前对应的样式对象
    • 获取其中的某个样式
      getComputedStyle(元素节点)[样式名]
  • 为了兼容浏览器 将上面获取样式的操作封装成方法
    tag_node — 接受的是要获取样式的元素节点
    style_name — 接受要获取的样式名
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		p{
			background-color: palegoldenrod;
		}
	</style>
</head>
<body>
	<p style="color: red;">天上风筝渐渐多了,地上孩子也多了。城里乡下,家家户户,老老小小,也赶趟儿似的,一个个都出来了。舒活舒活筋骨,抖擞抖擞精神,各做各的一份事去。“一年之计在于春”,刚起头儿,有的是工夫,有的是希望。</p>
	<script>
		// 获取元素节点
		var p_node = document.querySelector("p")
		// 设置样式
		p_node.style.textIndent = "2em"
		// 获取样式
		var colorValue = p_node.style.color
		console.log(colorValue)
		// 内部设计的
		var backColorValue = p_node.style.backgroundColor
		console.log(backColorValue)
		
		// 获取内部样式
		backColorValue = p_node.currentStyle["background-color"]
		console.log(backColorValue)
		
		backColorValue = getComputedStyle(p_node)["background-color"]
		console.log(backColorValue)
		
		colorValue = getComputedStyle(p_node)["color"]
		console.log(colorValue)
		
		// 为了兼容浏览器 将上面获取样式的操作封装成方法
		function get_style(tag_node, style_name){
			if(tag_node.currentStyle){
				return tag_node.currentStyle[style_name]
			}else{
				return getComputedStyle(tag_node)[style_name]
			}
		}
		
		colorValue = get_style(p_node, "color")
		console.log(colorValue)	
	</script>
</body>

节点

节点的操作

添加 插入 替换 移除这些操作 都是有父节点完成的

// 创建一个段落节点 给添加在body上
var p_node = document.createElement("p")
// 添加在body   添加在指定标签节点的末尾
document.body.appendChild(p_node)

// 创建文本节点
var text_node = document.createTextNode("我是文本节点")
// 文本是嵌套在标签之间的  文本节点是元素节点的子节点
p_node.appendChild(text_node)

// 在指定元素前插入节点
var a_node = document.createElement("a")
a_node.innerText = "百度一下"
// 属性
a_node.setAttribute("href", "http://www.baidu.com")
// 新添加的节点   在哪个节点之前
document.body.insertBefore(a_node, p_node)

// 替换
var b_node = document.createElement("b")
b_node.innerText = "静夜思"
// 将b节点替换掉a节点   新节点   旧节点
document.body.replaceChild(b_node, a_node)

// 删除节点  删除p节点
document.body.removeChild(p_node)

元素节点常用的属性

<style>
		*{
			margin: 0;
			padding: 0;
		}
		.outer{
			width: 300px;
			height: 300px;
			border: 2px solid palevioletred;
			margin: 50px;
			/* 作为inner的参照物 */
			position: relative;
		}
		.inner{
			width: 100px;
			height: 100px;
			padding: 10px;
			border: solid 2px deepskyblue;
			margin: 100px;
		}
	</style>
</head>
<body>
	<div>
		<span>床前明月光</span>
		这个是静夜思的第一句
		<p class="page">疑<u>是</u>地上<font color="red">霜</font></p>
		这个是静夜思的第2句
		<b>举头望明月</b>
		这个是静夜思的第3句
		<i>低头思故乡</i>
		这个是静夜思的第4句
	</div>
	<div class="outer">
		<div class="inner"></div>
	</div>
	<script>
		// 获取p节点
		var page_node = document.querySelector(".page")
		
		// 获取该节点的父节点  最根部的节点 文档 document  
		console.log(page_node.parentNode.parentNode.parentNode.parentNode)
		
		// 获取与其平级的上一个节点
		// previousSibling 把文本节点包含在内的
		console.log(page_node.previousSibling)
		
		// 获取与其平级的上一个元素节点  忽略掉文本节点的
		console.log(page_node.previousElementSibling)
		
		// 获取与其平级的下一个节点
		// nextSibling 把文本节点包含在内的
		console.log(page_node.nextSibling)
		
		// 获取与其平级的下一个元素节点  忽略掉文本节点的
		console.log(page_node.nextElementSibling)
		
		// 获取的是子节点 包含文本节点在内的
		console.log(page_node.childNodes)
		// 只获取元素子节点
		console.log(page_node.children)
		
		// 关于元素节点大小间距的属性
		var inner_div_node = document.querySelector(".inner")
		
		console.log("内容区+内边距的宽:" + inner_div_node.clientWidth)
		console.log("内容区+内边距的高:" + inner_div_node.clientHeight)
		
		console.log("标签的宽 - 内容区+内边距+边框:" + inner_div_node.offsetWidth)
		console.log("标签的高 - 内容区+内边距+边框:" + inner_div_node.offsetHeight)
	
		console.log(inner_div_node.offsetLeft)
		console.log(inner_div_node.offsetTop)
	</script>
</body>

offsetLeft、offsetTop
默认是相对于body的左边间隙的宽度 和 上边间隙的宽度
left和top是跟定位属性相关的
如果设置了参照物(在指定的标签中设置有效的定位属性)
这个offsetLeft和offsetTop是相对于参照物的间隙

事件

用户引发的操作或者页面加载的时候主动触发的操作
如果想用户触发某个动作之后 有对应的操作出现

绑定事件

绑定事件的方式

  • 内联模式
    比较传统 也比较单一
    没有与HTML进行分离
    <标签名称 事件属性名=“js的代码”></标签名称>

  • 脚本模式
    与HTML进行分离
    1. HTML混写 但是JS代码是在script中写的
    事件 — 触发的是一个行为
    行为映射到程序中就是一个函数
    在script中写好了对应的函数
    在HTML中 事件绑定的时候 绑定的是这个函数
    2. 纯JS

<button οnclick="alert('我被点了')">你点我啊</button>

<!-- this就表示的是被点击的单签标签本身 -->
<p οnclick="node_click(this)">小桥流水人家 古道西风瘦马。</p>

<a href="http://www.baidu.com">百度一下</a>

<script>
	function node_click(tag){
		tag.style.border = "solid 2px blue"
	}
	
	// 纯JS的
	var a_node = document.querySelector("a")
	// 为期绑定事件
	a_node.onclick = function(){
		// 阻止跳转的操作  就是在对应的时间函数中 返回值false
		// 默认是true 所以一点击就跳转了
		return confirm("确认跳转吗????")
	}
</script>

事件对象

触发一个事件 执行该事件对应的行为时
会像事件对应的功能中传递一个实参 — 事件对象

<button class="btn">按钮</button>
<script>
	// 普通的功能
	function show(){
		console.log(arguments.length) // 0
	}
	show()
	
	// 绑定事件
	var btn = document.querySelector(".btn")
	btn.onclick = function(e){
		console.log(arguments.length) // 1
		// 表示传递进来了实参 这个实参就是事件对象
		console.log(e)
	}
	
	// 键盘时间
	document.onkeydown = function(e){
		console.log(e)
	}
	
	// 鼠标事件中 事件对象常用的属性
	document.onmousedown = function(e){
		console.log("鼠标的哪个按键被点击了?" + e.button)
		// 0 --- 左键
		// 1 --- 滚轮
		// 2 --- 右键
		
		// 鼠标的位置相对于浏览器边缘的间隙
		console.log("鼠标距离浏览器文档区(客户区)边缘的间隙:(" + 
			e.clientX + "," + e.clientY + ")")
		
		// 鼠标的位置相对于屏幕边缘的间隙
		console.log("鼠标距离屏幕边缘的间隙:(" + 
			e.screenX + "," + e.screenY + ")")
	}
</script>

鼠标

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		img{
			/* 绝对定位 */
			position: absolute;
			/* 初始定位值 */
			top: 0;
			left: 0;
		}
	</style>
</head>
<body>
	<img src="../img/cat.jpg" width="50px" />
	<script>
		// 点击右键阻止菜单上下文的显示
		document.oncontextmenu = function(e){
			console.log(e.button)
			return false
		}
		var img_node = document.querySelector("img")
		
		// 图片跟鼠标随动
		document.onmousemove = function(e){
			// 获取鼠标在文档上移动的水平与垂直坐标
			var x = e.clientX
			var y = e.clientY
			// 给标签赋值 这种形式 鼠标是位于图片的左上角
			// img_node.style.left = x + "px"
			// img_node.style.top = y + "px"
			
			// 鼠标位于图片的中心点
			// 鼠标无法完成了  只能动图片  把图片向上移动图片高度的一半
			// 想做移动图片宽度的一半`在这里插入代码片`
			img_node.style.left = (x - img_node.offsetWidth /2) + "px"
			img_node.style.top = (y - img_node.offsetHeight / 2) + "px"
		}
	</script>
</body>

键盘

document.onkeydown = function(e){
	if(e.altKey){
		console.log("alt键被按下")
	}else if(e.ctrlKey){
		console.log("ctrl键被按下")
	}else if(e.shiftKey){
		console.log("shit键被按下")
	}else if(e.metaKey){
		console.log("主键被按下")
	}
	
	// 几个键同时按
	if(e.altKey && e.ctrlKey){
		console.log("两个键同时被按下")
	}
	
	// 获取按键的标识符
	console.log(e.key)
	
	// Windows
	if(e.ctrlKey && e.key == "c"){
		console.log("拷贝")
	}
	// mac 
	if(e.metaKey && e.key == "c"){
		console.log("拷贝")
	}
	
	// 字母对应的大写字母的ascii码值
	console.log(e.keyCode)
}

document.onkeypress = function(e){
	console.log(e.charCode)
	// 区分了大小写
}

表单

字数限制的案例

<form action="" method="get">
	<p>用户名:<input class="username" type="text" name="uname" value="xiaomu"></p>
	<p>密码:<input class="psw" type="password" name="upsw" value="123456"></p>
	<p>
		<textarea class="comment" name="ucom" cols="80"></textarea>
		<span class="word_num">0</span>/<span class="total_num">50</span>
	</p>
	<p><input type="submit" value="登陆"></p>
</form>
<script>
	var name_input = document.querySelector(".username")
	// 获取焦点
	name_input.onfocus = function(){
		this.style.color = "red"
	}
	// 失去焦点
	name_input.onblur = function(){
		this.style.color = "black"
	}
	
	// 评论区
	var comment_input = document.querySelector(".comment")
	// 当前字数的标签
	var cur_num_span = document.querySelector(".word_num")
	// 获取一下总字数
	var total_num = parseInt(document.querySelector(".total_num").innerText)
	// 给评论框添加监听事件
	comment_input.oninput = function(e){
		// 获取数据的字数  --- 内容的长度
		var len = this.value.length
		if(len > total_num){
			// 内容长度大于了总字数
			alert("长度超过了限制字数")
			// 再输入的话 允许输入 但是只拿前total_num个
			this.value = this.value.substr(0, total_num)
		}
		// 显示当前字数的标签 重新设置数据
		cur_num_span.innerText = this.value.length + ""
	}
</script>

表单提交的事件

  • 在表单中数据之所以能提交成功 是因为表单的 onsubmit事件的 结果默认是return true
    阻止表单提交 只需要对onsubmit事件return false即可
<form action="" method="get" οnsubmit="return false">
	<p>用户名:<input type="text" name="uname"></p>
	<p>密码:<input type="password" name="upsw"></p>
	<p><input type="submit" value="登录"></p>
</form>
  • 表单的提交事件 是在表单的属性中写的
    注意一下 JS的函数的运行的结果是true或者false
    submit要求的是return true 或者 return false
    所以 绑定函数的时候 return必须添加
    假设没有 return 代码直接写成 οnsubmit=“submit_data()”
    那么onsubmit这个的数据 就表示为 οnsubmit=true 或者 οnsubmit=false
    所以这一块必须添加return
<form action="" method="get" οnsubmit="return submit_data()">
	<p>用户名:<input type="text" class="username" name="uname"></p>
	<p>密码:<input type="password" class="psw" name="upsw"></p>
	<p><input type="submit" value="登录"></p>
</form>

<script>
	// 已知的用户名  xiaomu
	// 已知的密码:  xiaomu123
	var username = "xiaomu"
	var passwd = "xiaomu123"
	function submit_data(){
		// 获取用户输入的用户名和密码
		var name_input = document.querySelector(".username")
		var pwd_input = document.querySelector(".psw")
		// name_input.value 输入框的数据
		if(name_input.value == username && pwd_input.value == passwd){
			return true
		}else{
			alert("用户名或者密码错误")
			// 阻止提交
			return false
		}		
	}
</script>
<form action="" method="get"  class="form">
	<p>用户名:<input type="text" class="username" name="uname"></p>
	<p>密码:<input type="password" class="psw" name="upsw"></p>
	<p><input type="submit" value="登录"></p>
</form>

<script>
	/**
	 * 已知的用户名  xiaomu
	 * 已知的密码:  xiaomu123
	 */
	var username = "xiaomu"
	var passwd = "xiaomu123"
	
	// 获取表单
	var form = document.querySelector(".form")
	
	// 为其添加提交事件
	form.onsubmit = function(){
		// 获取用户输入的用户名和密码
		var name_input = document.querySelector(".username")
		var pwd_input = document.querySelector(".psw")
		// name_input.value 输入框的数据
		if(name_input.value == username && pwd_input.value == passwd){
			return true
		}else{
			alert("用户名或者密码错误")
			// 阻止提交
			return false
		}
		
	}
</script>

表单的change事件

省市联动
数据结构:
有很多的省份
每个省份下有很多的市

<body οnlοad="init()">
	<select class="province"></select>
	<select class="city"></select>
	<script>
		var province_arr = [
			{
				province_name:"北京",
				cities:["海淀区","朝阳区","丰台区","怀柔区"]
			},
			{
				province_name:"河北省",
				cities:["石家庄","唐山","保定","秦皇岛","衡水","沧州"]
			},
			{
				province_name:"河南省",
				cities:["郑州","安阳","信阳","濮阳","洛阳","驻马店"]
			},
			{
				province_name:"山东省",
				cities:["菏泽","青岛","济南","烟台","威海","德州","济宁"]
			}
		]
		
		// 获取省份的下拉菜单
		var province_select = document.querySelector(".province")
		// 获取市的下拉菜单
		var city_select = document.querySelector(".city")
		
		// 页面初始化的时候 加载所有的省份 与第一个省份对应的市
		function init(){
			// 遍历数组 获取所有的省份
			for(var i = 0; i < province_arr.length; i++){
				// province_arr[i]  小对象  要获取省份的名字 需要在对象中提取
				// 有一个省份 就在下拉菜单中有一个选项 就相当于有一个option的元素
				// 在HTML上有一个option标签 就有一个option对象
				var option = new Option(province_arr[i].province_name, province_arr[i].province_name)
				// 添加在指定的下拉菜单上
				province_select.appendChild(option)
			}
			
			// 获取第一省份下的所有市  添加在市的下拉菜单中
			var cities = province_arr[0].cities
			// 对其进行遍历  添加到市的下拉菜单中
			for(var i = 0; i < cities.length; i++){
				var option = new Option(cities[i], cities[i])
				city_select.appendChild(option)
			}
		}
		
		// 省份的数据发生变化
		province_select.onchange = function(e){
			// 更新市的下拉菜单发生对应的变化
			// 用户选择的省份是哪个????
			// 下拉菜单有一个属性 selectedIndex 获取的是被选中项目的索引
			// 根据这个索引获取选择的省份
			var province = province_arr[this.selectedIndex]
			// 获取该省份下的所有市
			var cities = province.cities
			
			// 在选择省份 更新市的下拉菜单时  市之前的选项应该给移除掉
			// 否则 数据全部叠加在一起了
			// 下拉菜单有一个属性  length  获取的下拉菜单中选项的数量
			// length市可以获取 也可以重置的
			city_select.length = 0
			
			// 对其进行遍历  添加到市的下拉菜单中
			for(var i = 0; i < cities.length; i++){
				var option = new Option(cities[i], cities[i])
				city_select.appendChild(option)
			}
		}
	</script>
</body>

滚动的事件

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		body{
			height: 2000px;
			background: linear-gradient(red, orange, yellow, pink, purple);
		}
		div{
			/* 以body为参照物 */
			position: absolute;
			
			/* 给其一个定位的位置 */
			top: 300px;
			/* 左右都为0  那就是跟参照物等宽 */
			left: 0;
			right: 0; 
			background-color: deepskyblue;
			height: 50px;
		}
	</style>
</head>
<body>
	<div></div>
	<script>
		// 获取div 
		var div_node = document.querySelector("div")
		document.onscroll = function(e){
			// 向上滚动的位移
			// document.body.scrollTop 不适配谷歌
			var scroll_top = document.documentElement.scrollTop || document.body.scrollTop
			console.log(scroll_top)
			
			if(scroll_top >= 300){
				// 设置成固定定位 固定在页面的顶端
				div_node.style.position = "fixed"
				div_node.style.top = 0
			}else{
				div_node.style.position = "absolute"
				div_node.style.top = "300px"
			}
		}
	</script>
</body>

事件的传递机制

事件的传递机制分为两种:冒泡传递(默认的)和捕获传递
冒泡传递 理解 鱼吐泡泡
叠加的标签都有事件 事件是会传递的

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		.outer{
			width: 300px;
			height: 300px;
			background-color: plum;
		}
		.center{
			width: 200px;
			height: 200px;
			background-color: deepskyblue;
		}
		.inner{
			width: 100px;
			height: 100px;
			background-color: deeppink;
		}
	</style>
</head>
<body>
	 <!-- 水面 -->
	 <div class="outer">
		 <!-- 水 -->
		 <div class="center">
			 <!-- 鱼 -->
			 <div class="inner"></div>
		 </div>
	 </div>
	 
	 <script>
		 var outer_div = document.querySelector(".outer")
		 var center_div = document.querySelector(".center")
		 var inner_div = document.querySelector(".inner")
		 
		 outer_div.onclick = function(e){
			 console.log("水面")
		 }
		 inner_div.onclick = function(e){
		 	console.log("鱼 吐了泡泡")
			// 阻止事件传递
			// 是否取消冒泡传递
			e.cancelBubble = true
		 }
		 center_div.onclick = function(e){
		 	console.log("水")
			
			// 另外一个阻止事件传递的方式
			e.stopPropagation()
		 }
	 </script>
</body>

事件的监听

事件的监听 — 可以理解为为标签绑定事件的另外一种方式
— 绑定了之后可以解绑

注册监听

监听的事件类型
绑定事件的时候 on…事件
事件类型 就是去掉on后面的内容 就是事件类型
例如 onclick ===> click
监听到该事件之后执行的行为
是否设置为捕获传递 默认为false(默认为冒泡传递)

btn.addEventListener("click", function(){
	console.log("哎呀,我被点击了")
})

取消监听

取消监听的设置要与设置监听是一致的 否则取消失败

btn.removeEventListener("click", function(){
	console.log("哎呀,我被点击了")
})

看起来明明设置的是一致的 但是却取消失败
原因: 就是因为监听事件之后执行的行为 不是一个行为
function(){} 这种是匿名函数 执行一次之后就会被
在内存中释放掉了 之后再写是新生成了一个 与原来那个无关
取消成功的话
函数不适用匿名函数了

<button class="btn">按钮</button>
 <script>
	 var btn = document.querySelector(".btn")

	 function btn_click(){
		 console.log("哎呀,我又被点击了")
	 }
	 btn.addEventListener("click", btn_click)
	 btn.removeEventListener("click", btn_click)
 </script>

JQ

引入JQ文件

如果想用JQ的内容就得先将其引入
head中

  1. 本地有JQ文件
<script src="../js/jquery-3.4.1.min.js"></script>
  1. 内容分布网络 CDN 百度CDN的
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

JQ的基本语法

$(选择器).行为()
$是JQ的符号 — 表示的是jQuery

$(选择器)
获取的是所有满足选择器要求的元素 — 节点集

  • JS中是没有办法对节点集进行操作的 只能从节点集中提取具体节点,然后给改节点设置
  • JQ是可以直接针对于节点集操作的
    进行行为操作的时候 操作的是所有满足选择器的元素

body中

<div>忽如一夜春风来,千树万树梨花开。</div>
<div>忽如一夜春风来,千树万树梨花开。</div>
<div>忽如一夜春风来,千树万树梨花开。</div>
<ul>
	<li>苹果</li>
	<li>香蕉</li>
	<li>鸭梨</li>
	<li>橘子</li>
</ul>
<p class="page">飞流直下三千尺,疑是银河落九天。</p>

<script type="text/javascript">
	// JS 设置其文字颜色
	var div_node = document.querySelector("div")
	div_node.style.color = "red";

	var div_node = document.querySelectorAll("div")
	for(var i=0;i<div_node.length;i++){
		div_node[i].style.color = "red";
	}
	
	// JQ的语法
	$("div").css("background-color", "pink")
	
	// JS元素与JQ元素之间的相互转换
	// JQ ---> JS
	var JQ_li = $("li")
	var li_js = JQ_li.get(0) // 拿的是第一个元素
	li_js.style.color = "green"
	
	// JS ----> JQ
	var page_node = document.querySelector(".page")
	var jq_page = $(page_node)
	jq_page.css("color", "orange")
</script>

JQ和JS是可以共存的
但是JQ对象只能使用JQ的行为 不能使用JS的操作方式
也就是说 jq_page只能使用css()设计样式 不能使用.style.样式名设计样式
JS只能使用JS的操作行为 不能使用JQ
也就是说 page_node只能使用.style.样式名设计样式 不能使用css()设计样式

JQ中的选择器

<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js"></script>
</head>
<body>
	<p>皇宫中和朝廷里的大臣,本都是一个整体,奖惩功过,不应有所不同。如有作恶违法的人,或行为忠善的人,都应该交给主管官吏评定对他们的惩奖,以显示陛下处理国事的公正严明,而不应当有偏袒和私心,使宫内和朝廷奖罚方法不同。</p>
	<div>
		<p>先帝开创的大业未完成一半却中途去世了。现在天下分为三国,指蜀汉国力薄弱,处境艰难</p>
		<p>(陛下)你实在应该扩大圣明的听闻,来发扬光大先帝遗留下来的美德,振奋有远大志向的人的志气,不应当随便看轻自己,说不恰当的话,以致于堵塞人们忠心地进行规劝的言路。</p>
	</div>
	<p>这确实是国家危急存亡的时期啊。不过宫廷里侍从护卫的官员不懈怠,战场上忠诚有志的将士们奋不顾身,大概是他们追念先帝对他们的特别的知遇之恩(作战的原因),想要报答在陛下您身上。</p>
	<span>(陛下)你实在应该扩大圣明的听闻,来发扬光大先帝遗留下来的美德,振奋有远大志向的人的志气,不应当随便看轻自己,说不恰当的话,以致于堵塞人们忠心地进行规劝的言路。</span>
	<p>皇宫中和朝廷里的大臣,本都是一个整体,奖惩功过,不应有所不同。如有作恶违法的人,或行为忠善的人,都应该交给主管官吏评定对他们的惩奖,以显示陛下处理国事的公正严明,而不应当有偏袒和私心,使宫内和朝廷奖罚方法不同。</p>

	<div>
		<span>好好学习 天天向上</span>
		<p>少壮不努力 老大徒伤悲</p>
	</div>
	
	<div>
		<span>好好学习 天天向上</span>
		<b>good good study  day day up</b>
		<p>少壮不努力 老大徒伤悲</p>
	</div>
	
	<ul>
		<li>A</li>
		<li>B</li>
		<li>C</li>
		<li>D</li>
		<li>E</li>
		<li>F</li>
	</ul>
	
	<script>
		// 页面中第一个p标签
		$("p:first").css("color","red")
		
		// 指定的是div下第一个p标签
		$("div p:first").css("border", "solid 1px blue")
		
		// 页面中组后一个p标签
		$("p:last").css("color","green")
		
		// 指定的是div下最后一个p标签
		$("div p:last").css("border", "solid 1px pink")
		
		// 设置的是作为第一个子标签存在的span的样式
		$("span:first-child").css("font-size", "25px")
		
		//  + 相邻的下一个元素
		// 设计与span相邻的下一个p元素的样式
		$("span + p").css("text-shadow", "3px 3px 5px red")
		
		// 设置索引为 2的li元素的样式
		//$("li:eq(2)").css("list-style", "none")
		// 或者
		$("li").eq(2).css("list-style", "none")
		
		// 大于2的
		$("li:gt(2)").css("list-style", "circle")
		
		// 小于2的
		$("li:lt(2)").css("list-style", "square")
		
	</script>
</body>

文本操作

JQ中的行为是获取和设置集于一身的

  • 获取
    • html() —> innerHTML
    • text() ----> innerText
    • val() ---->value — 应用于表单的
  • 设置
    • html(内容)
    • text(内容)
    • val(内容)
<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js"></script>
</head>
<body>
	<p>春眠不觉晓,处处闻啼鸟</p>
	<p>夜来风雨声,花落知多少</p>
	<input type="text" value="雷猴啊" />
	<script>
		var content = $("p").html()
		console.log(content)
		console.log($("input").val())
		 
		$("p").html("我是由JQ给设置的")
		$("p").html("<b>我是由JQ给设置的</b>") // 识别标签
		$("p").text("<b>我是由JQ给设置的</b>") // 不识别
		$("input").val("123")
		
		html(function(index, curcontent){
			return 设置的新文本
		})
		text(function(index, curcontent){
			return 设置的新文本
		})
		val(function(index, curcontent){
			return 设置的新文本
		})
		// index -- 根据选择器查找到的元素对应的索引
		// curcontent ---  当前元素中的内容
		$("p").text(function(index, curcontent){
			return index == 1 ? "我是清空内容 新增加的" : curcontent + "  我是追加的"
		})
	</script>
</body>

属性操作

设置属性

  • 设置一个属性
    $(选择器).attr(属性名,属性值)
  • 设置多个属性
    $(选择器).attr({key:value, key:value…})

获取属性
$(选择器).attr(属性名)

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		#page{
			height: 100px;
			background-color: palegoldenrod;
			border: solid 2px plum;
		}
		.bin{
			border-radius: 20px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div title="我是一个div"></div>
	<script>
		$("div").attr("id", "page")
		$("div").attr({
			id:"page",
			class:"bin"
		})

		console.log($("div").attr("title"))
	</script>
</body>

CSS样式的设计

设置样式

  • 设置一个样式
    $(选择器).css(样式名, 样式值)
  • 设置多个样式
    $(选择器).css({key:value, key:value…})

获取样式
$(选择器).css(样式名)

<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js" ></script>
</head>
<body>
	<div>hello nice to meet you </div>
	<script>
		$("div").css("color", "plum")
		$("div").css({
			"background-color":"#3c5c5d",
			"border":"2px solid blue",
			"color":"white"
		})
		console.log($("div").css("color"))
	</script>
</body>

html&css

关于元素的操作

  • 添加元素

    • after 在指定的元素后添加兄弟元素
    • append 在指定元素的末尾添加一个子节点
    • appendTo 将一个节点作为子节点添加到指定元素的末尾
    • prepend 在指定元素的开头添加一个子节点
    • prependTo 将一个节点作为子节点添加到指定元素开头
  • 插入元素

    • before 在指定的元素前添加兄弟元素
    • insertBefore 将指定标签移动到 已存在的标签之前
    • insertAfter 将指定标签移动到 已存在的标签之后
  • 替换元素

    • replaceWith 将已经存在元素替换为 指定的元素
    • replaceAll 将指定元素 替换已存在的元素
  • 删除元素

    • empty 只是将标签的内容清空不会删除标签
    • detach 与remove 直接把标签页删除了

包裹节点

包裹: 就是将指定标签使用 要求的标签给包裹起来

<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<p class="page">庆历四年春,滕子京谪守巴陵郡。越明年,政通人和,百废具兴。乃重修岳阳楼,增其旧制,刻唐贤今人诗赋于其上。属予作文以记之。</p>
	<div>予观夫巴陵胜状,在洞庭一湖。衔远山,吞长江,浩浩汤汤,横无际涯;朝晖夕阴,气象万千。此则岳阳楼之大观也,前人之述备矣。然则北通巫峡,南极潇湘,迁客骚人,多会于此,览物之情,得无异乎?</div>
	
	<div>
		<button>包裹节点</button>
		<button>去除包裹</button>
		<button>整体包裹</button>
		<button>包裹内部</button>
	</div>
	
	<span>葵花宝典</span>
	<span>九阳真经</span>
	<span>九阴真经</span>
	<span>降龙十八掌</span>
	<span>葵花点穴手</span>
	<span>排山倒海</span>

	<div>1</div>
	<div class="x">2</div>
	<div>3</div>
	<div class="x">4</div>
	
	<script>
		// 关于类的操作
		// 添加类  在原有的基础上添加的
		$("p").addClass("yue")
		// 移除类
		$("p").removeClass("page")
		
		// 关于元素的操作
		// 添加元素
		$("p").after("<u>摘自岳阳楼记</u>")
		$("p").append("<font color='blue'>岳阳楼记第一句</font>")
		$("<a href='https://www.w3school.com.cn'>w3school</a>").appendTo($("p"))
		$("p").prepend("<img src='http://img3.imgtn.bdimg.com/it/u=378824344,1185609431&fm=26&gp=0.jpg' width=100px />")
		$("<img src='http://image.biaobaiju.com/uploads/20180803/23/1533309822-GCcDphRmqw.jpg' width=100px />").prependTo($("p"))
		// 插入元素
		$("p").before("<h3>岳阳楼记</h3>")
		$("<img src='http://img3.imgtn.bdimg.com/it/u=378824344,1185609431&fm=26&gp=0.jpg' width=100px />").insertBefore($("u"))
		$("<img src='http://img3.imgtn.bdimg.com/it/u=378824344,1185609431&fm=26&gp=0.jpg' width=100px />").insertAfter($("u"))
		// 替换元素
		$("u").replaceWith("<del>摘自岳阳楼记</del>")
		$("<del>摘自岳阳楼记</del>").replaceAll($("u"))
		// 删除元素
		$("div").empty()
		$("div").detach()
		$("div").remove()
		$("div").remove(".x")
		
		// 包裹节点
		$("button").eq(0).click(function(){
			// 给每个指定标签设置一个父节点
			$("span").wrap("<div></div>")
		})
		// 去除包裹
		$("button").eq(1).click(function(){
			// 去除包裹的父节点
			$("span").unwrap()
		})
		// 整体包裹
		$("button").eq(2).click(function(){
			// 给所有的指定标签包裹在一个父标签中
			$("span").wrapAll("<div></div>")
		})
		// 内部包裹
		$("button").eq(3).click(function(){
			// 给每个指定标签设置一个子标签
			$("span").wrapInner("<b></b>")
		})
	</script>
</body>

全选、全不选

  • attr是添加属性 和 移除属性来完成全选和全不选的
  • prop这个操作属性时 对于判定性的属性 是通过true和false来完成操作的
<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js"></script>
</head>
<body>
	<button>全选</button>
	<button>全不选</button>
	
	<p>
		<span>爱好是:</span>
		<input type="checkbox"><span>打篮球</span>
		<input type="checkbox"><span>踢足球</span>
		<input type="checkbox"><span>沙滩球</span>
		<input type="checkbox"><span>棒球</span>
	</p>
	
	<script>
		// 全选
		$("button").eq(0).click(function(){
			
			 //$("input").attr("checked", "checked")
			
			 $("input").prop("checked", true)
		})
		$("button").eq(1).click(function(){
			 //$("input").removeAttr("checked")
			  $("input").prop("checked", false)
		})
		
	</script>
</body>

盒子模型

盒子模型包含四个部分:
内容区 内边距 边框 外边距

  • width()/height() — 内容区的大小
  • innerWidth()/innerHeight() 内容区+内边距
  • outerWidth()/outerHeight() 内容区+内边距+边框
  • outerWidth(true)/outerHeight(true) 内容区+内边距+边框+外边距
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		div{
			width: 300px;
			height: 300px;
			background-color: plum;
			padding: 10px;
			border: solid 2px cadetblue;
			margin: 10px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div></div>
	<script>
		console.log("内容区大小:(" + $("div").width() + "," + $("div").height() + ")") 
		console.log("内容区+内边距大小:(" + $("div").innerWidth() + "," + $("div").innerHeight() + ")") 
		console.log("内容区+内边距+边框大小:(" + $("div").outerWidth() + "," + $("div").outerHeight() + ")") 
		console.log("内容区+内边距+边框+外边距大小:(" + $("div").outerWidth(true) + "," + $("div").outerHeight(true) + ")") 
	</script>
</body>

遍历

<head>
	<meta charset="utf-8">
	<title></title>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<h4>木兰辞</h4>
	<p>唧唧复唧唧,木兰当户织。不闻机杼声,惟闻女叹息。</p>
	<p>问女何所思,问女何所忆。女亦无所思,女亦无所忆。昨夜见军帖,可汗大点兵,军书十二卷,卷卷有爷名。阿爷无大儿,木兰无长兄,愿为市鞍马,从此替爷征。</p>
	<span>东市买骏马,西市买鞍鞯,南市买辔头,北市买长鞭。旦辞爷娘去,暮宿黄河边,不闻爷娘唤女声,但闻黄河流水鸣溅溅。旦辞黄河去,暮至黑山头,不闻爷娘唤女声,但闻燕山胡骑鸣啾啾。</span>
	
	<div>
		<h3>图片展示</h3>
		<img src="../img/pic20.jpg" />
		<img src="../img/pic21.jpg" />
	</div>
	
	<div>
		<h3>静夜思</h3>
		<span>床前明月光,疑是地上霜。</span>
		<p>举头望明月,低头思故乡。</p>
	</div>
	
	<h3>悯农</h3>
	<span>锄禾日当午,汗滴禾下土</span>
	
	<script>
		// add  有其他标签与指定选择器的的样式一致 可以使用add的操作  类似与组合选择器
		$("p").add($("h4")).add($("h3")).css("color", "blue")
		// children()  找到所有的子元素
		$("div").children().css("border", "dashed 2px blue")
		
		//find(选择器) 根据对应的选择器 找到对应的子元素
		$("div").find($("h3")).css("border", "dashed 2px blue")
		// each $(选择器) 获取的是满足选择器的所有节点 他就是一个节点集合  each 就是遍历这个集合 获取集合中的每一个节点的
		/**
		 * index 集合中元素的索引
		 * curelement  被遍历到的元素   JS的对象
		 */
		$("p").each(function(index, curelement){
			console.log(index + "-----" + curelement.innerHTML)
			// 函数中 this  谁访问这个函数 this就表示的是谁  this也是JS的对象
			if(index == 1){
				$(this).css("color", "red")
			}else{
				$(this).css("color", "plum")
			}
		})
		
		// 获取平级的元素
		/**
		 * prev()  平级的上一个节点
		 * prevAll()  上面平级的所有节点
		 * next() 平级的下一个节点
		 * nextAll() 下面平级的所有节点
		 * siblings() 所有平级的
		 */
		$("span").prev().css("border", "dashed 2px blue")
		
		// span节点上一个节点是h3的 g给其设计样式
		$("span").prev("h3").css("border", "dashed 4px blue")
		
		// $("span").prevAll().css("border", "dashed 2px blue")
		$("span").prevAll("div").css("border", "dashed 2px blue")
	</script>
</body>

事件

事件的语法
$(选择器).事件名(触发事件执行的函数)
鼠标悬浮的事件 : 包含两个函数 鼠标进入的时候执行的函数 鼠标离开的时候执行的函数 只给一个函数的话 两个鼠标的动作都会执行这个函数

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		div{
			width: 200px;
			height: 200px;
			background-color: red;
			margin-left: 100px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
	
	<script>
		/**
		 * JS获取元素节点的时候 动作写在head中 
		 * 必须把这个动作放在 文档加载完成的事件中才可以
		 * 否则 获取节点会失败
		 */
		window.onload = function(){
			console.log("页面加载完成")
		}
		
		// JQ
		$(document).ready(function(){
			console.log("JQ页面加载完成")
		})
		
		//简化
		$(function(){
			console.log("JQ简化页面加载完成")
		})
	</script>
</head>
<body>
	<img src="../img/pic15.jpg" />
	<br /><br />
	<button>this is a button</button>
	<br /><br />
	<button class="btn">one event</button>
	<div></div>
	<script>
		$("img").hover(function(e){
			console.log("鼠标悬浮 ------ 离开")
		})
		$("img").hover(
			// 鼠标悬浮指定的动作
			function(e){
				$(this).css("border", "solid 2px red")
			},
			// 鼠标离开执行的动作
			function(e){
				$(this).css("border", "0")
			}
		)
		
		// 绑定事件 on  可以绑定多个事件
		$("button").on({
			"click": function(e){
				console.log("哎呀 我不知道被谁点了一下")
			},
			"mouseover":function(e){
				console.log("哎呀 有只小老鼠爬上来了")
			},
			"mouseleave":function(e){
				console.log("哎呀 小老鼠终于走了")
			}
		})
		
		// 移除事件  可以移除多个事件  每个事件之间使用空格隔开
		$("button").off("click mouseleave")
		
		// 一次性事件
		$(".btn").one("click", function(e){
			console.log("我被点击了")
		})
		
		// 事件对象及其属性
		$("div").mousedown(function(e){
			//console.log(e)
			// 获取鼠标相对与浏览器客户区的间隙
			console.log("获取鼠标相对与浏览器客户区的间隙" + e.clientX + "-----" + e.clientY)
			// 标签相当于body的左边间隙和上边间隙
			console.log("标签相当于body的左边间隙和上边间隙" + this.offsetLeft + "-----" + this.offsetTop)
			// 获取鼠标相当于标签的位置 --- 要完成的需求
			console.log("获取鼠标相当于标签的位置" + (e.clientX - this.offsetLeft) + "----" +   (e.clientY - this.offsetTop))
		})
	</script>
</body>

动画

隐藏和显示

  • 隐藏
    hide(动作完成需要的时间(毫秒), 动作完成后执行的函数)
  • 显示
    show(动作完成需要的时间(毫秒), 动作完成后执行的函数)
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		.box{
			width: 300px;
			height: 300px;
			background-color: red;
		}
		button{
			width: 100px;
			height: 50px;
			margin: 10px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div class="box"></div>
	<div>
		<button>隐藏</button>
		<button>显示</button>
		<button>隐藏与显示</button>
	</div>
	<script>
		$("button").eq(0).click(function(){
			// 隐藏标签
			$(".box").hide(3000, function(){
				console.log("隐藏完成")
			})
		})
		
		$("button").eq(1).click(function(){
			// 显示标签
			$(".box").show(3000)
		})
		
		$("button").eq(2).click(function(){
			// 
			$(".box").toggle(3000)
		})
	</script>
</body>

淡入淡出

  • 淡出
    fadeOut(动作完成需要的时间(毫秒), 动作完成后执行的函数)
  • 淡入
    faseIn(动作完成需要的时间(毫秒), 动作完成后执行的函数)
  • 淡入淡出
    fadeToggle
  • 淡出/淡入到指定模糊度
    fadeTo
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		.box{
			width: 300px;
			height: 300px;
			background-color: red;
		}
		button{
			width: 100px;
			height: 50px;
			margin: 10px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div class="box"></div>
	<div>
		<button>淡出</button>
		<button>淡入</button>
		<button>淡出与淡入</button>
		<button>淡出到指定模糊度</button>
	</div>
	<script>
		$("button").eq(0).click(function(){
			// 淡出
			$(".box").fadeOut(3000, function(){
				console.log("淡出完成")
			})
		})
		
		$("button").eq(1).click(function(){
			// 淡入
			$(".box").fadeIn(3000)
		})
		
		$("button").eq(2).click(function(){
			// 淡入淡出
			$(".box").fadeToggle(2000)
		})
		
		$("button").eq(3).click(function(){
			// 淡入淡出到指定模糊度
			$(".box").fadeTo(1000, 0.5)
		})
	</script>
</body>

下滑与上拉

  • 上滑
    slideUp(动作完成需要的时间(毫秒), 动作完成后执行的函数)
  • 下拉
    slideDown(动作完成需要的时间(毫秒), 动作完成后执行的函数)
  • 上滑与下拉
    slideToggle
<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		.box{
			width: 300px;
			height: 300px;
			background-color: red;
		}
		button{
			width: 100px;
			height: 50px;
			margin: 10px;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div class="box"></div>
	<div>
		<button>上滑</button>
		<button>下拉</button>
		<button>上滑与下拉</button>
	</div>
	<script>
		$("button").eq(0).click(function(){
			// 上滑
			$(".box").slideUp(3000)
		})
		
		$("button").eq(1).click(function(){
			// 下拉
			$(".box").slideDown(3000)
		})
		
		$("button").eq(2).click(function(){
			// 
			$(".box").slideToggle(3000)
		})
	</script>
</body>

颜色动画

  • 那些样式需要发生动画的变化效果 {key:value,key:value}
    动画过渡完成需要的时间 毫秒的
    动画完成之后 调用的函数 可以省略的

  • 如果有多个动画 是依次执行动画的顺序的
    $(selector).stop(stopAll,goToEnd);
    可选的 stopAll 参数规定是否应该清除动画队列。默认是 false,即仅停止活动的动画,允许任何排入队列的动画向后执行。
    可选的 goToEnd 参数规定是否立即完成当前动画。默认是 false。

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		div{
			width: 300px;
			height: 300px;
			background-color: red;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
	<!-- JQ中颜色动画需要的插件 -->
	<script src="../js/jquery.color-2.1.2.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<button>开启动画</button><button>关闭动画</button>
	<div></div>
	<script type="text/javascript">
		$("button").eq(0).click(function(){
			$("div").animate({marginLeft:"200px", opacity:"0.3", backgroundColor:"blue"}, 2000, function(){
				console.log("动画完成了")
			})
			
			$("div").animate({marginTop:"200px"}, 2000, function(){
				console.log("动画完成了")
			})
			
			$("button").eq(1).click(function(){
				$("div").stop()  //仅停止当前动画 继续执行后续动画  而且停止的当前动画的状态保持在停止的状态
				$("div").stop(true) //停止所有的动画 而且停止的当前动画的状态保持在停止的状态 
				$("div").stop(true, true)//停止所有的动画 而且停止的当前动画立即完成了动画状态
			})
		})
	</script>
</body>

轮播图

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
			font-size: 0;
		}
		#box{
			width: 276px;
			height: 276px;
			border: solid 3px deeppink;
			margin: 100px auto;
			/* 溢出 */
			overflow: hidden;
			/* 参照物 */
			position: relative;
		}
		.imglist{
			width: 1380px;
			height: 276px;
			/* 设置定位 */
			position: absolute;
			/* 定位位置 */
			top: 0;
			left: 0;
		}
		.dotlist{
			position: absolute;
			width: 60px;
			height: 10px;
			bottom: 10px;
			left: 10px;
		}
		.dot{
			display: inline-block;
			width: 10px;
			height: 10px;
			background-color: deeppink;
			border-radius: 50%;
			margin-right: 2px;
		}
		.select{
			background-color: deepskyblue;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<!-- 图片可视区域 -->
	<div id="box">
		<!-- 图片列表 -->
		<div class="imglist">
			<img src="../img/pic19.jpg" />
			<img src="../img/pic20.jpg" />
			<img src="../img/pic21.jpg" />
			<img src="../img/pic22.jpg" />
			<img src="../img/pic23.jpg" />
		</div>
		<!-- 点的列表 -->
		<div class="dotlist">
			<span class="dot select"></span>
			<span class="dot"></span>
			<span class="dot"></span>
			<span class="dot"></span>
			<span class="dot"></span>
		</div>
	</div>
	<script>
		// 获取图片列表
		var imglist = $(".imglist")
		// 声明一个变量 记录一下当前是第几张图片
		var curImg = 1
		// 定时器
		setInterval(function(){
			// 每隔一定的时间  图片就得在原来的基础上向左移动一张图片的大小
			// 获取移动之前 图片原本的相当于的参照物左边的距离
			var oldLeft = parseInt( imglist.css("left"))
			// 设置新的相当于参照物左边的间隙  因为是距离左边向左移动 所以是负数
			var newLeft = oldLeft - ($("img").width())
			// 设置图片的移动
			imglist.css("left", newLeft + "px")
			// 记录当前第几张图片的数值该+1
			curImg++
			// 边界判断
			/**
			 * 当图片从1 ---- 5的时候 下一张应该是 1了  所以这一块需要做一个边界判断
			 */
			if(newLeft < -4 * ($("img").width())){
				// 定位到第一张图片的位置
				imglist.css("left", "0px")
				curImg = 1
			}
			// 修改点的颜色
			 change_dot_color()
		}, 2000)
		
		// 设置根据第几张图片 切换不同的点
		function change_dot_color(){
			// 先把所有的恢复到没有选中的状态
			$(".dot").removeClass("select")
			// 把当前图片的点设置为选中状态
			$(".dot").eq(curImg - 1).addClass("select")
		}
	</script>
</body>

放大器

移动框相对于小图的可移动范围 与 大图相对于大图可视框的移动范围是成比例的

  • 移动框的可移动范围
    横向的 小图的宽度 - 移动块的宽度
    纵向的 小图的高度 - 移动块的高度
  • 大图的移动范围
    横向 大图的宽度 - 可视框的宽度
    纵向 大图的高度 - 可视框的高度

换句话说
移动块移动的距离 / 移动框的移动范围 = 大图的移动位移 / 大图的移动范围
在这个公式中 大图的移动位移是未知项

<head>
	<meta charset="utf-8">
	<title></title>
	<style>
		*{
			margin: 0;
			padding: 0;
		}
		#container{
			height: 400px;
			width: 1200px;
			margin: 100px auto;
			background-color: palegoldenrod;
		}
		.smallimg{
			/* 作为移动框的参照物 */
			position: relative;
			float: left;
		}
		.move{
			position: absolute;
			left: 0;
			top: 0;
			width: 200px;
			height: 200px;
			background: url(../img/Tb2.png);
			/* 一开始的时候隐藏 */
			display: none;
		}
		.bigimg{
			width: 400px;
			height: 400px;
			/* 溢出部分隐藏 */
			overflow: hidden;
			float: right;
			/* 一开始隐藏 */
			display: none;
		}
		.clear{
			clear: both;
		}
	</style>
	<script src="../js/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
	<div id="container">
		<!-- 小图 -->
		<div class="smallimg">
			<img src="../img/simg.jpg" />
			<div class="move"></div>
		</div>
		
		<!-- 大图 -->
		<div class="bigimg">
			<img src="../img/bimg.jpg" />
		</div>
		
		<div class="clear"></div>
	</div>
	<script>
		var small = $(".smallimg") // 小图区域
		var move = $(".move") // 移动块
		var big = $(".bigimg") //大图区域
		
		// 鼠标悬浮到小图区域上  移动块和大图区域显示 离开 隐藏
		small.hover(
			function(){
				move.css("display", "block")
				big.css("display", "block")
			},
			function(){
				move.css("display", "none")
				big.css("display", "none")
			}
		)
		
		// 鼠标在小图区域移动  移动块随动  
		small.mousemove(function(e){
			// 鼠标相对于浏览器的位置
			var mouse_client_X = e.clientX
			var mouse_client_Y = e.clientY
			
			// 小图区域相对于body的间隙
			var smallX = small.offset().left  // 等价与JS的offsetLeft
			var smallY = small.offset().top
			
			// 鼠标在小图标签上的坐标
			var mouse_tag_x = mouse_client_X - smallX
			var mouse_tag_y = mouse_client_Y - smallY
			
			// 移动块相对与标签的移动的位移
			var move_x = mouse_tag_x - move.width() / 2
			var move_y = mouse_tag_y - move.height() / 2
			
			// 移动块移动的边界的判断
			// 横向出界
			if(move_x < 0){
				// 左侧出界
				move_x = 0
			}else if(move_x + move.width() > small.width()){
				move_x = small.width() - move.width()
			}
			
			// 纵向出界
			if(move_y < 0){
				// 上边
				move_y = 0
			}else if(move_y + move.height() > small.height()){
				move_y = small.height() - move.height()
			}
			
			// 然后设置移动框 随着鼠标移动
			move.css({
				"left": move_x + "px",
				"top": move_y + "px"
			})
			
			// 移动块移动的距离 与 移动范围之间的比例
			var scaleX = move_x / (small.width() - move.width())
			var scaleY = move_y / (small.height() - move.height())

			// 大图的移动范围 
			var bigimgW = big.find("img").width() - big.width()
			var bigimgH = big.find("img").height() - big.height()
			
			// 大图移动的位移
			var bigimgX = bigimgW * scaleX
			var bigimgY = bigimgH * scaleY
			
			// 设置大图的移动位移
			big.find("img").css({
					marginLeft: -bigimgX + "px",
					marginTop: -bigimgY + "px"
				})
		})
	</script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值