JavaScript

1. 什么是JavaScript

JavaScript是一门脚本语言(一个后端人员,必须要精通JavaScript)
脚本语言和编程语言区别,不需要编译链接,是直接解释型语言,在含有解释器的环境中直接可以运行。主要用于管理,方便部署.

2. 快速入门

2.1 引入javaScript

1.内部标签使用(标签成对出现)

<script>
 //....
<script>
  1. 引入js文件
<script src="**.js"></script>

例:

<!DOCTYPE html>
<html lang ="en">
<head>
	<meta charset="UTF-8">
	<title>javaScript</title>
	<!--script标签内写js,可以放在body里,但通常放head里-->
	<!-- 写法一,直接html里写-->
	<script>
		alert("hello,world");
	</script>
	
	<!--写法二,引入script标签必须成对出现
	<script src="js/js1.js"></script>-->
	
	<!--这种不常用,type不标注默认也是javaScript
	<script type="text/javascript">
		alert("hello,world");
	</script>-->
</head>
<body>

</body>
</html>

2.2 基本语法入门
区分大小写,变量定义用var没有其他类型,注释等和java语法一样

<!DOCTYPE html>
<html lang ="en">
<head>
	<meta charset="UTF-8">
	<title>js</title>
	
	<script>
		//1.不同于java定义变量不需要设置类型,直接是var
		var score=75;
		var name="happy";
		
		//2.条件控制
		if(score >60 && score<70){
			alert("60-70");
		}else if(score>70&& score<80){
			alert("70-80");
		}else{
			alert("other");
		}
		/* 调试的时候在浏览器中审查元素->consle选项
			1. 可以直接输入alert(变量名)查看变量值
			2. 输入console.log(变量名)相当于system.out.println
		*/
	</script>
</head>
<body>


</body>
</html>

调试,浏览器控制台的使用:

  1. 使用console调试
  2. 使用source选项卡
    点中哪行就是在该行设置断点,然后刷新就可以运行

    3.使用application选项卡
    查看存在浏览器里的数据
  3. 使用Network用来抓包
  4. 使用Element调网页div等元素

2.3 数据类型

数值,文本,图形,音频,视频...

  • 变量
    var 定义不能以数字开头
  • number
    --js不区分整数小数还是科学计数法,NAN表示not a number, Infinity表示无限大
  • 字符串
    'abc' "abcd",单引号 双引号都行,也可以是各种转义字符
  • 布尔值
    true,false
  • 逻辑运算
    &&,||, !
  • 比较运算
    = 赋值
    == 等于(类型不一样,值一样算相等)
    === 绝对等于(类型不一样值一样,不等)
    这是JS的一个缺陷,坚持不要使用两个等于号,作比较用三个等于号
    须知:
    • NAN===NAN返回为false,这个值与所有值都不相等,包括自己
    • 只能使用isNAN来判断一个值是不是NAN
      浮点数问题:
      console.log((1/3)==(1-2/3))返回false,和java一样会有精度损失,尽量避免使用浮点数进行运算
      console.log(Math.abs(1/3-(1-2/3))<0.0000001)
  • null和undefined
    null是空
    undefined未定义
  • 数组
    java的数组必须是一系列相同类型的对象,js中不需要这样
 //保证代码的可读性,尽量使用[]中括号的写法
 var arr = [1,2,3,4,'hello',null,true];
 new Array(1,2,3,4,"hello",null,true);

取数组下标如果越界了,提示undefine.

  • 对象
    对象定义使用大括号,数组用中括号
    每个属性使用逗号隔开,最后一个不需要添加
var person = {
	name:"xiaoming",
	age:3,
	tags:['js','java','web','...']
}

取对象的值

>person.age
  3
>person.name
  "xiaoming"

2.4 严格检查格式

前提设置IDEA支持ES6语法(Settings->JavaScript->version ECMAScript6)
'use strict':严格检查模式,写在javaScript的第一行,预防JavaScript的随意性导致产生一些问题
局部变量建议使用Let来定义

<script>
	'use strict';
	let i=1;
</script>

3. 数据类型

3.1 字符串

  1. 正常字符串我们使用单引号或者双引号包裹,特殊字符使用转义字符\
\'
\n
\t
\u4e2d \u#### unicode字符
"\x41"   Ascii字符
  1. 多行字符串编写
    使用反引号包裹多行字符(tab和ESc中间的字符)
