CGB2105第二阶段-8前端技术JavaScript实现网站交互

目录

一、静态网页和动态网页

1、动态网页的描述

2、网页如何和后端交互?

二、JS

1、JS概述

2、解释

3、特点和优势

三、HTML中引入JS的方式

1、js的引入入门案例

2、通过Script标签引入js代码或js文件

四、JS语法

1、注释

2、基本数据类型

3、js的复杂数据类型

4、js的变量

5、js的运算符

6、JS的语句(流程控制结构)

7、JS数组

8、JS函数(方法)

8.1练习统计字符出现的次数

9、JS对象

9.1内置对象

9.2自定义对象的两种方式

五、DOM树的作用

1、组成

2、DOM树的结构

 3、Document对象

3.1作用:

获取、解析网页各个元素

3.2练习:使用dom解析网页中的元素

六、console浏览器控制台调试网页


一、静态网页和动态网页

1、动态网页的描述

HTML和CSS实现了静态网页,文字、表格、图片、超链接等的展现,并可以进行美化;

但是如果我们要做注册、聊天、发表论文等功能呢?信息如何根据不同的使用者,展现不同的内容呢?

使用javaScrip实现浏览器用户和后台服务器进行交互,业界把这样的网页称为动态网页,把这样的网站称为动态网站。

静态网站只能看,不同浏览者看到内容一致不能变化;动态网站可以读写数据,内容根据不同浏览者展示不同的信息。

2、网页如何和后端交互?

动态网站的软件架构是怎么样的?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-br6P2qaO-1622526184994)(RackMultipart20210601-4-1vdjb36_html_a71a298b5faabd1f.png)]

用户访问页面,页面触发事件创建XHR对象,进行ajax请求,请求访问服务器端,请求被web中间件拦截并进行处理,由控制层框架springmvc中的controller进行接收,controller请求业务层spring框架的service服务,service请求持久层mybatis框架的mapper映射,mapper访问数据库。操作完数据库,返回结果,mybatis封装成java对象传回service,service把java对象传回controller,controller把java对象又转换为json字符串,然后传回浏览器,浏览器传回给调用者XHR,XHR调用回调方法callback,callback进行json字符串的解析,从中拿到要展现的数据,通过javascript处理,最终回显到页面上。

可以看到这个调用过程是非常复杂的,跨越网络,跨域多个服务器,很多技术应用其中,而这一切的始作俑者是谁呢?谁让这一切成为可能,它就是javascript,它实现了用户的请求和响应,实现了数据的动态展现,使早期静态的网站走向了动态的网站。
 

二、JS

1、JS概述

JavaScript 是 web 前端开发者必学的三种语言之一:

  • HTML 定义网页的内容 H5
  • CSS 规范网页的布局 CSS3
  • JavaScript 实现网站的交互 ES6

2、解释

js是一种弱类型语言,同其他语言一样,有它自身的语法,数据类型,表达式,算术运算符等。JS是一门 基于对象 和 事件驱动 的 脚本语言 ,通常用来提高网页与用户的交互性。

基于对象:它不仅可以创建对象,也能使用现有的对象。JS没有类的概念,也没有编译的过程。是一边解释一边执行。

事件驱动:在JS中,大部分情况下都是通过事件触发驱动函数执行的,从而实现特定的功能。(比如点击div将内容替换为时间、当鼠标滑过元素,元素就有翻转的动态。)

脚本语言:在网络前端开发环境下,用于嵌入在客户端浏览器中的一段小程序

3、特点和优势

特点:

(1)JS是一门直译式的语言,直接执行的就是源代码.

是一边解释一边执行,没有编译的过程(不像Java需要提前编译为class文件再运行).

(2)JS是一门弱类型的语言,没有严格的数据类型.

优势:

(1)良好的交互性

(2)一定的安全性(JS被强制的要求,不能访问浏览器以外的东西,只能访问浏览器和浏览器内部的资源)

(3)跨平台性(Java语言具有跨平台性,是因为有虚拟机),只要有浏览器的地方都能执行JS

三、HTML中引入JS的方式

