使用AJAX发送表单信息

为什么要使用AJAX发送表单数据?

因为使用表单发送时,一旦失败,错误信息总会显示在第二个页面内。用户体验不好。

使用AJAX发送时,一旦失败,错误信息显示在本页。用户可以不必其它操作,直接修改即可。

表单序列化

如果使用表单本身去提交,数据都是浏览器帮忙组织的。

使用AJAX提交表单数据时,只能够自己组织数据。

一个两个表单控件,好说,一两个表单也好说。但是,总会出现新的表单,表单的结构总会变化。此时,自己一个一个的组装数据会显得很麻烦。于是我们定义一个函数,让函数帮助我们把表单中的数据给序列化好。

表单序列化的应用场景: 使用AJAX提交整个表单的数据

为什么要表单序列化: 没有人帮助我们组织表单中的数据

jQuery中的序列化函数

​$(form).serialize(); ​

返回值:form中所有控件的key与value组成的字符串

demo:

$("form").serialize();

console:

Node服务器与AJAX(四)_JavaScript

自己封装的序列化函数

举例:

// 定义函数 该函数接收一个表单元素作为参数 返回的是该表单元素的所有控件名与控件值组成的字符串
function serialize(form) {
// 定义字符串
var str = '';
// 获取所有的表单控件
// var elements = form.elements;
var elements = form.getElementsByTagName("*");
// 将所有带有name属性的控件过滤出来
var arr = [];
// 循环所有的elements
for(var i = 0; i < elements.length; i++) {
// 判定是否具备name属性
if (elements[i].name) {
arr.push(elements[i]);
}
}
// 挨个匹配
for(var i = 0; i < arr.length; i++) {
if (arr[i].type === "text" || arr[i].type === "password" || arr[i].type === "select-one" || arr[i].type === "textarea" ) {
str += arr[i].name + "=" + encodeURIComponent(arr[i].value) + "&";
} else if (arr[i].type === "radio" && arr[i].checked) {
str += arr[i].name + "=" + encodeURIComponent(arr[i].value) + "&";
}
}
str = str.slice(0, -1);
return str;
}

转码

因为URL上不可以有中文,所以需要转码。

转码函数

encodeURIComponent是一个转码函数,作用就是转码

有如下字符串

var str = "username=王老五&password=123&sex=male&age=18&suggest=aaaa"

进行转码:

var str1 = encodeURIComponent(str);

转码结果:

Node服务器与AJAX(四)_表单_02

解码函数

decodeURIComponent 该函数用于解码

有已经转码的字符串如下:

var str = "username=%E7%8E%8B%E8%80%81%E4%BA%94&password=123&sex=male&age=18"

解码:

var result = decodeURIComponent(str);

解码结果:

"username=王老五&password=123&sex=male&age=18"

一、瀑布流

瀑布流指的是一种页面模型。

特点是随着用户浏览页面,页面会一直往下撑开。像瀑布一样。

瀑布流布局

我们发现,花瓣网的瀑布流属于定宽瀑布流,每一个列的宽度都是相等的。

我们找了99个图片,探讨一下布局方式

代码1:

var lis = document.getElementsByTagName("li");
for(var i = 0; i < 100; i++) {
var img = new Image();
img.src = "img/" + i + ".png";
lis[i % 3].appendChild(img)
}

结论:发现因为每一个图片的高度不一致,所以导致页面的底部不平。

改进:按照高度去上树

// 我们现在决定按照高度上树
var lis = document.getElementsByTagName("li");
// 定义一个高度映射数组
var arr = new Array(lis.length).fill(0);
// 循环
for(var i = 0; i < 100; i++) {
var img = new Image();
img.src = "img/" + i + ".png";
img.onload = function() {
// 获取数组中的最小项的下标
var idx = getMinIdx(arr);
// 找到对应的li
lis[idx].appendChild(this);
// 图片已经上树 li的高度发生了变化 li的映射数组的值也应当发生变化
arr[idx] += this.height;
}
}
// 定义函数 获取数组中最小的值的下标
function getMinIdx(arr) {
var idx = 0;
var min = arr[idx];
for(var i = 1; i < arr.length; i++) {
if (min > arr[i]) { // 如果最小值比下一个数值还要大 那么应该更换最小值 并 更换下标值
min = arr[i];
idx = i;
}
}
return idx;
}

上树方式

AJAX请求回来数据之后,想要将这些内容上树,让用户看到。有多种方式。

第一种上树方式

有几个元素 ,就创建几个元素。

缺点:代码太多。

第二种上树方式

不论一个结构内有几个元素,只创建最外层元素。将内层元素作为外层元素的innerHTML来拼接。

优点:比第一种好

缺点:当dom结构复杂时,不好分清楚结构。

第三种上树方式

使用模板引擎方式。

定义模板: 将内容写在一个不可以执行的script标签内

<script type="text/template" id="tpl">
<div class="container">
<div class="item">
<span>用户名</span><span><%username%></span>
</div>
<div class="item">
<span>性别</span><span><%sex%></span>
</div>
<div class="item">
<span>年龄</span><span><%age%></span>
</div>
<div class="item">
<div class="type">
<span>卡片类型</span><span><%card.type%></span>
</div>
<div class="num">
<span>卡片号码</span><span><%card.number%></span>
</div>
<div class="yue">
<span>余额</span><span><%card.money%></span>
</div>
</div>
</div>
</script>

定义字典: AJAX请求回来的数据

{
"error": 0,
"data": {
"username": "wanglaowu",
"age": 13,
"sex": "nan",
"card": {
"type": "招商银行",
"number": 19823619823173,
"money": 25
}
}
}

格式化: 将模板与字典结合。

// 定义一个函数 该函数接收两个参数 第一个是模板字符串 第二个是对象
function format(tplStr, dictionary) {
// 替换方法 将字符串中某些内容替换掉
return tplStr.replace(/<%((\w+)(\.\w+)*)%>/g, function(match, $1) {
// 将$1以.分割成数组
var arr = $1.split(".");
var result = dictionary;
// 循环arr 从dictionary中获取数据
for(var i = 0; i < arr.length - 1; i++) {
result = result[arr[i]];
}
return result[arr[i]];
})
}
调用
var str_format = format(str, data.data)

上树:上树

msg.html(str_format)

underscore

这是一个JS实用库。变量名是下划线: _

里面有许多的函数式编程风格的功能。

这里只介绍_.template函数

该函数用于格式化模板

第一步: 将定义好的字符串模板放入该函数

// 定义字符串模板
var tpl_str = "<div><%=name%></div>"
// 生成函数
var format = _.template(tpl_str);

此时,format就是一个函数,该函数与tpl_str字符串模板绑定。只要想生成tpl_str结构的模板,就调用format并传递字典。

第二步:调用format并传递字典

format({name: "王老五"})

第三步:结果

<div>王老五</div>

underscore: 这是一个JS工具库包含了许多JS的常用方法例如filter、map、reduce、some等