JavaScript——DOM(Document Object Model)文档对象模型

节点:Node

构成HTML文档最基本的单元。常用节点分为四类

  • 文档节点:整个HTML文档(#document)
  • 元素节点:HTML文档中的HTML标签
  • 属性节点∶元素的属性
  • 文本节点:HTML标签中的文本内容(#text)

实例

<button id="btn">我是一个按钮</button>
<script type="text/javascript">
	/*
	 * 浏览器已经为我们提供 文档节点 对象这个对象是window属性
	 * 	可以在页面中直接使用,文档节点代表的是整个网页
	 */
	//console.log(document);
	//获取到button对象
	var btn = document.getElementById("btn");
	
	//修改按钮的文字
	btn.innerHTML = "I'm Button";
</script>

实例二

<button id="btn">我是一个按钮</button>
<script>
	/* onload事件会在整个页面加载完成之后才触发
	为window绑定一个onload事件
	该事件对应的响应函数将会在页面加载完成之后执行,
	这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了 */

	window.onload = function() {
		var test = document.getElementById("btn")
		test.onclick = function() {
			alert("hello")
		}
		var result = test.innerHTML;
		console.log(test)
	}
</script>

获取元素节点

通过document对象调用
1、getElementById()
	-通过id属性获取一个元素节点对象,没找到则返回null,找到则返回对象
	var test = document.getElementById("btn");
	var result = test.innerHTML;
	console.log(result)
2、getElementsByTagName()
	-通过标签名获取一组元素节点对象,没找到则返回null,找到则返回类数组对象
	var test = document.getElementsByTagName("p");
	var result = p[0].innerHTML;//innerText和innerHTML类似但是会去掉标签
	console.log(result)
3、getElementsByName()
	-通过name属性获取一组元素节点对象
4、getElementsByClassName()//IE8及以下不支持

图片切换例子

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			.outer{
				width: 550px;
				padding:10px;
				margin: 50px auto;
				text-align: center;
				background-color: #8b9bff;
			}
		</style>
		<script>
			window.onload = function() {
				var image=["./1.jpg","./2.jpg","./3.jpg","./4.jpg","./5.jpg"]
				//当前图片的索引
				var index=0;
				var img=document.getElementsByTagName("img")[0];
				//
				var info = document.getElementById("info");
				info.innerHTML="一共"+image.length+"张图片"+"  "+"这是第"+(index+1)+"张";
				
				var prev = document.getElementById("prev")
				prev.onclick = function() {
					index--;
					if(index<0){
						index=image.length-1;
					}
					img.src=image[index];
					info.innerHTML="一共"+image.length+"张图片"+"  "+"这是第"+(index+1)+"张";
				}
				
				var next = document.getElementById("next")
				next.onclick = function() {
					index++;
					if(index>=image.length){
						index=0;
					}
					img.src=image[index];
					info.innerHTML="一共"+image.length+"张图片"+"  "+"这是第"+(index+1)+"张";
				}
				
			}
		</script>
	</head>
	<body>
		<div class="outer">
			<h2 id=info></h2>
			<img src="./1.jpg" />
			<button id="prev">上一张</button>
			<button id="next">下一张</button>
		</div>
	</body>
</html>

在这里插入图片描述

获取元素节点的子节点

通过具体的元素节点调用
1. getElementsByTagName()
	-方法,返回当前节点的指定标签名后代节点
2. childNodes
	-属性,表示当前节点的所有子节点
	childNodes属性会获取包括文本节点在呢的所有节点
	根据DOM标签标签间空白也会当成文本节点
	注意:在工E8及以下的浏览器中,不会将空白当成子节点
	
	children属性可以获取当前元素的所有子元素

3. firstChild
	-属性,表示当前节点的第一个子节点
	//firstChild可以获取到当前元素的第一-个子节点(包括空白文本节点)
	var fir = phone.firstChild;
	//firstElementChild获取当前元素的第一个子元素
	firstElementChild不支持IE8及以下的浏览器,
	如果需要兼容他们尽量不要使用
	*/

4. lastChild
	-属性,表示当前节点的最后-个子节点

获取父节点和兄弟节点

通过具体的节点调用
1. parentNode
	-属性,表示当前节点的父节点
2. previousSibling
	-属性,表示当前节点的前一个兄弟节点,也可能获取空白文档
	previousElementSibling不会获取空白文档,不兼容ie8及以下
3. nextSibling
	-属性,表示当前节点的后一个兄弟节点

全选练习

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

		<script>
			window.onload = function() {

				var items = document.getElementsByName("items");
				//全选/全不选
				var checkedAllBox = document.getElementById("checkedAllBox");

				//全选
				var checkedAllBtn = document.getElementById("checkedAllBtn");
				checkedAllBtn.onclick = function() {

					for (var i = 0; i < items.length; i++) {
						items[i].checked = true;
					}
					checkedAllBox.checked = true;
				}
				//全不选
				var checkedNoBtn = document.getElementById("checkedNoBtn");
				checkedNoBtn.onclick = function() {

					for (var i = 0; i < items.length; i++) {
						items[i].checked = false;
					}
					checkedAllBox.checked = false;
				}
				//反选
				var checkedRevBtn = document.getElementById("checkedRevBtn");
				checkedRevBtn.onclick = function() {
					checkedAllBox.checked = true;
					
					for (var i = 0; i < items.length; i++) {
						items[i].checked = !items[i].checked;
						//判断四个多选框是否全选
						if (!items[i].checked) {
							checkedAllBox.checked = false;
						}
					}
				}
				//提交按钮
				var sendBtn = document.getElementById("sendBtn");
				sendBtn.onclick = function() {
					for (var i = 0; i < items.length; i++) {
						if (items[i].checked == true) {
							alert(items[i].value);
						}
					}
				}
				
				checkedAllBox.onclick = function() {
					for (var i = 0; i < items.length; i++) {
						items[i].checked = checkedAllBox.checked;
					}
				}

				/* 如果四个多选框全都选中,则chec kedAllBox也应该选中
				如果四个多选框没都选中,则chec kedAllBox也不应该选中
				*/
				//为四个多选框分别绑定点击响应函数
				for (var i = 0; i < items.length; i++) {
					items[i].onclick = function() {
						checkedAllBox.checked = true;
						for (var j = θ; j < items.length; j++) {
							//判断四个多选框是否全选
							if (!items[j].checked) {
								checkedAllBox.checked = false;
							}
							break;
						}
					}
				}
			}
		</script>
	</head>
	<body>
		<form method="post" action="">
			你爱好的运动是? <input type="checkbox" id="checkedAllBox" />全选/全不选
			<br />
			<input type="checkbox" name="items" value="足球" />足球
			<input type="checkbox" name="items" value="篮球" />篮球
			<input type="checkbox" name="items" value="羽毛球" />羽毛球
			<input type="checkbox" name="items" value="乒乓球" />乒乓球
			<br />
			<input type="button" id="checkedAllBtn" value="全选" />
			<input type="button" id="checkedNoBtn" value="全不选" />
			<input type="button" id="checkedRevBtn" value="反选" />
			<input type="button" id="sendBtn" value="提交" />
		</form>

	</body>
</html>

在这里插入图片描述

DOM查询的其他方法

//获取body标签
				var body=document.getElementsByTagName("body")[0];
				//或
				var body=document.body;
			//获取html标签
				var html=document.documentElement;
			//document.all代表页面的所有元素
			//document.querySelector(),如果有多个,但是只会返回第一个
				document.querySelector(".box1 div")
			//document.querySelectorAll(),如果有多个返回多个,只有一个也会返回数组
				document.querySelectorAll(".box1")

创建节点

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

		<script>
			window.onload = function() {
				myClick("btn01", function() {
					//创建节点
					var p = document.createElement("p");
					//创建文本节点对象
					var bjText=document.createTextNode("北京");
					//添加子节点:语法:父节点.document.appendChild(子节点)
					p.appendChild(bjText);
					
					var add = document.getElementById("addp");
					add.appendChild(p);
					//=========或则使用以下方法,更简便==================================
					var p = document.createElement("p");
					p.innerHTML="湛江";
					var add = document.getElementById("addp");
					add.appendChild(p);
				})
				
			}

			function myClick(idStr, fun) {
				var btn = document.getElementById(idStr);
				btn.onclick = fun;
			}
		</script>
	</head>
	<body>
		<button id="btn01">创建节点</button>
		<h3 id="addp"></h3>

	</body>
</html>

CDES

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

		<script>
			function delA() {
				//点击哪个,this就是哪个按钮
				//获取当前的tr
				var tr = this.parentNode.parentNode;
				//获取员工的名字
				var deleteName = tr.children[0].innerHTML;
				//是否删除提示
				var flag = confirm("是否" + deleteName + "删除?")
				//删除<tr>
				if (flag) {
					tr.parentNode.removeChild(tr);
				}
				return false;
			}
			window.onload = function() {
				//删除信息
				//获取超链接
				var allA = document.getElementsByTagName("a");
				for (var i = 0; i<allA.length; i++) {
					allA[i].onclick = delA; //将对象赋值过去而不是返回值
				}

				//添加信息
				//提交按钮
				var addEmpButton = document.getElementById("addEmpButton");
				addEmpButton.onclick = function() {
					
					//获取名字
					var name = document.getElementById("empName").value;
					alert(name);
					//获取email
					var email = document.getElementById("email").value;
					//获取salary
					var salary = document.getElementById("salary").value;

					//创建一个<tr>
					var tr = document.createElement("tr");

					//设置tr的内容
					tr.innerHTML = "<td>"+name+"</td>" +
						"<td>"+email+"</td>" +
						"<td>"+salary+"</td>" +
						"<td><a href='javascript:;'>Delete</a></td>";
					//获取超链接
					var a = tr.getElementsByTagName("a")[0];
					a.onclick = delA;
					
					
					// //创建四个<td></td>
					// var nameTd = document.createElement("td");
					// var emailTd = document.createElement("td");
					// var salaryTd = document.createElement("td");
					// var aTd = document.createElement("td");

					// //创建一个a
					// var a = document.createElement("a");

					// //创建文本节点
					// var nameText = document.createTextNode(name);
					// var emailText = document.createTextNode(email);
					// var salaryText = document.createTextNode(salary);
					// var delText = document.createTextNode("Delete");

					// //将文本添加到td中
					// nameTd.appendChild(nameText);
					// emailTd.appendChild(emailText);
					// salaryTd.appendChild(salaryText);
					// a.appendChild(delText);
					// aTd.appendChild(a);

					// //将td添加到tr中
					// tr.appendChild(nameTd);
					// tr.appendChild(emailTd);
					// tr.appendChild(salaryTd);
					// tr.appendChild(aTd);

					// //向a中添加href属性
					// a.href = "javascript:;";
					// a.onclick = delA;

					//获取table
					//var employeeTable = document.getElementById("employeeTable");

					//获取employeeTable中的<tbody>
					var tbody = employeeTable.getElementsByTagName("tbody")[0];

					//将tr添加到tbody中
					tbody.appendChild(tr);
				};
			};

			// function myClick(idStr, fun) {
			// 	var btn = document.getElementById(idStr);
			// 	btn.onclick = fun;
			// }
		</script>
	</head>
	<body>
		<table id="employeeTable">
			<tr>
				<th>Name</th>
				<th>Email</th>
				<th>Salary</th>
				<th>&nbsp;</th>
			</tr>
			<tr>
				<td>wang</td>
				<td>787@qq.com</td>
				<td>8000</td>
				<td><a href="deleteEmp?id=001">delete</a></td>
			</tr>
			<tr>
				<td>Tony</td>
				<td>742347@qq.com</td>
				<td>10000</td>
				<td><a href="deleteEmp?id=002">Delete</a></td>
			</tr>
		</table>

		<div id="formDiv">
			<h4>添加信息</h4>
			<table>
				<tr>
					<td class="word">name:</td>
					<td class="inp">
						<input type="text" name="empName" id="empName" />
					</td>
				</tr>
				<tr>
					<td class="word">email:</td>
					<td class="inp">
						<input type="text" name="email" id="email" />
					</td>
				</tr>
				<tr>
					<td class="word">salary:</td>
					<td class="inp">
						<input type="text" name="salary" id="salary" />
					</td>
				</tr>
				<tr>
					<td colspan="2" align="center">
						<button id="addEmpButton">
							Submit
						</button>
					</td>
				</tr>
			</table>
		</div>
	</body>
</html>

操作“内联”样式

修改

通过JS修改元素的样式:
	语法:元素.style.样式名=样式值
注意:如果CSS的样式名中含有一,
	这种名称在JS中是不合法的比如background-color
	需要将这种样式名修改为驼峰命名法,
	去掉-,然后将-后的字母大写
box1.style.width="300px" ;
box1.style.height = " 300px" ;
box1.style backgroundColor = "yellow";
我们通过sty1 e属性设置的样式都是内联样式,
而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
但是如果在样式中写了! important,则此时样式会有最高的优先级,
即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效
所以尽量不要为样式添加!important

读取

语法:元素.style.样式名
box1.style.height

获取元素的样式(只读)

currentStyl
	获取元素当前正在显示的样式,不局限内联样式
	语法:元素.currentStyle.样式名
	currentStyle只有IE支持
	box1.currentStyle.height
在其他浏览器中可以使用
getComputedstyle( )这个方法来获取元素当前的样式
	这个方法是window的方法,可以直接使用!
	需要两个参数
	第一个:要获取样式的元素
	第二个:可以传递一个伪元素,-般都传null
		alert(getComputedStyle(box1,null).width);
	该方法会返回一个对象,对象中封装了当前元素对应的样式
	可以通过对象.样式名来读取样式
	如果获取的样式没有设置,则会获取到真实的值,而不是默认值
	比如:没有设置width,它不会获取到auto,而是一个长度
		alert(getComputedStyle(box1,null).backgroundColor);不兼容IE8

处理兼容问题
	定义一个函数,用来获取指定元素的当前的样式
		参数:
		obj要获取样式的元素
		name要获取的样式名
	alert(getStyle(box1,backgroundColor));
	function getStyle(obj,name){
		if(window.getComputedStyle){
			//正常浏览器
			return getComputedStyle(obj,null)[name];
		}
		else{
			//IE8
			return obj.currentStyle[name];
		}
	}	

其他样式的相关属性

获取元素的宽度和高度(只读)

clientWidth
clientHeight
	-这两个属性可以获取元素的可见宽度和高度
	-这些属性都是不带px的,返回都是一个数字, 可以直接进行计算
	-会获取元素宽度和高度,包括内容区和内边距
	box1.clienwidth
offsetWidth
offsetHeight
	获取元素的整个的宽度和高度,包括内容区、内边距和边框
offsetParent
	-可以用来获取当前元素的定位父元素
	-会获取到离当前元素最近的开启了定位的祖先元素,如果所有的祖先元素等候没有开启定位,则返回body
	var op = box1. offsetParent ;
	alert(op.id);
offsetL eft
	-当前元素相对于其定位父元素的水平偏移量
offsetTop
	当前元素相对于其定位父元素的垂直偏移量
scrollWidth
scrollHeight
	可以获取元素整个滚动区域的高度和宽度
scrollLeft
	可以获取水平滚动条滚动的距离
scrollTop
	可以获取垂直滚动条滚动的距离
scrollHeight-scrollTop==clientHeight时垂直滚动条滚动到底
	例如:info.scrollHeight-info.scrollTop==info.clientHeight
scrollWidth-scrollLeft==clientWidth时水平滚动条滚动到底

事件对象

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			#areaDiv {
				width: 200px;
				height: 50px;
				border: 1px solid #000000;
			}

			#showMsg {
				width: 200px;
				height: 20px;
				border: 1px solid #000000;
				margin-top: 10px;
			}
		</style>
		<script>
			window.onload = function() {
				var areaDiv = document.getElementById("areaDiv");
				var showMsg = document.getElementById("showMsg");
				// 事件对象
				// 当事件的响应函数被触发时,浏览器每次都会将一一个事件对象作为实参传递进响应函数

				areaDiv.onmousemove = function(event) {
					// clientX	返回当事件被触发时,鼠标指针的水平坐标。
					// clientY	返回当事件被触发时,鼠标指针的垂直坐标。
					//通过判断兼容浏览器
					if (!event) {
						event = window.event;
					}
					//或则evnet=event||window.event;
					var x = event.clientX;
					var y = event.clientY;

					showMsg.innerHTML = "x=" + x + "," + "y = "+y;
					
				}
			};
		</script>
	</head>
	<body>
		<div id="areaDiv"></div>
		<div id="showMsg"></div>
	</body>