1、js的引入入门案例

方法1:在<body>行内引入js,在body内会通过相应的操作弹框

方法2:通过script标签在<head>行内嵌入js,在head行内打开浏览器会自动跳出弹框

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试js的入门案例</title>
		<!--2、 在HTML嵌入js,写法2:内部js -->
		<script>	
		alert(100);/*弹100*/
		confirm();/*单击确定弹框*/
		prompt("请输入年龄");/*单击输入框*/
		</script>
	</head>
	<body>
		<!-- 1、js使网页动起来 写法1:行内js
		js是基于对象的事件驱动的脚本语言 
		时间的驱动是指:给网页的不同元素,添加各种触发的方式
		onclick是单击 ondbclick是双击 onmouseenter是鼠标划入  onmouseleave是鼠标划出
		alter弹出框 prompt输入框 confim确认框-->
		<!-- 单击弹框 -->
		<a href="#" onclick="alert(10);">单击弹框</a>
		<a href="#" onclick="prompt();">单击输入框</a>
		<a href="#" onclick="confirm();">单击确定框</a>
		<!-- 双击弹框 -->
		<a href="#" ondblclick="alert(10);">双击弹框</a>
		<!-- 鼠标划入弹框 -->
		<a href="#" onmouseenter="alert(10);">鼠标划入弹框</a>
		<!-- 鼠标划出弹框 -->
		<a href="#" onmouseleave="alert(10);">鼠标划出弹框</a>
	</body>
</html>

效果:

1.1 关于a标签超链接弹框确认是否跳转的解决方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>是否跳转</title>
	</head>
	<body>
		<div id="app">
			<!-- 事件绑定方法 -->
			<a href="#" @click="a()">点我</a>
			
		</div>
		
		<script src="../js/vue.js"></script>
		
		<script>
			const app = new Vue({
				el:"#app",
				data:{
					num:2
				},
				methods:{
					a(){
						//confirm("是否跳转?")
						if(confirm("是否跳转?")==true){
							window.location.href="http://baidu.com";
						}
					}
				}
			})

		</script>
	</body>
</html>

2、通过Script标签引入js代码或js文件

1、引入js代码:

<head>
	<meta charset="utf-8"/>
	<script>/* JS代码 */
		function fn(){
			alert("JS的第1种引入方式");
		}
	</script>
</head>
<body>
	<div id="div1" onclick="fn();">Hello JavaScript</div>
</body>

2、引入js文件:

第一步创建1.js文件

function fn(){
	alert("JS的第2种引入方式");
}

第二步在html中引入文件

<head>
	<meta charset="utf-8"/>
	<script src="1.js"> </script>
</head>
<body>
	<div id="div1" onclick="fn();">Hello JavaScript</div>
</body>

注意:

不要同时通过一个script标签引入js代码和js文件,会导致代码不会执行

不能在同一个方法名下使用两种引入方式,只能执行一个

比如:

<script src="demo1.js">
	alert("哈哈哈哈。。。");//代码不会执行!!
</script>

四、JS语法

1、注释

单行//

多行/*xxx*/

2、基本数据类型

1)number数值类型,在JS中,数值类型只有一种,就是浮点型,需要时会自动的进行数据类型的转换,比如:在显示和处理的时候,浮点型和整型会自动的转换。

2)String字符串类型,在JS中,字符串是基本数据类型。字符串直接量是通过单引号或者双引号引起来。

3)boolean布尔类型,值为true或者是false。

4)null,值也只有一个,就是null。表示空值或者不存在的对象。

5)undefined,值只有一个就是undefined。表示变量没有初始化值。

JavaScript中的数据类型有: 字符串、数字、布尔、数组、对象、Null、Undefined

3、js的复杂数据类型

函数、数组、对象(自定义对象、内置对象、DOM对象、BOM对象…)

4、js的变量

在JS中是通过 var 关键字来声明一个变量,声明的变量是不区分类型的, 可以指向任意的数据类型。

5、js的运算符

JS中的运算符和Java中的运算符大致相同