`hello 
你好
天天好心情`
  1. 模板字符串
    ES6里面直接可以${变量名}取出变量值
let name ="xiaoming";
console.log("你好,${name}");
  1. 字符串长度
    console.log(str.length);
  2. 字符串不可变,不同于java,它的每个字符可以通过下标取出来
    student[0]=1;这种赋值失败的,不能该改变student这个字符串
  3. 大小写转换
    toUpperCase()
    toLowerCase()
  4. indexOf()
  5. subString
    subString(1)从第一个字符到最后
    subString(1,3) [1,3)

3.2 数组

Array可以包含任意的数据类型

var arr ={1,3,'hello',4,7,10};
arr[0]=6;
console.log(arr);
  1. 长度
    arr.length
    注意:假如给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失
  2. indexOf 通过元素获得下标索引
  3. slice()类似于substring,截取Array的一部分,返回一个新数组
  4. push/pop
    push 压入元素到数组尾部,pop弹出尾部元素
  5. unshift/shift
    从数组头部添加/删除元素
  6. sort()排序
  7. reverse()元素反转
  8. concat()拼接
    注意:concat并没有修改数组,只是返回一个新的数组
  9. 连接符 join
    打印拼接数组,使用特定的字符出连接
var arr=['a','b','c'];
arr.join('-');

10.多维数组

arr=[[1,2],[3,4],[5,6]]
arr[1][1]

数组:存储数据(重要的是知道如何存,如何取,其他方法都可以自己实现)

3.3 对象

若干个键值对

var 对象名={
  属性名:属性值,
  属性名:属性值,
  属性名:属性值
}

js中对象,{...}表示一个对象,键值对描述属性xxxx:xxxx,多个属性之间使用逗号隔开,最后一个属性不加逗号
js中所有键都是字符串,值是任意对象

  1. 对象赋值
    person.name="xiaoming"
  2. 使用一个不存在的对象属性,不会报错!undefined
    person.haha
    undefined
  3. 动态的删除属性
    delete person.name
    true
  4. 动态的添加属性,直接给新的属性赋值即可
    person.haha="haha"
  5. 判断某个属性是否在这个对象中 xx in xxx
'age' in person
true
//继承
'toString' in person
true
  1. 判断一个属性是否是这个对象自身拥有的 hasOwnProperty
    person.hasOwnProperty("toString")
    false

3.4 流程控制

  1. if 判断
  2. for循环, while, do-while
  3. forEach循环
var age={13,2,12,2,323,454,234,1,45}
//函数
age.forEach(function(value)){
  console.log(value)
}
  1. for ... in
//for(var index in object){}
for (var num in age){
  if(age.hasOwnProperty(num)){
    console.log('存在')
    console.log(age[num])
}
}

对新增的特性存在一个bug

var arr = [3,4,5];
arr.name ="213";
for( let x in arr){
  console.log(x)
}

新增的会输出name,这是个遗留下来的bug,所以es6里引入了iterator
5. for.. of

var arr = [ 3, 4,5]
for(var x of arr){
  console.log(x)
}
//遍历map
var map = new Map([["tom",100],["jack",90],["haha",80]]);
for(let x of map{
  console.log(x)
}

3.5 Map和Set

Map: get获取值,set设置值或者新增
//ES6新特性

var map = new Map(['tom',100],['jack',90],['haha',80]]);
var name = map.get('tom');
map.set('admin',123456);
map.delete('tom')

Set: 无序不重复的集合

var set = new Set([3,1,1,1,1])//set 可以去重
set.delete(1);
console.log(set.has(3));//是否包含某个元素

3.6 Iterator迭代器

4. 函数

4.1 定义函数

  • 定义方式一
function abs(x){
  if(x>=0){
    return x;
  }else{
    return -x;
  }
}

一旦执行return代表函数结束,如果没有执行return,函数执行完也会返回结果,结果是undefined

  • 定义方式二
 var abs = function(x){
    if(x>=0){
    return x;
  }else{
    return -x;
  }
}