</html>

在这里插入图片描述

使div跟随鼠标移动

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			#box1 {
				width: 100px;
				height: 100px;
				background-color: #00FF00;
				/*开启定位*/
				position: absolute;
			}
		</style>
		<script>
			window.onload = function() {
				var box1 = document.getElementById("box1");
				document.onmousemove = function(event) {
					//使div跟随鼠标移动
					if (!event) {
						event = window.event;
					}
					//获取滚动条的滚动距离
					var st =document.body.scrollTop || document.documentElement.scrollTop;
					var sl =document.body.scrollLeft || document.documentElement.scrollLeft;
					
					//获取到鼠标的坐标
					/*
					clientX和clientY
					用于获取鼠标在当前的可见窗口的坐标
					div的偏移量,是相对于整个页面的
					pageX和pageY可以获取鼠标相对于当前页面的坐标
					但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用
					*/

					var left = event.clientX;
					var top = event.clientY;

					//设置div的偏移量
					box1.style.left = left+sl + "px";
					box1.style.top = top +st+ "px";

				}
			}
		</script>
	</head>
	<body>
		<div id="box1"></div>
	</body>
</html>

事件的冒泡

取消冒泡
可以将事件对象的cancelBubble设置为true,即可取消冒泡
event=event || window.event;
event.cancelBubble=true;

