Ajax学习笔记第三天

做决定之前仔细考虑,一旦作了决定就要勇往直前、坚持到底!

1 ikunGG邮箱注册

整个流程展示:

024.gif

1.文件目录

021.png

2.页面效果展示及代码

  • mysql数据库中的初始表

022.png

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。

023.png

<!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.com
      </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-www-form-urlencoded');
    xhr.send(str)
  }
})()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/107836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

美颜SDK集成指南:为应用添加视频美颜功能

随着社交媒体和直播应用的兴起&#xff0c;视频美颜功能已成为用户追求的一项热门特性。用户希望能够在拍摄照片或进行实时视频直播时&#xff0c;使用美颜功能来增强其外观。为了满足这一需求&#xff0c;开发者可以考虑集成美颜SDK&#xff0c;为其应用增加这一吸引人的功能。…

【Docker】Python Flask + Redis 练习

一、构建flask镜像 1.准备文件 创建app.py,内容如下 from flask import Flask from redis import Redis app Flask(__name__) redis Redis(hostos.environ.get(REDIS_HOST,127.0.0.1),port6379)app.route(/) def hello():redis.incr(hits)return f"Hello Container W…

融云AIGC专题:高知识密度与大数据处理双向奔赴的「金融大模型」

融云出海方案全线升级 点击上方小程序报名「爱嗨游」线上发布会 “怎么用大语言模型去提升生产效率和服务表现&#xff1f;”在时代交替之际&#xff0c;这是每个行业都要回答的问题。关注【融云 RongCloud】&#xff0c;了解协同办公平台更多干货。 而新技术的渗透不会在所有…

Kibana功能栏中找不到Timelion功能模块的解决

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

echarts中横向柱状图的数字在条纹上方

实现效果&#xff1a; 数字在条纹的上方 实现方法&#xff1a;这些数字是用新添加一个坐标轴来实现的 直接添加坐标轴数字显示是在条纹的正右边 所以需要配置一下偏移 完整代码 var option {grid: {left: "3%",right: "4%",bottom: "3%",cont…

【工具问题】IDEA每次关闭的时候都会弹框显示closing project,然后弹框持续很久就像卡住了

idea关闭的时候出现问题 问题展示为什么会出现这种情况怎么解决 问题展示 我idea已经关闭了&#xff0c;但是这个弹框要持续很久才能关闭 为什么会出现这种情况 我的plugins原本是加载不出来的&#xff0c;所以我按照网上说法去做 怎么解决 file->setting,再如图选择…

HBuilderX代码变量名称翻译插件

对于许多开发者而言&#xff0c;怎么规范的命名变量是一个非常痛苦的事&#xff0c;而在HBuilderX中有一个的插件可以快速的帮助你完成中文转带格式的变量名&#xff0c;格式可以选择小驼峰、大驼峰、下划线、常量、CSS类名等。 以下为添加此插件的步骤 1、打开插件安装 选择…

Unity Spine 指定导入新Spine动画的默认材质

指定导入新Spine动画的默认材质 找到Spine的Editor导入配置如何修改方法一: 你可以通过脚本 去修改Assets/Editor/SpineSettings.asset文件方法二&#xff1a;通过面板手动设置 找到Spine的Editor导入配置 通常在 Assets/Editor/SpineSettings.asset 配置文件对应着 Edit/Prefe…

【机器学习合集】优化目标与评估指标合集 ->(个人学习记录笔记)

文章目录 优化目标与评估指标1. 优化目标1.1 两类基础任务与常见优化目标1.2 分类任务损失0-1损失交叉熵损失与KL散度softmax损失的理解与改进Hinge损失 1.3 回归任务损失L1/L2距离L1/L2距离的改进 Huber loss 2. 评测指标2.1 分类任务中评测指标准确率(查准率)/召回率(查全率)…

037-第三代软件开发-系统音量设置

第三代软件开发-系统音量设置 文章目录 第三代软件开发-系统音量设置项目介绍系统音量设置QML 实现C 实现 总结一下 关键字&#xff1a; Qt、 Qml、 volume、 声音、 GPT 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Obj…