function(x){...}这是一个匿名函数,但是可以把结果赋值给abs,通过abs可以调用函数

  • 调用函数
    abs(-10);
  • 参数问题
    js可以传递任意个参数,也可以不传递参数
    参数进来是否存在问题?假设不存在参数,如何规避?
    手动检查,抛出异常
 var abs = function(x){
    if(typeof x!== 'number'){
      throw 'Not a Number';
    }
    if(x>=0){
    return x;
  }else{
    return -x;
  }
}
  • arguments
    'arguments'是一个js免费赠送的关键字,代表传递进来的所有参数,是一个数组
 var abs = function(x){
    console.log("x=>"+x);
    for(var i=0;i<arguments.length;i++){
      console.log(arguments[i]);
    }
}

问题 arguments包含所有的参数,有时候想使用多余的参数来进行附加操作,需要排除已有的参数

  • rest
    ES6引入的新特性,获取除了已经定义的参数之外的所有参数
    以前
if(arguments.length>2){
  for(var i =2;i<arguments.length;i++){
//截取后面的参数,前提事知道已经定义了几个
}

新特性

function aaa(a,b,...rest){
  console.log(a);
  console.log(b);
  console.log(rest);
}

rest参数只能写在最后面,必须用...标识(可变参数)

4.2 变量的作用域

  • 在js中var定义的变量是有作用域的,假设在函数体中声明,在函数体外是不可以使用的(非要使用的话,研究下闭包)
  • 两个函数内部各自定义了相同名字的变量,使用起来不会冲突
  • 内部函数可以访问外部函数的成员,反之则不行
  • 内部函数变量和外部函数变量重名,按照从'内'向'外'查找,内部使用自己定义的变量(覆盖外部的)
    提升变量作用域
function a(){
  var x='x'+y;
  console.log(x);
  var y ='y';
}

结果:xundefined
说明,js执行引擎,自动提升了y的声明,但是不会提升它的赋值

function a(){
  var y;
  var x ='x'+y;
  console.log(x);
  car y='y';
}

这是javaScript建立之初就存在的特性,建立规范所有代码在函数之初定义变量。

  • 全局函数
    略 就是定义在script里,非局部块内的函数
  • 全局对象Window
var x ='xxx';
alert(window.x)//默认所有全局变量都被绑定在window里
window.alert(window.x)

js实际上只有一个全局作用域,任何变量(函数也可以视为变量)全局的都被绑定在window对象上,如果往上找也没找到,就会报错ReferenceError

  • 规范
    由于所有全局变量都被绑定到windows上,如果不同Js文件有相同的全局变量,冲突怎么解决?
//自己定义的唯一全局变量
var kuangApp ={};
//把其他变量绑定上去
kuangApp.name="xiaoming";
kuangApp.add=function(a,b){
	return a+b;
}

把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题(不直接绑定到window对象上)
扩展jQuery就是这么做的jQuery.xxx简写${}

  • 局部作用域let
function aaa(){
  for(var i=0;i<100;i++){
    console.log(i);
  }
  console.log(i+1);//问题i出了作用域还可以用,输出了101,是js的bug
}

引入let局部作用域解决这个问题

function aaa(){
  for(let i=0;i<100;i++){
    console.log(i);
  }
  console.log(i+1);//报错,i is not defined
}

建议使用let去定义局部变量

  • 常量const
    在ES6之前定义常量:只要用全部大写命名的变量就是常量,只是个口头约定,人为还是可以修改使用
    现引入const来定义常量
    const PI ='3.14';

4.3 方法

方法就是把函数放在对象里面

var person = {
	name:"xiaoming",
	birth:2000,
	//方法,age是key
	age:function(){
		var now = new Date().getFullYear();
		return now - this.birth;
	}
}

调用方法要写括号person.age()
this 表示调用该方法的对象,上述代码可以拆开写

function getAge(){
	var now = new Date().getFullYear();
	return now - this.birth;
}
var person = {
	name:"xiaoming",
	birth:2000,
	//方法
	age:getAge
}
getAge()NaN window是没有getAge这个方法的
person.age() OK
  • apply
    不同于java,js中this的指向是可以控制的,js里所有函数都有apply方法,有两个参数,第一个是想要指向的对象,第二个是参数
    getAge().apply(person,[]) 这样调用就可以使用了。
    此时this指向了person对象,没有参数参数为空[]

5 内部对象

  • 标准对象
    typeof 123
    "number"
    typeof NaN
    "number"
    typeof true
    "boolean"
    typeof "123"
    "string"
    typeof[]
    "object"
    typeof{}
    "object"
    typeof Math.abs
    "function"
    typeof undefined
    "undefined"

5.1 Date

基本使用

var now = new Date();
now.getFullYear();年
now.getMonth();月 0~11
now.getDate();日
now.getDay();星期
now.getHours();时
now.getMinutes();分
now.getSeconds();秒
now.getTime(); 时间戳世界统一,从1970 1.1 0:00:00开始的毫秒数

console.log(new Date(1578106175991))//时间戳转化为时间

转换

now = new Date(1578106175991)
Sat Jan 04 2020 10:49:35 GMT+0800 (China Standard Time)
now.toLocaleString()
"1/4/2020, 10:49:35 AM"
now.toGMTString()
"Sat, 04 Jan 2020 02:49:35 GMT"

5.2 JSON

JSON是一种轻量级的数据交换格式。有简洁的层次结构,易于人阅读和编写,同时也易于机器解析和生成.
在JavaScript一切皆为对象,任何js支持的类型都可以转化为JSON来表示
格式:

  • 对象都用{}
  • 数组都用[]
  • 所有键值对,都是用key:value
    JSON和js对象的转换
var user ={
	name:"zhangsan",
	age:"12",
	home:"chengdu"
}
//转换为json字符串
JSON.stringify(user);
//转换为对象
var  obj = JSON.parse('{"name":"zhangsan","age":"12","home":"chengdu"}')

JSON和js对象区别
var obj = {a:'hello',b:'hellob'}//对象key,value类型不限制
var json='{"a":"hello","b":"hellob"}'//json key value都是string

5.3 Ajax(略后面讲)

  • 原生的js写法 xhr异步请求
  • jQuery封装好的方法${"#name"}.ajax
  • axios请求

6. 面向对象编程

6.1 什么是面向对象

javascript,java,c#...面向对象
类 ----- 模板 (javascript 类对应原型对象)
对象 ---- 具体实例

  • 原型:
    将对象B的__proto__指向另一个对象A,就可以调用A中的方法属性
    js里原型指向一个对象相当于java里的父类,各个对象之间可以互为原型
var user ={
	name:"zhangsan",
	age:"12",
	run: function(){
		console.log(this.name+"run...");
	}
}
var xiaoming = {
	name:"xiaoming"
}
//小明的原型是user
xiaoming.__proto__= user;//_按两下
xiaoming.run();//小明就可以跑了
  • Class 继承
    class关键字是在ES6中引入
function Student(name) {
  this.name = name;
}
//给student新增一个hello方法
Student.prototype.hello = function(){
  alert('hello')
}

现在ES6中
1.定义一个类,属性,和方法

class Student{
	constructor(name){
		this.name = name;
	}
	hello(){
		alert("hello")
	}
}
var xiaoming = new Student("xiaoming");
var xiaohong = new Student("xiaohong");

继承也遵守java语法,但本质上还是用的原型

class pupil extends Student{
	constructor(name,grade){
		super(name);
		this.grade = grade;
	}
	myGrade(){
		alert("我是一个小学生")
	}
}
var xiaolan = new pupil("xiaolan",3)

7 操作BOM对象(重点)

  • 浏览器介绍
    Javascript:能够在浏览器中运行的脚本
    BOM:浏览器对象模型
    有自己内核的浏览器
    • IE6~11
    • Chrome
    • Safari
    • FireFox

三方

  • QQ 浏览器
  • 360 浏览器 (极速模式,兼容模式就是在切换内核,如IE)
    常用的浏览器BOM对象
  • Window对象(重要)
    window代表浏览器窗口,除此之外它代表全局作用域。
  window.alert("hell")
  undefined
  window.innerHeight
  969
  window.innerWidth
  893
  window.outerHeight
  1040
  • Navigator
    Navigator封装了浏览器的信息
navigator.appName
"Netscape"
navigator.appVersion
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.54"
navigator.userAgent
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.54"
navigator.platform
"Win32"

通常不使用navigator对象信息来编码判断,因为它里面的值可以人为修改,用它来判断是否是windows电脑浏览还是在手机浏览,是不准确的

  • screen
    可以获取计算机屏幕信息
screen.width
1920
screen.height
1080
  • location(重要)
    代表当前页面的URL信息, 常用的属性方法如下
host: "www.baidu.com"
href: "https://www.baidu.com/"
protocol: "https:"
reload: ƒ reload() //刷新网页,重新加载
//设置新的地址,访问A的网站js里有这段代码,就会跳到B网站
location.assign("https://cn.bing.com/?scope=web&FORM=ANNTH1")
  • document
    document代表当前的页面,HTML DOM文档树
    • document.title //页面标题
    • 获取具体的文档树节点
      document.getElementById('app')
    • 获取cookie
      document.cookie
      劫持cookie
      恶意网站在js里获取你的cookie上传到它的服务器里
      服务器端可以设置cookie:httpOnly,那么通过js脚本将无法读取到cookie信息
  • history
    代表浏览器的历史记录,不推荐使用
    history.back() 后退
    history.forward()前进

8. 操作DOM对象(重点)

  • 核心
    浏览器网页就是一个DOM树形结构
    可以结合选择器获取DOM节点,实现动态更新增删改
  • 获取DOM节点
    document原生方式可以直接调用如下代码:
    var domElement = document.getElementByTagName('h1')
    document.getElementById('p1')
    document.getElementByClassName('p2')
    使用JQuery可以简化写法
  • 更新节点
    • 操作文本
      • domElement.innerText="123"修改文本的值
      • domElement.innerHTML='123'可以解析的html文本
    • 操作css样式
      • domElement.style.color = 'yellow';
      • domElement.style.fontSize='20px';
      • domElement.style.padding = '2em';
  • 删除节点
    删除步骤:先获取父节点,然后再删除当前节点
  var self = document.getElementById('p1')
  var father = self.parentElement;
  father.removeChild(p1);

注意:删除多个节点的时候,children是动态变化的,大小是不断在减少的
如,假设father下只有三个节点,如下方式删除是错的,
删除0后已经就两个节点了,[1]是原来的[2],没有2了

  father.removeChild(father.children[0])
  father.removeChild(father.children[1])
  father.removeChild(father.children[2])
  • 插入节点
    使用innerHTML/innerText原来是空的那么就相当于插入了,原来非空则覆盖原有的
    所以通常用追加的方式插入
    • 追加
      domElementA.appendChild(domElementB)
    • Insert插入
      list.insertBefore(newchild,oldchild); //list里的
  • 创建一个新的dom元素
    可以创建一个新的dom对象来追加
var newP = document.createElement('p')//创建一个P标签
newP.id = 'newP';
newP.innerText='hello,a luo';
list.appendChild(newP);

使用setAttribute方法可以设置任何属性,更好一点

//例<script type ="text/javascript" src=""></script>
var myScript = document.createElement('script');
myScript.setAttribute('type','text/javascript')

学习Jquery推荐的网站

9. 操作表单

  • 表单 用来提交信息
    • 文本框 text
    • 下拉框 select
    • 单选框 radio
    • 多选框 checkbox
    • 密码框 password
    • 隐藏域 hidden
      ...
  • 获取表单项的值,修改/设置该项值
<form action="post">
	<span>用户名:</span> <input type="text" id="username">
	<!--多选框,单选框的值就是定义好的value值-->
	<span>性别:</span> <input type="radio" name="sex" value="man" id="boy">男</input>
	<input type="radio" name="sex" value="woman" id="girl">女</input>
</form>
	<script>
	var inputText = document.getElementById("username");
	//得到输入框的值
	inputText.value;
	//修改输入框的值
	inputText.value=9080;
	var boy_radio = document.getElementById("boy");
	var girl_radio = document.getElementById("girl");
	
	//判断单选框或者复选框是否被选中用checked,true为选中,而不是直接取value
	boy_radio.checked
	//修改值选中女
	girl_radio.checked=true;
	</script>
  • 提交表单
    • 提交表单可以用form上的onsubmit属性来实现,注意onsubmit要return,true的时候会成功提交
    • 利用button的onclick来手动提交
      注意所有表单提交的数据项,必须要要有name和value,没有name的是不会提交的
      处理密码,使其密文提交给后台
    1. 将password md5加密后重新赋值给该dom元素,缺点提交的一瞬间,password回写变长
    2. 使用隐藏域,原来的inputpassword输入框不设置名字,隐藏域的input值对inputpassword实施md5加密
      这样原来的明文不会提交,真正提交的是隐藏域的值,抓包看不到明文
<body>
<!--
表单绑定提交事件
onsubmit绑定一个提交检测的函数true, false
将这个结果返回给表单
-->
<form action ="https://www.baidu.com/" method="post" onsubmit="return aaa()">
	<p>
		<span>用户名:</span> <input type="text" id="username" name="username" >
	</p>
	<p>
		//<span>密码:</span> <input type="password" id="password" name="password">
               <span>密码:</span> <input type="password" id="password">
	</p>
	<input type="hidden" id=“md5-password” name="md5-password">
	<!--绑定事件
	<button type="submit" onclick="aaa()">提交</button>
	-->
	<button type="submit" >提交</button>
</form>
<script>
	function aaa(){
		var uname = document.getElementById("username");
		var upwd = document.getElementById("password");

      		//加密后写回框里
		//upwd.value = md5(upwd.value);
                var md5pwd= document.getElementById("md5-password");
                md5pwd.value = md5(upwd.value);
		console.log(uname.value);
		
		//可以校验判断表单内容,true就是通过提交,false就是终止提交
		return true;
	}
</script>
</body>

10. jQuery

JQuery库:里面存了大量的javascript函数

10.1 获取jQuery

  1. 官网下载
    第一个版本上线的时候用,第二个开发时用
  2. 使用jquery CDN(内容分发网络) 可以找到在线引用jquery的地址

10.2 语法

$(选择器).事件(事件函数体)

  $(selector).action()

<!DOCTYPE html>
<html lang ="en">
<head>
	<meta charset="UTF-8">
	<title>js</title>
	<!--在线的cdn引入-->
	<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
	<!--导入本地下载的jquery
	<script src="lib/jquery-3.6.0.js"></script>-->
</head>
<body>
<a href="" id="test-jquery">点我</a>
<script>
	//不用这样写document.getElementById('test-jquery');
        //选择器和css里一样
	$('#test-jquery').click(function(){
		alert('hello,jquery');
	})
</script>
</body>
</html>

10.3 jquery选择器

css中的选择器jquery都能用

$('p').click() //标签 选择器
$('#id').click()//id选择器
$('.class').click()//类选择器

更多选择器,查看文档工具站 https://jquery.cuishifeng.cn/

10.4 事件

鼠标事件、键盘事件、其他事件
例获取鼠标坐标
mousemove事件处理函数会被传递一个变量——事件对象,其.clientX 和 .clientY 属性代表鼠标的坐标

<style>
	#divMove{
		width:500px;
		height:500px;
		border: 1px solid red
	}