注意:html不执行js语句的原因:

  1. 有任何注释不对的地方,整个html都不执行
  2. 英文单词是否拼正确
  3. 分号用于分隔 JavaScript 语句。通常我们在每条可执行的语句结尾添加分号。使用分号的另一用处是在一行中编写多条语句。在 JavaScript 中,用分号来结束语句是可选的。但是想在一行写多条语句的时候就必须加的了。

常见运算符测试:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试 js的数据类型</title>
		
		<!-- 在HTML里嵌入JS代码 -->
		<script>
			/* 2. js的运算符 */
				//三元运算符  求两个数里的大值
				var j=10;
				var k=20;
				alert( j < k ? k : j );
			
				//==   ===  
				alert(1==1); //比值,true
				alert(1===1); //比类型和值,true
				alert(1==='1');//比类型和值,false
			
				// % /  求25的个位数和十位数
				var g=25;
				alert( g%10 );//%取余,个位数
				alert( g/10 ); //2.5
				
				// ++  --
				var h = 10;
				h = h++ ;
				alert(h); //10
			
				/*  java里,以下两行代码的区别?
					byte d = 1;
					d = d+1;  //报错,必须强转
					d += 1;  //解决方案,自动类型转换
				*/
			
			/* 1. js是弱类型的语言,没有严格意义上的数据类型,包括:number string boolean null undefined */
				var a = 10;//number类型
				a = 1.1; //number类型
				a = "hello js" ; //string类型
				a = 'hello js' ; //string类型
				a = true ; //boolean类型
				a = null ; //null类型
				alert(a);
				
				var b ; alert(b); //undefined
				var c = 1.1 + 1.9 ; //+用来求和
				alert(c); //自动类型转换
				alert("c"+c); //+用来拼串
				
				//变量交换值--首尾相连
				var d = 1;
				var e = "hello" ;
				var f = d;
				d=e;
				e=f;
				alert(d +","+e);			
		</script>
	</head>
	<body>
	</body>
</html>

typeof运算符: 用于返回变量或者表达式 的数据类型:

var i = 3;
console.log(typeof i);//number
i=true;
console.log(typeof i);//boolean
i="hello";
console.log(typeof i);//string
console.log(typeof 123+"abc");//先求类型再拼接numberabc
console.log(typeof (123+"abc"));//先拼接再求类型string

6、JS的语句(流程控制结构)

JS中的语句和Java中的语句用法也大致相同

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试JS语句</title>
		<!-- 在HTML嵌入JS代码 使用script-->
	<script>
	
	//5. 循环结构
	//5.3在控制台输出1亿每天花一半能花多少天,f12查看
	var f =0;
	var g=100000000;
	while(g>1){
		g=g/2;//每天花一半
		f++;//统计天数什么时候花完
	}
	console.log(f);
	
	//5.1在控制台输出结果,用f12看console输出的1~10
	for(var i = 1;i<11;i++){
		console.log(i);
	}
	//5.2在控制台输出结果,用f12看console输出的1~10的和
	var sum =0;
	for(var i = 1;i<11;i++){
		sum+=i;
	}
	console.log(sum);
	//4.根据用户输入的数字,弹出周几
	/* var d =prompt("请输入周几"); 默认是String类型*/
	//使用parseInt把默认的String类型转换成number类型
	var d =parseInt(prompt("今天周几"));
	switch(d){
		case 1:alert("今天是周一");break;
		case 2:alert("今天是周二");break;
		case 3:alert("今天是周三");break;
		case 4:alert("今天是周四");break;
		case 5:alert("今天是周五");break;
		case 6:alert("今天是周六");break;
		case 7:alert("今天是周七");break;
	}
		//3.判断平年闰年
		var b1=prompt("请输入年份:");
		if((b1%4==0 && b1%100!=0) || b1%400==0){
			alert("这是一个闰年!");
		}else{
			alert("这是一个平年!");
		}
		
		//2.接收用户输入的成绩,判断成绩所属的等级
		var b=prompt("请输入你的成绩:");
		if(b>=80 &&b<=100){
			alert("优秀");
		}else if(b>=60 && b<80){
			alert("中等");
		}else if(b<60 && b>=0){
			alert("不及格");
		}else{
			alert("输入错误!");
		}
		
	//	1.输入一个数并判断
		var a=prompt("请输入一个数");//浏览器接收用户输入进行判断
			if(a>10){
				alert(1);
			}else{
				alert(0);
			}	
	</script>	
	</head>
	<body>
	</body>