事件的委派

我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的
我们可以尝试将其绑定给元素的共同的祖先元素

事件的委派
	指将事件统一-绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会- -直 冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
	事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
ul.οnclick=function(event){
	//如果触发事件的对象是我们期望的元素,则执行否则不执行
	event=event || window.event;
	if(event.target.className=="link"){
		alert("只有点击a中的内容才会触发事件");
	}
}

<ul id="ul">
	<li><a href="javascript:;" class="link">超链接一</a></li>
	<li><a href="javascript:;" class="link">超链接一</a></li>
	<li><a href="javascript:;" class="link">超链接一</a></li>
</ul>

事件的绑定

同时为一个元素的相同事件同时绑定多个响应函数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script>
			window.onload = function() {
				var btn01 = document.getElementById("btn01");
				// addEventListener( )
				// -通过这个方法也可以为元素绑定响应函数
				// -参数:
				// 1.事件的字符串,不要on
				// 2.回调函数,当事件触发时该函数会被调用
				// 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false

				// 使用addEventListener( )可以同时为一个元素的相同事件同时绑定多个响应函数,
				// 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行

				//addEventListener//IE8以下不支持

				// btn01.addEventListener("click",function(){
				// 	alert(1)
				// },false)
				// btn01.addEventListener("click",function(){
				// 	alert(2)
				// },false)
				// btn01.addEventListener("click",function(){
				// 	alert(3)
				// },false)

				//attachEvent不兼容

				// btn01.attachEvent("onclick",function(){
				// 	alert(1);
				// })
				// btn01.attachEvent("onclick",function(){
				// 	alert(2);
				// })
				// btn01.attachEvent("onclick",function(){
				// 	alert(3);
				// })
				bind(btn01,"click",function(){
					alert(this);
				});
			}
			//定义一一个函数,用来为指定元素绑定响应函数
			// addEventListener( )中的this,是绑定事件的对象
			// attachEvent( )中的this,是window
			// 需要统-两个方法this

			/*
			参数:
			*
			obj要绑定事件的对象
			*
			eventStr事件的字符串(不用on)
			*
			callback回调函数
			*/
			//兼容的解决方法

			function bind(obj, eventStr, callback) {
				if (obj.addEventListener) {
					//大部分浏览器兼容的方式
					obj.addEventListener(eventStr, callback, false);
				} else {
					//this由调用方式决定
					//IE8及以下
					obj.attachEvent("on" + eventStr, function(){
						callback.call(obj);
					});
				}
			}
		</script>
	</head>
	<body>
		<button id="btn01"></button>
	</body>
