Ajax学习笔记第三天
- 开源代码
- 2025-08-15 04:09:02

做决定之前仔细考虑,一旦作了决定就要勇往直前、坚持到底! 【1 ikunGG邮箱注册】
整个流程展示:
1.文件目录
2.页面效果展示及代码
mysql数据库中的初始表2.1 主页 09.html:里面代码部分解释
display: inline-block;让块元素h1变成行内块元素,不然块级元素h1的宽度会撑满父元素宽度
box-sizing: border-box;盒子的大小:盒子大小固定,与margin,padding,border无关,但会自动调节content的大小
position: absolute;绝对定位会使元素脱离文档流 ,绝对定位元素 是根据 离其(自身)最近并且**有定位设置(static定位除外)的父元素** 作为 定位位置的参考起点
cursor:text大写I的点击填写
z-index: 999;参数越大,表示越会显示在其他堆叠元素之上。Z-index 仅能在定位元素上有效(例如 position:absolute;)
display: none;该元素不显示 ,相当于html标签里面没有这个元素盒子了
letter-spacing:属性增加或减少字符之间的空白(字符间距)
如果label标签设置了for=“xxx”,input标签设置了id=“xxx”【xxx一样】,那么,label标签简单理解为可以绑定表单元素。label本身与某个表单绑定,当用户点击了label标签则会触发表单,也就相当于点击了表单。 <!-- label标签是行内元素 --> <label for="emailadd">邮箱地址</label> <input type="text" class='username' name="username" id="emailadd"> previousSibling返回当前元素上一个兄弟元素节点【请点击此处】
下面代码打印i时,全部都是3,最后一个。???为什么会出现这样的情况??? console.log(window); for (var i = 0; i < inputs.length; i++) { // 聚焦时 inputs[i].onfocus = function () { // 当聚焦的时候让label消失 console.log(i);//全部是3 console.log(this); // this => 触发聚焦这个事件的input元素 } }解答:
原因就是:js事件处理器在线程空闲时间不会运行,导致最后运行的时候输出的都是i最后的值。在每个点击事件函数的作用域链中都保存着windows的活动对象**(for语句不构成作用域),所以它们引用的是同一个变量i,即i属于一个全局变量**,所以在给每个li绑定事件后,每个函数内部i的值都是3。
【意思就是说:外面的for循环已经执行完了,i已经是3了,再等你点击绑定的事件时,打印的i可不就是3了吗?】
通俗点来说就是:先给每个li绑定点击事件,绑定完点击事件后,每次没有被执行罢了。执行的时候已经被赋值成3了,(同步执行,异步执行问题)i是一个全局变量,所以再点击某个li输出i的时候,输出的自然是3了。
解决问题:使用ES6中Let完美解决。var i = 0 —> let i = 0
我们不点击input框,直接我们打印一下window对象身上有没有i。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { background: #eff8ff; } /* 整个最外层包裹的盒子的样式 */ .container { width: 470px; /* 内边距10px */ padding: 10px; border: 1px solid #333; /* 上下30px,左右自动居中对齐 */ margin: 30px auto; } .container h1 { /* 让块元素h1变成行内块元素,不然块级元素h1的宽度会撑满父元素宽度 */ display: inline-block; font-size: 30px; /* 字体粗细层度 */ font-weight: 400; color: #333; /* h1字号:原本32px = 2rem=2*16px */ line-height: 34px; } /* 父级元素container里的所有item子元素 */ .container .item { width: 470px; /* 距离上面同级元素底边的距离 */ margin-top: 35px; /* 定位 */ position: relative; } .container .item input { width: 100%; height: 46px; /* 盒子的大小:盒子大小固定,与margin,padding,border无关,但会自动调节content的大小 */ box-sizing: border-box; border: 1px solid #cbcbcb; border-radius: 5px; /* 上11 右0 下10 左16 */ padding: 11px 0 10px 16px; font-size: 16px; } .container .item label { height: 46px; box-sizing: border-box; border-radius: 3px; padding: 14px 0 10px 17px; font-size: 16px; /* 绝对定位会使元素脱离文档流 */ /* 绝对定位元素 是根据 离其(自身)最近并且有定位设置(static定位除外)的父元素 作为 定位位置的参考起点 */ position: absolute; top: 0; left: 0; color: #bfbfbf; /* cursor:text(大写I的点击填写) */ cursor: text; /* 参数越大,表示越会显示在其他堆叠元素之上。Z-index 仅能在定位元素上有效(例如 position:absolute;) */ z-index: 999; } .container .item .username { /* 距离右边父级元素120px */ padding-right: 120px; } .container .item .domain { width: 131px; color: #343434; /* 绝对定位会使元素脱离文档流 */ position: absolute; top: 0; right: 0; border: none; height: 46px; /* 盒子的大小:盒子大小固定,与margin,padding,border无关,但会自动调节content的大小 */ box-sizing: border-box; border-radius: 3px; padding: 11px 0 10px 16px; font-size: 16px; line-height: 25px; } .tip { height: 17px; line-height: 17px; /* 上面两行代码,是内容垂直居中对齐 */ font-size: 13px; color: #9e9e9e; /* 该元素不显示 */ display: none; margin-top: 10px; } #error { color: #ff5b5b; font-size: 12px; display: none; font-size: 13px; margin-top: 10px; } #success { color: #33a853; font-size: 12px; display: none; font-size: 13px; margin-top: 10px; } .btn { color: #fff; background: #3b78dd; font-size: 22px; letter-spacing: 2.2px; /* 该元素盒子被内容,line-height撑高 */ line-height: 46px; /* display:block就是将元素显示为块级元素 */ display: block; text-align: center; border-radius: 5px; margin-top: 35px; } </style> </head> <body> <div class="container"> <h1>欢迎注册ikunGG邮箱</h1> <div class="item"> <!-- label标签简单理解为可以绑定表单元素。label本身与某个表单绑定,当用户点击了label标签则会触发表单,也就相当于点击了表单 --> <!-- label标签是行内元素 --> <label for="emailadd">邮箱地址</label> <input type="text" class='username' name="username" id="emailadd"> <p class="tip">6~18个字符,可使用字母、数字、下划线,需要以字母开头</p> <div class="domain"> 164 </div> <p id="error"> 该邮箱已经被注册 </p> <p id="success">恭喜,该邮件地址可以注册</p> </div> <div class="item"> <label>密码</label> <input type="text" name="password"> <p class="tip">6~16个字符,区分大小写</p> </div> <div class="item"> <label>手机号</label> <input type="text" name="phone"> <p class="tip">可通过该手机号找回密码</p> </div> <div class="btn" id="btn">立即注册</div> </div> <!-- 引入封装好的Ajax技术 --> <script src="js/ajax.js"></script> <script> // 获取所有的input框 var inputs = document.getElementsByTagName("input"); var username = document.getElementsByClassName("username")[0]; var successTip = document.getElementById("success"); var errorTip = document.getElementById("error"); var btn = document.getElementById("btn"); // 记录存储名称 var keys = { "username": "邮箱地址", "password": "密码", "phone": "手机号" } // 设置一个状态,用来判断当前的邮箱地址是否已经被注册了,如果被注册了,就不允许提交 var emailFlag = true; // console.log(window); for (var i = 0; i < inputs.length; i++) { // 聚焦时 inputs[i].onfocus = function () { // 当聚焦的时候让label消失 // console.log(i);//全部是3 // console.log(this); // console.log(this.previousSibling.previousSibling);//label // this => 触发这个事件的input元素 // previousSibling 返回当前元素上一个兄弟元素节点【重点补充】 // previousSibling和nextSibling是获取上一个、下一个同胞元素,如果上一个或下一个同级节不存在,则此属性返回值是null // this.previousSibling.previousSibling.style.display = 'none' // 和上面代码一样,但下面的代码兼容性不行 this.previousElementSibling.style.display = "none"; // 当聚焦的时候让下面的提示文案显示 // this.nextSibling.nextSibling.style.display = "block"; this.nextElementSibling.style.display = "block"; // 如果input的name属性为username,即,如果聚焦的为第一个input框,那么让成功和失败的提示消失 if (this.name == 'username') { // 强制让成功和失败的提示消失 successTip.style.display = "none"; errorTip.style.display = "none"; } } // 失去焦点 inputs[i].onblur = function () { // 当失去焦点的时候,判断,如果有value值,就不让label显示,否则就显示label if (!this.value) { this.previousSibling.previousSibling.style.display = 'block' } // 失去焦点的时候让下面的提示文案隐藏 this.nextSibling.nextSibling.style.display = "none"; // 如果是用户名则发送ajax请求去判断当前的用户是否已经被注册 // 找到用户名这个框且不能为空,才能校验 if (this.name == "username" && this.value) { // 发送Ajax请求校验 validate(this.value); } } } // 校验请求 function validate (value) { // 可以直接调用封装好的 ajax.get("check.php", { "username": value }, function (data) { // 返回的数据时SUCCESS,那么就是可以注册email if (data == "SUCCESS") { // 显示成功提示 successTip.style.display = "block"; // 邮箱的可提交状态为true emailFlag = true; } else if (data == "ERROR") { //显示失败提示 errorTip.style.display = "block"; // 邮箱的可提交状态为false,即不可提交 emailFlag = false; } }) } // 发送请求提交数据 btn.onclick = function () { // 第一步:要先判断用户名是否可以使用,如果不可以抛出错误 // emailFlag 不可以注册是 true if (!emailFlag) { alert("当前用户名已经被占用,请输入新的邮箱地址") return; } // 提交参数 var subObj = {}; // 第二步:判断所有的表单信息是否都填上了,如果没有就抛出错误提示 for (let i = 0; i < inputs.length; i++) { // inputs[i].value :不为空,就是真 if (!inputs[i].value) { return; alert("请完善" + keys[inputs[i].name]); } else { // 表单信息赋值,相当于以k-v的形式存进空白对象subObj中 subObj[inputs[i].name] = inputs[i].value; } } // 如果都没有被return就将所有的信息提交到数据库 add(subObj); } // 发送请求 function add (json) { // 提交逻辑 ajax.post("add.php", json, function (data) { // 注册成功后,那么emailFlag状态变为false,即不可注册 if (data == "SUCCESS") { alert("提交成功") emailFlag = false; } else { alert("提交失败!请重试") } }) } </script> </body> </html>2.2 add.php
<?php // 从客户端传递过来的数据, // 得到邮箱地址,密码和手机号,并存在变量中 $username= $_POST["username"]; $phone= $_POST["phone"]; $password= $_POST["password"]; // 链接数据库 $connect = mysql_connect("localhost",'root','xjf123456'); // 选择数据库 mysql_select_db("ikungg"); // 设置字符集 mysql_query("SET NAMES UTF8"); // 插入SQL $sql = "INSERT INTO email_form (username,password,phone) VALUES ('{$username}','{$password}','{$phone}')"; // 执行SQL,存进数据库了 $result = mysql_query($sql); // 如果$result返回1了,就说明提交成功了,服务器操作数据库,并返回数据 SUCCESS 或者 ERROR if($result == 1) { echo "SUCCESS"; } else { echo "ERROR"; } ?>2.3 check.php
<?php // 得到邮箱地址 $username= $_GET["username"]; // 链接数据库 $connect = mysql_connect("localhost",'root','xjf123456'); // 选择数据库 mysql_select_db("ikungg"); // 设置字符集 mysql_query("SET NAMES UTF8"); // 查询SQL $sql = "SELECT * FROM email_form WHERE username = '{$username}'"; // 执行SQL $result = mysql_query($sql); // 返回查询出来的结果数量 ,符合条件的数据有多少行 $num = mysql_num_rows($result); // 当前的结果如果大于0就说明有查询结果 if($num > 0) { echo "ERROR"; } else { echo "SUCCESS"; } ?>2.4 ajax.js
(function(){ // 唯一暴露的参数变量 // 把ajax空对象放到Windows上 window.ajax = ajax = {}; function common(xhr,JSON,callback) { // 如果用户只传了两个参数,第二个参数如果不是JSON就是函数 // 如果第二个参数的类型是函数了,说明第二个参数就是回调函数 if(typeof JSON == "function") { // 如果第二个参数是回调函数了,让callback参数就等于这个函数 callback = JSON; JSON = {}; } xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { callback(xhr.responseText) } } } // 拼接JSON数据,比如我们的参数{"id":10001,"name":"小明","age":18} // 转换为id=10001&name=小明&age=18 var temp = []; for(var k in JSON) { temp.push(k+"="+encodeURI(JSON[k])); } // 将temp的数据转换为字符串格式的,共最后提交请求使用 return temp.join("&"); } ajax.get = function(url,JSON,callback) { var xhr = new XMLHttpRequest(); // 调用公共方法 var str = common(xhr,JSON,callback) // 防止没有参数 if(str) { url+="?"+str } xhr.open("get",url,true); xhr.send(null); } ajax.post = function(url,JSON,callback) { var xhr = new XMLHttpRequest(); // 调用公共方法 var str = common(xhr,JSON,callback) xhr.open("post",url,true); xhr.setRequestHeader('Content-Type','application/x- -form-urlencoded'); xhr.send(str) } })()Ajax学习笔记第三天由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Ajax学习笔记第三天”
上一篇
宽带电力载波稳定吗?有丢数据吗?
下一篇
3D数据过滤为2D数据集并渲染