</html>

7、JS数组

JS数组用于在单个的变量中存储多个类型的值(其实就是一个容器)。

JS中的数组可以存储例如:数值、字符串、布尔值、undefined、null、对象、函数等。

注意:

(1)JS数组中可以存放不同的数据类型且多个值

(2)JS中的数组长度可以被改变

(3)js中使用for..in进行数组的遍历,其中i指下标,c指数组

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试JS数组</title>
		<script >
                 /*数组的第一种创建方式:new Array
                 而在java中Array调用顶级父类无参构造才能创建*/
				 var a =new Array();
				 a=new Array(10,1.1,'hello',10,1.1);
				 console.log(a);
				 console.log(a.length);
				 
				 a[99]=0;
				 console.log(a.length);
				 console.log(a);//数组长度会改变,没有值的补0
				 /*数组第二种创建方式:直接赋值*/
				 var arr=[123,"abc",false,new Object()];
				 for(var i=0;i<arr.length;i++){
					 console.log(arr[i]);
				 }
				 //for..in遍历
				 for (var i in a) {
				 	console.log("i:::"+i);
				 	console.log(a[i]);
				 }
				 
				 var b=[];
				 b=[100,2.3,"js",a,"码"];
				 for(var i=0;i<b.length;i++){//遍历
					 console.log(b[i]);
				 }
				 //求数组偶数的和
				 var c=[1,2,3,4,5,6,7,8,9,10];
				 var j=0;
				 var a1=0;
				 while(j<=c.length){
					 if(c[j]%2==0){
						 a1+=c[j];
					 }j++;
				 }
				 console.log(a1);
                 //js中使用for..in进行数组的遍历
				 //for..in语法其中i指下标,c指数组
				 for(var i in c){
					 console.log(c[i]);
				}
		</script>
	</head>
	<body>
	</body>
</html>

拓展:JavaScript Array 对象push()方法/unshift()方法

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

 let dat = demoTree.getValue();//获取下拉框的值
let selectOrgArray = [];
for (let i=0;i<dat.length;i++){
selectOrgArray.push(dat[i].value)//循环在末尾添加到一个数组中
}

要想数组的开头添加一个或多个元素,请使用 unshift() 方法

8、JS函数(方法)

函数就是一个具有功能的代码块, 可以反复调用:

  1. JS中使用function进行声明,函数名(参数列表);调用。
  2. 函数名不能使用同一个,js不能实现函数的重载。
  3. 注意: 在JS中调用函数时, 传递的参数个数如果与声明的参数个数不相同, 也不会报错;但是最好按声明的个数来传递, 因为个数不符, 可能会引发一些问题!!!

8.1练习统计字符出现的次数

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试 js的函数</title>
		
		<script>
			// 1. 函数写法1:有特定功能的一块代码
				// 声明函数 :function  函数名(参数列表){函数体}
                //调用:函数名(参数列表);
				function a(){
					var b=[1,2,2,3,4];//定义数组
					for(var i in b){//遍历数组
						console.log(b[i]);//打印数据
					}
				}
				// 调用函数
				a();
			// 2. 函数写法2:有特定功能的一块代码	
				// 声明函数 :	var 函数名 = function(参数列表){函数体}
				var b = function(){
					console.log(100);
				}
				//调用:函数名(参数列表); -- 被调用的函数必须存在!!
				b();
			
			//3. 定义并调用含参函数
				function c(a,b){ //定义含参函数
					console.log(a+b);
				}
				c("hello",1);	  //调用含参函数
				
				var d = function(a,b){
					console.log(a+b);
				}
				d(1.1,2.6);
			//4. 定义并调用含参的有返回值的函数
				function e(a,b){
					return a+b;//把结果返回给调用者
				}
				var f = e(1,2);
				console.log(f);
				
				var g = function(){
                把参数通过return中的运算方式得到结果再返回给调用者
					return "hello js" ;
				}
				var h = g();//调用方法
				console.log(h);
			
			//练习:统计字符串里a字符出现的次数
				function cishu(str,chara){
					var count = 0 ;// 记录次数
					//for(var j = 0 ; j < str.length ;j++){//遍历字符串
                    for(var i in str){//使用js数组高效遍历也可以
						var data = str.charAt(j);//获取每个字符
						//和a字符比较
						if(data == chara){
							//如果是a字符,就++
							count++; 
						}
					}
					return count;//返回给调用者,参数列表有参数,一定设置返回值类型,retrun
				}
				//调用cishu函数,统计字符串abcaaaaa中字符a出现的次数
				var result = cishu(prompt("请输入一串字符:"),prompt("统计哪个字符:"));
				console.log("a字符串出现的次数是:"+result);
				
		</script>
	</head>
	<body>
	</body>
