JavaScript

1 JavaScript简介

1.1 JavaScript了解

  1. js也是一门编程语言 它也是可以写后端代码的
    用js一统天下 前后端都可以写
    nodejs 支持js代码跑在后端服务器上
    然而并不能 想的太天真了!!!
  2. JavaScript跟Java一毛钱关系都没有,纯粹是为了蹭当时java的热度

1.2 ECMAScript和JavaScript的关系

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。

1.3 JavaScript特点

JavaScript 是脚本语言
JavaScript 是一种轻量级的编程语言。
JavaScript 是可插入 HTML 页面的编程代码。
JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
JavaScript 很容易学习

1.4 JavaScript版本

主要还是用的5.1和6.0

2 注释

// 单行注释

/*
多行注释1
多行注释2
多行注释3
*/

3 引入JavaScript的方式

# 两种引入方式

1.script标签内部直接书写js代码
2.script标签src属性引入外部js代码

4 js语法结构

js是以分号作为语句的结束
但是如果不写分号,也能够正常执行 
但是它就相当于没有结束符

5 变量

"""
在js中 首次定义一个变量名的时候需要用关键字声明
	1.关键字var
		var name='jason'
	2.es6推出的新语法
		let name='jason'
		如果编辑器支持的版本是5.1那么无法使用let
		如果是6.0则向下兼容 var let
"""

# var与let的区别
1 申明变量n=10
2 for循环中使用了局部变量n
3 循环结束后
# var申明的n!=10		let申明的n=10


"""
var在for循环里面定义也会影响到全局
let在局部定义只会在局部生效
"""

"""
js变量的命名规范
	1.变量名只能是 
		数字 字母 下划线 $
	2.变量名命名规范(不遵循也可以)
		1.js中推荐使用驼峰式命名
			userName
			dataOfDb
		2.python推荐使用下划线的方式
			user_name
			data_of_db
		3.不能用关键字作为变量名
			不需要记忆 

js代码的书写位置
	1.可以单独开设js文件书写
	2.还可以直接在浏览器提供的console界面书写
		在用浏览器书写js的时候 左上方的清空按钮只是清空当前页面 代码其实还在
		如果你想要重新来 最好重新开设一个 页面
		(在使用浏览器书写 你自己的js代码的时候推荐你在 自己的html页面打开)
"""

6 常量

# python中没有真正意义上的常量 约定全大写就表示常量
# js中是有真正意义上的常量的
const pi = 3.14

7 数据类型

js也是一门面向对象 的编程语言 即一切皆对象!!!

js/python是一门动态语言

js是弱类型

python是强类型

name = 'jason'
name = 123
name = [1,2,3,4]
# name可以指向任意的数据类型 
# 但是有一些语言中,变量名之内指向一种后续不能更改 

数据类型

7.1 数值类型

数值类型(number)

整数,浮点数都为数值类型

NaN也属于数值类型 NOT A NUMBER

var a = 11;
var b = 11.11;
// 查看当前数据类型的方法:
typeof a;

var a = 11;
var b = 11.11;

typeof a;
"number"
typeof b;
"number"

// 特殊的 NaN:数值类型 表示的意思是“不是一个数字” NOT A NUMBER

// 类型转换
parseInt()
parseFloat()


parseInt('12312312')
12312312
parseFloat('11.11')
11.11
parseInt('11.11')
11
parseInt('123sdasdajs2312dasd')
123
parseInt('asdasdad123sdasdajs2312dasd')
NaN

7.2 字符类型

字符类型(string)

多行字符串使用``

格式化字符串: `ooooooo${name}`

字符串拼接推荐使用 + 号

7.2.1 字符串格式

var s = 'jason'
typeof s
"string"


var s1 = "jason"
typeof s1;
"string"


var s2 = '''egon'''  // 不支持三引号
VM665:1 Uncaught SyntaxError: Unexpected string



// 模版字符串
var s3 = `
asdkajsd
sdjkladj
asdjlajdkl
`
typeof s3
"string"
// 模版字符串除了可以定义多行文本之外还可以实现格式化字符串操作
// 书写${} 会自动去前面找大括号里面的变量名对应的值 如果没有定义直接报错
var name = 'jason'

var age = 18

var sss = `
   my name is ${name} and my age is ${age}
`
sss
"
   my name is jason and my age is 18
"

var s4 = `my name is ${namemmmmm}`
VM1140:1 Uncaught ReferenceError: namemmmmm is not defined
    at <anonymous>:1:24
// 在写js代码的时候 不要去管左侧箭头的内容


// 字符串的拼接
// 在python中不推荐你使用+做拼接 join
// 在js中推荐你直接使用+做拼接
name + age

7.2.2 字符类型常用方法

"""
string.length	返回长度
string.trim()	移除空白
string.trimLeft()	移除左边的空白
string.trimRight()	移除右边的空白
string.charAt(n)	返回第n个字符
string.concat(value, ...)	拼接
	联想记忆
		MySQL
			concat
			concat_ws
			group_concat
		python
			join
string.indexOf(substring, start)	子序列位置
string.substring(from, to)	根据索引获取子序列
string.slice(start, end)	切片
string.toLowerCase()	小写
string.toUpperCase()	大写
string.split(delimiter, limit)	分割
"""

# 记忆的时候一定要对比python记 

# 返回长度
var name = 'egondsb'
name.length
7


