1、JavaScript概述:
什么是:简称js,是一个运行在【js解释器】中的一个【解释型】【弱类型】【面向对象】脚本语言
1、js解释器:
运行程序之前,不需要检查程序是否有报错,直接运行,碰到错误了才会停止,比如:JavaScript、 php... - 自由
1、浏览器自带js解释器
2、以后我们确实也会自己安装一个js解释器 - Node.js
2、编译型:在运行程序之前,需要先检查程序是否有报错,如果有报错直接不运行,比如:java、c#、c++... - 严格
解释型:在解释型:在运行程序之前,不需要检查程序是否有报错,直接运行,碰到错误了才会停止,比如:JavaScript、php... - 自由 3、弱类型:变量想保存什么数据类型就保存什么数据类型,由数据决定了数据类型是什么,比如: javascript、php... - 自由
强类型:变量能保存什么数据类型,需要提前声明出来,由数据类型来决定了能保存的数据是什么,比如:java... - 严格
2、JavaScript特点:
1、用任何文本编辑器编写代码:HBuilder、VSCode、记事本开发都可以...
2、解释型
3、弱类型
4、面向对象:以后我们会经常见到带有一种写法:万物皆对象
对象名.属性名;
对象名.方法名();
3 、JavaScript如何使用:
1、js的引入方式有2种:
1、在HTML中书写一个script标签: - 仅用于临时测试
<script>
js代码
</script>
2、创建一个xx.js文件,再在HTML进行引入 - 正式开发中
如何引入:<script src="xx.js">//不能在这里书写js代码了</script>
建议js放在我们的HTML和CSS的后面,最好是最后
2、打桩输出:疯狂打桩:非常重要的一种找错方式:3种
*1、在控制台输出日志:console.log(想要输出的内容);
2、在页面上输出:document.write(想要输出的内容); - 可以识别标签,缺点:如果有点击事件触发document.write会导致页面原来的HTML全被覆盖掉,那你写的网页白写了
3、用警告框输出:alert(想要输出的内容); - 缺点:会卡主页面,只能看到白板
1、JavaScript概述:
什么是:简称js,是一个运行在【js解释器】中的一个【解释型】【弱类型】【面向对象】脚本语言
1、js解释器:
1、浏览器自带js解释器
2、以后我们确实也会自己安装一个js解释器 - Node.js
2、编译型:在运行程序之前,需要先检查程序是否有报错,如果有报错直接不运行,比如:java、c#、c++... - 严格
解释型:在运行程序之前,不需要检查程序是否有报错,直接运行,碰到错误了才会停止,比如:JavaScript、php... - 自由
3、弱类型:变量想保存什么数据类型就保存什么数据类型,由数据决定了数据类型是什么,比如:javascript、php... - 自由
强类型:变量能保存什么数据类型,需要提前声明出来,由数据类型来决定了能保存的数据是什么,比如:java... - 严格
2、JavaScript特点:
1、用任何文本编辑器编写代码:HBuilder、VSCode、记事本开发都可以...
2、解释型
3、弱类型
4、面向对象:以后我们会经常见到带有一种写法:万物皆对象
对象名.属性名;
对象名.方法名();
3、JavaScript如何使用:
1、js的引入方式有2种:
1、在HTML中书写一个script标签: - 仅用于临时测试
2、创建一个xx.js文件,再在HTML进行引入 - 正式开发中
如何引入:<script src="xx.js">//不能在这里书写js代码了</script>
建议js放在我们的HTML和CSS的后面,最好是最后
2、打桩输出:疯狂打桩:非常重要的一种找错方式:3种
*1、在控制台输出日志:console.log(想要输出的内容);
2、在页面上输出:document.write(想要输出的内容); - 可以识别标签,缺点:如果有点击事件触发document.write会导致页面原来的HTML全被覆盖掉,那你写的网页白写了
3、用警告框输出:alert(想要输出的内容); - 缺点:会卡主页面,只能看到白板
4.25
1、***数据类型的转换:【一切的页面上获取来的数据类型都是字符串】
JavaScript是一个弱类型的语言
有数据 决定了 我们的数据类型是什么
1 number
"1" string
number + number = number
string + number = string
查看数据库类型:typeof(想要检查的变量);
1、*隐式转换:悄悄地我们程序员看不见的转换
算术运算符具有隐式转换:
作用:我们如果精通了隐式转换,我根本不需要console.log我也知道最后的结果是什么
默认:都是转为数字,在运算
特殊: 1、不管是什么运算,只要没碰上字符串,都会悄悄的转为一个数字
true->1
false->0
undefined->NaN
null->0
2、+运算并且碰上字符串,则为拼接,最后的结果也就还是一个字符串
3、-*/%,就算是字符串也可以转为数字,前提是纯数字组成的字符串,但是如果包含了一个非数字字符,则为NaN
"1000" -> 1000
"100a0" -> NaN
NaN:Not a Number:不是一个数字,但是确实是数字类型,只不过不在三界之内
全是缺点:
1、不在三界之内,不大于,不小于,不等于,任何值,包括自己
2、参与任何算数运算+-*/%,结果仍为NaN
问题:正是因为NaN参与任何比较运算结果都为false,甚至自己都不认识自己,
所以我们没有办法用一个普通的比较运算来判断x是不是NaN
解决:!isNaN(x):此方法不管你放的x是什么都会悄悄的隐式转换为数字
true->说明是一个有效数字
false->说明是一个NaN
目的:防止用户恶意输入,但是目前为止,只能防止用户输入的必须是一个数字(比如验证的话我们做不了:正则学了才能做)
2、显式转换:也叫作强制转换:
何时使用:隐式转换出来的结果不是我们想要的,先强制转换为需要的数据,再运算
如何使用:
1、转为字符串:
var str=xx.toString();//xx不能是undefined和null,undefined和null不能使用.操作
因为一切的页面上获取来的数据类型都是字符串
2、*转为数字:3种
*1、parseInt(x); - parse解析 Int整型:解析为一个整数
执行原理:从左向右,依次读取每个字符,碰到非数字字符就停止,不认识小数点,如果一来就不认识则为NaN
去掉单位
*2、parseFloat(x); - parse解析 Float浮点数:解析为一个小数
执行原理:几乎和parseInt一致,但是认识第一小数点
去掉单位
以上两个方法很重要:但是x只能是数字或者字符串,不能是别的,如果是别的统一的认为是不认识的,不认识的结果就为NaN了
个人感觉,这两个方法是专门用于str to num
3、Number(x); - 万能的,任何人都可以转为数字,垃圾:此方法完全等效于隐式转换
其实隐式转换的底层,就是悄悄地使用了此方法,所以我们绝对不会手动使用
还不如 x-0 /1 *1 %1
2、*****Function:自定义函数:也称之为方法:需要【预定义好】的,可以【反复使用】的一个【代码段】
rotate(45deg) - 完成了一个根据角度值顺时针旋转45度的功能
url(图片路径) - 完成了一个根据图片路径显示图像的功能
...
js中的函数 - 完成了一个。。。。。。的功能
1、创建函数:
function 函数名(){
代码段;//若干操作
}
2、调用函数:
1、直接在js中程序员写几次调用,就会执行几次操作:
函数名();
2、让用户来自己触发:
3、以后何时使用函数:
1、以后任何作业都要封装成一个函数,因为函数的js地位很高,属于第一等公民地位
2、你不希望打开页面立刻执行
3、能够反复执行
4、他是个独立的功能体
5、你不是自己释放内存,函数调用完毕会自动释放内存/变量
4、带参数的函数:
电饭煲 -> 看做是一个函数:功能:把....煮熟
原材料 -> 参数
语法:形参:其实就是一个变量名,只不过不需要写var这个关键字,每个形参之间用,间隔,形式参数,简称形参
function 函数名(形参,...){
函数体;
}
调用:实参:实际参数
函数名(实参,...);
function zwjs(name,age,hobby){
console.log("我的名字叫"+name+",今年"+age+"岁,喜欢"+hobby);
}
zwjs("张三丰",128,"打太极");
zwjs("张无忌",18,"撩妹");
zwjs("张三",28,"说法");
特殊:实参的个数以及顺序 和 形参的个数以及顺序都要一一对应
5、普通函数:操作永远是固定的
带参数的函数:根据传入的实参,执行略微不同的操作
3、***分支结构:
1、代码流程控制语句:
1、顺序结构:默认的,代码从上向下
2、分支结构:根据条件不同,选择部分代码执行
3、循环结构:根据条件满不满足,考虑要不要再执行一次相同 或 相似代码
2、关系/比较运算符:> < >= <= == !=
结果:一定都是一个布尔值
注意:==才叫比较 =叫赋值:右边的东西放到了左边保存起来
3、逻辑运算符:
&&:与(并且):全部条件都满足,结果为true
只要有一个条件不满足,结果为false
||:或:全部条件都不满足,结果为false
只要有一个条件满足,结果为true
!:颠倒布尔值
4、分支的语法:
1、一个条件一件事,满足就做,不满足就不做
if(条件){
操作
}
2、一个条件两件事,满足就做第一件,不满足就做第二件
if(条件){
操作;
}else{
默认操作;
}
3、多个条件多件事:满足谁就做谁
if(条件1){
操作1;
}else if(条件2){
操作2;
}else if(条件3){
操作3;
}else{
默认操作;
}
else可以省略,但是不推荐
4.26
1、***循环结构
问题:在控制台打印输出10000句hello world
console.log("1hello world");
...
console.log("1000hello world");
解决:循环结构:反复执行相同 或 相似的代码
生活中的循环:
吃饭
睡觉
做作业
上课
上班
活着
循环三要素:
1、循环条件:从哪里开始,到哪里结束
2、循环体:操作-要做什么事
3、循环变量、变量还要变化
1、while循环:其实循环从宏观上看是一起执行的,但是微观上看是一次一次执行的,只不过这个执行速度很快
语法:
var 循环变量=几;
while(循环条件){
循环体;
循环变量变化;
}
执行原理:先判断循环条件满足吗,如果为true,则执行循环体一次,再一次判断循环条件满足吗,如果为true,则再执行循环体一次
.......直到循环条件不满足,才会退出循环
特殊:
死循环:永远不会结束的循环,但是还真用:往往不确定循环次数的时候就要使用
while(true){
循环体;
}
往往死循环还要搭配上,退出循环语句:break; - 只能写在循环里面
2、***for循环:执行原理跟while一模一样,只是语法更加的简洁
for(循环变量的创建;循环条件;变量的变化){
循环体;
}
特殊:1、循环变量的创建和循环变量的变化,其实可以写多个
2、死循环:for(;;){操作}
总结:1、while:语法更加繁琐,建议只用于不确定循环次数的时候 - 死循环
2、for:语法更加简洁,建议只用于确定循环次数的时候 - 大部分情况
问题:函数 和 循环 都是可以反复执行的,区别在哪里?
函数 - 要么程序员调用几次,执行几次,或者,用户来触发几次,执行几次
循环 - 程序员写好的,而且几乎是一瞬间就执行完毕了的
2、*****数组:
问题:保存1000个同学的姓名:
var name1="周洁";
var name2="周杰";
var name3="周杰伦";
...
以上写不合理:变量就是一个内存,我们开辟的内存空间太多的话,会影响网页效率
希望,一个变量名,就可以保存住所有的数据 - 数组:
数组里面的元素,是按照线性顺序排列的,除了第一个元素,每个元素都有一个唯一的前驱元素
除了最后一个元素,每个元素都有一个唯一的后继元素
*每个元素都有一个唯一的位置序号,称之为【下标】:从0开始,到最大长度-1
1、创建数组:2种
1、*直接量方式:var arr=[];//空数组
var arr=[元素,...];
2、构造函数方式:var arr=new Array();//空数组 - 个人不推荐,更麻烦,其实直接量方式是ES2过后才添加上的,原来只有构造函数方式
var arr=new Array(元素,...);
2、访问/获取:获取出数组中的某个元素
数组名[下标]
3、添加/覆盖:
数组名[下标]=新元素;
特殊:
1、下标处没有元素,则为添加
2、下标处有元素,则为覆盖/替换
4、数组的三大不限制:
1、不限制元素的类型
2、不限制元素的个数
3、不限制下标越界 - 算是一个缺点:
获取时 - 下标越界,返回undefined
添加时 - 下标越界,会变成稀疏数组,导致下标不连续,不好
5、数组有一个唯一的属性:数组名.length; - 获取到数组的长度
***三个固定套路:
1、向末尾添加元素:arr[arr.length]=新元素;
2、获取倒数第n个元素:arr[arr.length-n];
3、缩容:删除末尾n个元素:arr.length-=n;
6、其实经常我们不会去拿出数组中的某一个来做操作,往往是拿出所有的东西来做操作
遍历数组:将数组中的每一个元素取出来执行 相同 或 相似的操作;
公式:
for(var i=0;i<arr.length;i++){
arr[i];//当前次元素
}
4.27
1、为什么我们前三天的内容感觉和网页没啥关系?
javascript其实一共由3部分组成:
1、ECMAScript - 简称ES3/5/6,核心语法 - 内功心法(逻辑部分)
2、Document Object Model - 简称DOM,文档对象模型 - 外功招式(专门用于操作网页文档HTML+CSS的)
3、Browser Object Model - 简称BOM,浏览器对象模型 - 外功招式(专门用于操作浏览器的)
2、DOM树:DOM将HTML看做了是一个倒挂的树状结构,但是树根不是你们理解的HTML标签
*树根:是一个document对象,document对象不需要我们程序员创建,由浏览器的JS解释器创建,一个页面只有一个document
作用:提供了一些属性和方法,可以让我们程序员去操作整个DOM树(增删改查每一个DOM节点)
DOM节点:一个标签、文本、属性、元素
3、查找元素:
1、通过HTML的特点去查找元素
1、id查找:var elem=document.getElementById("id值");
在当前DOM树中,根据元素的id,获取具体的DOM节点
返回:找到了,返回对应的元素
没找到,null
特殊:1、如果页面上有多个重复的id,只会返回第一个
2、此方法找到的是单个元素 - DOM节点是可直接用于做操作的
2、此方法你不能使用 - 以后留给后端工程师使用
*2、标签名查找:var elems=document/已经找到的父元素.getElementsByTagName("标签名");
在当前DOM树中,根据标签名获取元素们
返回:找到了,返回一个DOM集合
没找到,空数组
特殊:1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部
2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素
*3、class查找:var elems=document/已经找到的父元素.getElementsByClassName("标签名");
在当前DOM树中,根据标签名获取元素们
返回:找到了,返回一个DOM集合
没找到,空数组
特殊:1、返回的不是一个DOM节点,而是一个DOM集合,是不能直接用来做操作的,要么使用下标拿到某一个,要么使用遍历拿到全部
2、不一定非要从树根开始查找元素,也可以写一个你已经找到的某个父元素
2、节点之间的关系进行查找:前提:必须先要找到一个人,才能使用关系
父:elem.parentNode;//单个元素
子:elem.children;//集合
第一个儿子:elem.firstElementChild;//单个元素
最后一个儿子:elem.lastElementChild;//单个元素
前一个兄弟:elem.previousElementSibling;//单个元素
后一个兄弟:elem.nextElementSibling;//单个元素
4、操作元素:<标签名 属性名="属性值" style="样式">内容</标签名>
1、内容:
*1、innerHTML属性:获取 或 设置 某个元素的内容,并且可以识别标签
获取内容:elem.innerHTML;
设置内容:elem.innerHTML="新内容";
2、innerText属性:获取 或 设置 某个元素的文本,不能可以识别标签
获取内容:elem.innerText;
设置内容:elem.innerText="新内容";
以上两个属性,是为双标签准备的
3、value属性:专门为单标签(input)操作内容准备的
获取内容:input.value;
设置内容:input.value="新内容";
2、属性:什么是属性:HTML属性:id、class、title、alt、style、type、href...只要是放在HTML标签上的都是一个属性
1、获取属性值:elem.getAttribute("属性名");
2、设置属性值:elem.setAttribute("属性名","属性值");
以上两个方法有点繁琐 - 但是无敌的
能够简化:
1、获取:elem.属性名;
2、设置:elem.属性名="属性值";
缺陷:1、不能操作自定义属性,只能操作标准属性
2、class在ES6升级为了一个关键字,所以想要写class换为了className
3、样式:
1、css定义的方式:3种
1、内联样式 - 二阶段
2、内部样式表
3、外部样式表 - 最适合写样式的时候使用此方法
2、JS操作内联样式的好处:
1、优先级最高,写的JS样式必定生效
2、一次只会操作一个元素,不会牵一发动全身
3、语法:
获取:elem.style.css属性名;
设置:elem.style.css属性名="css属性值";
特殊:1、css属性名,要把有横线地方,换成小驼峰命名法
2、获取的时候,代老湿只交了大家获取内联样式,不能获取样式表中的样式
4、元素绑定事件:
单个元素:elem.onclick=function(){
操作;
this->单个元素绑定事件,this->elem绑定事件的这个元素
}
多个元素:for(var i=0;i<elems.length;i++){
elems[i].onclick=function(){
操作
this->多个元素绑定事件,this->当前触发事件的元素
}
}
***总结:
1、一切的获取都是为了判断
2、一切的设置都是为了修改
3、千万不要对着一个集合做操作,要么遍历拿全部,要么下标拿一个
作业:
1、开关门效果
2、表格隔行变色,奇数次点击,奇数行变色,偶数次点击,偶数行变色
3、选项卡效果
4、购物车 - 回来在教你们封装版
5、写博客 - 回忆这一周你学了什么,推荐:掘金、csdn、简书、知乎...
规则:1、不要看笔记,凭着心里记得的东西写
2、写完过后,在对应笔记进行补充
每天来了作业就发给班长,收完,打包,发送我
4.28
0、输出方式:
1、在控制台输出:console.log();
2、在页面上输出:document.write();//绑定事件函数里面写了document.write()把页面上原来的HTML全部替换
3、在警告看输出:alert();//卡主整个页面
1、变量和常量
var 变量名=值;
const 常量名=值;
2、算术运算符:+ - * / %
特殊:%:模,取余
3、数据类型:
原始类型:5个,Number、String、Boolean、Undefined、Null
引用类型:11个,Array、Function
4、数据类型转换:
隐式转换:
算术运算符具有隐式转换:
默认,转为数字,在运算
true->1
false->0
undefined->NaN
null->0
特殊:1、+运算碰上了字符串,则变为拼接
2、-*/%:字符串也能转为数字,纯数字组成的才行,包含非数字字符,则为NaN
"1000"->1000
"100x0"->NaN
NaN:不是一个数字,但是确实是数字类型
缺点:
1、参与任何算术运算结果仍为NaN
2、参与任何比较运算结果都为NaN - 无法使用普通的比较运算判断x是不是NaN
解决:!isNaN(x)
强制转换:
转字符串:xx.toString();//页面上一切的数据都是字符串,所以此方法几乎很少使用
//undefined和null不能使用,因为他们不能使用.操作
转数字:3个
parseInt/Float(str);//从左向右依次读取每个字符,碰到非数字字符就停止,Int不认识小数点,Float认识第一个小数点
Number(x);//完全等效于隐式转换,不会手动使用,还不如*1 /1 -0
5、Function:需要提前创建好的,以后可以反复使用的代码段 - 时机:要么程序员调用几次就执行几次,要么用户触发几次就执行几次
何时:1、不希望打开页面立刻执行
2、希望可以反复执行
3、独立的功能体 - 每一个作业(轮播、选项卡、购物车、正则验证、数据渲染...)
如何:
1、创建函数
function 函数名(形参,...){
函数体;
}
2、调用函数
函数名(实参,...);
要不要带参数的函数具体看你自己:
如果函数体是固定的,则不用
如果函数体需要根据实参的不同,进行略微不同的操作,则需要带参数的函数
6、分支结构:
比较运算符:> < >= <= == !=
逻辑运算符:
&&:全部满足,才满足
一个不满足,则不满足
||:全部不满足,才不满足
一个满足,则满足
!:颠倒布尔值
以上的所有的运算符结果都是布尔值
if(){}
if(){}else{}
if(){}else if(){}else{}
7、循环:反复执行 相同 或 相似的代码 - 时机:程序员写好的,而且几乎就一瞬间做完了,其实一次一次执行的,只不过速度很快
var 变量=几
while(条件){
操作;
变量变化
}
for(var 变量=几;条件;变量变化){
操作
}
死循环:while(true){} for(;;){}
退出循环:break;
8、数组:一个内存空间,可以保存多个数据
如何:
1、创建:
var arr=[];
var arr=new Array();
2、访问:arr[i]; - 下标越界:undefined
3、添加:arr[i]=新值; - 下标越界:稀疏数组,下标不连续,遍历的时候就会得到很多很多的undefined
4、arr.length:获取数组的长度
三个固定套路:
末尾添加:arr[arr.length]=新值;
获取末尾第n个元素:arr[arr.length-n];
缩容:arr.length-=n;
5、数组三大不限制:类型、长度、下标越界(缺点)
6、遍历数组:
for(var i=0;i<arr.length;i++){
arr[i];//当前元素
}
ECMAScript - 核心语法
DOM:Document Object Model - 文档对象模型,专门用于操作文档(HTML)
DOM树:DOM将HTML看做了是一个倒挂的树状结构,树根:document对象,不需要创建
DOM将每一个【元素】、文本、属性、注释,都看为是一个DOM节点/元素/对象
树根作用:找到任何元素,找到元素后就可以操作元素
1、查找元素:
1、通过 HTML 特性:
id:单个元素 - 没找到返回null
标签/class名:var elems=document/parent.getElementsByTag/ClassName("标签/class名");
特殊:1、DOM集合 - 不允许直接做操作的,要么加下标拿到某个,要么加遍历拿到所有
2、parent:你之前已经找到的某个父元素
3、没找到:[]
2、通过 关系:至少要找到一个人,才能使用关系网
父元素:elem.parentNode;
子元素:elem.children; - 集合
第一个儿子:elem.firstElementChild;
最后一个儿子:elem.lastElementChild;
前一个兄弟:elem.previousElementSibling;
后一个兄弟:elem.nextElementSibling;
2、操作元素:
1、内容:innerHTML(能识别标签)/innerText(纯文本)/value(专门为input准备的)
获取:elem.xxxx
设置:elem.xxxx="新内容"
2、属性:
获取属性值:elem.getAttribute("属性名") -> elem.属性名
设置属性值:elem.setAttribute("属性名","属性值") -> elem.属性名="属性值"
简化版有缺陷:
1、class写为className
2、自定义属性不能操作到
3、样式:内联样式
获取:elem.style.css属性名
设置:elem.style.css属性名="css属性值";
特殊:1、css属性名有横线去掉横线变成小驼峰命名法
2、只能访问内联
3、绑定事件:
单个元素:elem.onclick=function(){}
多个元素:for(var i=0;i<elems.length;i++){
elems[i].onclick=function(){}
}
this关键字:目前只能在【事件】中使用
单个元素绑定事件this->这个元素:绑定事件的这个元素
多个元素绑定事件this->当前元素:当前触发事件的元素
4.29
1、***数据类型转换
1、强制转换:3类
1、转字符串:
1、x.toString();//x不能是undefined和null - undefined和null不能.
2、String(x);//万能的,任何人都可以转为字符串,不重要
不重要的原因:
1、页面上一切的数据都是字符串
2、String(); 完全相当于隐式转换 - 还不如+""
2、*转数字:
1、*parseInt/Float(str);//专门为字符串转数字准备的
原理:从左向右依次读取每个字符,碰到非数字字符就停止,如果一来就不认则为NaN,
Int不认识小数点,Float认识第一个小数点
2、Number(x);//万能的,任何人都可以转为数字,不重要 - 完全相当于隐式转换 - 还不如-0 *1 /1
3、转布尔:
Boolean(x);//万能的,任何人都可以转为布尔,不会手动使用的,还不如:!!x
***只有6个会为false:0,"",undefined,null,NaN,false,其余都为true
在分支、循环的条件之中,以后不管代老师写的是什么,他都会悄悄的隐式转换为布尔值,你只需要考虑为true还是为false
2、隐式转换:都是出现在运算符之中
2、****运算符和表达式:
1、*算术运算符:+ - * / %
特殊:1、%:取余,判断奇偶性
2、隐式转换:默认转为数字,在运算
true->1
false->0
undefined->NaN
null->0
特殊:1、+运算,碰到字符串,拼接
2、-*/%:字符串可以转为数字,但是纯数字组成才行,但凡包含一个非数字字符,则为NaN
2、*比较运算符:> < >= <= == != === !==
结果:布尔值
隐式转换:默认,转为数字,再比较大小
特殊:1、如果参与比较的左右两边都是字符串,则是按位PK每个字符的十六进制unicode号(十进制ascii码)
0-9<A-Z<a-z<汉字:常识:汉字的第一个字:一:unicode:4E00 - ascii:19968
最后一个字:龥:unicode:9FA5 - ascii:40869
2、NaN参与任何比较运算结果都是false,所以没有办法用普通的比较运算判断是不是NaN
!isNaN(x);
3、undefined==null;//true
区分:undefined===null;
=== !==:不带隐式转换的等值比较和不等比较,要求数值相同,并且数据类型也要相同
function String(x){
if(x===undefined){
return "undefined";
}else if(x===null){
return "null";
}else{
return x.toString();
}
}
3、*逻辑运算:
&&:全部满足,才true
一个不满足,则false
||:全部不满足,才false
一个不满足,则true
!:颠倒布尔值
特殊:短路逻辑:如果前一个条件,已经能够得出最后结论了,则不看后续
&&短路:如果前一个条件满足,才执行后续操作,如果前一个条件不满足,则不管后续操作
目的:简化【简单的】分支:1、一个条件一件事满足就做,不满足就不做 if(){} 2、操作只能有一句话
条件&&(操作);
举例:原来:if(money>=500){money*=0.8};
现在:money>=500&&(money*=0.8);
||短路:浏览器兼容:二选一操作
e=e||window.event;
4、位运算:
左移:m<<n,读作m左移了n位,翻译:m*2的n次方
右移:m>>n,读作m右移了n位,翻译:m/2的n次方
缺点:底数只能2
5、赋值运算:+= -= *= /= %=
一个操作两件事,先计算,在赋值回去。
i++;//递增:每次只会固定+1
i+=1;//累加:每次+几由我们程序员自己决定
i++ === i+=1 === i=i+1;
鄙视题:++i和i++的区别:
单独使用,放前放后无所谓,效果一样。
但是如果参与了别的表达式,变量中的值都会+1
前++返回的是加了过后的新值
后++返回的是加了之前的旧值
6、三目运算:简化if...else 简化if...else if...else
语法:
1、条件?操作1:默认操作;
2、条件1?操作1:条件2?操作2:条件3?操作3:默认操作;
特殊:
1、只能简化简单的分支 - 操作只能有一句话
2、默认操作不能省略
总结:
if === &&短路
if else === 三目
if else if else === 三目
5.5
1、*****自定义Function:
什么是函数:需要先定义好,可以反复使用的一个代码段
何时使用:1、不希望打开页面立刻执行 2、以后可以反复使用 3、希望绑定在页面元素之上
如何使用:
1、创建并且调用:2种
1、创建
*1、【声明方式】创建函数
function 函数名(形参,...){
函数体;
return 返回值/结果;
}
2、【直接量方式】创建函数 - 无用
var 函数名=function(形参,...){
函数体;
return 返回值/结果;
}
2、调用
var 接住返回的结果=函数名(实参,...);
//其实return的本意退出函数,但是如果return后跟着一个数据,
//顺便将数据返回到函数作用域的外部,但return只负责返回,不负责保存
//就算省略return,默认也会return undefined;
//具体需不要得到函数的结果,看你自己
2、***作用域:2种
1、全局作用域:全局变量 和 全局函数,在页面的任何一个位置都可以使用
2、函数/局部作用域:局部变量 和 局部函数,在【当前函数调用时内部可用】
*变量的使用规则:优先使用自己的,自己没有找全局,全局没有报错
特殊:缺点:1、千万不要再函数中对着未声明的变量直接赋值 - 全局污染
2、局部可以用全局的,但是全局不能用局部的 - 解决:看上面return
3、***声明提前:
在程序正式执行之前
将var声明的变量(轻)和function声明的函数(重)
都会悄悄集中定义在当前作用域的顶部
但是赋值留在原地
声明方式创建的函数会完整的提前(第一种方式)
直接量方式创建的函数不会完整提前,只有变量部分会提前(第二种方式)
何时使用:永远不会自己使用,垃圾干扰我们判断 - 只会在鄙视中遇到,为什么平时开发根本不可能遇到它?
只要你遵守以下原则:
1、变量名和函数名尽量的不要重复
2、先创建后使用
3、如果鄙视时需要先试用后创建,多半都是在考你声明提前
4、***按值传递:两个变量之间赋值,分两种情况
如果传递的是原始类型的值:
修改一个变量,另一个变量是不会受到影响的,其实是复制了一个【副本】给对方
如果传递的是引用类型的对象:
修改一个变量,另一个变量是会受到影响的,引用类型其实根本没有保存到变量中,仅仅只是保存了一个地址值
两者用的是同一个地址值,所以会相互影响
2、预定义全局函数:前辈们提前定义好的,我们程序员可以直接使用的,在任何位置都可以使用
*parseInt/Float/isNaN/eval... 其实都是预定义全局函数,但是alert/prompt不属于我们现在学的范畴:确实也是全局预定义函数,只不过属于BOM
1、编码和解码
问题:url中不允许出现多字节字符(汉字,utf-8编码格式下,一个汉字占3字节),如果出现会乱码
解决:发送前,前端将多字节字符编码为单字节字符(数字、字母、符号)
发送后,后端将单字节字符在解码为多字节原文
如何:
编码:var 不认识=encodeURIComponent("大梵");
解码:var 原文=decodeURIComponent(不认识);
这个东西没有用,在某一次浏览器更新后,当前就被淘汰了,浏览器自带此功能 - 唯一的用处,现在就是玩了:悄悄话
2、isFinite(num):判断num是不是有效范围 - 垃圾并不能用于判断是不是NaN,因为有三个人会是false
哪些会为false:NaN,Infinity,分母为0
3、***分支结构:根据条件的不同,选择部分代码执行
1、if分支
2、三目&短路
3、switch...case...语法
switch(变量/表达式){
case 值1:
操作1;
case 值2:
操作2;
case 值3:
操作3;
default:
默认操作;
}
特殊:1、不具备隐式转换
2、问题:默认只要一个case满足后,就会将后面所有操作全部做一次
解决:break;
建议:每一个case的操作后都要跟上一个break
有的地方可以不加break:
1、最后一个操作default可以省略break
2、如果中间连续的多个操作,是相同的,也可以省略掉中间部分
面试题:if vs switch
1、switch:缺点:必须要知道最后的结果才能使用,不能做范围判断
优点:执行效率相对较高
2、if : 优点:可以做范围判断
缺点:执行效率相对较慢
建议:代码优化:尽量的将if替换为switch或者三目或短路
5.6
1、***循环结构:宏观几乎是一瞬间执行的,相同 或 相似的 代码
1、*var 循环变量=几;
while(循环条件){
操作;
变量变化;
}
2、do...while循环语法:
var 循环变量=几;
do{
操作;
变量变化;
}while(循环条件)
面试题:while和do...while的区别?
只看第一次,如果大家都满足,则没区别
如果不满足,while一次都不执行,而dowhile至少会执行一次
3、*for(var 循环变量=几;循环条件;变量变化){
操作;
}
4、*退出循环语句:
break - 退出整个循环
continue - 退出本次循环
5、死循环:while(true){} for(;;){}
forEach for in for of - 专门为遍历数组准备的
2、*****数组的基础:
1、什么是数组:一个集合可以保存多个数据
何时使用:多个相关的数据,都要集中的定义在一个集合中
为什么:因为一个好的数据结构,能够极大的提升我们程序员的开发效率
2、创建:2种
1、*直接量方式:var arr=[值1,...];
2、构造函数方式:var arr=new Array(值1,...);
坑:new Array(num); - 懂不起:以为你是创建了一个长度为num的空数组
3、访问:数组名[下标];
添加/修改:数组名[下标]=新值;
特殊:访问时,下标越界 - 返回undefined
添加时,下标越界 - 变为稀疏数组,导致下标不连续,导致以后遍历一定会得到undefined
4、数组三大不限制
1、不限制类型
2、不限制长度
3、不限制下标越界 - 不推荐
5、数组唯一的一个属性:数组名.length - 获取数组的长度
三个固定套路:
1、末尾添加:arr[arr.length]=新值
2、获取倒数第n个:arr[arr.length-n];
3、缩容:arr.length-=n;
6、遍历数组:对数组中的每个元素执行 相同 或 相似的操作
for(var i=0;i<arr.length;i++){
arr[i];//当前次元素
}
7、*如何释放一个引用类型:看清楚此引用类型有几个变量关联着,每个变量都要释放后,才能真正的释放干净
建议:我们的代码都要封装在一个函数中,函数中的一切变量都会自动释放
索引数组:下标都是由数字组成的数组
8、*关联(hash)数组:下标是可以自定义的数组
为什么:索引数组的下标无具体的意义,不便于查找
如何使用:
1、创建:2步
1、创建一个空数组:var arr=[];
2、为数组添加自定义下标并且赋值:arr["自定义下标"]=新值
2、访问:arr["自定义下标"]
3、强调:hash数组length永久失效,永久为0!
问题:hash数组不能使用for遍历,必须使用 for in循环遍历数组,语法:
for(var i in 数组名){
console.log(i);//自动获得当前数组的所有的下标,不需要我们去设置从哪里开始到哪里结束
console.log(arr[i]);//当前次元素
}
牛逼:不光可以遍历hash数组,也可以遍历索引数组:
建议:hash用for in,索引用for
4、*js中一切东西都是对象,万物皆对象,除了undefined和null,【一切对象的底层都是hash数组】
上午练习:
1、循环的do...while和continue试一试
2、尝试一下hash数组的创建和访问和遍历
3、尝试一下join这个方法的两个固定套路
3、*****数组的API:数组的函数,前辈们定义好的,只有数组可以使用:
1、*****arr 转为 str:
1、语法:var str=arr.join("自定义连接符");
作用:
1、鄙视时:给你一个数组,将他无缝拼接在一起:
var arr=["h","e","l","l","o"];
var str=arr.join("");
console.log(str);
2、拼接为页面元素:
//以后从数据库中取出数据
var cities=["-请选择-","北京","南京","西京","东京","重庆"];
//拼接成页面元素后,innerHTML是识别标签的
sel.innerHTML=""+cities.join("")+"";
2、*拼接数组:添加元素的新方式:
语法:var newArr=arr.concat(值1,arr1,...);
特殊:1、此方法不修改原数组,只会返回一个新数组
2、支持传入数组参数,悄悄的将我们传入的数组打散,不会变成二维数组
3、*截取子数组:取出数组中想要的某一部分组成的一个新数组
语法:var subArr=arr.slice(starti,endi);
特殊:1、此方法不修改原数组,只会返回一个新数组
2、含头不含尾
3、第二参数可以省略不写,截取到末尾
4、第一个参数也可以省略不写,如果两个参数都没写,从头截取到尾 - 深拷贝(复制了一份副本)
5、支持负数参数,-1代表倒数第一个
以上的API都不会修改原数组
以下的API都会修改原数组
4、*删除、插入、替换:
删除:var dels=arr.splice(starti,n);//n代表删除的个数
特殊:此方法其实也有返回值,返回的就是你删除的元素组成的一个新数组
插入:arr.splice(starti,0,新值1,....);
特殊:1、没有删除,也有返回值,返回的是一个空数组
2、原starti位置的元素以及后续元素都会向后顺移
3、不建议插入数组,会变得不伦不类
替换:var dels=arr.splice(starti,n,新值1,....);
特殊:删除的个数和插入的个数不必相同
5、反转数组:arr.reverse();
作业:
0、*****从今天开始我们每天都会学习一些API,每个API都要求要熟记熟背
1、二级联动:关键点:
1、必须有二维数组:再次细分分类
2、select的专属事件:onchange -> 只有选中项发生变化
3、select的专属属性:select.selectedIndex -> 获取到当前选中项的下标,但是只有select自带此功能
4、其实事件名其实就是函数名
2、思考题:随便写一个全是数字组成的数组,乱的,排序 ,不准用我没教过的API
3、PPT26页 2、3题
4、创建两个数组,一个arr1数组全部放着国家的名称,另一个arr2数组是一个空数组,页面上有4个按钮:
:把arr1里面所有的东西全部放到arr2中
<<:把arr2里面所有的东西全部放到arr1中
>:把arr1里面的第一个元素放到arr2的末尾
<:把arr2里面的第一个元素放到arr1的末尾
只需要每次点击在控制台输出,让我看到数组的变化即可
5.7
1、*****Array API
1、*****排序:
1、鄙视时:不允许使用数组的API - 冒泡排序:拿着数组中的每一个元素,
让前一个和后一个做比较,如果前一个>后一个,两者应该交换位置:固定公式
var arr=[32,14,43,453,6,58,56,531,5,57];
for(var j=1;j<arr.length;j++){
for(var i=0;i<arr.length-j;i++){
if(arr[i]>arr[i+1]){
var m=arr[i];
arr[i]=arr[i+1];
arr[i+1]=m;
}
}
}
console.log(arr);
2、数组的API:语法:arr.sort();
默认:悄悄的转为字符串,按位PK每个字符的unicode号,默认是按照字符串排序
问题1:希望按照数字升序排序
解决:
arr.sort(function(a,b){
return a-b;
});
原理:1、匿名函数回调,一般都是前辈们规定好的,我们只能学习怎么使用,自动调用,而且有多少对儿就会调用多少次
2、a:后一个数字 b:前一个数字
3、返回结果,如果是正数,说明后一个大
如果是负数,说明前一个大
如果是0,说明一样大
4、而我们的sort方法会根据你返回的正数负数0,来判断要不要交换位置
问题2:希望按照数字降序排列
arr.sort(function(a,b){
return b-a;
});
建议:开发中使用API排序,鄙视可能会碰到冒泡排序
强调:切记前端所有技术中:唯独只有数组可以排序,意味着以后如果网页中有一个排序功能,说明他的底层一定是一个数组
2、栈和队列:
栈:其实就是一个数组,只不过要求只能从一端进出,另一端是封闭的
何时:始终希望使用最新的数据时,现实中很少,代码中也很少
如何:
前进:arr.unshift(新元素,...) - 添加元素的新方式,建议不要添加数组
前出:var first=arr.shift(); - 删除元素的新方式,一次只能删除一个,而且是第一个
后进:arr.push(新元素,...) - 添加元素的新方式,建议不要添加数组
后出:var last=arr.pop(); - 删除元素的新方式,一次只能删除一个,而且是最后一个
队列:其实就是一个数组,只不过要求一端进,另一端出
何时:按照先来后到的顺序
如何:
前进:arr.unshift(新元素,...) - 添加元素的新方式,建议不要添加数组
后出:var last=arr.pop(); - 删除元素的新方式,一次只能删除一个,而且是最后一个
后进:arr.push(新元素,...) - 添加元素的新方式,建议不要添加数组
后出:var last=arr.pop(); - 删除元素的新方式,一次只能删除一个,而且是最后一个
2、二维数组:数组的元素,又引用着另一个数组
何时使用:在一个数组内,希望再次细分每个分类
如何使用
创建:
var arr=[
["杨杰",18,1200],
["周洁",19,1500],
["盛蕾",20,3500]
];
访问:arr[行下标][列下标];
特殊:列下标越界 - 返回undefined
行下标越界 - 报错:行下标越界确实会得到undefined,但是undefined没有资格再加[]
遍历二维数组:必然两层循环,外层循环控制行,内层循环控制列
for(var r=0;r<arr.length;r++){
for(var c=0;c<arr[r].length;c++){
console.log(arr[r][c]);
}
}
总结:ES3提供的数组,我们学习完毕了:
1、数组的基础(创建、访问、添加、length、遍历)
2、数组的API:10个(转字符串、拼接、截取、翻转、删插替、排序、栈和队列)
3、二维数组
3、*****String的概念:
1、什么是字符串:多个字符组成的【只读】字符【数组】:
1、只读:我们下周一要学习的所有的字符串的API,都不会修改原字符串,只会返回一个新字符串
2、数组:和数组有相同点:
1、可以使用下标得到某个字符
2、可以使用length获取字符串的长度
3、遍历字符串
4、数组不修改原数组的API,字符串也可以使用(拼接 - 垃圾还不如直接+运算,截取)
当然和数组也有很多的不同点,数组修改原数组的API,字符串一个都用不到,字符串也有十几个API等待我们学习
2、引用/对象类型:11个
*String Number Boolean - > 具有包装类型
*Array *Function Math(数学) Date(日期) *RegExp(正则表达式:验证)
Error(错误)
*Object(面向对象)
Global - 全局对象:在前端/浏览器端/客户端/js中被window代替了:功能:保存着全局变量和全局函数,只有window可以省略不写
3、***包装类型:专门用于将原始类型的值封装为一个引用类型的对象的(带了属性和方法)
为什么:原始类型的值原本是不具备任何属性和方法的,但是前辈们发现我们程序员会经常操作到字符串
前辈们为了方便我们程序员,为三个原始类型提供了包装类型
何时使用:只要试图用原始类型的变量去用.调用属性和方法时,就会悄悄的用上包装类型变为对象
何时释放:方法调用完毕后,自动释放包装类型,并且返回数据(又会变回原始类型)
为什么undefined和null不能用. - 没有提供包装类型
5.9
1、StringAPI:只有字符串可以使用的函数,特点:只读!
1、转义字符:\
作用:
1、将字符串中和程序冲突的符号编译为原文
""" '''
2、包含特殊功能的符号:
换行:\n
制表符:\t
*3、输出unicode编码的字符:
\uXXXX:第一个汉字:4e00 - ascii:19968
最后一个汉字:9fa5 - ascii:40869
2、*大小写转换:将字符串中的每个英文统一的转为大写 或 小写
何时:只要程序不区分大小写,就要【先统一】的转为大写 或 小写,再比较(验证码)
如何:
大写:var upper=str.toUpperCase();
小写:var lower=str.toLowerCase();
3、获取字符串中指定位置的字符:str.charAt(i) 还不如直接 str[i]
4、获取字符串中指定位置的字符的ascii码:
var ascii=str.charCodeAt(i);
根据ascii码在转回原文:
var 原文=String.fromCharCode(ascii);
5、***检索字符串:检查索引:获取关键字的下标
var i=str/arr.indexOf("关键字",starti);
从starti位置开始,查找右侧【第一个关键字】的位置
特殊:
1、starti可以省略不写,从0开始查找
2、返回值:找到了,返回的第一个关键字的第一个字符的下标
*没找到,返回-1,我们不关心下标为多少,我只关心下标为不为-1
作用:判断有没有,以后如果不想有重复的,就一定要用上他
3、此方法不光字符串可以使用,数组也可以使用,后期才为数组添加上的,老IE上的数组就没有此方法
4、笔试题:默认只能获取到第一个关键字的下标,如何才能获取到所有的关键字的下标
var str="no zuo no die no can no bibi";
var i=-1;
while((i=str.indexOf("no",i+1))!=-1){
console.log(i);
}
6、*截取字符串:3种
*var subStr=str/arr.slice(starti,endi+1);//用法和数组的slice一摸一样
str.substring(starti,endi+1);//几乎和slice一致,不支持附属参数
*str.substr(starti,n);//n代表截取的个数,不必考虑含头不含尾
7、拼接字符串:var newStr=str.concat(新字符串,...);//还不如+运算
8、*替换字符串:本身强大,但是必须搭配正则表达式
var newStr=str.replace("关键字","新内容");
9、*****切割/分割字符串:
var arr=str.split("任意切割符");
作用:将字符串=>数组
特殊:1、切割后,切割符就不存在了
2、切割符"",切散每一个字符
扩展:如何使用JS生成元素:3步
1、创建空标签:var elem=document.createElement("标签名");
2、为此元素设置必要的属性 或 事件
elem.属性名="值";
elem.on事件名=function(){}
3、渲染页面,上DOM树:
父.appendChild(新);
5.10
1、*****正则表达式:
什么是:定义字符串中【字符出现规则】的一个表达式
何时使用:切割 替换【验证】
如何使用:语法:/正则表达式/
1、最简单的正则:关键字原文 "no" -> /no/gi 只要用上正则就可以添加后缀
g:全部 i:忽略大小写
2、备选字符集:/[备选字符集]/
强调:1、一个中括号,只管一位数字
2、正则表达式【默认只要满足条件,不管其他了】,解决:前加^,后加/ -
代表要求:用户从头到尾必须完整匹配我们的要求 - 只要是做验证就必然前加^,后加$
特殊:如果备选字符集中的ascii码是连续的,中间的部分可用-代替掉
一位数字:[0-9]
一位字母:[A-Za-z]
一位数字、字母、下划线:[0-9A-Za-z_]
一位汉字:[\u4e00-\u9fa5]
除了数字之外的:[^0-9] - 很少使用,范围太广了
3、预定义字符集:前辈们提前定义好的,我们直接使用的
目的:简化备选字符集
一位数字:\d === [0-9]
一位数字、字母、下划线:\w === [0-9A-Za-z_]
一位空白字符:\s === 包含:空格、换行、制表符
一位除了换行外的任意字符:. - 很少使用,范围太广了
建议:优先使用预定义字符集,满足不了的时候再用备选字符集自定义
问题:不管是备选字符集,还是预定义字符集,一个都只管一位
4、量词:规定一个字符集出现的次数
有明确数量
字符集{n,m}:前边相邻的字符集,最少出现n次,最多出现m次
字符集{n,}:前边相邻的字符集,最少出现n次,多了不限
字符集{n}:前边相邻的字符集,必须出现n次
无明确数量:
?: 前边相邻的字符集,可有可无,最多1次
*: 前边相邻的字符集,可有可无,多了不限
+:前边相邻的字符集,至少一次,多了不限
5、选择和分组
选择:多个规则中选择其中一个
规则1|规则2
分组:将多个字符集临时组成一组子规则
(规则1|规则2)
6、指定匹配位置:
^:开头
$:结尾
特殊:如果两者同时出现,要求从头到尾完全匹配 - 只要是做验证,必须加上
7、密码验证:4位,数字和字母,必须出现一位大写和一位数字
/^[0-9A-Za-z]{4}$/
预判公式:(?![0-9]+$) -> 不能全由数字组成
(?![a-z]+$) -> 不能全由小写组成
(?![0-9a-z]+$) -> 不能全由数字组成,也不能全由小写组成,也不能只由数字和小写的组合组成
/^(?![0-9a-z]+)[0-9A-Za-z]{4}$/; - 4位,数字和字母,必须出现一位大写和一位数字
/^(?![0-9a-z]+)(?![A-Z0-9]+/ - 4位,数字和字母,必须出现一位大写和一位数字和小写
2、*****字符串中支持正则表达式的API
1、切割:
var arr=str.split("固定切割符"/regexp)
2、*****替换
1、基础替换法:
var newStr=str.replace("固定关键字"/regexp,"新内容");
2、高级替换法:
var newStr=str.replace("固定关键字"/regexp,function(a,b,c){
console.log(a);//第一个形参保存的是正则匹配到的每一个关键字
console.log(b);//第二个形参保存的是正则匹配到的每一个关键字的第一个字符的下标
console.log(c);//原文本身
return a.length==2?"":"*";
});
3、格式化:在使用replace替换时,如果搭配上了正则,并且正则中加入分组,那么我们的高级替换法会得到更多的形参
有几个分组,就会多出几个形参。
var newStr=id.replace(reg,function(a,b,c,d,e,f,g,h){
//// console.log(a);//第一个形参保存的是正则匹配到的关键字
//// console.log(b);//第二个形参会第一个分组匹配到的关键字
//// console.log(c);//第三个形参会第2个分组匹配到的关键字
//// console.log(d);//第四个形参会第3个分组匹配到的关键字
//// //....说不清楚有多少个,具体看有多少个分组
//// console.log(e);//关键字下标
//// console.log(f);//原文本身
// return c+"年"+d+"月"+e+"日";
// })
3、*****正则对象:API
1、创建正则对象:
*直接量方式:var reg=/正则表达式/后缀;
构造函数方式:var reg=new RegExp("正则表达式","后缀")
为什么有时候要加 前加^后加$,为什么有时候又要加后缀g
1、验证:前加^后加$ - 用户要和我们的规则完全匹配
2、替换:加后缀g
2、API:var bool=reg.test(用户输入的东西);
返回true,说明用户验证成功,否则验证失败
作业:
1、QQ注册:ssl.zc.qq.com/v3/index-ch…
1、onfocus获取焦点事件 -> 为了在后面的元素显示提示文字(不同的input有不同的提示文字)
2、onblur失去焦点事件 -> 获取到用户输入的,和我们的正则(不同的input有不同的正则)进行验证:给出对的提示和错的提示
3、onsubmit提交事件是绑定在form上面的,阻止:return false;
后天交
5.11
1、Math对象:提供了一些数学计算的API
强调:不需要创建,直接使用:全局对象window、Math
属性:Math.PI 得到3.1415926
API:
1、取整:3种
1、上取整:超过一点点,就取下一个整数
var result=Math.ceil(num);
2、下取整:哪怕超过的再多,也会省略掉小数部分
var result=Math.floor(num);
3、四舍五入取整
var result=Math.round(num);
//以上三个操作都只能取整:
//取整的方式:以上三个 + *parseInt + *num.toFixed(0)
//个人更推荐:num.toFixed(d):优点:具有四舍五入,并且小数位数可以自己设置
缺点:返回是一个字符串,搭配上一个parseFloat
//*笔试题:要求不允许使用toFixed,自己封装出toFixed的操作
2、乘方和开方
*乘方:var result=Math.pow(底数,幂)
开方:var result=Math.sqrt(num);//只能开平方
3、最大值和最小值:
var max/min=Math.max/min(a,b,c,d,....);
问题:本身不支持数组参数的
解决:固定用法:var max/min=Math.max/min.apply(Math,arr);
apply是ES5才会学习的东西,apply具有打散数组的功能
4、绝对值:把负数变为正数
Math.abs(负数)
5、***随机数:Math.random(): 在0-1之间取随机的小数,但是有可能取到0,不可能取到1
有可能取到最小数,但是绝对不可能取到最大数
公式:parseInt(Math.random()*(max-min+1)+min);
强调:只要以后网页中某一块有一个随机的功能,那么一定需要用到随机数
注意:其实Math还提供了三角函数
2、Date对象:提供了操作日期的API
1、创建:4种
1、*创建一个当前时间:
var now=new Date();
2、*创建一个自定义时间:
var birth=new Date("yyyy/MM/dd hh:mm:ss");
3、创建一个自定义时间:
var birth=new Date(yyyy,MM-1,dd,hh,mm,ss);
缺点:月份需要进行修正,0 代表 1月
4、复制一份日期:
为什么:日期的所有的API都是直接修改原日期对象的,无法获得修改之前的日期
所以,在执行API之前都要先进行复制,然后在操作复制后的日期
var end=new Date(start);
2、操作:
1、两个日期对象之间可以相减,得到一个毫秒差,换算出你想要的任何一部分 - 日期的本质底层保存的就是一个毫秒
其实创建还有第五种方式:var date=new Date(毫秒)
2、API:
分量:时间的单位
年月日星期:FullYear Month Date Day
时分秒毫秒:Hours Minutes Seconds Milliseconds
每一个分量都有一对儿getXXX/setXXX的API
get用于获取
set用于设置
特殊:
1、取值范围:
年 - 当前年份的数字
月 - 0~11
日 - 1~31
星期 - 0~6:外国人觉得星期天是一周的第一天
小时 - 0~23
分秒 - 0~59
2、唯独星期不允许设置set
3、建议如果你希望对某个分量做加减
date.setXXX(date.getXXX()+/-n);
date.setFullYear(date.getFullYear()+3);//对日期+3年
4、格式化日期对象->字符串:
date.toLocaleString();//locale本地 - 具有兼容性问题,在不同的浏览器显示出来的效果是不一样,一般来说我们都要自定义格式化方法
日期可以用日期自己的API - 日期屌在日期会自动进制
字符串也只可以用字符串自己的API
一旦格式化为字符串则不可用日期的API
作业:
1、笔试题:自己封装一个toFixed
2、机选双色球:
红球:1-33 6个
蓝球:1-16 1个
3、让用户输入,自己是什么时候入职的,3年后合同会到期,计算出合同到期时间
提前1个月人力会让此员工续签,如果续签时间是周末,提前到周五,计算出合同续签时间
续签的前一周要进行提醒,计算出提醒时间
4、自定义格式化函数
5、继续完成QQ注册
3、Number对象
4、Boolean对象
*String Number Boolean - > 具有包装类型
*Array *Function Math(数学) Date(日期) *RegExp(正则表达式:验证)
Error(错误)
*Object(面向对象)
Global - 全局对象:在前端/浏览器端/客户端/js中被window代替了:功能:保存着全局变量和全局函数,只有window可以省略不写
Error Function Object
5.12
1、Error:错误对象
1、***浏览器自带四种错误类型:可以快速找到自己的错误
语法错误:SyntaxError - 符号写错了
引用错误:ReferenceError - 没有创建就去使用了
类型错误:TypeError - 不是自己的方法,你却去使用了,最典型的,就是你们经常会undefined.xxx或null.xxx
范围错误:RangeError - 只有一个API会碰到:num.toFixed(d);//d的取值范围只能是0~100之间
2、只要发生错误,就会报错,会导致后续代码不执行(如果APP报错,那会直接闪退),我们程序不希望报错
错误处理:就算发生错误,也不会报错,不希望抛出错误,而是希望给一个错误提示即可,后续代码依然可以继续允许
语法:
try{
只放入你可能出错的代码
}catch(err){
发生错误的时候才会执行
console.log(err);
}
try...catch...的性能非常差,几乎里面的代码效率会被降到最低,所以不推荐使用
*可以用一个技术代替:if...else... 提前预判
*开发经验:一切的用户都是坏人,都要防一手(!isNaN(x)、正则:把用户控死)
3、抛出自定义错误:
throw new Error("自定义提示");
2、*****Function:函数对象:提前创建好的,以后可以反复使用的代码段
1、创建:3种
1、声明方式:function 函数名(形参列表){函数体;return 返回值} - 完整的提前
2、直接量方式:var 函数名=function(形参列表){函数体;return 返回值}
3、构造函数方式:var 函数名=new Function("形参",.....,"函数体;return 返回值");
何时使用:函数体是动态拼接的
2、调用:如果有return,记得接住结果
var 结果=函数名(实参);
3、考点:
1、创建的三种方式
2、作用域:变量的使用规则:优先使用自己的,自己没有找全局,全局没有就报错
3、声明提前:
4、按值传递:
5、重载overload:相同的函数名,根据传入的实参的不同,自动选择对应的函数执行
为什么:减轻程序员负担!
问题:JS不支持重载!
JS不允许多个同名函数同时存在,如果存在,最后的会覆盖之前的所有
解决:在【函数中】有一个对象:arguments对象,不需要我们创建,自带
什么是arguments:是一个类数组对象:但是不是数组,和数组有3个相同点
1、都可以使用下标
2、都可以使用length
3、都可以遍历
作用:***接受住传到函数内部的所有实参,哪怕你不写一个形参
可以做的事儿:
1、实现重载:可以通过在函数内部判断arguments的不同,执行不同的分支操作
2、以后有没有形参无所谓
3、正式开发中,有可能会将多个函数整合为一个函数 - 代码优化
6、***匿名函数:没有名字的函数
1、匿名函数自调:
//此函数只会执行一次,执行后会自动释放,优点,自动释放 - 代替全局写法,提升网页的性能
(function(){
var a=2;
console.log(a);
btn.onclick=function(){
console.log("释放了码");
}
//引用类型:在还有人使用的情况下,是不会自动释放的
})();
2、匿名函数回调:将函数作为实参,传递给了其他函数调用 - 没有名字就是匿名函数,匿名函数只有自调和回调,没有自调,则是回调
1、学习回调函数的目的:让你们知道哪些属于回调函数
arr.sort(function(a,b){return a-b;})
str.replace(reg,function(){})
btn.onclick=function(){}
这些东西都是前辈们规定好的,我们只能学习如何使用的
2、ES6 - 一切的回调函数,都可以简化为箭头函数
3、了解了回调函数的原理
7、*****闭包 - 明天讲,面试题:两链一包(作用域链、原型链、闭包)
5.13
1、*****Function
***作用域:
1、全局:成员,随处可用,可以反复使用,缺点:容易被污染
2、函数:成员,只能在函数调用时内部可用,不会被污染,缺点:一次性的,是会自动释放的
***函数的执行原理:
1、程序加载时:
创建执行环境栈(ECS): 保存函数调用顺序的数组
首先压入全局执行环境(全局EC)
全局EC引用着全局对象window
window中保存着全局变量
2、定义函数时
创建函数对象:封装代码段
在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
全局函数的scope都是window
3、调用前
在执行环境栈(ECS)压入新的EC(函数的EC)
创建活动对象(AO):保存着本次函数调用时用到的局部变量
在函数的EC中有一个scope chain(作用域链)属性引用AO
AO有一个parent属性是函数的scope引用的对象
4、调用时
正是因为有前面三步,我们才有了变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错
5、调用完:
函数的EC会出栈,没人引用AO,AO自动释放,所以局部变量也就释放了
两链一包:
作用域链:以函数的EC中的scope chain属性为起点,经过AO,逐级引用,形成的一条链式结构,就称之为叫做作用域链
作用:变量的使用规则,查找变量
*****闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样
何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:4步
1、两个函数相互嵌套
2、外层函数创建出受保护的变量
3、外层函数要return返回内层函数
4、内层函数要操作受保护的变量
强调:
1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏
使用场景:防抖节流 - 有三个事件需要做防抖节流:执行的速度非常的快,减少DOM树的渲染
1、elem.onmousemove - 鼠标移动事件
2、input.oninput - 输入内容有变化就会触发
3、window.onresize - 当前窗口的尺寸如果发生了变化就会触发:JS版本的媒体查询
公式:
elem.on事件名=function(){
inner();
}
function fdjl(){
var timer=null;//1 2 3 - 定时器序号
return function(){
if(timer){clearTimeout(timer);timer=null}
timer=setTimeout(function(){
//操作
},1000)
}
}
var inner=fdjl();
作业:
1、根据函数的执行原理,画图
2、防抖节流三个事件都试一试
对象:Array/String/Function/Math...对象具有属性和方法,都是预定义好,现在我们学习自定义对象
2、*****面向对象:Object:三大特点:封装、继承、多态
1、***开发方式:
面向过程:经过 - 开始->结束,其实我们一直以来的开发方式都是面向过程:先干什么再干什么最后干什么
面向对象:对象(属性和方法),js有一句话万物皆对象,假设一个人是一个对象的话:
属性:姓名、性别、身高、体重、爱好、智商...
方法:吃饭、睡觉、拉粑粑、跑步、走路、打字、说话...
为什么要面向对象:现实生活中所有的数据都要保存在一个事物中才有意义
何时使用面向对象:以后做任何操作都要封装在一个对象中 - 建议:不太适合初学者
2、封装对象:创建自定义对象:3种
1、直接量方式:
var obj={
"属性名":"属性值",
...
"方法名":function(){},
...
}
强调:
1、其实属性名和方法名的""可以省略不写的 - 暂时建议写上,以后我们会学习JSON数据格式,要求必须加""
2、访问对象的属性和方法
*对象名.属性名 === 对象名["属性名"]
*对象名.方法名(); === 对象名"方法名";
JS种一切对象的底层都是hash数组
3、访问到不存在的属性或者方法,返回undefined
4、可以后期随时随地的添加新属性和新事件
5、如果希望遍历出对象中的所有东西
for(var i in 对象名){
对象名[i]
}
6、***如果你希望在对象的【方法中】使用对象自己的属性:写为:this.属性名
*****难点:this的指向:
1、*单个元素绑定事件:this->这个元素
2、*多个元素绑定事件:this->当前触发事件的元素
3、***函数中使用this:this->谁在调用此方法,this指向就是谁
4、定时器this->window
5、箭头函数this->外部对象
2、预定义构造函数方式:
var obj=new Object();//空对象
//需要自己后续添加属性和方法
obj.属性名="属性值";
obj.方法名=function(){}
以上两种方法创建都有一个缺陷:一次只能创建一个对象,适合创建单个对象的时候使用(第一种方式)
3、自定义构造函数方式:- 何时创建多个对象:2步
1、创建自定义构造函数
function 类名(name,age,salary){
this.name=name;
this.age=age;
this.salary=salary;
}
2、反复调用自定义构造函数创建出对象
var xxx=new 类名("实参",...)
面向对象:
优点:1、逼格高,所有的属性和方法都是保存在一个对象之中 -更符合现实生活:代码风格、代码速度
2、每个功能特地的分开写 - 便于维护
3、铁锁连舟 - 一个方法触发多个方法联动
缺点:1、对新手不友好 - this的指向
5.16
1、*****Object:
1、*****继承:父对象的成员(属性和方法),子对象可以直接使用、
为什么:代码重用!节约内存空间!提升网站的性能!
何时继承:只要多个子对象公用的属性和【方法】,都要集中定义在父对象之中
2、***如何找到父对象(原型对象):保存一类子对象共有属性和共有方法的父对象:2种
1、子对象.proto;//前提:必须先有一个对象
2、构造函数名.prototype;//构造函数名,几乎人人都有,除了Math/Undefined/Null
3、*面试题:两链一包:
作用域链:查找变量
闭包:保护一个可以反复使用的局部变量的一种词法结构
原型链:每个对象都有一个属性:proto,可以一层一层的找到每个人的父亲,形成的一条链式结构,就称之为叫做原型链
可以找到所有父对象的成员(属性和方法),作用:查找属性和【方法】
最顶层是Object的原型,上面放着我们眼熟的toString,怪不得人人都可以使用toString
JS种万物皆对象
4、有了原型对象,设置共有属性和共有的方法
1、原型对象.属性名=属性值
2、原型对象.方法名=function(){}
***笔试题1:判断自有和共有:
1、判断自有:
obj.hasOwnProperty("属性名");
如果结果为true,说明一定是自有,如果结果为false,可能是共有可能是没有
2、判断共有:
if(obj.hasOwnProperty("属性名")==false&&"属性名" in obj){//in 会自动在整条圆形脸上进行查找,找到结果为true,找不到结果为false
说明是共有
}else{
说明是没有
}
完整版公式:
if(obj.hasOwnProperty("属性名")){
自有
}else{
if("属性名" in obj){
共有
}else{
没有
}
}
***笔试题2:修改/删除自有和共有
自有:修改:obj.属性名=新值;
删除:delete obj.属性名;
共有:修改:obj.proto.属性名=新值;
删除:delete obj.proto.属性名;
共有千万不要操作本地:
修改:会在本地添加同名属性
删除:没有效果
***笔试题3:如何为老IE的数组添加indexOf方法:如何为一类人添加某个方法
原理:
if(Array.prototype.indexOf===undefined){//老IE
Array.prototype.indexOf=function(key,starti){
starti===undefined&&(starti=0);
for(var i=starti;i<this.length;i++){
if(key==this[i]){
return i;
}
}
return -1;
}
}
***笔试题4:判断x是不是一个数组:4种方式
1、判断x是不是继承自Array.prototype:
Array.prototype.isPrototypeOf(x);
2、判断x是不是由Array这个构造函数创建的
x instanceof Array
3、只有数组可用:ES5提供的一个叫Array.isArray(x);
4、最麻烦:输出【对象的字符串】形式
在Object的原型上保存着最原始的toString方法
最原始的toString方法输出:[object 构造函数名]
***多态:子对象觉得父对象的成员不好用,在本地定义了同名成员,覆盖了父对象的成员
如果我们这道题能够跳过数组的爸爸,拿到数组的爷爷上面的toString也就能判断了
固定套路:借用:Object.prototype.toString.apply(x);
***笔试题5:实现自定义继承:
1、两个对象之间的继承:
子对象.proto=父对象
2、多个对象之间设置继承:
构造函数名.prototype=父对象
注意时机:一定要在创建对象之前
5.17
1、ES5:
1、保护对象:保护对象的成员(属性和方法)
如何保护:
1、四大特性:
Object.defineProperties(obj,{
"属性名":{
value:实际保存值,
writable: true/false,//开关:控制着这个属性名是否可以被修改
enumerable: true/false,//开关:控制着这个属性名是否可以被for in循环遍历到
configurable: true/false,//开关:控制着这个属性名是否可以被删除 - 这一句是总开关,一旦设置为false,其他特性不允许在修改,一旦设置为false不可逆
}
})
2、三个级别:
1、防扩展:禁止给对象添加新属性
Object.preventExtensions(obj);
2、密封:禁止给对象添加新属性和删除属性
Object.seal(obj);
3、冻结:禁止给对象添加和删除和修改
Object.freeze(obj);
其实保护对象对于我们程序员并没有多大用处:为什么
1、如果你用的是面向过程开发,你保护个屁
2、别人基本不可能知道我们的对象名字叫什么
3、前辈们都没有保护,你保护个屁
2、*****数组的新的API:3组6个
1、判断:判断结果一定是一个布尔值
every:每一个 - 要求每一个元素都要满足,结果才为true,只要有一个不满足就为false - 类似于&&
语法:var bool=arr.every(function(val,i,arr){
return 判断条件;
})
//val - 当前值
//i - 当前下标
//arr - 数组本身,前辈们确实提供了3个形参给我们,但我们需要哪个在用哪个
some:有一些 - 要求每一个元素都不满足,结果才为false,只要有一个满足就为true - 类似于||
语法:var bool=arr.some(function(val,i,arr){
return 判断条件;
})
2、遍历:将数组中的每个元素取出来执行相同或相似的操作:
forEach:遍历数组,直接修改原数组
语法:arr.forEach(function(val,i,arr){
直接做操作
})
map:遍历数组,不修改原数组返回一个新数组
语法:var newArr=arr.map(function(val,i,arr){
return 操作的结果
})
3、过滤和汇总:
过滤:筛选出自己想要的,但是不会修改原数组
语法:var subArr=arr.filter(function(val,i,arr){
return 判断条件;
})
汇总:把数组中的每个元素汇总到一起
语法:var sum=arr.reduce(function(prev,val,i,arr){
return prev+val;
},基础值);//基础值会和最后的结果加在一起
以上6个API的底层都是for循环,目的 - 简化for循环 - 以后能不写for就不写for
3、Object.create():根据父对象创建子对象,继承已经设置好了
语法:var 子对象=Object.create(父对象,{
"自有属性名":{四大特性},
...
});
4、面试时:严格模式:很严格
开启:在你的任何作用域的顶部加上一句话:"use strict";
功能:1、禁止给未声明的变量赋值 - 解决全局污染
2、静默失败升级为报错
5、*****call/apply/bind:不是自己的方法也可以使用 - 笔试面试也很容易碰到
call/apply:临时替换了函数中的this - 借用
语法:函数名.call(借用的对象,实参,...); - 单独传入每一个实参
函数名.apply(借用的对象,arr); - 只能传入一个实参是一个数组,apply其实会悄悄的将数组打散
强调:call/apply,相当于立刻调用函数,立即执行
bind:永久替换了函数中的this - 买
3件事:
1、创建了一个和原函数完全相同功能的新函数
2、将新函数中的this永久绑定为了指定对象,别人都借不走了
3、将新函数中的部分参数永久固定
用法:var 新函数=原函数.bind(指定对象,永久实参,...) - 不是立刻执行的,需要自己调用
强调:bind绑定的新函数没有办法被call/apply借走
个人更推荐:call/apply,借,白嫖
固定套路:
1、Math.max/min.apply(Math,arr);
2、Object.prototype.toString.call/apply(arr);
3、***类数组转为普通数组:类数组名称=Array.prototype.slice.call/apply(类数组);
ES5其实没有什么简化,是提供了一些API
2、ES6:简化ECMAScript - 语法较大的变化
1、*模板字符串:可以在字符串中放入变量 - 不需要再做字符串拼接,在字符串中实现了一个简单的js的环境
语法:我的名字叫${name}
2、*块级作用域:尽量以后【优先】使用let创建变量
let 变量名=值;
作用:1、禁止声明提前
2、添加了块级作用域,一个{}就是一个块
3、记录着当前触发事件的元素的下标
3、***箭头函数:简化回调函数:
公式:去掉function,()和{}之间添加=>,形参如果只有一个,则省略掉(),函数体如果只有一句话,省略{},
函数体只有一句话并且是return,return和{}都省略
特殊:千万不要将事件也简化为箭头函数 - 暂时
4、for...of循环:垃圾
for(var v of 数组名){
v;//value当前值
}
缺点:1、不能修改原数组,只能返回新数组
2、不能遍历hash数组,意味着也不能遍历对象,只能遍历索引数组
5、二阶段结束前,再将5个ES6的新特性,三阶段必用
5.18
今日目标:找元素和找数据
1、什么是DOM:Document Object Model(文档对象模型) - 操作HTML文档
将每个元素/标签/文本/属性/注释都会看作是一个DOM节点/元素/对象
面试题:HTML/XHTML/DHTML/XML?
1、HTML - 网页
2、XHTML - 更严格的网页
3、DHTML - Dynamic:动态的网页,其实并不是新技术,也不是新概念,而是现有技术的一个整合统称:让我们的网页再离线版也能具有动态效果
DHTML:HTML+CSS+JS
4、XML - 全部自定义,数据格式:淘汰了:JSON数据格式
DOM:原本是可以操作一切结构化文档的 HTML 和 XML,后来为了方便各类开发者分为了3个方向
1、核心DOM:【无敌】,既可以操作HTML也可以操作XML
缺点:API比较繁琐,getAttribute/setAttribute()
2、HTML DOM:只能操作HTML,API简单:缺点:自定义的东西操作不了
3、XML DOM:只能操作XML - 不会学习他
开发建议:优先使用HTML DOM,HTML DOM实现不了再用核心DOM补充
2、DOM树:树根:document - 不需创建,一个页面只有一个document,由js解释器自动创建
作用:通过树根,可以找到想要的DOM元素/节点/对象
3、每个DOM元素都有三大属性:
1、elem.nodeType:描述节点类型
document 节点:9
element 节点:1
attribute 节点:2
text 节点:3
以前有用:判断xx是不是一个页面元素 - 因为以前我们的方法和你们现在的方法不一样
2、elem.nodeValue:获取【属性节点】的值
3、***elem.nodeName:获取节点名称/标签名
注意:返回的是一个全大写组成的标签名
4、*通过 关系 获取元素
父:xx.parentNode
子:xx.children - 只能找到儿子
第一个儿子:xx.firstElementChild;
最后一个儿子:xx.lastElementChild;
前一个兄弟:xx.previousElementSibling;
后一个兄弟:xx.nextElementSibling;
5、*****递归:简单来说就是函数中再次调用了函数本身,迟早有一天会停下来
何时使用:遍历DOM树,专门用于【遍历层级不明确】的树状结构
如何使用:
function 函数名(根){
1、第一层要做什么直接做
2、判断它有没有下一级,如果有下一级,则再次调用此函数,但是传入的实参是自己的下一级
}
函数名(实际的根)
算法:深度优先!优先遍历当前节点的子节点,子节点遍历完才会跳到兄弟节点
缺点:同时开启大量的函数调用,浪费的内存,只有一个情况:【遍历层级不明确】
递归 vs 循环
递归:优点:直观,易用
缺点:性能较差
循环:优点:性能较好
缺点:难得一批
6、遍历层级不明确的API:TreeWalker:一个在DOM树上行走的人
缺点:只能遍历层级不明确的DOM树,不能遍历层级不明确的数据
如何使用:2步
1、创建TW
var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT);
2、反复调用tw的nextNode函数找到节点
while((node=tw.nextNode())!=null){
node要干什么
}
7、*直接找元素:
1、通过HTML的一些特点找元素
你会的:id/class/标签
新的:通过name找元素:var elems=document.getElementsByName("name值")
2、通过css选择器查找元素:2个方法 - 更适合用于复杂查找(多句才能找到最终元素)
1、var elem=document.querySelector("任意css选择器");
只会找到一个元素,如何同时匹配多个,也只会返回第一个
没找到null
2、var elem=document.querySelectorAll("任意css选择器");
找到了是一个集合
没找到是一个空集合
面试题:getXXXX和queryXXXX的区别?
返回的结果不一样:
1、getXXXX:返回的是一个动态集合HTMLCollection
特点:每一次DOM树修改过后,js都会悄悄的再次查找元素,保证数据和页面对应,效率相对较低
2、queryXXX:返回的是一个静态集合Nodelist
特点:只管查找的一次找出来的结果,后续DOM树的修改,我们的数据也不会变化,效率相对较高
优点:1、查找简单
2、还支持forEach
总结:找元素的方式:
1、直接找元素:getXXX、queryXXX
2、通过节点的关系
3、层级不明确的情况 - 递归
5.19
操作元素
1、元素的内容
1、*elem.innerHTML:获取或者设置开始标签到结束标签之间的HTML代码,没有兼容性问题,可以识别标签
获取:elem.innerHTML
设置:elem.innerHTML="新内容"
2、elem.textContent:获取或者设置开始标签到结束标签之间的纯文本,但是有兼容性问题,不可以识别标签
获取:elem.textContent
设置:elem.textContent="新文本"
特殊:老IE才叫elem.innerText;//第一见到小三上位,反而所有的主流浏览器来将就了老IE
3、*input.value:获取或设置单标签(input)的内容准备的
获取:input.value
设置:input.value="新值"
2、元素的属性:
1、*获取属性值:
核心DOM:elem.getAttribute("属性名")
HTML DOM:elem.属性名;
2、*设置属性值:
核心DOM:elem.setAttribute("属性名","属性值");
HTML DOM:elem.属性名="新值";
3、删除属性值:
*核心DOM:elem.removeAttribute("属性名")
HTML DOM:elem.属性名="" - 虽然简单,但是有的情况会删不干净,有的属性删不干净依然会有功能比如:href
4、判断有没有 - 垃圾
核心DOM:elem.hasAttribute("属性名");
HTML DOM:elem.属性名!="";
返回的结果是一个布尔值,只能判断有没有,不能判断是什么
HTML DOM:有两个小缺陷:
1、class需要写为className
2、一切自定属性不能操作
3、删除删不干净,依然会留下属性节点
3、元素的样式:
1、内联样式:
获取:elem.style.css属性名
设置:elem.style.css属性名="css属性值"
特殊:
1、css属性名如果有横线要省略,变为小驼峰命名法
2、获取的时候只能获取到内联样式,这个小缺陷可以忽略不计
2、样式表: - 不推荐
//获取到你想要操作的某个样式表
var sheet=document.styleSheets[i];
//获取样式表中所有的样式规则
var rules=sheet.cssRules;
//选出自己想要操作的某个规则
var rule=rules[i];
//操作
获取:console.log(rule.style.css属性名);
设置:rule.style.css属性名="css属性值"
为什么更推荐内联:
1、不会牵一发动全身
2、优先级一定是最高的
5.19
1、创建元素&渲染页面:3步
1、先创建空标签
var elem=document.createElement("标签名");
2、为其添加必要属性和事件
elem.属性名="属性值";
elem.on事件名=function(){操作}
3、渲染DOM树/页面:3种
*1、父元素.appendChild(elem);//elem追加到父元素里面,当最后一个儿子
2、父元素.insertBefore(elem,已有子元素);//elem追加到父元素里面,插入在已有子元素的前面 - 影响其他元素的下标,不推荐
3、父元素.replaceChild(elem,已有子元素);//elem追加到父元素里面,新元素替换掉已有子元素 - 不推荐
2、删除元素:elem.remove();
核心DOM学习完毕,你已经无敌了:总结一句话DOM可以干什么:增删改查DOM元素(元素、文本、属性、样式)
HTML DOM:简化核心DOM开发,核心语法太繁琐,提供了一些常用的对象
1、image对象:垃圾,仅仅只是简化了创建部分
创建:var img=new Image(); - 不是人人都可以简化为构造函数创建方式
2、form对象:垃圾,仅仅只是简化了查找部分
查找form元素:var form=document.forms[i];
以及找表单控件:var inp=form.elements[i];
3、*select对象:牛逼:提供了2个属性,2个方法,1个事件
属性:
1、select.options === select.children; 获取select里面的所有的option
2、*select.selectedIndex - 获取当前选中项的下标,一定是搭配联动一起使用
方法:
1、*sel.add(option); - 完全相当于appendChild
2、elem.remove(i); - 当时当remove删除元素出现过后,他就当场淘汰了
专属事件:onchange - 选中项发生了变化才会触发
4、*option对象:仅仅只是简化了创建部分
创建:var opt=new Option("innerHTML","value")
一句话完成4个操作:sel.add(new Option("榴莲","榴莲"));
1、创建了空的option
2、为option设置了innerHTML
3、为option设置了value
4、上树
5.20
用户确认框:var bool=confirm("提示文字");
5.24
1、BOM概述:Browser Object Model - 浏览器对象模型:专门为操作浏览器准备的一些对象,没有任何标准,不像DOM由W3C制定标准,所以存在很大的兼容性问题,使用率相对DOM较少
BOM有哪些对象:window、history、navigator、location、screen、event
个人认为重要的只有两个对象:window、event
2、window对象:在浏览器中扮演着两个角色:
1、代替了Global,充当全局对象 - 保存着全局变量和全局函数
2、指代当前窗口本身
3、*打开网页的新方式:
知道了:1、跳转用不用a标签无所谓
2、有点点用:提升用户的体验感,前端是距离用户最近的,多为用户做考虑
3、a标签的作用
1、当前页面打开,可以后退:
HTML:内容
JS:open("url","_self");
2、当前页面打开,禁止后退:何时:电商网站:结账过后不允许后退了
HTML:做不了
JS:history:当前窗口的历史记录,只有当前窗口有了历史记录才能前进后退
location:当前窗口的正在打开的url网址,提供一个方法:
location.replace("新url"); - 不叫作跳转,叫做替换,当时网址被替换了,页面也会跳转,但是不会产生历史记录
3、在新窗口打开,可以打开多个
HTML:内容
JS:open("url","_blank");
4、在新窗口打开,只能打开一个:何时:电商网站:购物车跳转到结账页面,结账页面只允许打开一个
HTML:内容
JS:open("url","自定义name");
其实在每一个窗口的底层都有一个名字name,_self指向的自己当前的名字
_blank始终会得到一个新名字
如果自定义名称,那么浏览器会发现这个窗口已经打开过了,那再次打开时,会把原来的窗口给替换掉
扩展:a标签的作用
1、跳转
2、锚点
3、下载:文字
4、打开:文字
5、运行js - a标签不需要绑定事件:文字
4、属性和方法:
打开新窗口:var 新窗口=open("url","target/自定义","width=,height=,left=,top=");
特殊:1、没有加第三个参数的时候,我们的新窗口会和浏览器融为一体
2、添加上第三个参数的时候,我们的新窗口就会脱离浏览器独立存在,而且可以把他保存起来
关闭窗口:window/新窗口.close();
移动窗口:新窗口.moveTo(x,y);
修改窗口的大小:新窗口.resizeTo(newW,newH);
获取屏幕的大小:screen.width/height
获取浏览器的完整大小:outerWidth/Height
获取浏览器文档显示区域的大小:innerWidth/Height
扩展:event对象可以获取鼠标的位置:2步
1、在你的事件处理函数中的第一个形参会自动获取到事件对象event
2、获取鼠标的位置:
获取鼠标相对于屏幕的坐标:e.screenX/Y
获取鼠标相当于文档显示区域的坐标:e.clientX/Y
获取鼠标相当于网页的坐标:e.pageX/Y
5、定时器:等待一段时间才会执行的代码,可能会反复执行,也可能只会执行一次
两种:
1、周期性定时器
开启:timer=setInterval(回调函数,延时);
停止:clearInterval(timer);
2、一次性定时器
开启:timer=setTimeout(回调函数,延时);
停止:clearTimeout(timer);
特殊:1、不管是一次性还是周期性,底层其实都是一样的,甚至两者可以互换
2、一次性<=>周期性
面试题:函数和循环和定时器,都可以反复执行代码,区别在哪里?- 时机
1、函数:要么程序员调用几次执行几次,要么用户触发几次执行几次
2、循环:几乎是一瞬间就完毕了
3、定时器:需要先等待一段时间才会执行
5.25
1、history:保存着当前窗口的历史记录 - 浏览器自带此功能
前进:history.go(1);
后退:history.go(-1);
刷新:history.go(0);
2、navigator:保存着当前浏览器的基本信息(浏览器名称以及版本号)
通过js判断用户打开的是什么浏览器 - 相当于js版本的css hack(专门为老IE准备),对不同的浏览器可以执行不同的操作
就一个属性:navigator.userAgent;
见:03.html - 说白就是想办法拿到你想要的部分
不重要 - 现在大部分的操作前辈们都提供了兼容的方式,不需要自己判断浏览器是什么
3、***location:保存着当前窗口的正在打开url
知道:1、常识:一个url由哪些部分组成
一定由5份组成:
1、协议:http/https
2、主机号/域名:但是域名是需要花钱购买的,白嫖就只能用主机号
3、端口号:默认端口可以省略不写,http默认为80,https默认为443
4、文件的相对路径:百度加密了
5、查询字符串/请求消息:客户端向服务器端发起的请求消息:表单提交带来的东西
协议名://主机号|域名:端口号/文件的相对路径?查询字符串
而且,location对象就可以获取到这5部分:不需要记忆,直接console.log(location)输出进行观察
2、可以干什么:跳转页面
location="新url"
location.href="新url"
location.assign("新url")
跳转页面,禁止后退:location.replace("新url") - 不会产生历史记录
刷新:location.reload();
4、*****event:事件对象
什么是事件:用户触发的 或 浏览器自动触发 的
1、绑定事件:3种
1、在HTML标签上添加事件属性
<elem on事件名="js代码">
缺点:1、不符合我们内容html与样式css与行为js的分离
2、一次只能绑定一个元素,不能动态绑定事件
3、一个事件只能放入一个事件处理函数
*2、在js中,使用事件处理函数属性绑定事件:
elem.on事件名=function(){
}
优点:1、符合我们内容html与样式css与行为js的分离
2、动态绑定事件
缺点:一个事件只能放入一个事件处理函数,我个人觉得不算缺点,你为什么不把代码放到一起?
3、绑定事件的API
主流:elem.addEventListener("事件名",callback);
老IE:elem.attachEvent("on事件名",callback);
兼容:if(elem.addEventListener){
elem.addEventListener("事件名",callback);
}else{
elem.attachEvent("on事件名",callback);
}
优点:1、符合我们内容html与样式css与行为js的分离
2、动态绑定事件
3、一个事件只能放入多个事件处理函数
缺点:不兼容老IE - 麻烦
4、事件周期:3个阶段
1、捕获阶段:记录要执行的事件有哪些,由外向内
2、目标触发阶段:目标元素:实际触发事件的元素
3、冒泡执行阶段:由内向外的冒泡执行
5、如何获取事件对象event:
主流:事件处理函数的第一个形参会自动获得
老IE:window.event;
兼容:e=event;
第二次小三上位:window.event,主流也支持
只有你获取到了事件对象event才可以做后续5个操作:
*1、获取鼠标的坐标
*2、阻止冒泡:- 不要用,用了就不能利用冒泡了,鄙视/面试
主流:e.stopPropagation();
老IE:e.cancelBubble=true;
兼容:if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble=true;
}
*****3、利用冒泡:也叫做事件委托:多个子元素都共有一个事件,把事件绑定在父元素身上,通过利用冒泡,点击儿子,父元素的事件也会触发
为什么:绑定的时间越多,创建的事件监听对象也就越多,网站性能就会越低下
何时:任何一个功能都要做成事件委托
当前元素:this -> 水性杨花(在不同的场景,指向的人是不一样的)
学会找到目标元素:永远是你事件触发的元素
主流:e.target;
老IE:e.srcElement;
兼容:var target=e.srcElement;
第三次小三上位:e.srcElement,主流也支持!
*4、组织浏览器的默认行为:- 看你需不需要阻止
比如:阻止右键(window.oncontextmenu)会弹出一框框,阻止键盘事件window.onkeydown(F12 、F5...)...
主流:e.preventExtensions();
老IE:e.returnValue=false;
兼容:if(e.preventExtensions){
e.preventExtensions();
}else{
e.returnValue=false;
}
*5、获取键盘键码:不需要记忆,直接console.log(e.keyCode); - 一般出现在游戏开发
5.26
1、学习的原因:
1、前端的招聘要求 - 熟悉 或 了解一门服务器端语言者优先
2、对于我们前端来说,了解服务器端的机制,更好更快的进行前端开发
扩展:
全栈工程师:客户端(PC+移动端+小程序) + 服务器端(php+node.js) + 数据库(MySQL+mongoDB)
技术类发展:
全栈 - 涉及多个领域,每个领域都会用,但是不必精通 -> 架构师 -> 项目经理 -> 技术总监CTO
专家 - 某个领域很强的,无敌:有创造的能力,vue的创造者
销售类发展:
产品 -> 产品经理 -> 产品总监
创业类:HTML + CSS
教学类:
可能成为全栈的语言:
1、java语言 - 不包含移动端(不包含ios)
2、javascript语言
客户端 - 开发根本
服务器端 - node.js 历史上第一次一门语言可以通吃前后端
移动端 - 网页/app/小程序/公众号(ios+andriod没落了:正是因为前端的崛起:一个前端可以跨平台开发 - 诞生了一个技术混合开发:uniapp框架)
数据库 - MySQL、mongoDB
server:2天
MySQL一天 + PHP一天
对服务器端的掌握 - 入门
最终目的:全栈开发:登录+注册+搭配上3天ajax完成全栈一条龙:对网页进行增删改查
小项目:图书/金夫人/咖啡管理系统
2、基本内容:
服务器概念:
简单来说就是一台电脑
生活中:微机
商业/国家:小型机(造价几十万,好的上百万)、中型机、大型机、超级计算机
拥有服务器的方式:
1、买 - 配置较好的微机:中小型公司
2、租一台云服务器 - 腾讯云/阿里云/百度云/新浪云... - 配置自己选择,价格好商量,按年收费
3、买一台小型机 - 对小公司遭不住
对于开发人员来说
硬件服务器 - 电脑
软件服务器 - 中间件(软件可以将你的电脑变成一台服务器:别人可以来访问)
软件架构:
C/S:clinet客户端/server服务器端
举例:QQ/微博/大型网络游戏
优点:用户体验感较好
运行稳定
对带宽要求低
缺点:占硬盘空间
更新过于麻烦 - 服务器端和客户端都要更新
B/S:browser浏览器端/server服务器端
举例:网页版QQ/微博/游戏
优点:几乎不占硬盘
更新简单 - 只需要更新服务器端
缺点:带宽要求高
体验感越来越棒了 - 云平台游戏(根本不关心你电脑的配置如何,也不需下载,打开即玩,但是带宽要求高)
XAMPP软件 - 中间件
安装:双击->一路往下冲
Apache - 用于运行PHP的环境
出现错误:
1、直接弹出一警告框:你的电脑里缺少api-ms-win-crt-conio-l1-1-0.dll文件
解决:粘贴到C:/windows/sysWow64
2、错误日志:error:apache shutdown .... - 你的端口号被占用了
修改:点击apache 对应的 config按钮,前两个选项:第一个选项把所有的80可以换成别的,第二选项把所有的443换成别的
能不改,就不改 - 默认端口可以省略不写
3、如果以上两个操作都不行,再看看你的安装路径是不是有错,必须在装载:盘符:/xampp
4、如果以上3个操作都不行,重装系统
TOMCAT - 用于运行java的环境
如果你的apache 成功运行了,恭喜你,你的服务器已经开启了(私网/局域网)
如何访问Apache服务呢(网站)?其实apache服务器控制这一个文件夹:d:/xampp/htdocs
自己访问:
打开浏览器:输入
127.0.0.1:端口号
localhost:端口号
主机号只有自己可用
其他人也可以来访问:
打开cmd输入ipconfig,把ipv4给对方就可以了
192.168.30.5
在服务器上搭建一个自己的项目
把自己做的做过的任意一个项目:全部复制到d:/xampp/htdocs
添加网页小图标:
任意图片,放到d:/xampp/htdocs,名字改为favicon.ico
修改顶级域名 - 假象(没花钱,只有自己可以用)
C:\Windows\System32\drivers\etc\hosts文件
在最后添加一句话127.0.0.1 www.daiyue.com
问题1:保存时,系统文件,不允许修改,另存为到桌面,拖进去覆盖它
问题2:打开是一个白板,把代老湿提供的覆盖过去
MySQL - 数据库产品:2大类
关系型数据库 - 以表格为主
Oracle - Oracle(甲骨文)
主要应用于【企业级】开发市场:大公司、国企、事业单位:警察局、医院...(不差钱) - 优势:安全性高 缺点:收费的
MySQL - Oracle(甲骨文)
主要应用于【互联网】开发市场 - 优势:免费、简单、开源 - 中小型企业
sqlserver - 微软:大学讲课
非关系型数据库 - 没有固定的格式
是一种运动 - 反关系型数据库
主流产品 - mongoDB,以JSON格式为主
MySQL
最初是由MySQL AB软点化公司推出
瞬间爆火 - 免费、简单、开源
个人:修改、查看、添加、删除源代码 - 开挂、私服
公司:免费聘请民间大佬帮你做测试,帮你升级,帮你维护
开源项目几乎不会赚钱:只能等你赞助
爆火的网站架构:LAMP - Linux系统 + Apache + MySQL + PHP - 这四个都是免费的,让中小公司的老板非常happy,只需支付员工费+场地费+水电气费
企业级网站架构:Linux(AIX) + JavaEE + Oracle + weblogic - 一套架构下来起码上百万 - 安全性高
MySQL AB被sun公司收购了
sun公司后期又被oracle公司收购了
oracle不会被收购,大佬,三款明星产品:
oracle
mysql - 社区版(免费)和商业版(收费)
java
为什么叫MariaDB?
MySQL的作者在oracle公司受到了歧视排挤,并不重视
MySQL的作者就自己出来重新做了原滋原味的MySQL了,但是名字不能再叫mysql,因为版权问题
用了自己小女儿的名字命名
go语句诞生原因之一,就是因为使用java底层的2句代码,被告了,赔偿了2个亿
b c
c++ c#
python java
巨蟒 sun:太阳
皮同
希腊过来的一个词 太阳神阿波罗
阿波罗杀了皮同
MySQL基本内容:
访问:2种
1、图形化界面(更加简单更美观)方式 - 傻瓜式操作
要求:同时打开mysql和apache
访问:127.0.0.1:端口号/phpmyadmin
localhost:端口号/phpmyadmin
有的同学可能打不开
2、*****命令行方式:复杂很多,但是只有这样你才能学到真正的技术:SQL语句
如何进入数据库:
1、打开cmd
2、输入cmd的命令,进入到d:/xampp/mysql/bind
1、输入:盘符: 回车
2、输入:cd xampp/mysql/bind
3、登录:mysql -uroot -p 回车不要加分号
4、退出:exit
5、SQL语句:关系型数据库SQL语句互通
1、数据库:
查看数据库:SHOW DATABASES;
创建数据库:CREATE DATABASE IF NOT EXISTS 数据库名称 CHARACTER SET utf8;
切换数据库:USE 数据库名称;
2、数据表:只教你如何创建数据表
数据库的数据类型:
数值:Int - 整型
Float/Double - 浮点型
Decimal - 精确值
字符串:
Char - 长度固定的
Varchar - 长度可变的
日期:
Date - YYYY/MM/DD
Datetime - YYYY/MM/DD hh:mm:ss
Timestamp - 时间戳(标识:唯一不重复 - id也可以)
创建数据表:
CREATE TABLE 表名(
字段名 数据类型,
...
);
举例:CREATE TABLE user(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(30),
pwd varchar(6),
email varchar(30),
vip varchar(1)
);
PRIMARY KEY:主键约束:绝对不会重复
AUTO_INCREMENT:主键自增:每次都会+1
3、*****数据/记录:
增:INSERT INTO 表名 VALUES(字段值,...);
举例:INSERT INTO USER VALUES(0,"张颜","123456","zy@qq.com","0");
删:DELETE FROM 表名 WHERE id=几; - 一旦删除数据就不回再回来了
改:UPDATE 表名 SET 字段名=字段值,... WHERE id=几;
查:3种语法:
SELECT * FROM 表名;
SELECT 字段名,字段名,... FROM 表名;
SELECT * FROM 表名 WHERE id=几;
疑惑:
1、为什么SQL语句要大写:约定,可以不遵守,放到PHP中为了瞬间一眼找到SQL语句
2、这些语句以后绝对不可能用cmd来运行,以后会在后端脚本php语言中运行
5.27
1、PHP:最简单的一门语言
爆火架构:LAMP
php文件,后缀.php
1、*****如何运行php
打开apache,将你的项目/文件夹放到htdocs里面,在用浏览器输入127.0.0.1,打开你需要运行的文件
特殊:其实php文件也支持前端代码(HTML+CSS+JS)和php代码,以后我们上网的时候,发现网页的后缀,不是.html也不必惊讶
任何一门语言,万变不离其宗,js(客户端:特效)和php(服务器端:沟通)都是一个脚本语言
2、***PHP的语法基础
1、输出方式:
1、*echo(想要输出的内容); 或者 echo 想要输出的内容;
echo只能输出4种标准类型,不能输出别的类型
2、var_dump(想要输出的内容)
var_dump可以输出一切数据类型,显示很详细,正是因为显示的太过详细,其实要不得,php输出在页面上的东西,某一天都会被前端用ajax拿走拿到前端去
2、变量和常量:
1、*变量:值可以变化的数据
语法:$变量名=值;
注意:使用时$不能省略
2、常量:值一旦创建了,不允许修改
语法:const 常量名=值;
3、*数据类型:
四种标准/基本/原始类型:
整型:Int
浮点型:Float/Double
布尔:Boolean
字符串:String - 有区别
单引号 - 只能放入纯文本
双引号 - 支持放入变量 - 类似js模板字符串
echo "{name}今年{age}岁,喜欢{$hobby}";
两种复合类型:
Array - 数组:保存多个相关数据
创建:
1、直接量:$arr=[值1,...] - 索引数组
2、内置对象:$arr=array( - hash数组:其实就是对象
key=>value,
...
)
访问:$数组名[下标]
遍历:循环
Object - 面向对象,不需要
两种特殊类型:
Resource - 资源类型
Null - 空,释放内存
"" - 有,值为空
null- 不存在
4、运算符:几乎和js一致,除了字符串拼接.,意味着php的API调用方法绝对不可能用.
5、分支:完全一样!if分支 switch分支 三目 都支持
6、循环:完全一样!
7、函数:完全一样!
8、所有的API:理论上来说完全一样,但是操作却不同,不需要学习,也不需要记忆,面向百度开发
上午练习:快速的熟悉php的语法
1、99乘法表 - php的循环和变量的拼接
2、计算标准体重 和 根据分数送礼物 - php的分支,php没有弹出框,服务器端的语言,本身是不支持浏览器操作的,是我们大发善心,借给他浏览器,让他在浏览器上可以显示输出内容
3、找出1-100之间所有的质数 - 逻辑提升
3、全栈开发:前端=>PHP<=>数据库
1、前端->后端
前端需要发起请求
1、表单请求/提交
注意:
1、input必须添加name属性,甚至有的input(radio、checkbox、select&option)可能还要添加value
2、form表单必须添加action="服务器端文件的路径";
3、method到底是用get还是post,和后端进行沟通/看开发文档
get->得到,只要跟安全性不挂钩的时候,大小有限制2kb:搜索框(把东西拿出来)
post->发送,只要跟安全性挂钩的时候,优先使用,举例:登录/注册(把东西放进去)
下周一新的请求方法:ajax:发送请求+可以把后端的东西拿回来
2、后端 需要接收住 前端传来的 请求消息
语法:_GET/POST/REQUEST["input的name的值"]
REQUEST - 请求:不管前端是GET还是POST,都能接住
2、后端<->数据库:php自带操作mysql的API,只需要学习4.5句话完毕
1、创建和数据库的连接对象
$conn=mysqli_connect("hostname","username","userpwd","dbname");
我们班的固定:
$conn=mysqli_connect("127.0.0.1","root","","h52202");
1.5、为此数据库设置中文编码
mysqli_query($conn,"SET NAMES utf8");
2、创建SQL语句:你要干什么
$sql="INSERT/UPDATE/DELETE/SELECT";
3、数据库要执行SQL语句
conn,$sql);
//增删改:true->执行成功 false->执行失败
//查:返回的是一个我们都不会认识的结果集对象
解决:php提供了一套方法
while((result))!=null){
var_dump($row);//拿到了数据要干什么?
echo "
";
}
4、断开和数据库的连接
mysqli_close($conn);
5.30
1、概念:
同步交互:客户端向服务器端发送请求,直到服务器端进行响应的全过程,用户是不能做其他事情的(等)
典型:网址请求、表单请求 - 都是属于同步交互
异步交互:客户端向服务器端发送请求,直到服务器端进行响应的全过程,用户是可以做其他事情的(不等)
典型:ajax请求
2、ajax:asynchronous javascript and xml:直译:异步的javascript和xml
不严格的定义:页面不会完全的刷新,只会导致局部页面发生改变
其实我们很早之前就已经见过一个异步技术了:
1、定时器 - 定时器里面的内容再耗时也不会卡主后续代码 - 做特效
2、ajax - 目的:在不刷新页面的情况下也可以和服务器端进行交互沟通,【可以将服务器端的数据放到前端】
3、如何使用:4个固定步骤
1、创建ajax的核心对象XMLHttpRequest - 简称XHR对象
var xhr=new XMLHttpRequest();
2、建立和服务器端的连接
xhr.open("GET/POST","xx.php");
3、向服务器发送请求
xhr.send("key=value&key=value&...");
特殊:
1、如果是GET请求,send方法会失效,但是还不能省略不写,必须写为xhr.send(null),请求消息放到url?后面
xhr.open("GET","xx.php?key=value&...");
xhr.send(null);
2、如果是POST请求,send方法可用,但是需要在之前设置请求头部
xhr.open("POST","xx.php");
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("key=value&...");
4、设置状态事件监听
xhr.onreadystatechange=()=>{
if(xhr.readyState==4&&xhr.status==200){
xhr.responseText;//response:响应。接收到服务器的响应:php放在页面上的一切东西 - 难在拿到东西你要干什么
}
}
上午练习:
1、随便写php,保证ajax可以拿到后端页面上的内容(后端echo的东西),不管get还是post都可以
2、你和对象的对话
3、真正的注册+根据数据库中所有的用户数据渲染了表格,并且支持删除操作:前端做不做验证,后端都要做验证
4、咖啡要加上百度地图:没难度
定位技术:GPS - 美国(缺陷:1、安全性 2、版权费)
北斗 - 中国:最初军用 - 惯性定位:不准确
后期民用 - 添加卫星:物联网 - 物体联网,车联网
基站 - 手机信号可以定位:不准确,一个基站覆盖范围大概半径1公里
ip
百度地图、高德地图 - gps定位:
如何使用:
1、打开百度搜索百度地图开放平台
2、注册/登录
3、拉到最下面申请注册为百度开发者
4、控制台->应用管理->我的应用->创建应用
5、创建应用时:注意:1、应用类型:浏览器端 2、白名单:*
6、恭喜你获得了密钥ak
7、鼠标放到导航条上开发文档->javascript API->示例DEMO->挑选你喜欢的地图,可以将多个喜欢的汇总为一个
切记:
1、密钥要用上
2、看清楚版本有的版本不能汇总:
老版本:未加gl版 - 几乎被淘汰了
新版本:gl版
5.31
1、XML数据格式:
1、面试题:HTML、XHTML、DHTML、XML分别是什么?
HTML - 网页
XHTML - 更严格的网页
DHTML - 动态的网页,不是新技术,也不是新概念,只是现有技术的整合(HTML+CSS+JS(dom)),导致我们的网页在离线时也具有动态特效
XML - 配置文件|数据格式 - 已经被淘汰了:x - 未知,ml - markup language 标记语言,未知的标记语言
它没有提供过任何预定义标签,所有的标签由你自定义,不在乎漂不漂亮
2、如何使用:
1、创建一个xx.xml文件
2、写入文档声明
version - 版本号:目前只有1.0和1.1,但是1.1升级的拉胯,所以没人使用,而且学完过后以后不需要再次学习,因为它再也不会更新了
encoding - 设置中文编码
必须出现在第一个行第一列
3、在下方写入一个根标签,注意必须是一个双标签:只有双标签才可以包裹住其他内容,而且只能有一个
4、里面其余标签你随意,恭喜你学完了
其实当初后端会把数据库的数据取出来,整理为XML数据格式
*前端开发人员:
1、依然使用ajax去获取
2、url写为"xx.xml";
3、不要使用xhr.responseText; 使用xhr.responseXML;可以当做DOM来处理(你学的叫做核心DOM - API繁琐)
一个好的数据格式能够极大的提升程序员的开发效率
2、*****JSON数据格式:javascript object notation:js对象表示法,本身就是js的一部分,只不过独立出来,各大主流语言都支持的一种轻量级【文本】数据
作用:类似于XML,都是一个数据格式,更简洁、更快、更容易解析
1、认识了哪些叫做JSON数据(JSON字符串):
1、'[1,2,3,4,5]'
2、'{"name":"代老湿","age":18}'
3、'[{},{},{},{}]'
4、'{"names":[],"ages":[],"salaies":[]}'
以上四种写法都是JSON字符串
2、PHP如何穿衣服:echo JSON_encode($arr); - 数据转为了JSON字符串
Node.js的语法和javascript几乎相同:如何穿衣服:JSON.stringify(arr);
3、前端依然使用ajax获取数据,xhr.responseText得到服务器端响应的的数据,如何脱衣服:
1、eval("("+jsonTxt+")");
*2、JSON.parse(jsonTxt);
3、为明天做准备:HTML+CSS+JS+PHP+MYSQL - 后台管理系统
客户端存储技术:
1、查询字符串:缺点:只适合双页面传输,多页面不方便,解析复杂
2、cookie:缺点:大小有限制2kb,保存解析非常麻烦,用户可以禁用cookie!
3、*****webStorage:几乎没有缺点:html5带来的新概念,老IE不支持。优点:大小有限制8mb,使用极其简单
分为两大类:
1、localStorage - 本地级:永久存在的
2、sessionStorage - 会话级:浏览器一旦关闭,数据就会死亡
保存:xxxStorage.属性名=值;
读取:xxxStorage.属性名
删除:xxxStorage.removeItem("属性名");
清空:xxxStorage.clear();
作业:
1、根据代老湿提供的XML/JSON渲染一个表格
2、根据代老湿提供的XML/JSON渲染一个多级联动
3、根据代老湿提供的XML/JSON渲染一个选项卡
4、7天内不用再次输入密码
5、皮肤/主题选择
6.1
logo免费生成:www.uugai.com/
6.2
1、规划:jQuery框架+Bootstrap框架+Node.js + 小东西(gulp/git/svn) - 除Node.js其余都非常简单,量大
要求:1、习惯使用帮助文档(官方文档|百度)
2、jQuery框架概念:
jQuery类库其实就一个.js文件
在三大框架(vue、react、angular)出现之前,曾经全球最火的一个框架
在三大框架(vue、react、angular)出现之前,曾经全球第二火的框架:prototype.js
...多不胜数,15年统计过一次,8000+类库,导致了一个问题,永远学不完,所以以某一个类库为案例,学习类库的特点
目的|特点:简化DOM开发、事件、ajax
3、面试题:为什么有的人称呼jQuery是一个框架,有的人称呼jQuery是一个类库?
因为大部分人不知道jQuery其实由4部分组成:
1、jQuery.js - 专门简化js开发 - 大部分人只知道它,所以称呼jQuery叫做一个类库
2、jQuery.ui.js - 专门针对UI开发 - 初衷:哪怕没有UI设计师,使用jQuery.ui,做出来的网页不会太丑(HTML+CSS+JS) - 插件库
3、jQuery.mobile.js - 专门针对移动端开发 - 淘汰的:三阶段学习uniapp
4、Qunit - 专门给测试人员(不懂代码,英语好)测试js代码的
4、jQuery的历史:
版本:1.xx - 在支持老IE的同时,还做了向上兼容(新版本带来的新特性,我们也可以使用到)
2.xx - 不再支持老IE
3.xx
诞生:06年
爆火:免费、简单、开源
目的:提供了10000多行代码,带来了一个叫做jQuery的对象(属性和方法) - 但是一定比以前简单的多
5、如何使用jQuery:
1、固定步骤:
1、在HTML页面引入jquery-1.11.3.js文件
2、*使用jQuery提供的选择器去获取元素
3、*使用jQuery提供的API去操作元素
2、jQuery提供了一个工厂函数(很重要,可以干很多操作):
语法:*$() 或者 jQuery()
作用:
1、查找元素:$("jQuery选择器") - 一切的css选择器都可以使用,但是jQuery提供了更多的选择器:jQuery的作者非常喜欢css选择器
注意:
1、千万不要记忆,习惯使用帮助文档:www.w3school.com.cn/jquery/jque…
2、封装js的底层代码:document.querySelectorAll(); 提供了更加丰富的选择器
3、*****返回:不再使用DOM集合,而是一个JQ对象:
2、转换:
问题:jQuery和DOM对象都只能使用自己提供的操作,不能用别人的方法
解决:
1、jQuery -> DOM
语法:$("jQuery选择器")[下标] - 绝对没用,不会把简单的变成复杂的
*2、DOM -> jQuery
语法:$(dom对象) - 真有用,this/e.target -> 自动是一个DOM对象,用不了jQuery的操作
3、jQuery的特性:
1、链式操作 - 找到一个元素后可以不断地连续的.操作它
2、隐式迭代 - 悄悄的自动的循环,不用/千万不要去循环他,千万不要加下标
4、*通过关系获取元素:前提:先找一个元素
父:$("xx").parent();
子:$("xx").children();
前一个兄弟:$("xx").prev();
后一个兄弟:$("xx").next();
*除了自己的其他兄弟:$("xx").siblings();
5、*操作元素
内容 - html/text/val - 完全等效于以前的innerHTML/innerText/value
语法:获取:$("xx").api()
设置:$("xx").api("新内容")
属性 - attr - 完全等效于以前的getAttribute/setAttribute
语法:获取:$("xx").attr("属性名")
设置:$("xx").attr("属性名","属性值")
删除:$("xx").removeAttr("属性名")
jQuery专门为class提供了一系列操作:
追加class:$("xx").addClass("新的class");
删除class:$("xx").removeClass();
-
如果不传入参数,清空所有class
-
如果传入参数,删除指定的class
切换class:$("xx").toggleClass("新的class");
- 在有此class和没有此class之间进行切换
样式 - css - 无敌的,不关系你的内联还是样式表,他只关心当前生效的样式是什么
获取:$("xx").css("css属性名")
设置:$("xx").css({ - 设置一定设置的是内联样式,优先级最高
"css属性名":"css属性值",
...
})
6、*创建元素&渲染页面&删除元素&克隆元素
工厂函数的第三个作用:
1、创建元素
var 新元素={变量}</结束标签>`)
2、渲染页面:4种
向里插入,当儿子
*$("父元素").append(新元素); - 最后一个儿子
$("父元素").prepend(新元素); - 第一个儿子
向外插入,当兄弟
$("兄弟").before(新元素); - 前一个兄弟
$("兄弟").after(新元素); - 后一个兄弟
3、删除元素:$("xx").remove();
4、克隆元素:垃圾
$("xx").clone(true);//添加原来xx的js的功能
总结:工厂函数:
1、找元素:$("选择器")
2、DOM->JQ:$(dom元素)
3、创建元素:$("标签")
6.6
1、JQ事件
1、回忆目前学过的事件有哪些:
click/change/mouseover(冒泡)|mouseenter(无冒泡)/mouseout(冒泡)|mouseleave(无冒泡)/mousemove/blur/focus/submit/input/dblclick/contextmenu/resize/mousedown/mouseup/keydown/load
2、JQ如何绑定事件:
$("xx").事件名(callback)
3、面试题:原生JS中 window.onload 和 $(document).ready(callback) 有什么区别
1、window.onload:一个页面只能使用一次,执行效率也很低下:等待所有的资源(HTML、CSS、JS、图片、视频、音频...)加载完毕后才会执行,可以说是最后才执行的代码
2、$(document).ready(callback):一个页面可以用多个:执行效率相对较高,只等待DOM树加载完毕就会执行
简写:1、$().ready(callback)
2、$(callback);//工厂函数的第四个功能
为什么:
1、面试题
2、有可能我们会去读别人写的代码
但是我们绝对不会使用,因为我们的js始终放在最后面
4、暂未学过的新事件:
1、*****滚动监听事件
作用:
1、做出更好看更多的特效
2、滚动监听搭配上ajax(往下滚动都显示出更多的新内容):等我们学了JQUERY提供的AJAX再说
如何使用:
$(window).scroll(()=>{
//1、获取滚动条当前的位置:$(window).scrollTop();
//2、获取xx距离页面顶部有多远:$("xx").offset().top/left;
})
上午练习:
0、面试题试一下
1、滚动监听:导航条 + 到了某处才显示出来的元素
2、JQ的预定义动画
2、JQ动画:
1、预定义动画:3组9个
1、隐藏hide和显示show:
$("xx").api(time,callback);
特殊:
1、如果没有传入任何一个参数,不带有动画,瞬间显示和瞬间隐藏
2、如果带有事件参数,则具有动画,同时修改元素的宽度和高度和透明度
3、回调函数在动画执行完毕后才会执行 - 屌
$("xx").toggle(time,callback); === show+hide;程序员连判断都不用自己写了
2、滑动效果:隐藏slideUp和显示slideDown:
$("xx").api(time,callback);
特殊:
1、如果没有传入任何一个参数,其实也会带有动画,只不过速度很快
2、如果带有事件参数,则具有动画,同时修改元素的高度
3、回调函数在动画执行完毕后才会执行 - 屌
$("xx").slideToggle(time,callback); === slideUp+slideDown;程序员连判断都不用自己写了
2、淡入淡出:隐藏fadeOut和显示fadeIn:
$("xx").api(time,callback);
特殊:
1、如果没有传入任何一个参数,其实也会带有动画,只不过速度很快
2、如果带有事件参数,则具有动画,同时修改元素的高度
3、回调函数在动画执行完毕后才会执行 - 屌
$("xx").fadeToggle(time,callback); === fadeOut+fadeIn;程序员连判断都不用自己写了
2、自定义动画:
1、并发动画:所有动画一起执行
$("xx").animate({
"css":"新值",
...
},time,callback)
2、排队动画:做完一个在做下一个
$("xx").animate({
"css":"新值"
},time,callback).animate({
"css":"新值"
},time,callback).animate({
"css":"新值"
},time,callback).animate({
"css":"新值"
},time,callback).animate({
"css":"新值"
},time,callback).animate({
"css":"新值"
},time,callback)
特殊:1、animate方法不支持颜色相关和transform转换相关的操作
解决:1、不用animate,用css代替,但是就会损失掉动画执行完毕的回调函数
2、等我们学习jQueryUI,jQueryUI会对animate方法进行增强操作
2、只要是动画就有可能会排队,有的情况要记得停止动画
$("xx").stop().animate()
作业:
1、使用滚动监听,做出(1、滚动时会变成固定定位的导航条 2、滚动到某处,某个东西才会显示出来)
2、重做鼠标跟随效果
3、无缝轮播:
判断是否具有动画:
$("xx").is(":animated") - xx具有动画才为true
!$("xx").is(":animated") - xx不具有动画才为true
4、联合答辩项目的规则:
1、两个人一组,自选项目电商(换logo,换交互色)
2、全栈开发:7个页面:首页、产品列表页、详情页、登录、注册、购物车页、结算页
3、要求页面美观
4、一个人只做前端(HTML+CSS+JS+AJAX),另一个人(HTML+CSS+JS+AJAX+PHP+MYSQL)
如果两个人实力相当,平均分配,最后在合并,以防有冲突
5、优先一起写一个开发文档:
首页:
业务功能:轮播、倒计时...
业务逻辑:跳转到哪些页面...
甚至可以规划出,数据库需要几个表,PHP的哪些接口对应着哪些操作
6、6月17号答辩:
三个方面:
1、表达能力 - 30分
2、页面美观 - 30分
3、逻辑方面 - 40分
6.7
1、jQueryUI:基于Jquery的开源网页用户界面代码库 - 提供了HTML、CSS、JS的一个组件/插
插件:跟组件差不多,但是具有JS功能
如何使用jQueryUI:固定步骤
1、下载jQueryUI - 不需要你做
2、*在页面中引入 - JS顺序千万不能乱:因为jQueryUI是基于jquery的
3、*挑选出你需要的/喜欢的插件,直接梭到你的项目中
4、*根据UI提供给你的设计图,修改样式 - 修改不成功,只有一个可能:权重不够!
5、*****利用ajax去获取数据库中的数据,进行页面的数据渲染
6、千万别忘了在最后调用jQueryUI提供的xx方法实现效果
个人比较推荐的jQueryUI的插件:
1、选项卡/标签页
2、菜单
3、手风琴/折叠面板
4、自动完成/模糊查询
5、特效还不错:爆炸效果:增强了原来的toggle("特效名称",time,callback)、show、hide方法
6、交互部分留给大家慢慢试
7、增强了animate:现在支持颜色操作了,但是依然不支持转换
8、拖动
作业:
1、从现在开始,学会整理一个属于自己的组件库(多多益善):建议:挑选的尽量的简单,不要太炫酷太复杂,为了以后方便修改成各种各样的东西
2、日期选择器
layUI:在去年年底下架了,因为白嫖的人太多了,没人赞助,开源项目没有收入,所以凉了
唯一缺点:下架了
优点:简单易用开源 - 学会看文档
3、无敌的插件库
1、百度搜索jQuery插件库
缺点:一个账号只能下次量词
2、jQuery之家,可以无线下载,不限制账号
6.8
jQuery封装的ajax
一定要先引入jquery.js:简化DOM、事件、ajax,带来了一些JS没有提供过的新东西
一切的框架:目的都是为了简化DOM开发
1、第一层:最麻烦,最无敌
$.ajax({//配置信息,其实是ES6提供的一个新语法,叫做解构赋值
url:"xx.php",//必写 - 要连接的服务器的路径
type:"GET/POST",//不是必写 - 默认值:GET
data:"key=value&...",//不是必写 - 看服务器端需不需要接受前端传到后端的消息
dataType:"HTML/XML/JSON",////不是必写 - 默认值为HTML,说白了json字符串
success:data=>{ //必写,成功后才会执行的回调函数,并且会自动帮你得到服务器端响应的消息
data->xhr.responseText
}
})
2、第二层:再次简化:3个API,缺点:不能做跨域操作
1、$("xx").load("url","data",callback); - 垃圾
缺点:
1、数据会直接放在xx元素上,不科学,不能把数据给用户看
2、无法设置get或者post请求类型
3、无法脱衣服
2、$.get("url","data",callback,"JSON");
3、$.post("url","data",callback,"JSON");
上午练习:
1、把第一层和第二层用法试一试,然后随便生成点什么,保证语法会用即可
3、第三层:特殊功能:跨域:你可以去拿别人电脑上的数据库和服务器,合作开发
同源策略:浏览器的保护机制,访问时服务器要求【协议、域名、端口号】相同的情况才可以,只要有一个不同则会触发此保护机制
跨域:跨过同源策略,能够访问别人的电脑上的东西:
技术:
1、JSONP
2、CORS - 后端
3、反向代理
前端:jQuery封装的第三层ajax自带JSONP技术,跨域技术,帮助跨域
$.getJSON("url?自定义键名=?","data",callback);
注意:
1、只能是GET请求
2、不需要脱衣服
3、?是固定写法,jQuery中JSONP会自动将?进行赋值,赋值为一个通行令函数
后端(PHP):
echo $_GET["自定义键名"]."(".JSON_encode(数据库整理出来的JSON数据).")";
沟通:
1、通行令的名字叫什么
2、你的ip完整的地址要给我:打开cmd:ipconfig - ipv4
3、前端还应该说些什么
4、git工具(9+) 对应 svn工具(1-)
git工具:分布式版本管理控制工具:分布式:人人都是客户端,人人都是服务器端(云端)
目的:就算我们在家里/多方合作开发
固定使用:
0、注册gitee
1、先安装:Git-2.18.0-64-bit - 命令行方式
2、再安装:TortoiseGit-2.6.0.0-64bit.msi - 小乌龟(简化操作,并且带来了一些提示标志),一定要重启电脑
注意:我忘了是哪个软件,要你输入你的gitee的用户名和邮箱
3、项目经理/组长:
打开网站:gitee码云:gitee.com/?from=osc-i…
登录
创建项目仓库
把仓库地址发给对应的开发人员 gitee.com/daiyue0221/…
4、开发人员
1、拿着项目经理给你的仓库地址,把仓库拉取到本地:任意位置右键git bash here:
git clone 仓库地址
2、关闭掉git bash here,在项目仓库文件夹中再次打开git bash here
3、开始进行项目开发/工作
4、在下班之前,要提交到云端gitee:
git add . - 文件提交到了本地
git commit -m"必须写日志" - 文件提交到了git服务器
git push origin master - 推送到云端
5、第二天上班之前,更新一下
git pull origin master - 更新
面试题:背一下你的git的仓库地址:gitee.com/用户名/仓库名
作业:
1、把两个练手项目 - 传到gitee云端,然后把仓库换成开源,直接把地址发给我
6.9
1、Bootstrap:简洁、直观、强悍的前端开发框架,让web开发更迅速、简单。类似于jQueryUI,提供了HTML/CSS/JS,程序员只要复制+修改
用于开发【响应式布局】、移动设备优先的 WEB 项目。
目的:简化响应式开发
重点:大部分都是直接复制,重点:1、栅格式布局 2、动态样式语言sass和less,静态样式语言css不是人写的
2、如果想要做出响应式布局必不可少的东西,即使有了bootstrap:
1、不用绝对单位(px,cm,mm),使用相对单位(rem+vw)
2、媒体查询@media
3、响应式图片,而不要直接给图片设置宽度为100%,导致图片失帧
4、元标签:
但是不是所有的网站都适合做成响应式网页:比如电商
3、固定使用:
0、打开官方文档:
1、下载:
2、引入:
3、去挑选你喜欢的东西,复制
4、根据设计图进行样式的修改
5、根据数据渲染页面
4、bootstrap提供了三方面:提供了大概1000+个class,只需要看文档,而且还提供了css reset
1、css全局样式
2、组件
3、javascript插件
作业:
1、认真的把bootstrap的文档看一看,然后你看上的东西梭过来再试一试
5、*****bootstrap栅格式布局方式 - 简化响应式布局开发
固定步骤:10步
1、必须放入一个父容器:
2、再其中放入行:
3、再其中放入列:
4、第一个*:屏幕:bootstrap把屏幕分为了4种:col-lg(>=1200)/md(>=992)/sm(>=768)/xs(<=767)
5、第二个*:占的列宽,要占几份,bootstrap把一行等分为了12份
6、正是因为class支持写多个,可以设置某个div在不同屏幕,占比不同
7、更小的屏幕可以管住更大的屏幕,但是最大的屏幕只能管住自己,但是自己有一定有用自己的
col-lg-* 只能管LG屏幕
col-md-* 只能管LG/MD屏幕
col-sm-* 只能管LG/MD/SM屏幕
col-xs-* 管所有屏幕
8、可以设置某列在某个屏幕下隐藏:
hidden-屏幕 只管当前屏幕
9、列可以设置偏移量:理解为向左顶出几份位置
col-lg-offset-* 只能管LG屏幕
col-md-offset-* 只能管LG/MD屏幕
col-sm-offset-* 只能管LG/MD/SM屏幕
col-xs-offset-* 管所有屏幕
10、栅格式布局是一个怪异盒模型:设置间距,绝对不能使用margin,使用边框设置间距
标准盒模型:内容+内边距+边框+外边距
怪异盒模型:内容+外边距
6、$sql="SELECT 字段名,... FROM 表名 ORDER BY id DESC LIMIT 开始位置,截取的个数;";
作业:
1、作业1和作业2
6.10
静态样式语言:css,作为一门语言,并不称职,不具备语言的一些基础概念(变量、运算、循环、分支、函数...)
所以,导致我们在开发和维护大型项目的时候极不方便
根本就不是人写的:
1、是动态样式语言【编译】出来的
2、写起来太麻烦
1、动态样式语言:scss、less:在css的基础上,添加了新特性,目的:简化css开发
常见动态样式语言:
1、sass->*scss
2、less
3、stylus - 和css的语法差别太大
scss和less,你只要会css,基本就会了
2、编译:浏览器只认识css,不认识其他的动态样式语言,动态样式语言=(编译)=>自动生成一个css,HTML真正引入的是css
如何编译:
1、vscode - 安装一个插件,easy sass,编写你的sass/scss只要一保存,就会自动生成一个css
2、HBuilder - 安装一个插件
3、网上还有很多很多的编译工具
3、学习:scss的新特性:
1、*变量:
创建:$变量名:值;
特殊:1、使用时:$不能省略
2、不区分中划线和下划线
3、依然具有类似于我们js的作用域:全局变量和局部变量,如果你的某个变量出现在某个选择器中,则为一个局部变量
2、*****嵌套:选择器可以进行嵌套
语法:
.d1{
...
.d2{
...
.d4{
...
}
}
+.d3{
...
}
&:hover{...}
}
编译:
.d1{...}
.d1 .d2{...}
.d1+.d3{...}
.d1 .d2 .d4{...}
.d1:hover{...}
特殊:
1、层级选择器:由你自己来决定,如果省略不写,默认是后代选择器(空格)
2、&类似于javascript中this,&在那个大括号里面,就是指的谁 .nav>.container+ul~li>a:hover
3、*引入/导入:
@import "文件名";
把多个scss汇总为一个css
4、注释:多行注释:/注释内容/
5、*****混合器:类似于javascript中函数:
1、创建混合器
@mixin 混合器名($形参名:默认值,...){
css属性名:$形参名,
...
}
2、调用混合器
@include 混合器名($形参名:实参);
特殊:
1、使用时,关键字别掉了
2、传参的顺序无所谓,并且不传实参,使用默认值
3、碰到重复的代码了,在提取出来封装成一个混合器
6、继承:垃圾
7、运算:尤其是颜色值运算,可以让我们满足土老板的要求,越往0靠近数字越小,就会越暗淡,数字越靠近f越大,就会越明亮
8、其实也支持分支和循环,但是不推荐,scss目的:简化css
学完scss就意外着学完了less,几乎完全相同:
1、变量:@变量名:值;
2、混合器,不用任何关键字
没了,其余都一模一样
了解着玩玩:bootstrap的源代码
但是需要慢慢看,才能慢慢改...
git(9+):分布式版本管理控制工具:人人都是客户端,人人都是服务器端(云端) - 有可能被黑客攻击、破解
svn(1-):集中式版本管理控制工具:小乌龟操作:一个公司里,只有一台电脑是服务器端,其余人都是客户端(局域网使用),缺点:服务器坏了,卵大爷
哪些公司:老公司,老项目,保密性要求极强的公司
使用步骤:
0、如果你是项目经理:安装svn服务器端:VisualSVN-Server-4.3.2-x64.msi
1、为每一个参与此项目的员工创建一个账号
2、创建项目仓库
3、把账号和仓库地址发你
4、统筹全局(监督、任务进度)
1、开发者:安装小乌龟:TortoiseSVN-1.14.1.29085-x64-svn-1.14.1.msi
1、任意位置右键svn checkout拉出/检出仓库
2、开发
3、下班之前,提交:右键svn commit,选中你修改的/创建的提交,记得写日志
4、第二天,更新:右键svn update
6.13.
1、Node.js概述:不是"JS",但是语法和javascript非常相似,他的竞争对手java、php、python、c#...
绝对不是做特效,而是和数据库进行交互
目的:
1、使用Node.js【代码】自己搭建一个服务器&文件系统
2、使用Node.js访问数据库 - 第三方模块
3、全栈项目:图书管理系统:JQ+Bootstrap+Node.js+MySQL
2、Node.js的安装:
版本号:16年初(0.10) 16年中(4.xx) 16年底(6.xx)
更新速度快:学习成本高、不成熟:一个行业如果能迅猛的发展,说明前景好
你们需要安装node-v12.1.0-x64.msi - win7不支持node.js14版本以上 - 其实一个运行Node.js的环境
一路往下点,不取消任何东西
检查自己安装是否成功:打开 cmd 输入 node -v
3、如何运行Node.js:3种
1、交互方式|命令行方式 - 临时测试
打开cmd:输入node回车,就可以开始敲你的"js"代码了
2、文件模式 - 真实开发使用
提前创建一个xx.js文件,里面写入你的Node.js代码
打开cmd:输入node 文件的绝对路径 回车
3、编辑器有插件,但是前提就是安装了node.js环境
vscode:code runner
HBuilder:也有插件
4、Node.js的知识点:
1、javascript和Node.js的区别:
javascript:ES+DOM+BOM - 完成想要的一切特效
Node.js:ES一切依然可用,但是没有DOM和BOM,有更多的新东西等待我们去学习(新模块:无数个)
2、模块分类:
1、官方模块
2、第三方模块 - npm去下载
3、自定义模块
新概念:模块 -> 模块化开发:一个电商项目,可以分为很多个模块,让不同人做不同模块,最后主模块汇总:
用户模块、商品模块、商家模块、促销模块....
其实一个.js文件就可以称之为叫做一个模块:
每个模块都可以公开/导出/暴露自己的成员给别人:2种
1、exports.成员名=成员值;
2、module.exports={
成员名:成员值,
...
}
每个模块(主模块)都可以去引入别人的模块,使我们的开发变得更加的轻松:
var xxx=require("./文件路径");
注意:自定义模块./不可以省略
面试题:exports和module.exports的区别?
两者都是用于公开导出的,其实node.js的底层能做到公开功能的是module.exports
node.js的底层有一句话:var exports=module.exports;
但是千万不能这么写: exports={} 把上面那句话给覆盖了,不在具备公开的功能
3、官方模块:不需要下载,在你安装node环境时已经下载安装好了,需不需要引入不确定,需要看文档
1、Global:不需要引入,直接可用
1、在我们Node.js不具备window全局对象,真正的全局是Global
2、为我们带来了5个全局变量可以直接使用
__filename - 得到此文件的完整的绝对路径,无用
__dirname - 得到此文件的文件夹的完整的绝对路径,你们个别同学有用!在学习node的时候我可以随时随地的写相对路径,某得同学可能不行,只能写绝对路径
exports - 公开成员的对象
require - 用于引入其他模块的一个函数
module - 指代当前模块本身,包含着以上4个操作
3、控制台和定时器:但底层绝对不是当初的控制台和定时器,用法和当初一模一样
多了一个瞬间定时器:setImmediate(callback) === setTimeout(callback,0);
2、querystring:查询字符串模块:用于解析查询字符串模块,方便获取前端传到后端的请求消息
需要引入:let qs = require('querystring'); - 官方模块不用+./
API:var obj=qs.parse("查询字符串")
垃圾:只能解析查询字符串,不能解析完整的网址
3、*url:小重点:用于解析url网址,使我们可以得到网址中各个部分
需要引入:let url = require('url');
API:var objUrl=url.parse("url",true);
获取路由:objUrl.pathname
获取请求消息:objUrl.query.键名 - 明天有用,前端=>后端
4、Buffer:缓冲区 - Node.js提供的一种新的数据类型,但是我们绝对不会主动使用它,但是我们会被动使用一些API的时候就会得到Buffer
但是,不必担心,Node.js一会儿要学的大部分API是支持Buffer的
5、***fs:中重点:fileSystem:文件系统:用代码可以增删改查我们的文件
Node.js提供了两套API,分别是同步的和异步的,我们喜欢异步,因为异步才可以最大返回Node.js的特点(快)
需要引入:let fs = require('fs');
*异步读取:
fs.readFile('文件路径', (err, data) => {
console.log(data);//我读到东西过后,要干什么,必须在这里做
});
异步写入:会替换掉原来的东西
fs.writeFile('文件路径', "新内容"||buffer ,(err) => {
//我写完东西过后,要干什么,必须在这里做
})
异步追加:不会替换掉原来的东西
fs.appendFile('文件路径', "新内容"||buffer ,(err) => {
//我写完东西过后,要干什么,必须在这里做
})
强调:vscode的同学,先试试,你的相对路径可不可以用,如果不可以使用,写绝对路径
小练习:现在public/css/style.css的文件,对其进行一次复制,生成一个public/css/style.backup.css文件
6、*****http:超级重点:搭建服务器
需要引入:let http = require('http');
//创建服务器
var app=http.createServer();
//设置监听端口
app.listen(80);
//绑定请求事件
app.on("request",(req,res)=>{
//req:request请求对象,req.url保存着前端发来的请求消息和路由这两部分,我们就需要解析得到前端传来路由,然后判断路由访问的是什么文件,我再去用fs读取那个文件发送给他看,今天虽然没用到请求消息,明天用
//res:reponse响应对象,res.end(发送给前端支持buf和str)
console.log("啊,我是服务器端,我收到了一个前端发来的请求");
})
一切的src和href,一切引入其实在服务器端看来都是一个请求