</html>

9、JS对象

9.1内置对象

1)Window对象–代表浏览器中一个打开的窗口,了解一下即可,很多被UI替代

window.onload() 		    在浏览器加载完整个html后立即执行!
window.alert("text") 				提示信息会话框
window.confirm("text") 			确认会话框
window.prompt("text") 			键盘输入会话框
window.event						事件对象
window.document					文档对象

2)Document对象–代表整个HTML文档,可用来访问页面中的所有元素

document.write()               	动态向页面写入内容
document.getElementById(id)  		获得指定id值的元素
document.getElementsByName(name)	获得指定Name值的元素

学会简单使用,后期被jQuery封装,在后期被Vue框架封装。

9.2自定义对象的两种方式

1)方式1:

  1. 声明对象:function Person(){}
  2. 创建对象:var p1 = new Person();
  3. 动态设置属性:p1.name = "张飞"; p1.age = 18;
  4. 查看属性:console.log(p1);
  5. 动态设置函数:p1.run=function(){console.log("追光者")};
  6. 调用函数:p1.run();

js的牛掰之处就在于,它的属性可以边写边创建,非常灵活,而java不行,必须先定义。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试JS创建对象</title>
		<script>
			/*2.创建对象方式2*/
			var a1={
				//绑定属性
				"name":"黑旋风",
				"age":20,
				//绑定函数
				"say": function(a){
					console.log(a);
				}
			}
			console.log(a1);
			a1.say("这厮着实很皮");//调用函数
			
			/*1.创建对象方式1*/
			//1.定义对象
			function Person(){};
			//2.创建对象
			var a =new Person();
			//3.动态绑定属性
			a.name="李逵";
			a.age=20;
			//查看
			console.log(a);
			//4.函数的定义
			a. run=function(){
				// a.name="花和尚";
				// a.age=12;
				/* this指该对象下的XXX,js中遵循就近原则
				而在java中this指本类下的XX成员变量 */
				console.log(this.name+this.age)
				};
			//调用函数
			a.run();

            <!--方式2练习  -->

			/*1.给哪个函数名直接赋值属性,设置方法*/
			var a1={
				"name":"旺达",
				"age":30,
				"power":function(){
					var a11=prompt(this.name+"的年龄是"+this.age+"吗?(回答yes或no)");
					if(a11=='yes'){
						alert("你真棒");
					}else{
						alert("回答错误");
					}
				}				
			}
			//调用方法		
			console.log(a1);
			a1.power();	
		</script>
	</head>
	<body>
	</body>
</html>

五、DOM树的作用

1、组成

  • ECMAScript描述了javascript语言的语法和基本对象
  • 文档对象模型DOM(Document Object Model)与HTML网页API接口
  • 浏览器对象模型BOM(Browser Object Model),与浏览器进行交互的API接口

DOM非常重要,实际开发更多通过js操作DOM对象实现对html页面的操作,BOM也用,比较少用

核心对象有:window浏览器窗口,navigator浏览器信息,location浏览器当前地址信息,history浏览器历史信息,screen用户屏幕信息。

2、DOM树的结构