# 移除空白
var name1 = '  egonDSB  '
name1
"  egonDSB  "
name1.trim()
"egonDSB"
name1.trimLeft()
"egonDSB  "
name1.trimRight()
"  egonDSB"

 # 不能加括号指定去除的内容(与python不同)
var name2 = '$$jason$$'
undefined
name2.trim('$') 
"$$jason$$"


# 返回第n个字符
var name2 = '$$jason$$'
name2.charAt(0)
"$"

# 子序列位置

# 不存在返回-1    第二个参数可以指定从该索引及该索引之后查找
# 返回索引值
var name='asdqweyiewfnmsfv'
name.indexOf('d',5);
-1
name.indexOf('i',5);
7
name.indexOf('iwds',5);
-1



# substring根据索引获取子序列(包头不包尾,负数当做0,比较两个参数大小,自动纠正顺序)
var name='asdqweyiewfnmsfv'
name.substring(0,5)
"asdqw"
name.substring(5,0)
"asdqw"
name.substring(5,-3)
"asdqw"
name.substring(0,-1)  # -1当做0,   取0-0,为空
""


# slice根据索引获取子序列(包头不包尾,支持负数索引)
name2.slice(0,5)
"$$jas"

name2.slice(0,-1)  # 后面推荐就使用slice就可以
"$$jason$"


# 全小写		全大写
var name3 = 'eGoNDsb123666HahA'
name3.toLowerCase()
"egondsb123666haha"
name3.toUpperCase()
"EGONDSB123666HAHA"


# split分割			 第二个参数是获取切割之后元素的个数(与python不同)
var name = 'tank|hecha|liaomei|mengsao|...'
name.split('|')
(5) ["tank", "hecha", "liaomei", "mengsao", "..."]
name.split('|',2)
(2) ["tank", "hecha"]0: "tank"1: "hecha"length: 2__proto__: Array(0)
name.split('|',10)  # 第二个参数不是限制切割字符的个数还是获取切割之后元素的个数
(5) ["tank", "hecha", "liaomei", "mengsao", "..."]



# concat  拼接
var name='asdqweyiewfnmsfv'
name.concat('abc','def')
"asdqweyiewfnmsfvabcdef"


var p = 1111
name.concat(p)  # js是弱类型(内部会自动转换成相同的数据类型做操作)
"asdqweyiewfnmsfv1111"



# 在python中数字与字符串做拼接会报错,因为python是强类型语言
l = [1,2,3,4,5,6,7]
res = '|'.join(l)  # 直接报错
print(res)

7.3 布尔值

布尔值(boolean)

"""
1.在python中布尔值是首字母大写的
	True
	False
2.但是在js中布尔值是全小写的
	true
	false
# 布尔值是false的有哪些
	空字符串、0、null、undefined、NaN
"""

7.4 null与undefined

undefined是没有数据类型也没有值

null是没有值,有数据类型

"""
null
	表示值为空 一般都是指定或者清空一个变量时使用
		name = 'jason'
		name = null
undefined
	表示声明了一个变量 但是没有做初始化操作(没有给值)
	函数没有指定返回值的时候 返回的也是undefined
	
	
	
	
var d;

d
undefined



参考博客图解:厕所卷纸
https://www.cnblogs.com/Dominic-Ji/p/9111021.html
"""

7.5 对象

js中 一切皆对象

7.5.1 数组

数组(类似于python里面的列表 [] )

不支持负数索引