bitlocker 加密锁定的固态硬盘,更换到别的电脑上,怎么把原密钥写进新电脑TPM芯片内,开启无需手动填密钥

环境: Win11 专业版 联想E14笔记本 512G ssd 问题描述: 一台笔记本因充电故障,需要拿去维修,不想重装系统,将bitlocker 加密锁定的固态硬盘拆下更换到别的笔记本电脑上,现在开机要手动填密钥,怎么把原密钥写进新电脑TPM芯片内,开启无需手动填密钥和之前那台电脑一…

Mybatis基础

文章目录 Mybatis基础XML语言概述使用Mybatis配置Mybatis增删改查复杂查询事务操作动态 SQLifchoose、when、otherwise 缓存机制注解开发 Mybatis基础 虽然我们能够通过JDBC来连接和操作数据库&#xff0c;但是哪怕只是完成一个SQL语句的执行&#xff0c;都需要编写大量的代码…

Unity性能优化一本通

文章目录 关于Unity性能优化一、资源部分&#xff1a;1、图片1.1、 图片尺寸越小越好1.2、使用2N次幂大小1.3、取消勾选Read/Write Enabled1.4、图片压缩1.5、禁用多余的Mip Map1.6、合并图集 2、模型2.1.限制模型面数2.2.限制贴图的大小2.3.禁用Read/Write Enables2.4.不勾选其…

使用Selenium和Java编写爬虫程序

以下是一个使用Selenium和Java编写的音频爬虫程序&#xff0c;该程序使用了proxy的代码。请注意&#xff0c;这个示例需要在IDE中运行&#xff0c;并且可能需要根据您的系统和需求进行调整。 import java.io.IOException; import java.util.List; import java.util.concurrent…

synchronized 的锁类型

之前的文章有讲过对同步锁的理解&#xff0c;实现同步锁的方式无非是多个线程抢占一个互斥变量&#xff0c;如果抢占成功则表示获得了锁&#xff0c;而没有获得锁的线程则阻塞等待&#xff0c;直到获得锁的线程释放锁 如图所示&#xff0c;在Mark Word中&#xff0c;我们发现锁…

wangeditor 富文本编辑器使用

使用环境vue3 ts &#xff0c;添加了字数限制 尝试了两种&#xff0c;使用方法类似&#xff08;参考文档&#xff09;&#xff0c;工具栏图标有不同&#xff0c;最后选用了第一种。 一、wangeditor 安装 npm i wangeditor --save 使用 这里封装了个简单组件 <templat…

IO流框架,缓冲流

一.缓冲流有什么优点 Java中的缓冲流&#xff08;Buffered Stream&#xff09;具有以下优势&#xff1a; 提高效率&#xff1a;缓冲流通过在内存中缓存一部分数据&#xff0c;减少了直接从内存到磁盘或从磁盘到内存的频繁IO操作&#xff0c;从而提高了读写效率。缓冲区大小调整…

macOS 12 Monterey v12.7.1正式版:开启全新的操作系统体验

macOS 12 Monterey已经向所有兼容的Mac设备推出&#xff0c;为您带来了一系列强大的新功能和改进。这个全新的操作系统版本&#xff0c;不仅带来了更流畅的用户体验&#xff0c;还增强了与iOS设备的无缝集成&#xff0c;让您的设备使用更加高效&#xff0c;更加便捷。 macOS 1…

RabbitMQ生产者的可靠性

目录 MQ使用时会出现的问题 生产者的可靠性 1、生产者重连 2、生产者确认 3、数据持久化 交换机持久化 队列持久化 消息持久化 LazyQueue懒加载 MQ使用时会出现的问题 发送消息时丢失&#xff1a; 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生…

Vue 3.3.6 ,得益于WeakMap,比之前更快了

追忆往昔&#xff0c;穿越前朝&#xff0c;CSS也是当年前端三剑客之一&#xff0c;风光的很&#xff0c;随着前端跳跃式的变革&#xff0c;CSS在现代前端开发中似乎有点默默无闻起来。 不得不说当看到UnoCss之前&#xff0c;我甚至都还没听过原子化CSS[1]这个概念&#xff08;…