小A最终考核(一):所有基本功能的完成
小A二轮考核(一)基本要求实现
- 整个页面我首先以完成功能为核心,暂未进行仔细的设计布局,只是大致做了一些简单的布局
使用的全局变量
1.baseURL(用于数据传输前与相应的后缀拼接再发送AJAX请求)
const baseURL = "http://www.rushmc.top/api/";
2.queryURL (用于查询服务器上文件(配合src))
- 例如上传头像后为了显示,利用参数拼接插入设置好的img标签的src属性中
const queryURL = "http://www.rushmc.top/";
//参数拼接
let userAvatar = document.getElementById("userImg");
userAvatar.setAttribute("src",queryURL + user.data.photo);
3.window.userInfoG
- 为了获取登陆之后的用户数据对象(在AJAX响应时赋值数据对象)
- 获取:
window.userInfoG = false;
//这里的value是AJAX发送成功后的得到的响应数据(是对象)
postForm(data,"login").then(
function(value){
if(value.code == 200){
//获取登陆后的用户所有信息
window.userInfoG = value;
alert("账户密码正确,登陆成功!");
// 切换用户信息,并且利用动态结点显示
putHtmlStr(value);
}
else if(value.code ==300){
alert("账户或者密码错误!");
}
else{
alert("后台tmd炸了!!!!");
}
},
function(reason){
alert("请求发送失败,请检测网络!");
}
);
}
- 使用
- 个人发布动态时自动在formdata中加入ID
- 注销时,该属性置为false
- 进入个人空间的时候看看有没有登陆
- 在个人空间查看个人动态时,参数拼接用这里面的id
//以第4个为例子
let urls = "dynamicState/select/" + window.userInfoG.data.id;
pathGetData(urls).then(function(value){...},
function(reason){...} );
封装的AJAX请求(配合Promise使用)
GET请求
function dyGetForm(urls){
//urls是调用功能域名的后面的内容
let p1 = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("GET", baseURL+urls,true);
xhr.send();
//每次xhr的状态发送改变就调用handle函数
xhr.onreadystatechange = handle;
function handle() {
if (this.readyState != 4) {
return;
}
if (this.status == 200) {
//返回信息
let info = JSON.parse(xhr.responseText);
//resolve把p1这个promise对象状态改变为成功,并且将值传进去
resolve(info);
} else {
let info = JSON.parse(xhr.responseText);
//resolve把p1这个promise对象状态改变为失败,并且将值传进去
reject(info);
}
}
});
//返回Promise对象
return p1;
}
使用
queryDyAllBtn.onclick = function(){
// 查询所有动态的页面出现,个人空间消失
dyGetForm("dynamicState/select/all").then(
value=>{
...对响应报文进行展示或处理
},
reason=>{
...AJAX返回的状态码不为200
}
POST请求
- 基本每个功能都会用
//用于上传输入数据,得到响应数据
//用户发送AJAX通用函数
function postForm(data,urls){
let p1 = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open("POST", baseURL+urls,true);
xhr.send(data);
xhr.onreadystatechange = handle;
function handle() {
//这一步操作很关键,因为一开始readyState的值是1,按以往写肯定会reject,然后就无法改变了
//所以我们要让它非4的时候赶紧出来,不要执行resolve和reject
if (this.readyState != 4) {
return;
}
if (this.status == 200) {
let info = JSON.parse(xhr.responseText);
resolve(info);
} else {
let info = JSON.parse(xhr.responseText);
reject(info);
}
}
});
return p1;
}
使用
- 动态查询模块为例
Ipt = document.getElementById("searchIpt").value;
if(Ipt){
let urls = "dynamicState/search/" + Ipt;
pathGetData(urls).then(
value=>{
if(value.code == 200){
//插入内容到页面中
insertSearchHtml(value);
//获得点击标题实现查看详细的键
let detailBtn = document.getElementsByClassName("detailDyS");
//在这个函数里面为按钮绑定事件
toSearchDetail(value,detailBtn);
}
else if(value.code == 11000){
alert(value.msg);
}
},
reason=>{}
)
}
用户模块
用户登陆/注册/注销
登陆流程以及代码
流程:
获取输入框的内容–>进行正则验证–>利用remember函数看是否需要记住账户密码–>利用changeData函数按POST发送输入框内容并返回响应数据
代码:
注册流程以及代码
流程:
获取输入框的内容–>进行正则验证账户和手机号–>利用changeData函数按POST发送输入框内容并返回响应数据–>弹出框告诉您的账号
代码:
注销流程以及代码
流程:
- window中专门存登陆后的用户信息的对象清空(window.userInfoG)
- 用户信息界面消失
- 输入框清空,记住账户密码勾选重置
- 移除localStorage中的账户密码
- 如果在登陆时候打开了个人空间,注销时候会关掉个人空间
代码:
修改密码
流程:
- 注意:修改密码是在用户登陆后才能进行的
构造FormData对象data -->将window.userInfoG中的id自动append到data中 -->弹出输入框输入新密码 --> 将密码放入data中 --> 弹出框告诉用户新密码 -->注销重新登陆(正常操作)
代码:
登陆注册的正则验证
流程:
- 定义两个正则表达式,用于验证账号和手机号码是否格式正确,其他密码,用户名则是利用了maxlength限制输入的字数。
定义–>点击登陆(注册)–>判断输入框内容数据是否符合–>符合才发送AJAX请求
代码:
let reg1 = /\W{1,10}/;
let reg2 = /[1][3]\d{0,9}$|[1][5]\d{0,9}$|[1][7]\d{0,9}$|[1][8]\d{0,9}$/;
if(!reg1.test(usernameV)){
if(reg2.test(phoneV)){
changeData();
}
else{
alert("电话应该是以13、15、17、18开头的电话的11位数字!")
}
}
else{
alert("账号只由英文,数字和下划线‘_’的10位以内字符组成");
}
}
记住账号密码
流程:
检查记住账户密码勾选是否勾上–>利用localStorage存入账户密码–>刷新页面或重新打开时利用window.onload检查localStorage中的是否是否有存账户密码–>有就获取相应的值放入输入框,并且自动勾选(没有或注销就清空,不勾选)
函数:
//remName和remPW是存入localStorage的键名
let remember = function(){
if(remName.checked){ window.localStorage.setItem("remName",lgNameInner.value);
}
else{
window.localStorage.removeItem("remName");
}
if(remPW.checked){
window.localStorage.setItem("remPW",pwInner.value);
}
else{
window.localStorage.removeItem("remPW");
}
}
//刷新页面或重新打开页面自动检测
window.onload = function (){
if(window.localStorage.getItem("remName")){
remName.checked = true;
lgNameInner.value = window.localStorage.getItem("remName");
}
else{
remName.checked = false;
lgNameInner.value = "";
}
if(pwInner.value = window.localStorage.getItem("remPW")){
remPW.checked = true;
pwInner.value = window.localStorage.getItem("remPW");
}
else{
remPW.checked = false;
pwInner.value = "";
}
}
用户个人信息展示
流程:
继登陆后会自动显示数据–>传入用户登陆后的响应数据给putHtmlStr函数的参数user用户信息展示–>利用选择器把展示用户数据的div中的li取出并用模板字符串。
函数:
let putHtmlStr = function(user){
//传进来的user是后台的用户登陆后的响应数据
//下面两行是显示用户的头像
let userAvatar = document.getElementById("userImg");
userAvatar.setAttribute("src",queryURL + user.data.photo);
// 这里是显示用户信息
let li = document.querySelectorAll(".userInfo li");
li[0].innerHTML = `欢迎回来,${user.data.name}`
li[1].innerHTML = `ID:${user.data.id}`
li[2].innerHTML = `密码:${user.data.password}`
li[3].innerHTML = `电话:${user.data.phone}`
//用户信息界面覆盖登陆界面弹出
userInfoBox.style.display = "flex";
}
上传/显示用户头像
流程:
构造FormData对象data -->获取图片文件并加入data中 --> 将window.userInfoG中的id自动append到data中 -->交换数据 --> 利用setAttribute将img的路径改变为服务器传出来的。
代码:
动态模块
发布动态
输入内容的输入框的样式(textarea)
让它跟接近是输入内容的效果
流程:
获取输入的各个信息 --> 查看勾选框是否勾选从而选择是否上传文件 -->是否标题和内容里面不为空 --> 利用POST进行数据交换 -->发布界面消失
代码:
删除动态
流程:
删除按钮触发 --> 输入要删除的动态 ID --> 输入的ID是否为数字 --> 利用POST进行数据交换 --> 展示个人动态
代码:
展示所有用户的动态
注意:
- 这里我们只需要获取用户动态的部分信息来展示动态的小卡片,并非动态详细内容(我获取的是标题,内容(利用CSS省略过多的),发布者名称和发布者时间)
- 小卡片上内容省略的展示如下
所用到的全局变量:
重要的函数:
1.转换为模板字符串的函数()(用于所有动态累加插入页面)
2.插入函数(插入模板字符串到容器中)
3.触发事件
流程:
利用封装的GET发送AJAX请求结合Promise获得数据 --> 调用insertAllDyHtml将数据传入 --> 通过for遍历数据加到总的模板字符串之中 --> 插入到动态大容器的HTML中即可显示 --> 获取每个动态小卡片上面的标题按钮(为查看详细动态做准备)
查看所有用户的动态详情
注意:
用户的图片我们需要判断有多少张,查看下面的函数二
重要的函数:
1.为动态小卡片能进入详细动态的标题绑定事件的函数 toDetailDy
2.详细动态的模板字符串的函数 htmlDyDetail
展示和查看本人的动态
- 大体上与上面相似,只是获取的
搜索动态(没有滥用全局变量)
- 相对于展示查看所有动态有所优化,因为用全局变量来获取HTML里面的标签,在标签多且累赘的时候很容易出现问题,所以优化就是多利用函数传参
重要的函数:
1.为输入框敲击回车绑定事件
2.提交的时候触发的事件(插入所有动态小卡片,给标题按钮绑定事件)
3.为动态小卡片按钮绑定进入详细内容事件,再在动态详细中的回退按钮绑定事件的函数toSearchDetail
流程:
获取输入框数据 --> 是否输入框不为空 --> 发送请求并得到数据 --> 调用insertSearchHtml函数插入动态小卡片到容器中 --> 为小卡片的标题按钮绑定事件并且为动态详细中的返回按钮绑定事件
小结
-
结合Promise再来使用AJAX请求真的很方便
-
为了防止代码累赘不清晰,要优化代码,基本都变成模块化操作函数,使得结构更加清晰,也防止重复耦合
-
像此类与登陆用户连接的操作,要用在全局定义一个属性专门存登陆后的用户数据,同时注意什么时候清除(注销)
-
尽量将滥用全局变量的行为多变为传参到函数的行为,因为一些系列的动态操作可能使全局变量改变