`

常用方法:

方法 说明
.length 数组的大小
.push(ele) 尾部追加元素
.pop() 删除尾部的元素并获取该元素
.unshift(ele) 头部插入元素
.shift() 删除头部的元素并获取该元素
.slice(start, end) 切片
.reverse() 反转
.join(seq) 将数组元素连接成字符串
.concat(val, ...) 连接数组
.sort() 排序
.forEach() 将数组的每个元素传递给回调函数
.splice() 删除元素,并向数组添加新元素。
.map() 返回一个数组元素调用函数处理后的值的新数组
var l = [11,22,33,44,55]

typeof l
"object"
var l1 = [11,'sdasd',11.11,true]

l1[1]
"sdasd"
l1[-1]  # 不支持负数索引
undefined


# .length数组的大小
var l = [111,222,333,444,555,666]
l.length
6

# .push(ele)尾部追加元素
l.push(777)
7
l
(7) [111, 222, 333, 444, 555, 666, 777]

# .pop()删除尾部的元素并获取该元素
l.pop()
777
l
(6) [111, 222, 333, 444, 555, 666]

# .unshift(ele)头部插入元素
l.unshift(123)
7
l
(7) [123, 111, 222, 333, 444, 555, 666]

# .shift()删除头部的元素并获取该元素
l.shift()
123

# .slice(start, end)切片
l.slice(0,3)
(3) [111, 222, 333]

# .reverse()反转
l.reverse()
(6) [666, 555, 444, 333, 222, 111]

# .join(seq)将数组元素连接成字符串
l.join('$')  # 跟python刚好相反
"666$555$444$333$222$111"

# .concat(val, ...)连接数组  (类似于python中列表的extend方法)
l.concat([111,222,333])  # extend
(9) [666, 555, 444, 333, 222, 111, 111, 222, 333]

# .sort()排序
l.sort()
(6) [111, 222, 333, 444, 555, 666]



# 三个比较重要的方法

# .forEach()将数组的每个元素传递给回调函数
var ll = [111,222,333,444,555,666]
ll.forEach(function(value){console.log(value)},ll)
VM2277:1 111  # 一个参数就是数组里面每一个元素对象
VM2277:1 222
VM2277:1 333
VM2277:1 444
VM2277:1 555
VM2277:1 666

ll.forEach(function(value,index){console.log(value,index)},ll)
VM2346:1 111 0  # 两个参数就是元素 + 元素索引
VM2346:1 222 1
VM2346:1 333 2
VM2346:1 444 3
VM2346:1 555 4
VM2346:1 666 5
undefined

ll.forEach(function(value,index,arr){console.log(value,index,arr)},ll)  # 元素 + 元素索引 + 元素的数据来源
VM2430:1 111 0 (6) [111, 222, 333, 444, 555, 666]
VM2430:1 222 1 (6) [111, 222, 333, 444, 555, 666]
VM2430:1 333 2 (6) [111, 222, 333, 444, 555, 666]
VM2430:1 444 3 (6) [111, 222, 333, 444, 555, 666]
VM2430:1 555 4 (6) [111, 222, 333, 444, 555, 666]
VM2430:1 666 5 (6) [111, 222, 333, 444, 555, 666]
undefined

ll.forEach(function(value,index,arr,xxx){console.log(value,index,arr,xxx)},ll)  # 最多三个
VM2532:1 111 0 (6) [111, 222, 333, 444, 555, 666] undefined
VM2532:1 222 1 (6) [111, 222, 333, 444, 555, 666] undefined
VM2532:1 333 2 (6) [111, 222, 333, 444, 555, 666] undefined
VM2532:1 444 3 (6) [111, 222, 333, 444, 555, 666] undefined
VM2532:1 555 4 (6) [111, 222, 333, 444, 555, 666] undefined
VM2532:1 666 5 (6) [111, 222, 333, 444, 555, 666] undefined
  
  

# .splice()删除元素,并向数组添加新元素。
var ll = [111, 222, 333, 444, 555, 666]
ll.splice(0,3)  # 两个参数 第一个是起始位置 第二个是删除的个数
(3) [111, 222, 333]
ll
(3) [444, 555, 666]

ll.splice(0,1,777)  # 先删除后添加
[444]
ll
(3) [777, 555, 666]

ll.splice(0,1,[111,222,333,444])
[777]
ll
(3) [Array(4), 555, 666]
# 将[111,222,333,444]作为一个元素 替换删除的部分



# l.map(func)返回一个数组元素调用函数处理后的值的新数组
var l1 = [11,22,33,44,55,66]
l1.map(function(value){console.log(value)})
VM3115:1 11
VM3115:1 22
VM3115:1 33
VM3115:1 44
VM3115:1 55
VM3115:1 66
l1.map(function(value,index){return value*2})
(6) [22, 44, 66, 88, 110, 132]
l1.map(function(value,index,arr){return value*2})
(6) [22, 44, 66, 88, 110, 132]

7.5.2 自定义对象

Object结构提供了“字符串--值”的对应,键只能是字符串

Map结构提供了“值--值”的对应,是一种更完善的Hash结构实现。

# 类似于python中的字典 但是自定义对象的 键只能是字符串
# js中的自定义对象要比python里面的字典操作起来更加的方便

# 创建自定义对象 {}
"""第一种创建自定义对象的方式"""
var d1 = {'name':'jason','age':18}

var d = {'name':'jason','age':18}
typeof d
"object"

d['name']
"jason"
d.name  # 比python从字典获取值更加的方便
"jason"
d.age
18

for(let i in d){
  console.log(i,d[i])
}  # 支持for循环 暴露给外界可以直接获取的也是键


"""第二种创建自定义对象的方式  需要使用关键字 new"""
var d2 = new Object()  # {}

d2.name = 'jason'
{name: "jason"}

d2['age'] = 18
{name: "jason", age: 18}

7.5.3 内置对象

7.5.3.1 时间对象Date

let d3 = new Date()
Fri May 15 2020 14:41:06 GMT+0800 (中国标准时间)
   
d3.toLocaleString()
"2020/5/15 下午2:41:06"

# 也支持自己手动输入时间
let d4 = new Date('2200/11/11 11:11:11')
d4.toLocaleString()

let d5 = new Date(1111,11,11,11,11,11)
d5.toLocaleString()  # 月份从0开始0-11月
"1111/12/11 上午11:11:11"

# 时间对象具体方法
let d6 = new Date();
d6.getDate()  获取日
d6.getDay()		获取星期
d6.getMonth()		获取月份(0-11)
d6.getFullYear()		获取完整的年份
d6.getHours()			获取小时
d6.getMinutes()		获取分钟
d6.getSeconds()		获取秒
d6.getMilliseconds()  获取毫秒
d6.getTime()					获取时间戳

7.5.3.2 正则对象 RegExp

"""
在python中如果需要使用正则 需要借助于re模块
在js中需要你创建正则对象
"""
# 第一种 有点麻烦
let reg1 = new RegExp('^[a-zA-Z][a-zA-Z0-9]{5,11}')
# 第二种 个人推荐
let reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/

# 匹配内容
reg1.test('egondsb')
reg2.test('egondsb')

# 题目 获取字符串里面所有的字母s
let sss = 'egondsb dsb dsb'
sss.match(/s/)  # 拿到一个就停止了
sss.match(/s/g)	# 全局匹配  g就表示全局模式

sss.match(/s/)
["s", index: 5, input: "egondsb dsb dsb", groups: undefined]
sss.match(/s/g)
(3) ["s", "s", "s"]

# 全局匹配模式吐槽点
let reg3 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/g
reg2.test('egondsb')

reg3.test('egondsb')  # 全局模式有一个lastIndex属性
true
reg3.test('egondsb')
false
reg3.test('egondsb')
true
reg3.test('egondsb')
false

reg3.lastIndex
0
reg3.test('egondsb')
true
reg3.lastIndex
7

# 吐槽点二 
let reg4 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/
reg4.test()

reg4.test()  # 什么都不传 默认传的是undefined,并且由于js是弱类型,自动转换成字符串,进行正则匹配
true
reg4.test()
true

reg4.test(undefined)
true
let reg5 = /undefined/
undefined
reg5.test('jason')
false
reg5.test()
true

"""
总结 你在用js书写正则的时候一定要注意上述问题
一般情况下你后续也不会接触到了
"""

7.5.3.3 JSON对象

"""
在python中序列化反序列化
	dumps 		序列化
	loads			反序列化

在js中也有序列化反序列化
	JSON.stringify()			dumps
	JSON.parse()				loads			
"""


let d7 = {'name':'jason','age':18}
let res666 = JSON.stringify(d7)
"{"name":"jason","age":18}"



JSON.parse(res666)
{name: "jason", age: 18}

7.5.3.4 Math对象(了解)

abs(x)      返回数的绝对值。
exp(x)      返回 e 的指数。
floor(x)    对数进行下舍入。
log(x)      返回数的自然对数(底为e)。
max(x,y)    返回 x 和 y 中的最高值。
min(x,y)    返回 x 和 y 中的最低值。
pow(x,y)    返回 x 的 y 次幂。
random()    返回 0 ~ 1 之间的随机数。
round(x)    把数四舍五入为最接近的整数。
sin(x)      返回数的正弦。
sqrt(x)     返回数的平方根。
tan(x)      返回角的正切。

8 运算符

算术运算符 x++与++x的区别

比较运算符 =的区别

赋值运算符 = += -= *= /=

逻辑运算符 && || not

# 算术运算符
var x = 10;
var res1 = x++;
var res2 = ++x;

res1 10
res2 12
# ++表示自增1 类似于 +=1
# 加号在前则先加1后再赋值 
# 加号在后则先赋值后,再加1



# 比较运算符
1 == '1'  # 弱等于  弱类型语言下的比较(自动做数据类型转换)
true  

1 === '1'  # 强等于  强类型语言下的比较(内部不做类型转换)

1 != '1'		 # 弱不等于  弱类型语言下的比较(自动做数据类型转换)
false

1 !== '1'		# 强不等于  强类型语言下的比较(内部不做类型转换)
true




# 逻辑运算符
# python中 and or not
# js中 && || !
5 && '5'
'5'

0 || 1
1

!5 && '5'
false

"""
一定要注意到底什么时候返回的是布尔值 什么是返回的是数据
按照后端逻辑理解吧 js这块看看就行了
"""



# 赋值运算符
= += -= *= ....

9 流程控制

9.1 if-else if-else

# if判断
var age = 28;
# if(条件){条件成立之后指向的代码块}
if (age>18){
  console.log('来啊 来啊')
}
# if-else
if (age>18){
  console.log('来啊 来啊')
}else{
  console.log('没钱 滚蛋')
}
# if-else if else
if (age<18){
  console.log("培养一下")
}else if(age<24){
  console.log('小姐姐你好 我是你的粉丝')
}else{
  console.log('你是个好人')
}
"""
在js中代码是没有缩进的 只不过我们处于python书写习惯人为的加上了而已
()条件
{}代码块
"""

9.2 switch

# switch语法
"""
提前列举好可能出现的条件和解决方式
"""
var num = 2;
switch(num){
  case 0:
  	console.log('喝酒');
  	break;  # 不加break 匹配到一个之后 就一直往下执行
  case 1:
  	console.log('唱歌');
  	break;
  case 2:
  	console.log('洗脚');
  	break;
  case 3:
  	console.log('按摩');
  	break;
  case 4:
  	console.log('营养快线');
  	break;
  case 5:
  	console.log('老板慢走 欢迎下次光临');
  	break;
  default:
  	console.log('条件都没有匹配上 默认走的流程')
}

9.3 for循环

for循环中使用的局部变量的定义,for循环的条件

都可以写在小括号中

# for循环
# 打印0-9数字
for(let i=0;i<10;i++){
  console.log(i)
}
# 题目1  循环打印出数组里面的每一个元素
var l1 = [111,222,333,444,555,666]
for(let i=0;i<l1.length;i++){
  console.log(l1[i])
}

9.4 while循环

# while循环
var i = 0
while(i<100){
  console.log(i)
  i++;
}

9.5 三元运算符

# 三元运算符
# python中三元运算符 res = 1 if 1>2 else 3
# JS中三元运算  res = 1>2?1:3 
条件成立取问号后面的1 不成立取冒号后面的3
var res = 2>5?8:10 # 10
var res = 2>5?8:(8>5?666:444)  # 666
"""
三元运算符不要写的过于复杂 
"""

10 函数

# 在python定义函数需要用到关键字def
# 在js中定义函数需要用到关键字function

# 格式
function 函数名(形参1,形参2,形参3...){函数体代码}

# 无参函数
function func1(){
  console.log('hello world')
}
func1()  # 调用 加括调用 跟python是一样的

# 有参函数
function func2(a,b){
  console.log(a,b)
}
func2(1,2)

func2(1,2,3,4,5,6,7,8,9)  # 多了没关系 只要对应的数据
VM3610:2 1 2
undefined

func2(1)  # 少了也没关系
VM3610:2 1 undefined
  
# 关键字arguments
function func2(a,b){
  console.log(arguments)  # 能够获取到函数接受到的所有的参数
  console.log(a,b)
}

function func2(a,b){
  if(arguments.length<2){
    console.log('传少了')
  }else if (arguments.length>2){
    console.log('传多了')
  }else{
    console.log('正常执行')
  }
}


# 函数的返回值  使用的也是关键字return
function index(){
  return 666
}
function index(){
  return 666,777,888,999
}
res = index();
999
res
999  # 只能拿到最后一个

function index(){
  return [666,777,888,999]
}
# js不支持解压赋值


# 匿名函数  就是没有名字
function(){
  console.log('哈哈哈')
}
var res = function(){
  console.log('哈哈哈')
}

# 箭头函数(要了解一下)  主要用来处理简单的业务逻辑 类似于python中的匿名函数
var func1 = v => v;  """箭头左边的是形参 右边的是返回值"""
等价于
var func1 = function(v){
  return v
}

var func2 = (arg1,arg2) => arg1+arg2
等价于
var func1 = function(arg1,arg2){
  return arg1+arg2
}

10.1 函数的全局变量与局部变量

# 跟python查找变量的顺序一致(名称空间)
var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  //输出结果是?


var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 打印结果是?


var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();

11 BOM操作与DOM操作

# 截至目前为止 我们虽然已经学会了js语法 但是你会发现跟浏览器和html文件还是一点关系没有
"""
BOM
	浏览器对象模型  Browser Object Model
		js代码操作浏览器
DOM
	文档对象模型	  Document Object Model
		js代码操作标签
"""

11.1 BOM操作

浏览器对象模型 Browser Object Model

​ js代码操作浏览器

11.1.1 window对象

# window对象
window对象指代的就是浏览器窗口

window.innerHeight   打开的浏览器窗口的高度
900
window.innerWidth    打开的浏览器窗口的宽度
1680

window.open('https://www.mzitu.com/','','height=400px,width=400px,top=400px,left=400px')
# 新建窗口打开页面 第二个参数写空即可 第三个参数写新建的窗口的大小和位置
# 扩展父子页面通信window.opener()  了解

window.close()  关闭当前页面

11.1.2 window子对象之navigator对象

如果是window的子对象 那么window可以省略不写

`

