0、前端知识体系
想要成为真正的“互联网Java全栈工程师”还有很长的一段路要走,其中前端是绕不开的一门必修课。本阶段课程的主要目的就是带领Java后台程序员认识前端、了解前端、掌握前端,为实现成为“互联网Java全栈工程师”再向前迈进一步。
0.1、前端三要素
- HTML(结构):超文本标记语言(Hyper Text Markup Language),决定网页的结构和内容
- CSS(表现):层叠样式表(Cascading Style Sheets),设定网页的表现样式。
- JavaScript(行为):是一种弱类型脚本语言,其源码不需经过编译,而是由浏览器解释运行,用于控制网页的行为
0.2、结构层(HTML)
太简单,略
0.3、表现层(CSS)
CSS层叠样式表是一门标记语言,并不是编程语言,因此不可以自定义变量,不可以引用等,换句话说就是不具备任何语法支持,它主要缺陷如下:
- 语法不够强大,比如无法嵌套书写,导致模块化开发中需要书写很多重复的选择器;
- 没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护; 这就导致了我们在工作中无端增加了许多工作量。为了解决这个问题,前端开发人员会使用一种称之为【CSS预处理器】的工具,提供CSS缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性。大大的提高了前端在样式上的开发效率。
什么是CSS预处理器
CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只需要使用这种语言进行CSS的编码工作。转化成通俗易懂的话来说就是“用一种专门的编程语言,进行Web页面样式设计,再通过编译器转化为正常的CSS文件,以供项目使用”。
常用的CSS预处理器有哪些
- SASS:基于Ruby ,通过服务端处理,功能强大。解析效率高。需要学习Ruby语言,上手难度高于LESS。
- LESS:基于NodeJS,通过客户端处理,使用简单。功能比SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以如果我们后台人员如果需要的话,建议使用LESS。
0.4、行为层(JavaScript)
JavaScript一门弱类型脚本语言,其源代码在发往客户端运行之前不需要经过编译,而是将文本格式的字符代码发送给浏览器,由浏览器解释运行。
JavaScript框架
- JQuery:大家熟知的JavaScript库,优点就是简化了DOM操作,缺点就是DOM操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6,7,8;
- Angular:Google收购的前端框架,由一群Java程序员开发,其特点是将后台的MVC模式搬到了前端并增加了模块化开发的理念,与微软合作,采用了TypeScript语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如1代–>2 代,除了名字,基本就是两个东西;截止发表博客时已推出了Angular6)
- React:Facebook 出品,一款高性能的JS前端框架;特点是提出了新概念 【虚拟DOM】用于减少真实 DOM 操作,在内存中模拟 DOM操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习一门【JSX】语言;
- Vue:一款渐进式 JavaScript 框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了 Angular(模块化)和React(虚拟 DOM) 的优点;
- Axios:前端通信框架;因为 Vue 的边界很明确,就是为了处理 DOM,所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery 提供的AJAX 通信功能;
UI框架
- Ant-Design:阿里巴巴出品,基于React的UI框架
- ElementUI、iview、ice:饿了么出品,基于Vue的UI框架
- *BootStrap*:Teitter推出的一个用于前端开发的开源工具包
- AmazeUI:又叫“妹子UI”,一款HTML5跨屏前端框架
JavaScript构建工具
- Babel:JS编译工具,主要用于浏览器不支持的ES新特性,比如用于编译TypeScript
- WebPack:模块打包器,主要作用就是打包、压缩、合并及按序加载
注:以上知识点已将WebApp开发所需技能全部梳理完毕
0.5、三端同一
混合开发(Hybrid App)
主要目的是实现一套代码三端统一(PC、Android:.apk、iOS:.ipa)并能够调用到设备底层硬件(如:传感器、GPS、摄像头等),打包方式主要有以下两种:
- 云打包:HBuild -> HBuildX,DCloud 出品;API Cloud
- 本地打包: Cordova(前身是 PhoneGap)
微信小程序
详见微信官网,这里就是介绍一个方便微信小程序UI开发的框架:WebUI
1、什么是Javascript
1.1、概述
javaScript是一门世界上最流行的脚本语言 Java,JavaScript 10天 一个合格的后端人员,必须精通JavaScript
1.2、历史
见百度 ECMAScript它可以理解为JavaScript的一个标准 最新版本已经到es6版本~ 但是大部分浏览器还只停留在支持es5代码上! 开发环境–线上环境,版本不一致
2、快速入门
2.1、引入JavaScript
1、内部标签
<script>
//....
<script>
2、外部引入 hj.js
aert("hello,world");
test.html
<!--外部引入
注意:script必须成对出现
-->
<script src="js/hj.js"></script>
<!--不用显示定义type,也默认就是javaScript-->
<script type="text/javascript"></script>
测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--script标签内,写Javascript代码-->
<!--<script>
alert("hello,world");
</script>-->
<!--外部引入
注意:script必须成对出现
-->
<script src="js/hj.js"></script>
<!--不用显示定义type,也默认就是javaScript-->
<script type="text/javascript"></script>
</head>
<body>
<!--这里也可以存放-->
</body>
</html>
2.2、基本语法入门
//1.定义变量格式:var 变量名 = 变量值
//js 里定义变量时不用声明数据类型,后面值是什么类型他就是什么类型
var num =1;
var name = "wsn";
var boolean = true;
//2.条件控制
var score = 89;
if(score>60&&score<80){
alert("及格");
}else if(score>80&&score<100){
alert("优秀")
}else{
alert("不及格")
}
//3.打印变量
//console.log(sorce)在浏览器控制台打印变量 相当于java的sout
2.3、数据类型
数值,文本,图形,音频,视频...
- 变量
var a1;//js中所有变量都用var定义
- number
js不区分小数和整数,Number
123//整数
123.1//浮点数
1.123e3//科学计数法
-99//负数
NaN//not a number
Infinity//表示无限大
- 字符串
'abc'
"abc"
- 布尔值
true
false
- 逻辑运算
&&//与
||//或
!//非
- 比较运算
=//赋值
==//等于(类型不一样,值一样,也会判断为true)例如"123"==123 结果为true
===//绝对等于(类型和值都要一样) 常用这个做判断
NaN === NaN //这个与所有的数值都不相等,包括自己
isNaN(NaN)//只能通过这个来判断这个数是否为NaN
- 浮点数的问题
console.log((1/3)===(1-1/3))//结果为:false
//在js中尽量避免使用浮点数进行判断,存在精度问题
console.log(Math.abs((1/3)-(1-1/3))<0.0000001)//用math的abs()绝对值的方法,让两个数相减,如果绝对值小于0.000001,就证明结果无限接近于零,也算是相等。
- null和undefined
null //空
undefined //未定义
- 数组
java中的数组必须是一系列相同类型的数字,而js中不需要
//这两种方式都可以,但尽量用第一种中括号的形式,保证代码的可读性
var arr = [1,2,3,"wsn",null,true];
new Array(1,2,3,4,"sas",null);
//取数组下标如果越界了,就会报undefined
- 对象
数组是中括号,对象是大括号。
//1.定义对象
//对比在java中是:Person person = new Person(1,2,3);
/*js创建对象格式 var 对象名 = {
属性名:值,
属性名:值,
属性名:值
}
*/
var person = {
id:1,
name:"wsn",
arr:[1,2,"sds",null]
}
//2.取值 对象名.属性名
console.log(person.name);//结果:wsn
console.log(person.id);//结果:1
2.4、严格检查格式
//1.一个项目往往有特别多的js文件,所以我们应该避免使用这种全局变量
i = 1;//这样是全局变量,避免!!!
//2.局部变量建议都使用let声明
var i = 1;//这样就是局部变量
let i = 1;//在ES6以后 let也可以声明局部变量 效果同var一样
//3.如果要检测js代码中是否使用了全局变量可以在代码最上面加上'use strict'
'use strict'//代表严格检查模式,预防js的随意性所导致的一些问题,必须写在js的第一行
i = 1; //这个i就会变红报错
3、数据类型
3.1、字符串
1.正常字符串我们使用单引号或者双引号包裹。
2.如果需要输出单引号或双引号字符,使用反斜杠转义即可。
- 转义字符串
\'
\t
\n
\r
\u42d //unicode字符 格式\u####
\x41 //Ascll字符
- 多行字符串编写
//``飘可以包裹多行代码
var i = `hello
world
xxxxx
`
- 模板字符串
//通过${}可以进行拼接
let name = "wsn";
let age = 23;
let msg = `你好,${name},${age}`
console.log(msg);//结果为:你好,wsn,23
- 字符串长度
var student = "student";
var length = student.length;
console.log(length);
- 字符串的可变性,不可变性
var student = "student";
//1.通过下图可以看到console.log(student[0])可以直接打印出字符串的第一个字符
//2.当我们给student[0]赋值为1时,没有报错。但我们再将student输出时发现之前赋的值并没有成功。
- 大小写转换
//注意,这里是方法,而不是属性
student.toUpperCase();//转换为大写
student.toLowerCase();//转换为小写
- 获取下标
//获取字符串中t字符的下标
student.indexOf('t');
- 截取字符串
//截取字符串
student.substring(1);//截取从第一个到最后一个的字符串
student.substring(2,5);//截取第二个到第五个之间的字符串 包含前面不包含后面
- 11
3.2、数组
数组可以包裹任意的数组类型
var arr = [1,2,3,4,5]
arr[0]//取值
arr[0]=1;//赋值
1.长度
arr.length
注意:加入给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失。
2.indexOf,通过元素货的下标索引
arr.indexOf(2);//结果:1
3.slice()截取数组的一部分,返回一个新数组。类似于String的substring
slice(1,3);//包头不包尾
4.push(),pop()
push('a','b');//压入到尾部
pop();//弹出尾部的一个元素
5.unshift(),shift()
unshift();//压入到头部
shift();//弹出头部的一个元素
6.排序sort()
let arr =["B","A","C"];
arr.sort();//["A","B","C"]
7.元素反转
let arr =["B","A","C"];
arr.reverse();//["C","A","B"]
8.拼接concat
let arr =["B","A","C"];
arr.concat(1,2,3);//["B","A","C",1,2,3]
//注意:concat()并没有修改数组,只是会返回一个新的数组
9.join()
//打印拼接数组,使用特定的字符串连接
arr.join('-');
"B-A-V"
10.多维数组
let arr = [[1,2],[3,4],["5","7"]];
arr[1][1]//取值:4
3.3、对象
/*js创建对象格式 var 对象名 = {
属性名:值,
属性名:值,
属性名:值
}
*/
var person = {
id:1,
name:"wsn",
arr:[1,2,"sds",null]
}
//1.取值
preson.name//结果:wsn
//2.使用一个不存在的对象属性不会报错
person.haha//结果:undefined
//3.动态的删除属性
delete person.name//结果:true
//4.动态的添加属性
person.haha = "haha"//结果:true
//5.判断属性的值是否在这个对象中
'name' in person;//结果:true
//6.判断一个属性是否是这个对象自身拥有hasOwnProperty()
person.hasOwnProperty('toString');//结果:false
person.hasOwnProperty('name');//结果:true
3.4、流程控制
1.if循环
if(3>2){
if(2===2){
console.log('111');
}
}else{
console.log('222');
}
2.while循环
while(true){
console.log('111');
}
3.for循环
for(i=0;i<10;i++){
console.log(i);
}
4.foreach循环
let array=[1,2,3,'4','wsn']
//1.第一种方式
array.forEach(element => {
console.log(element);
});
//2.第二种方式
let array.forEach(function(val){
console.log(val);
})
5.for...in ..和for...of...循环
let array=[1,2,3,'4','wsn']
//val是array的下标
for(var val in array){
console.log(array[val]);
}
//此时这个val是元素本身,不是下标
for(var val of array){
console.log(val);
}
3.5、Map和Set
注:所有的遍历都用for of。for in有bug
Map:
//1.创建map,和java近似
var map=new Map([['tom',90],['jack',60],['wsn',70]]);
//2.取值
var score = map.get('tom');//通过key取value
//3.添加键值对
map.set('admin',88);
//4.删除
map.delete('tom');
//5.遍历Map
for (let x of map) {
console.log(x);
}
Set:无序不重复的集合
//1.创建set,同上一样,set可以去重
var set=new Set([1,2,3,4,5,6,1,1,1,1]);
//2.查询set种是否有这个元素
var rel = set.has(2);
console.log(rel);
//3.添加值
set.add(9);
//4.删除
set.delete(2);
//5.遍历Set
for (let x of set) {
console.log(x);
}
4、函数及面向对象
4.1、函数定义
举例:定义绝对值函数
//1.第一种定义方式
function abs(x){
if(x>=0){
return x;
}else{
return -x;
}
}
//2.第二种定义方式
var abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
}
//这两种定义方式等效,习惯哪个用哪个
//一旦执行到return代表函数结束,返回结果
//如果没有执行return,函数执行完也会返回结果,结果就是undefined
调用参数;
//1.正常情况下调用参数
abs(10);//结果:10
abs(10);//结果:10
//2.在js种还存在参数是否存在问题
abs();//这样调用也不会错,返回的是NaN,但是我们不想要这样的结果,我们就需要在函数中添加判断条件规避。
function abs(x){
if(typeof x!=='number'){//x的类型不等于number时 typeof,'number'都是固定写法
throw 'not a number'; //判断为true 用throw 抛出异常
}
if(x>=0){
return x;
}else{
return -x;
}
}
//3.在调用参数时还可以添加多个参数也不会报错
//我们函数定义是设定形参只有一个值,但我们调用传递实参时可以传入多个值
abs(10,2,3,2,3,23,,2);//结果:10
//同样,这样的情况我们也应该规避,同上面一样在函数内添加判断规避
function abs(x){
if(arguments.length>1){//arguments代表的是这个函数所接收到的所有参数
throw '只能输入一个参数'//当所接收到的所有参数大于1时抛出异常
}
if(x>=0){
return x;
}else{
return -x;
}
}
arguments
这个参数是js免费赠送的关键字
代表的是传递进来的所有的参数,是一个数组
//沿用上面的例子
//arguments这个关键字,我们还可以在函数中判断当它长度等于1时调用哪个方法,长度为2时调用哪个方法去玩
function abs(x){
for(i=0;i<arguments.length;i++){
console.log(arguments[i]);//由此可以看出arguments是一个数组
}
if(x>=0){
return x;
}else{
return -x;
}
}
rest
arguments的问题:arguments包含了所有传进来的参数,我们有时想使用多余的参数来进行附加操作。需要排除已有的参数。而rest
//还是用上面的例子,这次我们用rest去获取多余的参数
function abs(x,...rest){//...rest固定写法
console.log(rest)//结果是一个数组,除了第一个参数的其他多余的参数组成
if(rest.length>0){//当多余的参数大于0,我们就可以抛出异常
throw '只能输入一个参数';
}
if(x>=0){
return x;
}else{
return -x;
}
}
4.2、变量的作用域
- 在javascript中,var定义变量实际是有作用于的。假设在函数体重声明,则在函数体外不可以使用。
function str(){
var x = 1;
x = x + 1;
}
x = x + 2; // Uncaught ReferenceError: x is not defined
- 如果两个函数使用了相同的变量名,只要在函数内部就不冲突。
function str(){
var x = 1;
x = x + 1;
}
function str2(){
var x = 'A';
x = x + 1;
}
- 内部函数可以访问外部函数的成员,反之则不行。
function num() {
var x = 1;
// 内部函数可以访问外部函数的成员,反之则不行
function num2(){
var y = x + 1; // 2
}
var z = y + 1; // Uncaught ReferenceError: y is not defined
}
console.log(z);
- 假设,内部函数变量和外部函数变量,重名!
function num(){
var x=1;
function num2(){
var x = 'A';
console.log('inner' + x);
}
console.log('outer' + x);
num2();
}
num();
- 假设在JavaScript中,函数查找变量从自身函数开始~, 由“内”向“外”查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量。
提升变量的作用域
function f2() {
var y;
var x = "x"+y;
console.log(x);
y = 'y';
}
f2();
// 输出:xundefined
- 说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值;
function ft2() {
var y;
var x = "x" + y;
console.log(x);
y = 'y';
}
- 这个是在javascript建立之初就存在的特性。 养成规范:所有 的变量定义都放在函数的头部,不要乱放,便于代码维护;
function de() {
var x = 1,
y=x+1,
z,i,a;
}
全局变量
// 全局变量
x = 1;
function f() {
console.log(x);
}
f();
console.log(x);
- 全局对象Windows
var x = 'xxx';
alert(x);
alert(window.x);//默认所有的全局变量都自动绑定在windiw对象下
- alert() 这个函数本身也是一个window的变量;
var x = 'xxx';
window.alert(x);
var old_alter = window.alert;
window.alert = function () {
};
// alter()失效了
window.alert(123);
// 恢复
window.alert = old_alter;
window.alert(453);
- javascript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错 Refrence。
规范
- 由于我们的所有变量都会绑定到window上。如果不同的JS文件,使用了相同的全局变量,就会产生冲突—>如何减少这样的冲突?
// 唯一全局变量
var wsn = {};
// 定义全局变量
wsn.name = 'subeiLY';
wsn.add = function (a,b){
return a+b;
}
- 自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突问题~ jQuery中就是使用的该方法:jQuery.name,简便写法:$()
局部作用域
function bbb() {
for (var i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);//结果:101
}
bbb();
//在上面方法中,for循环内是用var定义的变量i,但是for循环结束后依然能打印出101,说明i的作用域在for循环外面依然生效,这是我们不希望看到的,我们希望的是i的作用就在for循环里面,出了for循环i就失效。
- ES6的let关键字,解决了局部作用域冲突的问题!
function bbb() {
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1); // Uncaught ReferenceError: i is not defined
}
bbb();
//这次我们使用let关键字去定义i,发现在for循环外i无法生效,就达到了我们想要的效果。
//结论:以后只要是声明局部变量都用let去定义
- 建议大家都用let去定义局部作用域的变量;
常量
- 在ES6之前,怎么定义常量:只有用全部大写字母命名的变量就是常量;建议不要修改这样的值。
//ES6之前,使用大写去规范常量,但是实际上常量的值是可以修改的。
var PI='3.14';
console.log(PI);
PI='213';//可以改变这个值
console.log(PI);
- 在ES6引入了常量关键字
const
。
//ES6之前,使用const声明常量,这个时候再去修改就会报错。
const PI = '3.14';
console.log(PI);
PI = '123'; // Uncaught SyntaxError: Identifier 'PI' has already been declared
console.log(PI);
4.3、方法
定义方法
- 方法就是把函数放在对象的里面,对象只有两个东西:属性和方法。
var wsn = {
name:'xxx',
birth:2000,
// 方法
age:function () {
// 今年-出生年
var now = new Date().getFullYear();
return now-this.birth;
}
}
// 属性
wsn.name;
// 方法,注意带()
wsn.age();
- this.代表什么?拆开上main的代码看看。
function getAge() {
// 今年-出生年
var now = new Date().getFullYear();
return now -this.birth;
}
var wsn = {
name:'wsn',
birth: 2000,
age:getAge//这个地方调用方法就不需要带括号了
}
wsn.age();//调用成功
getAge();//调用失败返回NaN,因为里默认是window调用的这个方法,而window没有this.birth属性。
- this是无法指向的,是默认指向调用它的那个对象的;
apply
- 在JS中可以控制this指向
function getAge() {
// 今年-出生年
var now = new Date().getFullYear();
return now -this.birth;
}
var wsn = {
name:'wsn',
birth: 2002,
age:getAge
}
// wsn.age();
var wzj= {
name:'wzj',
birth:2001,
age:getAge
}
//每个对象都有apply这个方法,他需要传递两个参数,第一个参数是要指向的对象,第二个参数是具体的值
getAge.apply(wzj,[]);//这里wzj中age没有值,所以传空参[]
5、内部对象
标准对象
typeof 123
typeof '123'
typeof true
typeof NaN
typeof []
typeof {}
typeof Math.abs
typeof undefined
5.1、Date
var now = new Date();
now.getFullYear(); // 年
now.getMonth(); // 月
now.getData(); // 日
now.getDay(); // 星期
now.getHours(); // 时
now.getMinutes(); // 分
now.getSeconds(); // 秒
now.getTime(); // 时间戳 自1970年1月1日至今的毫秒数
console.log(new Date()); //"2023-11-11T06:17:01.852Z" 时间戳转时间
- 转换
now = new Date(1625895623770);//时间戳转为时间
now.toLocaleString; // 注意:调用是一个方式是,不是一个属性。
now.toLocaleString();
now.toGMTString();
5.2、JSON
JSON是什么?
- 早期,所有数据传输习惯使用XML文件!
- JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。。
- 简洁和清晰的层次结构使得JSON成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
-
在javascript中,一切皆为对象,任何js支持的类型都可以用JSON表示。
-
格式:
- 对象都用{}
- 数组都用[]
- 所有的键值对,都是用key:value
-
JSON字符串和js对象转化
var admin = {
name:"admin",
age:31,
sex:'M'
}
// 1.对象转化为JSON字符
var jsonAdmin = JSON.stringify(admin);
// 2.JSON字符转化为对象,参数为 JSON字符
var obj = JSON.parse('{"name":"subei","age":"22","sex":"W"}');
- JSON和JS对象的区别:
var obj = {a:'hello',b:'javaScript'};//js对象用大括号包括,里面的属性名不需要双引号或单引号引起来,冒号后面的值也是确定的值,不一定要用双引号或单引号引起来
var json = '{"a":"hello","b":"javaScript"}';//json就是字符串,所以他首先在大括号外面就要用双引号或单引号引起来,大括号里面的属性也全都是字符串用双引号或单引号引起来
5.3、AJAX
- 原生的JS写法,xhr异步请求;
- jQuery封装好的方法$(#name).ajax("");
- axios请求;
6、面向对象
6.1、什么是面向对象
javaScript、java、c#------面向对象;但是javaScript有些区别!
- 类:模板
- 对象:具体实例
- 原型:本质就是继承。
var Student = {
name:"subeiLY",
age:20,
run:function () {
console.log(this.name + " run....");
}
};
var xiaoming = {
name:"xiaoming",
};
var bird = {
fly:function (){
console.log(this.name + " fly....")
}
}
// 原型对象
// xiaoming.__proto__ = Student;
xiaoming.__proto__ = bird;//这段代码的意思是,xiaoming这个对象的原型指向bird,然后xiaoming就可以使用bird对象里面的方法了
// ES6之前========================
function Student(name){
this.name = name;
}
// 给Student新增一个方法
Student.prototype.hello = function () {
alert('Hello');
}
Typora快速调整代码块格式快捷键:
- 使用 ‘Shift + Tab’ 快速格式化代码。
class集继承
-
class关键字,是在ES6引入的
- 定义一个类、属性、方法。
// ES6之后========================
// 定义一个学生的类
class Student{
constructor(name){
this.name = name;
}
hello(){
alert('hello');
}
}
var xiaoming = new Student("xiaoming");
var xiaohong = new Student("xiaohong");
2. 继承
- 本质:查看对象原型。
class student {
constructor(name){
this.name=name;
}
hello(){
alert(this.name+"hello....");
}
}
class xiaoxuesheng extends student{
constructor(name,grade){
super(name);
this.grade=grade;
}
bye(){
alert(this.name+this.grade+"byebye.....");
}
}
var xiaohong =new student("xiaohong");
xiaohong.hello();
var fxy = new xiaoxuesheng("fxy",80);
fxy.bye();
原型链:
7、操作BOM对象
浏览器介绍
javaScript和浏览器关系?
- JavaScript的诞生就是为了能在浏览器中运行!!!
BOM:浏览器对象模型
- IE6~Edge
- Chrome
- Vivaldi
- FireFox
- Opera
第三方浏览器
- QQ浏览器
- 360浏览器
window
// window代表浏览器窗口
window.alert(1);//弹窗
undefined
window.innerHeight;//浏览器内部当前高度
699
window.innerWidth//浏览器内部当前宽度
158
window.outerHeight//浏览器外部高度
818
window.outerWidth//浏览器外部宽度
1065
Navigator(不建议使用)
// Navigator封装了浏览器的信息
navigator.appName
navigator.appVersion
navigator.userAgent
navigator.platform
- 大多数时候,不会使用
navigator
对象,因为会被认为修改! - 不建议使用这些属性来判断和编写代码。
screen:代表屏幕尺寸。
screen.width//1920
screen.height//1080
location(重要):代表当前页面的URL 信息。
location;
// 设置新的地址
location.assign('https://blog.csdn.net/m0_46153949');
document(内容DOM):document代表当前的页面,HTML DOM文档树。
- 获取具体的文档树节点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
<script>
var dl = document.getElementById('app');
</script>
</head>
<body>
<dl id="app">
<dt>java</dt>
<dd>javaSE</dd>
<dd>javaWeb</dd>
<dd>javaEE</dd>
</dl>
</body>
</html>
- 获取cookie
- 劫持cookie原理:
<script src="str.js"></script>
<!--恶意人员获取本机cookie上传至其私人服务器 -->
- 服务器端可以设置cookie为httpOnly。
history(不建议使用 ):代表浏览器的历史记录。
history.back(); // 后退
history.forward(); // 前进
8、DOM对象
核心
浏览器网页就是一个Dom树形结构!
- 更新:更新Dom节点
- 遍历Dom节点:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
要操作一个Dom节点,就必须要先获得这个Dom节点。
获得Dom节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
// 对应CSS选择器
var h1 = document.getElementsByTagName('h1');
var p1 = document.getElementById('p1');
var p2 = document.getElementsByClassName('p2');
var father = document.getElementById('father');
var childerns = father.children; // 获取父节点下所有的子节点
father.firstChild;
father.lastChild;
</script>
</body>
</html>
- 之后尽量都使用jQuery();
更新节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="id1">
123
</div>
<script>
var id1 = document.getElementById('id1');
</script>
</body>
</html>
-
操作
id1.innerText='456';
修改文本的值。id1.innerHTML='<strong>123</strong>';
可以解析HTML文本的标签。
-
操作CSS
id1.style.color = 'blue';
修改文本颜色;id1.style.fontSize='22px';
修改文字大小;id1.style.padding='2em';
修改文本位置;
删除节点
- 删除节点的步骤:先获取父节点,再通过父节点删除自己。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var self = document.getElementById('p1');
var father = p1.parentElement;
father.removeChild(self);
// 删除是一个动态过程
father.removeChild(father.children[0]);
// father.removeChild(father.children[1]);
// father.removeChild(father.children[2]);
</script>
</body>
</html>
- 注意:当删除多个节点时,children是在时刻变化的,删除节点的时候一定要注意。
插入节点
- 当获得了某个Dom节点,假设这个dom节点是空的,通过innerHTML就可以增加一个元素了,但是这个Dom节点已经存在元素了,就不能这么干了!会产生覆盖。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p id="js">JavaScript</p>
<div id="list">
<p id="se">javaSE</p>
<p id="me">javaME</p>
<p id="ee">javaEE</p>
</div>
<script>
var js = document.getElementById('js');
var list = document.getElementById('list');
list.appendChild(js); // 追加到最后
</script>
</body>
</html>
创建一个新的标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p id="js">JavaScript</p>
<div id="list">
<p id="se">javaSE</p>
<p id="me">javaME</p>
<p id="ee">javaEE</p>
</div>
<script>
var js = document.getElementById('js'); // 已经存在的节点
var list = document.getElementById('list');
// 通过JS创建一个新的节点
var newP = document.creatElement('p'); // 创建一个p标签
newP.id = 'newP';//和newP.setAttribute('id','newP')等效
newP.innerText = 'Hello,subeiLY';
// 创建一个标签节点
var myScript = document.creatElement('script');
myScript.setAttribute('type','text/javascript');//(键值对)第一个值是属性名,第二个值是值
// 可以创建一个style标签
var myStyle = document.creatElement('style'); // 创建了一个空style标签
myStyle.setAttribute('type','text/css');
myStyle.innerHTML = 'body{background-color:chartreuse;}'; // 设置标签内容
document.getElementByTagName('head')[0].appendChild(myStyle);
</script>
</body>
</html>
insertBefore
var ee = document.getElementById('ee');
var js = document.getElementById('js');
var list = document.getElementById('list');
// 要包含的节点.insertBefore(要插入的新节点,目标位置节点)
list.insertBefore(js,ee);
9、操作表单
表单是什么?
- form-----DOM树
- 文本框----text
- 下拉框----select
- 单选框----radio
- 多选框----checkbox
- 隐藏域----hidden
- 密码框----password
- …
- 表单的目的提交信息
获得要提交的信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action = "post">
<p>
<span>用户名:</span>
<input type="text" id = "username" />
</p>
<!-- 多选框的值就是定义好的value -->
<p>
<span>性别:</span>
<input type = "radio" name = "sex" value = "man" id = "boy"/>男
<input type = "radio" name = "sex" value = "woman" id = "girl"/>女
</p>
</form>
<script>
var input_text = document.getElementById("username");
var boy_radio = document.getElementById("boy");
var girl_radio = document.getElementById("girl");
// 得到输入框的值
input_text.value;
// 修改输入框的值
input_text.value="admin";
// 对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
boy_radio.checked = true; // 赋值
// girl_radio.checked; // 查看返回的结果,是否为true,如果为true,则被选中。
</script>
</body>
</html>
- 提交表单。md5加密密码,表单优化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- MD5加密工具类 -->
<script src = "https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js">
</script>
</head>
<body>
<!--
表单绑定提交事件
οnsubmit= 绑定一个提交检测的函数,true;false
将这个结果返回给表单,使用onsubmit接收
如果要拦截表单,return 一个函数
-->
<!--
action:跳转的位置
method:提交的方式
onsubmit:绑定事件,当提交表单时执行的方法
-->
<form action="http://guozhivip.com/" method="post" onsubmit="return aaa()">
<p>
<span>用户名:</span>
<!--
type:表单类型
id:js获取这个表单
name:没有这个值抓不到这个包
-->
<input type="text" id="username" name="username"/>
</p>
<p>
<span>密码:</span>
<input type="password" id="password" />
</p>
<!--
1.这里将没有隐藏的密码框用js来接受用户输入的值
2.将name赋给隐藏的文本框用来显示到包中
-->
<input type="hidden" id="md5-password" name="password">
<!--绑定事件,onclick被点击-->
<button type="submit">提交</button>
</form>
<script>
function aaa(){
var username = document.getElementById("username");
var pwd = document.getElementById("password");
var md5pwd = document.getElementById("md5-password");
md5pwd.value = mad5(pwd.value);//将显示的密码框的文本转为md5赋给隐藏的密码框,包中显示的name就是加密后的密码
// 可以校验判断表单内容,true就是通过提交,false就是阻止提交
return false;
}
</script>
</body>
</html>
10、jQuery
JavaScript和jQuery的关系?
- jQuery库,里面存在大量的JavaScript函数
获取jQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.5.1.js"></script>
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>-->
</head>
<body>
<a href="" id="test-jquery">点我</a>
<script>
// document.getElementById('id');
// 选择器为CSS选择器
$('#test-jquery').click(function () {
alert('hello,jQuery!');
})
</script>
</body>
</html>
选择器
// 原生JS,选择器少,不方便记忆
// 标签
document.getElementByTagName();
// id
document.getElementById();
// class
document.getElementByClassName();
// jQuery CSS中的选择器它全部都能用!
$('p').click(); // 标签选择器
$('#id1').click(); // id选择器
$('.class1').click; // class选择器
事件:鼠标事件、键盘事件,其他事件。
mousedown()(jQuery) ----鼠标按下
mouseenter()(jQuery)----
mouseleave()(jQuery)----鼠标离开
mousemove()(jQuery) ----鼠标移动
mouseout()(jQuery)----
mouseover()(jQuery)----点击结束
mouseup()(jQuery)----
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<style>
#divMove{
width: 120px;
height: 120px;
border: 1px solid deepskyblue;
}
</style>
</head>
<body>
<!--获取当前鼠标坐标-->
mouse:<span id="mouseMove"></span>
<div id="divMove">
移动一下试试!
</div>
<script>
// 加载完成后,响应事件
$(function () {
$('#divMove').mousemove(function (e) {
$('#mouseMove').text("x: "+e.pageX + ",y: "+e.pageY);
});
});
</script>
</body>
</html>
操作DOM
- 节点文本操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.5.1.js"></script>
</head>
<body>
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="python">Python</li>
</ul>
<script>
$('#test-ul li[name=python]').text(); // 获得值
$('#test-ul li[name=python]').text('设置值'); // 设置值
$('#test-ul').html(); // 获得值
$('#test-ul').html('<strong>123</strong>'); // 设置值
</script>
</body>
</html>
- CSS的操作
$('#test-ul li[name=python]').css("color","red");//css传入的是键值对,多个属性用大括号分割
- 元素的显示和隐藏;本质——display:none;
$('#test-ul li[name=python]').show();//显示
$('#test-ul li[name=python]').hide();//隐藏
- 娱乐测试
$(window).width();//浏览器宽度
$(window).height();//浏览器高度
$('#test-ul li[name=python]').toggle();//轮换显示和隐藏
- 未来ajax();
$('#form').ajax();
$.ajax({url:"test.html",context:document.body,success:function(){
$(this).addClass("done");
}});
11、总结
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>学生抽奖界面</title>
<style>
*{
padding: 0px;
margin: 0px;
font-size: 20px;
font-family: "宋体";
color: #00ff00;
text-shadow: 7px 10px 1px #008800;
}
body{
background-color: #000000;
}
.all{
width: 100%;
height: 100vh;
perspective: 500px;
overflow: hidden;
perspective: 500px;
}
.strs{
display: flex;
width: 100%;
height: 100vh;
transition: 3s;
}
.strs div{
width: 30px;
text-align: center;
height: 100vh;
}
.cz{
width: 100px;
height: 10vh;
position: absolute;
top: 90vh;
left: 48%;
font-size: 2em;
font-weight: 900;
color: red;
text-shadow: 1px 1px 1px red;
}
.cz:hover{
color: #00ff00;
text-shadow: 1px 1px 1px #008800;
}
.result{
width: 40%;
height: 80px;
position: absolute;
top: 40vh;
left: 30%;
color: #00ff00;
text-shadow: 1px 1px 1px #008800;
font-size: 3em;
font-weight: 900;
opacity: 0;
transition: 2s;
text-align: center;
}
.rank{
width: 200px;
border: 2px solid #00FF00;
position: absolute;
top: 65vh;
left: 85%;
}
.rank p{
width: 100%;
text-align: center;
text-shadow: 0px 0px 0px transparent;
}
.rank p:hover{
color: yellow;
}
.update{
width: 500px;
height: 30vh;
position: absolute;
top: -35vh;
left: 38%;
background-color: black;
border: 1px solid #00FF00;
display: flex;
justify-content: center;
transition: 1s;
}
.tx{
background: transparent;
margin-top: 15vh;
text-align: center;
}
</style>
</head>
<body>
<div class="all" ondblclick="update()" onmousemove="moves(event)">
<div class="strs" id="strs"></div>
<div class="cz" id="cz" onclick="starts()">开始</div>
<div class="result" id="result"></div>
<div class="rank" id="rank" onmousedown="rankdown()" onmouseup="rankup()"><p>历史记录</p></div>
<div class="update" id="update">
<p>
<input type="text" list="updatelist" class="tx" id="tx"/>
<datalist id="updatelist"></datalist>
<input type="button" value="删除" class="tx" onclick="update1()"/>
<input type="button" value="添加" class="tx" onclick="update2()"/>
<input type="button" value="取消" class="tx" onclick="update3()"/>
</p>
</div>
</div>
<script>
var names = [
"刘欣",
"程贤政",
"谢行",
"邱思宇",
"廖永胜",
"刘东",
"刘向鸿",
"朱美琳",
"刘佳",
"董金杰",
"张瑞",
"赵文豪",
"黄俊涛",
"李小华",
"黄建军",
"余洋",
"江琳",
"张羽",
"肖怀智",
"王文宇",
"向俊瑾",
"秦渝均",
"邓桂兰",
"何洁",
"陈广",
"张士杰",
"李丹",
"肖晴",
"张渝",
"王子晓",
"陆恋钰",
"周兴怡",
"黎雪彬",
"刘琳",
"杜涛",
"米俊龙",
"陈益巧",
"周雪",
"许小祥",
"李林",
"邓东华",
"杨雪"
];
var namess = [];
bg();
function bg(){
document.getElementById("strs").innerHTML='';
for(var i=0;i<51;i++){
var rdmnum = Math.floor(Math.random()*names.length);
var str = '';
str+='<div>';
var rdmnum1 = Math.floor(Math.random()*10)+1;
for(var h=rdmnum1;h>0;h--){
str+='<font style="opacity: '+h/10+';">'+names[rdmnum]+'</font>';
}
str+='</div>';
document.getElementById("strs").innerHTML+=str;
}
}
var start1 = null;
var num1 = 0;
function starts(){
if(num1==0){
start1=setInterval(bg,100);
document.getElementById("cz").innerText="停止";
document.getElementById("strs").style.transform="translateZ(0px) translateY(0px)";
document.getElementById("result").style.opacity="0";
num1=1;
}else{
clearInterval(start1);
document.getElementById("cz").innerText="开始";
document.getElementById("strs").style.transform="translateZ(450px) translateY(350px)";
document.getElementById("result").style.opacity="1";
var rdmname = document.getElementById("strs").childNodes[25].firstChild.innerText;
document.getElementById("result").innerText='恭喜'+rdmname+'同学中奖了';
namess.unshift(rdmname+' 中奖');
rank();
num1=0;
}
}
function rank(){
document.getElementById("rank").innerHTML='<p>历史记录</p>';
for(var i=0;i<namess.length;i++){
if(i==10){
break;
}
document.getElementById("rank").innerHTML+='<p>'+namess[i]+'</p>';
}
}
function update(){
document.getElementById("update").style.top="18vh";
}
function updatelist(){
document.getElementById("updatelist").innerHTML='';
for(var i=0;i<names.length;i++){
document.getElementById("updatelist").innerHTML+='<option>'+names[i]+'</option>'
}
}
updatelist();
function update3(){
document.getElementById("update").style.top="-35vh";
document.getElementById("tx").value='';
}
function update1(){
var str = document.getElementById("tx").value;
for(var i=0;i<names.length;i++){
if(names[i]==str){
namess.unshift(names[i]+' 删除');
names.splice(i,1);
updatelist();
document.getElementById("tx").value='';
rank();
break;
}
}
}
function update2(){
var str = document.getElementById("tx").value;
namess.unshift(str+' 添加');
names.push(str);
updatelist();
rank();
document.getElementById("tx").value='';
}
var x,y,start2;
function rankdown(){
start2 = setInterval(rankmove);
}
function rankup(){
clearInterval(start2);
}
function rankmove(){
document.getElementById("rank").style.left=x-20+'px';
document.getElementById("rank").style.top=y-10+'px';
}
function moves(xy){
x=xy.clientX;
y=xy.clientY;
}
</script>
</body>
</html>
- 如何巩固JS:看jQuery源码、游戏源码。
- 巩固HTML、CSS:扒网站。