</html>

事件的传播

事件的拖拽1

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1 {
				width: 100px;
				height: 100px;
				background-color: #00FF00;
				position: absolute;
			}
		</style>
		<script>
			window.onload = function() {
				var box1 = document.getElementById("box1");
				/* 拖拽box1元素
				拖拽的流程
				1.当鼠标在被拖拽元素上按下时,开始拖拽onmousedown
				2.当鼠标移动时被拖拽元素跟随鼠标移动onmous emove
				3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup */
				box1.onmousedown = function() {
					document.onmousemove = function(event) {
						event = event || window.event;

						//获取鼠标的坐标
						var left = event.clientX;
						var top = event.clientY;

						//修改box1的位置
						box1.style.left = left + "px";
						box1.style.top = top + "px";
					}
					document.onmouseup = function() {
						//当鼠标松开时,被拖拽元素固定在当前位置onmouseup
						//取消document的onmousemove事件
						document.onmousemove = null;
						//取消document的onmouseup事件
						document.onmouseup = null ;

					}
				}

			}
		</script>
	</head>
	<body>
		<div id="box1"></div>

	</body>
</html>

事件的拖拽2

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			#box1 {
				width: 100px;
				height: 100px;
				background-color: #00FF00;
				position: absolute;
			}
		</style>
		<script>
			window.onload = function() {
				var box1 = document.getElementById("box1");
				/* 拖拽box1元素
				拖拽的流程
				1.当鼠标在被拖拽元素上按下时,开始拖拽onmousedown
				2.当鼠标移动时被拖拽元素跟随鼠标移动onmous emove
				3.当鼠标松开时,被拖拽元素固定在当前位置onmouseup */
				box1.onmousedown = function(event) {
					//div的偏移量鼠标.clentX -元素.offsetLeft
					//div的偏移量鼠标.clentY -元素.offsetTop
					event = event || window.event;
					var ol=event.clientX-box1.offsetLeft;
					var ot=event.clientY-box1.offsetTop;
					
					document.onmousemove = function(event) {
						event = event || window.event;

						//获取鼠标的坐标
						var left = event.clientX;
						var top = event.clientY;

						//修改box1的位置
						box1.style.left = left-ol + "px";
						box1.style.top = top-ot + "px";
					}
					document.onmouseup = function() {
						//当鼠标松开时,被拖拽元素固定在当前位置onmouseup
						//取消document的onmousemove事件
						document.onmousemove = null;
						//取消document的onmouseup事件
						document.onmouseup = null ;

					}
				}

			}
		</script>
	</head>
	<body>
		<div id="box1"></div>

	</body>
</html>

事件的拖拽3

//设置btn01对鼠标按下相关的事件进行捕获
//当调用一个元素的setCapture( )方法以后,这个元素将会把下一次所有的鼠标按下相关的事件捕获到自身上
if(box1.setCapture){
	box1.setCapture();
}
box1.setCapture&&box1.setCapture();

//当鼠标松开时,取消对事件的捕获
box1.releaseCapture && box1.releaseCapture( );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值