window.navigator.appName		# 查看当前窗口的浏览器app名字
"Netscape"		# 大多数浏览器appName都是Netscape


window.navigator.appVersion		# 查看当前窗口的浏览器app版本
"5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"

"5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"


window.navigator.userAgent		掌握  # 用来表示当前是否是一个浏览器
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"

"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"


window.navigator.platform  # 查看当前平台
"MacIntel"
"Win32"




# 如果是window的子对象 那么window可以省略不写



"""
扩展:仿爬措施
	1.最简单最常用的一个就是校验当前请求的发起者是否是一个浏览器
		userAgent
		user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
		
	如何破解该措施
		在你的代码中加上上面的user-agent配置即可
"""

11.1.3 window子对象之history对象

如果是window的子对象 那么window可以省略不写

window.history.back()  		# 回退到上一页
window.history.forward()    # 前进到下一页

# 对应的就是浏览器左上方的前进,后退按钮

11.1.4 window子对象之location对象(掌握)

如果是window的子对象 那么window可以省略不写

`

window.location.href	# 获取当前页面的url
window.location.href = url  # 跳转到指定的url
window.location.reload()  # 属性页面   浏览器左上方的小圆圈

11.1.5 window子对象之弹出框对象

如果是window的子对象 那么window可以省略不写

`

  • 警告框 alert
  • 确认框 confirm
  • 提示框 prompt