</style>
<body>
<!--获取鼠标的当前坐标-->
mouse:<span id ="mouseMove"></span>
<div id="divMove">
 在这里点击试试 
</div>
<script>
//当网页元素加载完毕之后,响应事件
//$(document).ready(function(){})-->简化$(function(){})
	$(function(){
		$('#divMove').mousemove(function(e){
			$('#mouseMove').text('x:'+e.pageX+'y:'+e.pageY);
		}
		
		)
	})
</script>

10.5 操作DOM

  • 节点文本操作
//document.getElementById()...
//无参获得值,有参设置值
$('#test-ul li[name="python"]').text();
$('#test-ul').html()
  • css操作
    直接调用.css键值对即可
$('#test-ul li[name="python"]').css({"color":"red","background":"yellow"});
  • 元素的显示和隐藏:本质是display:none
$('#test-ul li[name="python"]').show()
$('#test-ul li[name="python"]').hide()
  • 文档处理略
$(document)//具体查看工具网站
  • 扩展前端小技巧
  1. 如何巩固js(看jQuery源码,看游戏源码去源码之家,看别人做好的前端游戏源码)
  2. 巩固HTML CSS(扒网站,全部down下来,然后删删减减修改看对应效果)
    友人C
    layui-layer弹窗(layui-文档->弹出层->layer网址https://layer.layui.com/)
    Element-ui(https://element.eleme.cn/#/en-US/component/color)清新的组件
    Bootstrap就相对稳重风
    ant.design https://ant.design/components/overview/
    (注:6)
posted @ 2021-06-24 14:25  晒网达人  阅读(49)  评论(0编辑  收藏  举报