JavaScript简介
- js是一门编程语言,它也可以写后端代码(node.js)。
- js和java没有关系,仅仅是当时为了蹭Java的热度。
- ECMAScript和JavaScript的关系
- JavaScript 是脚本语言
- JavaScript 是一种轻量级的编程语言。
- JavaScript 是可插入 HTML 页面的编程代码。
- JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
- JavaScript 很容易学习。
1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这门语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。
该标准一开始就是针对JavaScript语言制定的,但是没有称其为JavaScript,有两个方面的原因。一是商标,JavaScript本身已被Netscape注册为商标。
而是想体现这门语言的制定者是ECMA,而不是Netscape,这样有利于保证这门语言的开发性和中立性。
因此,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。
JS版本 主要还是用的5.1和6.0 # js的注释 """ // 单行注释 /* 多行注释1 多行注释2 多行注释3 */ """ # 两种引入方式 1.script标签内部直接书写js代码 2.script标签src属性引入外部js代码 # js语法结构 js是以分号作为语句的结束 但是如果你不写分号,问题也不大 也能够正常执行 但是它就相当于没有结束符 #js代码的书写位置 1.可以单独开设js文件书写 2.还可以直接在浏览器提供的console界面书写 在用浏览器书写js的时候 左上方的清空按钮只是清空当前页面 代码其实还在 如果你想要重新来 最好重新开设一个 页面 (在使用浏览器书写 你自己的js代码的时候推荐你在 自己的html页面打开)
尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
- 核心(ECMAScript)
- 文档对象模型(DOM) Document object model (整合js,css,html)
- 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)
简单地说,ECMAScript 描述了JavaScript语言本身的相关内容。
变量
js中,变量的声明需要使用关键词,关键词有两个:var
、let
(es6推出的新语法)。
补充:var和let的区别
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页面打开)
常量
js中常量通过关键词 const
定义,默认全大写就是表示常量,定义后就不能被修改。如,const pi = 3.14
ps:常量指的是定义之后不可以被修改
数据类型
-
js也是一门面向对象 的编程语言 即一切皆对象!!!
-
js/python是一门拥有动态类型的编程语言(变量名可以指向任意数据类型的值,可以修改)。
- 查看当前数据类型的方法:typeof
数值类型:number 字符串类型:string 布尔型:bollean 空:null & undefined 对象:object
数值类型
-
特殊的
NaN
数值类型,表示的意思是“不是一个数字” not a number -
数字类型转换方法:
parseINT()
、parseFloat()
-
注意:只要首字符是数字,就可以
parseINT
,parseFloat
只保留整数部分
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
字符类型(string)
-
三种方式定义字符串:单引号、双引号、模版字符串
var s = 'jason' undefined typeof s "string" var s1 = "jason" undefined 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 "
-
模版字符串语法:反引号+$+{}
let info = `welcome to ${park_name}`
-
js中,字符串拼接推荐方式:
var info = name + age
注意:python中字符串拼接join ,不推荐使用+
字符类型常用方法:
var name = 'egondsb' undefined name.length 7 var name1 = ' egonDSB ' undefined name1 " egonDSB " name1.trim() "egonDSB" name1.trimLeft() "egonDSB " name1.trimRight() " egonDSB" var name2 = '$$jason$$' undefined name2.trim('$') # 不能加括号指定去除的内容 "$$jason$$" name2.charAt(0) "$" name2.indexOf('as') 3 name2.substring(0,5) "$$jas" name2.slice(0,5) "$$jas" name2.substring(0,-1) # 不识别负数 "" name2.slice(0,-1) # 后面推荐就使用slice就可以 "$$jason$" var name3 = 'eGoNDsb123666HahA' name3.toLowerCase() "egondsb123666haha" name3.toUpperCase() "EGONDSB123666HAHA" 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", "..."] name.concat(name1,name2) "tank|hecha|liaomei|mengsao|... egonDSB $$jason$$" var p = 1111 name.concat(p) # js是弱类型(内部会自动转换成相同的数据类型做操作) "tank|hecha|liaomei|mengsao|...1111" l = [1,2,3,4,5,6,7] res = '|'.join(l) # 直接报错 print(res)
注意:
- .trim(),不能加括号指定去除的内容
- .slice(0,-1),支持负数,但不是顾头不顾尾,只取至倒数第二个。
- .substring(0,4),不支持负数,推荐使用.slice()
- .split('|', 2),第二个参数不是限制切割字符的个数还是获取切割之后元素的个数。
- .concat(),可以直接拼接字符串和数字,内部自动转化。
布尔值
1.在python中布尔值是首字母大写的 True False 2.但是在js中布尔值是全小写的 true false # 布尔值是false的有哪些 空字符串、0、null、undefined、NaN
null & undefined
null 表示值为空 一般都是指定或者清空一个变量时使用 name = 'jason' name = null undefined 表示声明了一个变量 但是没有做初始化操作(没有给值) 函数没有指定返回值的时候 返回的也是undefined
数组(Array)
数组:类似于python里面的列表[]
var nums = [1,2,3,4,5,6] // 支持多数据再一个数组中 nums[1] //支持索引取值,从0开始,但不支持索引为负数
数组对象方法:
- sort()排序,默认按照字符编码表顺序排序,而不是数字的大小。
- forEach()方法,对数组中每个元素调用传入的函数。
- splice()方法,删除数组中指定元素并添加新元素
- map()方法,类似forEach()方法。
var l = [11,22,33,44,55] typeof l "object" var l1 = [11,'sdasd',11.11,true] l1[1] "sdasd" l1[-1] # 不支持负数索引 var l = [111,222,333,444,555,666] undefined l.length #返回对象长度 6 l.push(777) #尾部插入元素 7 l (7) [111, 222, 333, 444, 555, 666, 777] l.pop() #弹出尾部元素 777 l (6) [111, 222, 333, 444, 555, 666] l.unshift(123) #头部插入元素 7 l (7) [123, 111, 222, 333, 444, 555, 666] l.shift() #头部移除元l 123 l.slice(0,3) #切片 l.slice(start, end) (3) [111, 222, 333] l.reverse() #反转 (6) [666, 555, 444, 333, 222, 111] l.join('$') # 跟python刚好相反,在python中,列表中元素必须为字符串类型 "666$555$444$333$222$111" l.concat([111,222,333]) # 相当于python的extend,尾部插入多个元素 (9) [666, 555, 444, 333, 222, 111, 111, 222, 333] l.sort()#排序 (6) [111, 222, 333, 444, 555, 666] # 三个比较重要的方法 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 ll (6) [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] var l1 = [11,22,33,44,55,66] undefined l1.map(function(value){console.log(value)},l1) 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},l1) (6) [22, 44, 66, 88, 110, 132] l1.map(function(value,index,arr){return value*2},l1) (6) [22, 44, 66, 88, 110, 132]
运算符
算术运算符
++
表示自增,加号在前,先加再赋值;加号在后,先赋值再加
比较运算符
==
,弱等于,仅仅比较数值,不比较类型;同理有不等于!=
===
,强等于,比较数值和类型;同理有不等于!==
逻辑运算符
-
与
&&
、或||
、非!
-
遵循短路运算
三元运算符
-
var res =
条件 ? 条件true结果 : 条件false结果
-
三元运算符支持嵌套
-
三元运算符,一般用于简单的逻辑表达上,不要写的过于复杂,得不偿失。
# 算术运算符 var x = 10; var res1 = x++; #==>res1=x=10且x+=1(此时x=11) 先赋值, 后加 var res2 = ++x; #==>x+=1(此时x=12),res2=x=12 先加,后赋值 res1 10 res2 12 ++表示自增1 类似于 +=1 ps:加号在前先加后赋值 加号在后先赋值后加 # 比较运算符 1 == '1' # 弱等于 内部自动转换成相同的数据类型比较了 true 1 === '1' # 强等于 内部不做类型转换 1 != '1' false 1 !== '1' true # 逻辑运算符 # python中 and or not # js中 && || ! 5 && '5' '5' 0 || 1 1 !5 && '5' #!5:false false """ 一定要注意到底什么时候返回的是布尔值 什么是返回的是数据 """ # 赋值运算符 = += -= *= ....
# 三元运算符 # python中三元运算符 res = 1 if 1>2 else 3 # JS中三元运算 res = 1>2?1:3 条件成立取问好后面的值 不成立取冒号后面的值 #示例: var res = 2>5?8:10 # 10 var res = 2>5?8:(8>5?666:444) # 666 """ 三元运算符不要写的过于复杂 """
流程控制
if判断
完整语法:js中没有缩进,采用{}
的方式划分代码层级区域。
if(条件1){ // 代码块1 }else if(条件2){ // 代码块2 }else{ // 代码块3 };
# 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('你是个好人') }
switch判断
- 提前列举好可能出现的条件和解决方式
- 从上往下匹配每个
case
,匹配成功开始执行case
下的代码。 - 每个
case
都需要配一个break
,否则程序一直往下执行。
完整语法 var day = Sunday; switch(day){ case 'Monday': console.log('MoNday'); break; case 'Tuesday': console.log('Tuesday'); break; ..... default: console.log('other'); }
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('条件都没有匹配上 默认走的流程') }
for循环
完整语法,示例 for(var i=0; i<10; i++){ consolg.log(i) } #简写 var i=0; for(;;){ if(i<10){ i++; console.log(i); }else{ break; } }
# 打印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]) }
while循环
完整语法 while(条件){ 代码快 };
var i = 0 while(i<100){ console.log(i) i++; }
函数
函数定义
function 函数名(形参1, 形参2, ...){ 函数体代码 }
函数调用:函数名加括号调用。
- 调用时,实参个数不足或者实参个数过多,函数执行时都不会报错。只是结果不是预期的效果。
- 函数内置参数
arguments
接收传进来的参数。 - 函数返回值使用关键词
return
;注意:不支持返回多个返回值,如果返回多个则只有最后一个值被返回。 - 返回多个数据时,使用数组等对象
# 在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不支持解压赋值
匿名函数
//定义匿名函数,并绑定给一个变量 var hello = function (){ console.log('hello world'); } // 调用函数 hello()
# 匿名函数 就是没有名字 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 }
全局变量和局部变量、作用域的概念和python的一致。
局部变量:
在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。
全局变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
变量生存周期:
JavaScript变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
作用域
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。
# 跟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();
自定义对象
自定义对象可以看成是python中的字典,但是js中的自定义对象要比python里面的字典操作起来更加的方便。
创建自定义对象的方式
方式1:var d1 = {'name': 'xliu', 'age': 18};
方式2:var d2 = new Object();
# 查 d1['name'] d1.name #增 d2['name'] = 'xliu' d2.age = 18 #改 d2.age = 17 #删 delete d2.age
# 创建自定义对象 {} """第一种创建自定义对象的方式""" 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}
内置对象
Date对象
创建Date对象
//方法1:不指定参数 var d1 = new Date(); //方法2:参数为日期字符串 var d2 = new Date("2004/3/20 11:12"); console.log(d1.toLocaleString()); // 2020/5/15 下午5:30:44
时间对象具体方法。详细Date对象方法
let d6 = new Date(); d6.getDate() 获取日 d6.getDay() 获取星期 d6.getMonth() 获取月份(0-11) d6.getFullYear() 获取完整的年份 d6.getHours() 获取小时 d6.getMinutes() 获取分钟 d6.getSeconds() 获取秒 d6.getMilliseconds() 获取毫秒 d6.getTime() 时间戳
JSON对象
JS也是支持序列化和反序列化的,序列化对象JSON
python中序列化和反序列化:
dumps:序列化
loads:反序列化
JS中序列化和反序列化:
js的序列化:JSON.stringify()
js的反序列化:JSON.parser()
let d7 = {'name':'jason','age':18} # 序列化 let res = JSON.stringify(d7) "{"name":"jason","age":18}" # 反序列化 JSON.parse(res) {name: "jason", age: 18}
RegExp对象
在JS中需要自己创建正则对象,python中则可以直接调用re模块实现:
JS创建正则方式:
方式一:let reg1 = new RegExp('^[a-z0-9A-Z][0-9]{1,10}') # 匹配a-z 0-9 A-Z开头,后面是0-9的1位或10位字符
方式二:let reg2 = /^[a-z0-9A-Z][0-9]{1,10}/
匹配内容:
reg1.test('the3times') # false reg1.test('t2he3times') # true
练习:
# 获取字符串里面所有的字母s let sss = 'egondsb dsb dsb' sss.match(/s/) # 拿到一个就停止了 sss.match(/s/g) # 全局匹配 g就表示全局模式
全局匹配模式的吐槽点:全局模式有一个lastIndex属性。
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
吐槽点二 :正则匹配test没有参数时,默认使用undefined
let reg4 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/ reg4.test() # 什么都不传 默认传的是undefined true reg4.test(undefined) true let reg5 = /undefined/ undefined reg5.test('jason') false reg5.test() true
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) 返回角的正切。
BOM与DOM操作
# 截至目前为止 我们虽然已经学会了js语法 但是你会发现跟浏览器和html文件还是一点关系没有 JavaScript分为 ECMAScript,DOM,BOM。 """ BOM(Browser Object Model) 浏览器对象模型 js代码操作浏览器:它使 JavaScript有能力与浏览器进行'对话' DOM(Document Object Model) 文档对象模型 js代码操作标签:通过它,可以访问 HTML 文档的所有元素 """
BOM操作
window对象
# window对象 所有浏览器都支持 windowd对象,它表示浏览器窗口 所有JavaScript 全局对象、函数以及变量均自动称为 window对象的成员。 全局变量是 window对象的属性,全局函数是 window对象的方法。 HTML DOMd的document 也是 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() 关闭当前页面
window对象是客户端JavaScript最高层对象之一,由于window对象是其它大部分对象共同祖先,在调用window对象的方法和属性时,可以省略window对象的引用。例如:window.document.write()可以简写成:document.write()
window子对象
Navigator对象,浏览器对象,通过这个对象可以判断用户所使用的浏览器,包含了流浪器相关的信息。
window.navigator.appName #web浏览器全称 window 可以省略 "Netscape" window.navigator.appVersion "5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 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" """ 扩展:防爬措施 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配置即可 """ window.navigator.platform #浏览器运行所在的操作 2 系统 "MacIntel" # 如果是window的子对象 那么window可以省略不写
History对象
window.history对象包含浏览器的历史
浏览器对象,包含了用户对当前页面的浏览历史,但我们无法查看的地址,可以简单的用来前进和后退一个页面
window.history.back() 回退到上一页 window.history.forward() 前进到下一页 # 对应的就是你浏览器左上方的两个的箭头
location对象(重要)
window.location对象用于获得当前页面的地址(url),并且把浏览器重定向到新的页面
location是最有用的BOM对象之一,他提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能;location即是window子对象也是document子对象。
window.location.href # 获取当前页面的url window.location.href = url # 跳转到指定的url window.location.reload() # 属性页面 浏览器左上方的小圆圈
三种弹出框
弹出框都是window对象下面的方法:
1、警告框
#警告框 警告框用于确保用户可以得到某些信息 当警告框出现后,用户需要点击确定按钮后才能继续进行操作 语法: alert('你不要过来啊!!!') undefined
2、确认框
#确认框 确认框用于使用户可以验证或者接受某些信息。 当确认框出现后,用户需要点击确定或者取消按钮才能继续进行操作。 如果用户点击确认,那么返回值为 true。如果用户点击取消,那么返回值为 false。 语法: confirm('你确定真的要这么做吗?能不能有其他方式能够满足你...') false #点击取消结果显示 confirm('你确定真的要这么做吗?能不能有其他方式能够满足你...') true #点击确定结果显示
3、提示框
#提示框 提示框经常用于提示用户在进入页面前输入某个值。 当提示框出现后,用户需要输入某个值,然后点击确认或取消按钮才能继续操纵。 如果用户点击确认,那么返回值为输入的值。如果用户点击取消,那么返回值为 null。 语法: prompt('1111','2222') #'2222'为默认值,可以修改 "3333" #此处为输入内容
计时器相关
window对象下面的方法,提供计时相关的功能。
三个有用的方法:setTimeout()、setInterval()、clearInterval()
- setTimeout()表示等待多长时间之后,触发一个函数的执行,仅仅执行一次;setTimeout接收两个参数,一个是要执行的函数名,一个是定时的时间(单位毫秒)
- setInterval()表示每隔一段时间执行一次;同样它也接受两个参数,第一个是函数名,第二个时间间隔
- clearInterval()表示清楚计时器,接收一个参数,计时器对象
通过使用JavaScript,我们可以在一定时间间隔之后来执行代码,而不是在函数被调用后立即执行,我们称之为计时事件。主要分为两种情况:
1、过一段时间之后触发(一次)
#语法: let t=setTimeout('js语句',毫秒) setTimeout() 方法会返回某个值。在上面的语句中,值被储存在名为 t 的变量中。假如你希望取消这个 setTimeout(),你可以使用这个变量名来指定它。
2、每隔一段时间触发一次(循环)
#语法: let t=setInterval('js语句',时间间隔) setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
eg:练习
<script> function func1() { alert(123) } let t = setTimeout(func1, 3000); clearTimeout(t) // 取消事件 ,还没来得及执行就被取消啦。 function func2() { alert(123) } function show(){ let t = setInterval(func2, 3000); // 每隔3秒执行一次 function inner(){ clearInterval(t) // 清除定时器 } setTimeout(inner, 9000) // 9秒之后触发 } show() </script>
DOM操作
DOM(Document Object Model) 是一套对文档的内容进行抽象和概念的方法
当网页被加载时,浏览器会创建页面的文档对象模型 DOM。
HTML DOM模型被构造成对象的树。在这个树中,所有的标签都可以称之为节点。
#DOM树的概念 #所有的标签都可以称之为是节点 文档节点(document对象):代表整个文档 元素节点(element对象):代表一个元素(标签) 文本节点(text对象):代表元素(标签)中的文本 属性节点(attrbute对象):代表一个属性,元素(标签)才有属性 注释是注释节点(comment对象) #JavaScript 可以通过DOM创建动态的HTML: JavaScript 能够改变页面中的所有 HTML 元素 JavaScript 能够改变页面中的所有 HTML 属性 JavaScript 能够改变页面中的所有 CSS 样式 JavaScript 能够对页面中的所有事件做出反应
DOM操作操作的是标签 而一个html页面上的标签有很多
1、先学如何查找标签
2、再学DOM操作标签
3、DOM操作需要使用关键字document关键字打头
查找标签
直接查找(掌握)
""" id查找 类查找 标签查找 """ # 注意三个方法的返回值是不一样的 document.getElementById('d1') #根据ID 获取一个标签 <div id="d1">…</div> #拿到的是 id=1的div标签 document.getElementsByClassName('c1') #根据 class属性获取的是数组[] HTMLCollection [p.c1]0: p.c1length: 1__proto__: HTMLCollection document.getElementsByClassName('c1')[0] #可以通过数组索引拿到具体的标签 <p class="c1">…</p> document.getElementsByTagName('div') #拿到所有div标签,用数组表示 HTMLCollection(3) [div#d1, div, div, d1: div#d1] let divEle = document.getElementsByTagName('div')[1] #根据索引拿到具体的 div 标签 divEle <div>div>div</div> """ 当你用变量名指代标签对象的时候 一般情况下都推荐你书写成如下: xxxEle divEle aEle pEle """
间接查找
通过标签的层级关系查找
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 # 所拿的父节点如果没有,返回null <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>
节点操作
1、创建节点
var divEle = document.createElement("div");
2、添加节点
追加一个子节点(作为最后的子节点):somenode.appendChild(newnode);
把增加的节点放到某个节点的前边:somenode.insertBefore(newnode,某个节点);
eg:动态创建一个标签
var imgEle=document.createElement("img"); imgEle.setAttribute("src", "http://image11.m1905.cn/uploadfile/s2010/0205/20100205083613178.jpg"); var d1Ele = document.getElementById("d1"); d1Ele.appendChild(imgEle);
3、删除节点
获得要删除的元素,通过父元素调用该方法删除
somenode.removeChild(要删除的节点)
4、替换节点
somenode.replace(newnode,某个节点)
5、属性节点
获取文本节点的值:
var divEle = document.getElementById("d1") divEle.innerText divEle.innerHTML #两者获取的值一样
设置文本节点的值:
var divEle = document.getElementById("d1") divEle.innerText="1" #不识别html标签 divEle.innerHTML="<p>2</p>" #识别html标签
属性操作
setAttribute() 设置属性 getAttribute() 获取属性 removeAttribute() 移除属性 var divEle = document.getElementById("d1"); divEle.setAttribute("age","18") divEle.getAttribute("age") divEle.removeAttribute("age") // 自带的属性还可以直接.属性名来获取和设置 imgEle.src imgEle.src="..."
eg:案例练习
""" 通过DOM操作动态的创建img标签 并且给标签加属性 最后将标签添加到文本中 """ #img 标签 #1、创建标签 let imgEle = document.createElement('标签名:img') # 创建标签 #2、给标签添加默认属性 imgEle.src = '111.png' # 给标签设置默认的属性 "111.png" #3、添加自定义属性 imgEle.username = 'jason' # 自定义的属性没办法点的方式直接设置 "jason" imgEle <img src="111.png"> #没有username属性 #正确添加自定义属性 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标签 设置属性 设置文本 添加到标签内部 添加到指定的标签的上面 """ #a 标签 #1、创建标签 let aEle = document.createElement('a') aEle <a></a> #2.添加默认属性 aEle.href = 'https://www.mzitu.com/' "https://www.mzitu.com/" aEle <a href="https://www.mzitu.com/"></a> #3、给标签设置文本内容 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> # innerText与innerHTML divEle.innerText # 获取标签内部所有的文本 "div 点我有你好看! div>p div>span" divEle.innerHTML # 内部文本和标签都拿到 "div <a href="https://www.mzitu.com/">点我有你好看!</a><p id="d2">div>p</p> <span>div>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>"
获取值操作
标签内部的数据
<!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> <input type="text" id="d1"> <input type="file" id="d3"> <select name="" id="d2"> <option value="111">哈哈</option> <option value="222">嘿嘿</option> <option value="333">么么</option> </select> </body> </html>
console调试
# 获取用户数据标签内部的数据 let selEle = document.getElementById('d2') sllEle.value "111" selEle.value "333" let inputEle = document.getElementById('d1') inputEle.value #拿到的是用户输入内容
上传文件的数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <body> <input type="file" name="" id="d1"> </body> </html>
console调试
let fileEle = document.getElementById('d3') fileEle.value # 无法获取到文件数据,拿到的仅仅是路径 "C:fakepath 2_测试路由.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, …}
class操作
classLsit 获取所有样式类名(字符串)
.classList.remove(cls) 删除指定类
classList.add(cls) 添加类
classList.contains(cls) 存在返回true,否则返回false
classList.toggle(cls) 存在就删除,否则添加
案例:开关灯案例初始模型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .c1 { height: 400px; 400px; border-radius: 50%; } .bg_green { background-color: greenyellow; } .bg_red { background-color: red; } </style> </head> <body> <div id="d1" class="c1 bg_red bg_green"></div> <p>哈哈哈</p> </body> </html>
ps:运行上面html代码,页面显示圆圈颜色是红色
console调试:
let divEle = document.getElementById('d1') undefined divEle.classList # 获取标签所有的类属性名 DOMTokenList(3) ["c1", "bg_red", "bg_green", value: "c1 bg_red bg_green"] divEle.classList.remove('bg_red') # 移除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,无则添加,结果返回ture false #此时存在,所以删除,结果返回false divEle.classList.toggle('bg_red') true #此时不存在,所以添加,结果返回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
CSS操作
# DOM操作操作标签样式 统一先用style起手 let pEle = document.getElementsByTagName('p')[0] #拿到第一个p标签 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"
ps:在js中,所有CSS样式名都是以驼峰式命名规范:
在CSS中:background-color====>在js中:backgroundColor
在CSS中:font-size======>在js中:fontSzie
事件
HTML4.0的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript。
1、script标签放在body内
""" 达到某个事先设定的条件 自动触发的动作 """ # 绑定事件的两种方式 <body> <button id="d1">点我1</button> <button onclick="func1()">点我2</button> <!--当点击按钮时会触发 func1()函数--> <script> //第一种绑定方式 let buttELe = document.getElementById('d1'); buttELe.onclick=function () { alert('这是第一种绑定方式') }; //第二种绑定方式 function func1() { alert('这是第二种绑定方式') } </script> </body> </html> """ script标签既可以放在head内 也可以放在body内 但是通常情况下都是放在body内的最底部 若script代码放在head里时,会报错,因为 html 代码也是顺序执行,当加载 script 时此时 let btnEle = document.getElementById('d1'); #d1 是找不到的,所以会报错,因此我们需要等待器窗口加载完毕 body 程序之后才能执行 script代码 # 等待浏览器窗口加载完毕之后再执行代码 window.onload = function () { // 第一种绑定事件的方式 function func1() { alert(111) } // 第二种 let btnEle = document.getElementById('d1'); btnEle.onclick = function () { alert(222) } } """
2、script放在head内
若script代码放在head里时,会报错,因为html代码也是顺序执行,当加载head时,此时let btnEle = document.getElementById('d1');d1是找不到该元素的,所以会报错,因此我们需要等待器窗口加载完毕 文档body内容加载之后才能执行script代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> //等待浏览器窗口加载完毕之后再执行代码,即body内容加载完毕后再执行 window.onload = function () { //第一种绑定方式 let buttELe = document.getElementById('d1'); buttELe.onclick=function () { alert('这是第一种绑定方式') } }; //第二种绑定方式 function func1() { alert('这是第二种绑定方式') } </script> </head> <body> <button id="d1">点我1</button> <button onclick="func1()">点我2</button> <!--当点击按钮时会触发 func1()函数--> </body> </html>
script标签既可以放在head内 也可以放在body内,但是通常情况下都是放在body内的最底部。
常用事件
onclick 当用户点击某个对象时调用的事件句柄。 ondblclick 当用户双击某个对象时调用的事件句柄。 onfocus 元素获得焦点。 // 练习:输入框 onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证. onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(select联动) onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交. onkeypress 某个键盘按键被按下并松开。 onkeyup 某个键盘按键被松开。 onload 一张页面或一幅图像完成加载。 onmousedown 鼠标按钮被按下。 onmousemove 鼠标被移动。 onmouseout 鼠标从某元素移开。 onmouseover 鼠标移到某元素之上。 onselect 在文本框中的文本被选中时发生。 onsubmit 确认按钮被点击,使用的对象是form。
具体案例
案例一:onclick事件(开关灯)
<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 () { // 绑定点击事件 divEle.classList.toggle('bg_red') // 动态的修改div标签的类属性 } </script>
案列二:onfocus事件和onblur事件
<input type="text" value="老板 去吗?" id="d1"> <script> let iEle = document.getElementById('d1') iEle.onfocus = function () { // 获取焦点事件 iEle.value = '' // 将input框内部值清空 } iEle.onblur = function () { // 失去焦点事件 iEle.value = '没钱 不去!' // 给input标签重写赋值 } </script>
案例三:onchange事件(省市联动)
<select id="d1" name="pro"> <option disabled selected value="">--请选择--</option> </select> <select id="d2" name="city"> <option disabled selected value="">--请选择--</option> </select> <script> let proEle = document.getElementById('d1'); let cityEle = document.getElementById('d2'); data = { "河北": ["廊坊", "邯郸",'唐山'], "北京": ["朝阳区", "海淀区",'昌平区'], "山东": ["威海市", "烟台市",'临沂市'], '上海': ['浦东新区','静安区','黄浦区'], '深圳': ['南山区','宝安区','福田区'] }; // 选for循环获取省 for(let key in data){ // 将省信息做成一个个option标签 添加到第一个select框中 let opEle = document.createElement('option'); opEle.innerText = key; opEle.value = key; proEle.appendChild(opEle) } // 文本域变化事件, onchange事件,获取该省下的市列表并循环添加到select的option里 proEle.onchange = function () { let currentPro = proEle.value; let currentCityList = data[currentPro]; cityEle.innerHTML = '<option disabled selected>请选择</option>'; // for循环所有的市 渲染到第二个select中的option里 for (let i=0; i<currentCityList.length; i++){ let currentCity = currentCityList[i]; let opEle = document.createElement('option'); opEle.innerText = currentCity; opEle.value = currentCity; cityEle.appendChild(opEle) } } </script>