window.alert('你不要过来啊!!!')
undefined


window.confirm('你确定真的要这么做吗?能不能有其他方式能够满足你...')
false

window.confirm('你确定真的要这么做吗?能不能有其他方式能够满足你...')
true


window.prompt('手牌号给我看一下','22号消费888')
"用户在提示框内输入的字符串"

# prompt的第一个字符串为提示信息,
# 第二个字符串为默认输入的字符串,用户可以更改

11.1.6 计时器相关

  • 过一段时间之后触发(一次)
  • 每隔一段时间触发一次(循环)
普通计时器		setTimeout(执行的函数,时间);		 时间毫秒为单位

​		取消普通计时器	clearTimeout(计时器对象)		需要提前使用变量保存计时器对象

循环计时器		setInterval(执行的函数,时间);		 时间毫秒为单位

​		取消循环计时器	clearInterval(计时器对象)		需要提前使用变量保存计时器对象
<script>
    function func1() {
        alert(123)
    }
    let t = setTimeout(func1,3000);  // 毫秒为单位 3秒之后自动执行func1函数

    clearTimeout(t)      // 取消定时任务  如果你想要清除定时任务 需要日前用变量指代定时任务


    function func2() {
        alert(123)
    }
    function show(){
        let t = setInterval(func2,3000);  // 每隔3秒执行一次
        function inner(){
            clearInterval(t)  // 清除定时器
        }
        setTimeout(inner,9000)  // 9秒中之后触发
    }
    show()