DOM 是一项 W3C (World Wide Web Consortium) 标准,

DOM(Document Object Model)文档对象模型为JS操作html文档所提供的一套API,

通过这套API可以很方便的对html元素进行访问及增删改查操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mw8l1nxY-1622526185008)(RackMultipart20210601-4-1vdjb36_html_1b9343e8dd3a0f7a.png)]

 3、Document对象

3.1作用:

获取、解析网页各个元素

--获取对象: window.document
window可省略,默认会有
--调用方法: 
		getElementById("元素的id的属性的值")--返回1个元素
		getElementsByName("元素的name属性的值")--返回多个元素(用数组)
		getElementsByClassName("元素的class属性的值")--返回多个元素(用数组)
		getElementsByTagName("元素的标签名的值")--返回多个元素(用数组)
write()--向文档写 HTML 表达式 或 JavaScript 代码
.style.--设置元素的样式
title--返回网页的标题--alert(document.title);
id--设置或返回元素的id
innerHTML--设置或返回元素的内容

注意:dom树在描述标签时除id方式,其它都是以数组形式体现,哪怕是一个元素,所以在修改会修饰该元素时,必须要指定元素数组的下标

3.2练习:使用dom解析网页中的元素

/*innerHTML和innerText的区别是:
        前者能解析标签名,
        后者不能解析反而是把标签名当做元素打印在了网页上*/

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试DOM解析网页元素</title>
		<script>
			function method(){
				/*4.获取标签名是p的元素*/
                //按照标签名可获取多个元素
				var d =document.getElementsByTagName("p");
                d[0].style.color="red";//必须指定下标哪个元素才可设置样式
				d[1].style.fontSize="100px";
				d[0].innerHTML="eat..";
				console.log(d[0].innerHTML);
				
				/*3.获取class="f"*/
				var c=document.getElementsByClassName("f");
				c[0].innerHTML="hi..";
				console.log(c[0].innerHTML);
				
			/*2.获取name="d"*/
			var b=document.getElementsByName("d");//获取所有d元素
			//b[0].innerHTML="test...";//修改第一个元素的内容
			b[0].style.color="red";//修改第一个元素的样式
			//console.log(b);
			console.log(b[0].innerHTML);//获取修改第一个元素的内容
			
		// 	/* /*1.获取id='a1'*/
		// 	var a=window.document.getElementById("a1");
		// 	a.innerHTML="<h1>hello</h1>";//修改内容
		// 	//console.log(a.innerHTML);//获取内容
		// 	document.write(a.innerHTML);//直接向网页写出数据
			
		// //innerText和innerHTML的区别?innerHTML能解析HTML标签
		// 	a.innerText="<h1>hello</h1>";//修改内容
		// 	//console.log(a.innerText);//获取内容
		// 	document.write(a.innerText);//直接向网页写出数据 */
			}
		</script>
	</head>
	<body>
		<div name="d" onclick="method();">俺是v1</div>
		<div name ="d">俺是v2</div>
		<div>俺是v3</div>
		
		<a href="#" id="a1">俺是a1</a>
		<a href="#" class="f">俺是a2</a>
		
		<p calss="f">p1</p>
		<p>p2</p>
	</body>
</html>

六、console浏览器控制台调试网页

1、Chrome

浏览器调试谷歌、火狐最佳,使用F12打开调试窗口,快捷键打开:ctrl+shift+i。

  • 支持自动补全,提示下,按tab键补全
  • 清除日志
  • Console控制台菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6y32hLZF-1622526185013)(RackMultipart20210601-4-1vdjb36_html_1faab11e37410c47.png)]

 2、log--日志

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ApmBOpKD-1622526185014)(RackMultipart20210601-4-1vdjb36_html_452ff1cab3407fbf.png)]

 3、warn--警告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qynkg3CR-1622526185016)(RackMultipart20210601-4-1vdjb36_html_12bf66c013182cde.png)]

4、 table

以表格形式展现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eEb87EdJ-1622526185019)(RackMultipart20210601-4-1vdjb36_html_d037d642cdad2159.png)]

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值