</script>

11.2 DOM操作

文档对象模型 Document Object Model

​ js代码操作标签

"""
DOM树的概念

所有的标签都可以称之为是节点

JavaScript 可以通过DOM创建动态的 HTML:

JavaScript 能够改变页面中的所有 HTML 元素
JavaScript 能够改变页面中的所有 HTML 属性
JavaScript 能够改变页面中的所有 CSS 样式
JavaScript 能够对页面中的所有事件做出反应


DOM操作操作的是标签 而一个html页面上的标签有很多 
	1.先学如何查找标签
	2.再学DOM操作标签
	
DOM操作需要用关键字document起手



DOM标准规定HTML文档中的每个成分都是一个节点(node):

文档节点(document对象):代表整个文档
元素节点(element 对象):代表一个元素(标签)
文本节点(text对象):代表元素(标签)中的文本
属性节点(attribute对象):代表一个属性,元素(标签)才有属性
注释是注释节点(comment对象)
"""

11.2.1 查找标签

11.2.1.1 直接查找(*****)

"""
document.getElementById           根据ID获取一个标签
document.getElementsByClassName   根据class属性获取
document.getElementsByTagName     根据标签名获取标签合集
"""
# 注意三个方法的返回值是不一样的
document.getElementById('d1')
<div id=​"d1">​…​</div>​

document.getElementsByClassName('c1')
HTMLCollection [p.c1]0: p.c1length: 1__proto__: HTMLCollection
      
document.getElementsByTagName('div')
HTMLCollection(3) [div#d1, div, div, d1: div#d1]
                   
                   
let divEle = document.getElementsByTagName('div')[1]
divEle
<div>​div>div​</div>​
"""
当你用变量名指代标签对象的时候 一般情况下都推荐你书写成
xxxEle
	divEle
	aEle
	pEle
"""

11.2.1.2 间接查找

parentElement            父节点标签元素
children                 所有子标签
firstElementChild        第一个子标签元素
lastElementChild         最后一个子标签元素
nextElementSibling       下一个兄弟标签元素
previousElementSibling   上一个兄弟标签元素
let pEle = document.getElementsByClassName('c1')[0]  # 注意是否需要索引取值

pEle.parentElement  # 拿父节点
<div id=​"d1">​"div
    "<div>​div>div​</div>​<p class=​"c1">​…​</p>​<p>​div>p​</p>​</div>​
    
pEle.parentElement.parentElement
<body>​…​</body>​

pEle.parentElement.parentElement.parentElement
<html lang=​"en">​<head>​…​</head>​<body>​…​</body>​</html>​

pEle.parentElement.parentElement.parentElement.parentElement
null




let divEle = document.getElementById('d1')
divEle.children  # 获取所有的子标签,得到数组
divEle.children[0]
<div>​div>div​</div>​

divEle.firstElementChild
<div>​div>div​</div>​

divEle.lastElementChild
<p>​div>p​</p>​

divEle.nextElementSibling  # 同级别下面第一个
<div>​div下面div​</div>​

divEle.previousElementSibling  # 同级别上面第一个
<div>​div上面的div​</div>​

11.2.2 节点操作

11.2.2.1 元素节点方法

创建节点:		createElement(标签名)


添加节点:		
		1 追加一个子节点(作为最后的子节点)
			somenode.appendChild(newnode);
		2 把增加的节点放到某个节点的前边。
			somenode.insertBefore(newnode,某个节点);
		
		
删除节点:		somenode.removeChild(要删除的节点)


替换节点:		somenode.replaceChild(newnode, 某个节点);

11.2.2.2 属性节点方法

var divEle = document.getElementById("d1");
divEle.setAttribute("age","18")		# 设置属性
divEle.getAttribute("age")			# 取属性对应的值
divEle.removeAttribute("age")		# 移除属性 


如果该属性是自带的属性,而非自定义属性,可以直接	.属性名来获取和设置
imgEle.src				# 取属性对应的值
imgEle.src="..."		# 设置属性

实例演示 :

"""
通过DOM操作动态的创建img标签
并且给标签加属性
最后将标签添加到文本中
"""
let imgEle = document.createElement('img')  # 创建标签

imgEle.src = '111.png'  # 给标签设置默认的属性
"111.png"
imgEle

imgEle.username = 'jason'  # 自定义的属性没办法点的方式直接设置
"jason"
imgEle
<img src=​"111.png">​


imgEle.setAttribute('username','jason')   # 既可以设置自定义的属性也可以设置默认的书写
undefined
imgEle
<img src=​"111.png" username=​"jason">​
imgEle.setAttribute('title','一张图片')
imgEle
<img src=​"111.png" username=​"jason" title=​"一张图片">​

let divEle = document.getElementById('d1')
undefined
divEle.appendChild(imgEle)  # 标签内部添加元素(尾部追加)
<img src=​"111.png" username=​"jason" title=​"一张图片">​


"""
创建a标签
设置属性
设置文本
添加到标签内部
	添加到指定的标签的上面
"""
let aEle = document.createElement('a')

aEle
<a>​</a>​
aEle.href = 'https://www.mzitu.com/'
"https://www.mzitu.com/"
aEle
<a href=​"https:​/​/​www.mzitu.com/​">​</a>​

aEle.innerText = '点我有你好看!'  # 给标签设置文本内容
"点我有你好看!"
aEle
<a href=​"https:​/​/​www.mzitu.com/​">​点我有你好看!​</a>​
let divEle = document.getElementById('d1')
undefined
let pEle = document.getElementById('d2')
undefined
divEle.insertBefore(aEle,pEle)  # 添加标签内容指定位置添加
<a href=​"https:​/​/​www.mzitu.com/​">​点我有你好看!​</a>​


"""
额外补充
	appendChild()
		removeChild()
		replaceChild()
	
	
	setAttribute()  设置属性
		getAttribute()  获取属性
		removeAttribute()  移除属性
"""

11.2.2.3 获取值的方法

元素对象.value

fileEle.files[0] # 获取文件数据

var iEle = document.getElementById("i1");
iEle.value;

var sEle = document.getElementById("s1");
sEle.value;

var tEle = document.getElementById("t1");
tEle.value;

实例演示 :

# 获取用户数据标签内部的数据
let seEle = document.getElementById('d2')
seEle.value
"111"
seEle.value
"333"

let inputEle = document.getElementById('d1')
inputEle.value

# 如何获取用户上传的文件数据
let fileEle = document.getElementById('d3')
fileEle.value  # 无法获取到文件数据
"C:\fakepath\02_测试路由.png"

fileEle.files
FileList {0: File, length: 1}0: File {name: "02_测试路由.png", lastModified: 1557043082000, lastModifiedDate: Sun May 05 2019 15:58:02 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 29580, …}length: 1__proto__: FileList
      
fileEle.files[0]  # 获取文件数据
File {name: "02_测试路由.png", lastModified: 1557043082000, lastModifiedDate: Sun May 05 2019 15:58:02 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 29580, …}

11.2.2.4 文本节点方法

获取文本节点的值:

var divEle = document.getElementById("d1")
divEle.innerText		# 获取标签内部所有的文本
divEle.innerHTML		# 获取标签内部文本和标签

设置文本节点的值:

var divEle = document.getElementById("d1")
divEle.innerText="<p>2</p>"			# 不可以识别html语法
divEle.innerHTML="<p>2</p>" 		# 可以识别html语法(标签)

实例演示 :

# innerText与innerHTML
divEle.innerText  # 获取标签内部所有的文本
"div 点我有你好看!
div>p
div>span"

divEle.innerHTML  # 内部文本和标签都拿到
"div
        <a href="https://www.mzitu.com/">点我有你好看!</a><p id="d2">div&gt;p</p>
        <span>div&gt;span</span>
    "
    
divEle.innerText = 'heiheihei'
"heiheihei"
divEle.innerHTML = 'hahahaha'
"hahahaha"

divEle.innerText = '<h1>heiheihei</h1>'  # 不识别html标签
"<h1>heiheihei</h1>"
divEle.innerHTML = '<h1>hahahaha</h1>'  # 识别html标签
"<h1>hahahaha</h1>"

11.2.2.5 class相关的操作

classList 		 获取标签所有的类属性

classList.remove(cls)  删除指定类
classList.add(cls)  添加类
classList.contains(cls)  存在返回true,否则返回false
classList.toggle(cls)  存在就删除,否则添加

实例演示 :

let divEle = document.getElementById('d1')

divEle.classList  # 获取标签所有的类属性
DOMTokenList(3) ["c1", "bg_red", "bg_green", value: "c1 bg_red bg_green"]


divEle.classList.remove('bg_red')  # 移除某个类属性
undefined

divEle.classList.add('bg_red')  # 添加类属性
undefined
divEle.classList.contains('c1')  # 验证是否包含某个类属性
true
divEle.classList.contains('c2')
false

divEle.classList.toggle('bg_red')  # 有则删除无则添加
false
divEle.classList.toggle('bg_red')
true
divEle.classList.toggle('bg_red')
false
divEle.classList.toggle('bg_red')
true
divEle.classList.toggle('bg_red')
false
divEle.classList.toggle('bg_red')
true


11.2.2.6 css相关的操作

# DOM操作操作标签样式 统一先用style起手
let pEle = document.getElementsByTagName('p')[0]
undefined
pEle.style.color = 'red'
"red"
pEle.style.fontSize = '28px'
"28px"
pEle.style.backgroundColor = 'yellow'
"yellow"
pEle.style.border = '3px solid red'
"3px solid red"

12 事件

HTML 4.0 的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript。下面是一个属性列表,这些属性可插入 HTML 标签来定义事件动作。

12.1 常见事件

onclick        当用户点击某个对象时调用的事件句柄。
ondblclick     当用户双击某个对象时调用的事件句柄。

onfocus        元素获得焦点。               // 练习:输入框
onblur         元素失去焦点。               应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange       域的内容被改变。             应用场景:通常用于表单元素,当元素内容被改变时触发.(select联动)

onkeydown      某个键盘按键被按下。          应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress     某个键盘按键被按下并松开。
onkeyup        某个键盘按键被松开。
onload         一张页面或一幅图像完成加载。
onmousedown    鼠标按钮被按下。
onmousemove    鼠标被移动。
onmouseout     鼠标从某元素移开。
onmouseover    鼠标移到某元素之上。

onselect      在文本框中的文本被选中时发生。
onsubmit      确认按钮被点击,使用的对象是form。

12.2 绑定事件的两种方法

"""
达到某个事先设定的条件 自动触发的动作
"""
# 绑定事件的两种方式

// 第一种绑定事件的方式
<div id="d1" onclick="changeColor(this);">点我</div>
<script>
  function changeColor(ths) {
    ths.style.backgroundColor="green";
  }
</script>


// 第二种绑定事件的方式
<div id="d2">点我</div>
<script>
  var divEle2 = document.getElementById("d2");
  divEle2.onclick=function () {
    this.innerText="呵呵";
  }
</script>


"""
script标签既可以放在head内 也可以放在body内
但是通常情况下都是放在body内的最底部
"""




# 拓展:	等待浏览器窗口加载完毕之后再执行代码
window.onload = function () {
            // 第一种绑定事件的方式
            function func1() {
                alert(111)
            }
            // 第二种
            let btnEle = document.getElementById('d1');
            btnEle.onclick = function () {
                alert(222)
            }
        }

12.3 开关灯案例

<div id="d1" class="c1 bg_red bg_green"></div>
<button id="d2">变色</button>

<script>
        let btnEle = document.getElementById('d2')
        let divEle = document.getElementById('d1')
        btnEle.onclick = function () {  // 绑定点击事件
            // 动态的修改div标签的类属性
            divEle.classList.toggle('bg_red')
        }
</script>

12.4 input框获取焦点失去焦点案例

<input type="text" value="老板 去吗?" id="d1">

<script>
    let iEle = document.getElementById('d1')
    // 获取焦点事件
    iEle.onfocus = function () {
        // 将input框内部值去除
        iEle.value = ''
        //  点value就是获取   等号赋值就是设置
    }
    // 失去焦点事件
    iEle.onblur = function () {
        // 给input标签重写赋值
        iEle.value = '没钱 不去!'
    }
</script>

12.5 实时展示当前时间

<input type="text" id="d1" style="display: block;height: 50px;width: 200px">
<button id="d2">开始</button>
<button id="d3">结束</button>

<script>
    // 先定义一个全局存储定时器的变量
    let t = null
    let inputEle = document.getElementById('d1')
    let startBtnEle = document.getElementById('d2')
    let endBtnEle = document.getElementById('d3')
    // 1 访问页面之后 将访问的时间展示到input框中
    // 2 动态展示当前时间
    // 3 页面上加两个按钮 一个开始 一个结束
    function showTime() {
        let currentTime = new Date();
        inputEle.value = currentTime.toLocaleString()
    }

    startBtnEle.onclick = function () {
        // 限制定时器只能开一个
        if(!t){
            t = setInterval(showTime,1000)  // 每点击一次就会开设一个定时器 而t只指代最后一个
        }
    }
    endBtnEle.onclick = function () {
        clearInterval(t)
        // 还应该将t重置为空
        t = null
    }
</script>

12.6 省市联动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<select name="" id="d1">
    <option value="" selected disabled>--请选择--</option>
</select>
<select name="" id="d2"></select>

<script>
    let proEle = document.getElementById('d1')
    let cityEle = document.getElementById('d2')
    // 先模拟省市数据
    data = {
        "河北": ["廊坊", "邯郸",'唐山'],
        "北京": ["朝阳区", "海淀区",'昌平区'],
        "山东": ["威海市", "烟台市",'临沂市'],
        '上海':['浦东新区','静安区','黄浦区'],
        '深圳':['南山区','宝安区','福田区']
    };
    // 选for循环获取省
    for(let key in data){
        // 将省信息做成一个个option标签 添加到第一个select框中
        // 1 创建option标签
        let opEle = document.createElement('option')
        // 2 设置文本
        opEle.innerText = key
        // 3 设置value
        opEle.value = key  // <option value="省">省</option>
        // 4 将创建好的option标签添加到第一个select中
        proEle.appendChild(opEle)
    }
    // 文本域变化事件  change事件
    proEle.onchange = function () {
        // 先获取到用户选择的省
        let currentPro = proEle.value
        // 获取对应的市信息
        let currentCityList = data[currentPro]
        // 清空市select中所有的option
        cityEle.innerHTML = ''
        // 自己加一个请选择
        let ss = "<option disabled selected>请选择</option>"
        // let oppEle = document.createElement('option')
        // oppEle.innerText = '请选择'
        // oppEle.setAttribute('selected','selected')
        cityEle.innerHTML = ss

        // for循环所有的市 渲染到第二个select中
        for (let i=0;i<currentCityList.length;i++){
            let currentCity = currentCityList[i]
            // 1 创建option标签
            let opEle = document.createElement('option')
            // 2 设置文本
            opEle.innerText = currentCity
            // 3 设置value
            opEle.value = currentCity  // <option value="省">省</option>
            // 4 将创建好的option标签添加到第一个select中
            cityEle.appendChild(opEle)
        }
    }
</script>
</body>
</html>

参考 https://www.cnblogs.com/Dominic-Ji/p/9111021.html

 posted on 2020-05-14 22:44  wwwpy  阅读(243)  评论(0编辑  收藏  举报