form表单和模板引擎
1、form表单的基本使用
1、表单:在网页中主要负责数据采集功能,HTML中的form标签就是用于采集用户的输入信息的,并通过form标签的提交操作,把采集的数据信息提交到服务器。
2、form表单的基本组成:
- 表单标签:form
- 表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等
- 表单按钮:button
<form>
<input type="text" name="email_or_mobile" />
<input type="password" name="password" />
<input type="checkbox" name="remember_me" checked />
<button type="submit">提交</button>
</form>
3、form标签的属性:用来规定如何把采集的数据发送到服务器
属性 | 值 | 描述 |
---|---|---|
action | URL地址 | 规定当提交表单的时候,向何处发送表单数据 |
method | get或post | 规定以何种方式把表单数据提交到action的URL |
enctype | application/x-www-form-urlencoded multipart/form-data text/plain | 规定在发送表单数据之前,对其如何编码 |
target | _blank、_self、_parent、_top、framename | 规定在何处打开action中的URL |
1、action属性:
- 规定了当提交表单的时候,向何处发送表单数据
- action属性值以应该是后端提供的一个URL地址,这个地址专门负责接收表单提交过来的数据
- 当表单在未指定action属性值的时候,action属性值默认为当前页面的URL地址
2、target属性:规定在何处打开URL地址
值 | 说明 |
---|---|
_blank | 在新的窗口打开 |
_self | 默认值,在当前相同的框架窗口打开 |
_parent | 在父框架窗口打开 |
_top | 在顶级窗口打开 |
framename | 在指定的框架中打开 |
3、method属性:
1、method属性规定以何种方式把表单数据提交到action中的URL地址,可选值有get和post,默认是get方式。
2、get适用于提交少量、简单的数据。
3、post适用于提交大量的、复杂的、包含文件上传的数据。
4、enctype属性
1、enctype属性规定在发送表单数据之前对表单数据如何编码,在涉及到文件上传的操作时,必须将 enctype 的值设置为 multipart/form-data,如果表单的提交不涉及到文件上传操作,则直接将 enctype 的值设置为 application/x-www-form-urlencoded 即可。
属性值 | 说明 |
---|---|
application/x-www-form-urlencoded | 在发送前编码所有字符,默认值 |
multipart/form-data | 不对字符编码,在包含文件上传控件的时候,必须使用该值 |
text/plain | 空格转换为 “+” 加号,但是不对特殊字符编码 |
5、表单的同步提交及其缺点
1、通过点击submit按钮,触发表单的提交操作,从而使页面跳转到action的URL地址的操作,叫做表单的同步提交。
2、同步提交的缺点:
-
form表单同步提交之后,整个页面发生跳转,跳转到action的URL地址,用户体验很差
-
form表单同步提交之后,页面的状态和数据会丢失
2、通过Ajax提交表单数据
1、在jQuery中,使用如下两种方式,监听表单的提交事件。
$('#form1').submit(function(e) {
alert('监听到了表单的提交事件')
})
$('#form1').on('submit', function(e) {
alert('监听到了表单的提交事件')
})
1、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/jquery.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<script>
$(function () {
// 第一种方式
// $('#f1').submit(function () {
// alert('监听到了表单的提交事件');
// })
// 第二种方式
$('#f1').on('submit', function () {
alert('监听到了表单的提交事件2');
})
})
</script>
</body>
</html>
2、阻止表单的默认提交行为
1、当监听到表单的提交事件以后,可以调用事件对象的 event.preventDefault() 凼数,来阻止表单的提交和页面的跳转。
$('#form1').submit(function(e) {
// 阻止表单的提交和页面的跳转
e.preventDefault()
})
$('#form1').on('submit', function(e) {
// 阻止表单的提交和页面的跳转
e.preventDefault()
})
2、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/jquery.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<script>
$(function () {
// 第一种方式
// $('#f1').submit(function (e) {
// alert('监听到了表单的提交事件');
// e.preventDefault();
// })
// 第二种方式
$('#f1').on('submit', function (e) {
alert('监听到了表单的提交事件2');
e.preventDefault();
})
})
</script>
</body>
</html>
3、快速获取表单中的数据
1、serialize() 凼数:可以一次性获取到表单中的所有的数据。
$(selector).serialize()
2、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./lib/jquery.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" />
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<script>
$(function () {
// 第一种方式
/* $('#f1').submit(function (e) {
e.preventDefault();
var data = $(this).serialize();
console.log(data);
}) */
// 第二种方式
$('#f1').on('submit', function (e) {
e.preventDefault();
var data = $('#f1').serialize();
console.log(data);
})
})
</script>
</body>
</html>
3、模板引擎的基本概念
1、渲染UI结构时遇到的问题
var rows = []
$.each(res.data, function (i, item) { // 循环拼接字符串
rows.push('<li class="list-group-item">'+ item.content +'<span class="badge
cmt-date">评论时间:'+ item.time +'</span><span class="badge cmt-person">评论人:'+
item.username +'</span></li>')
})
$('#cmt-list').empty().append(rows.join('')) // 渲染列表的UI结构
上述是通过字符串的拼接形式来渲染UI结构的,如果UI比较复杂,则拼接的字符串需要格外注意引号之前的嵌套,但是需要一旦发生变化,修改起来也很麻烦。
2、模板引擎:可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面。
3、模板引擎的好处:
- 减少字符串的拼接操作
- 使代码结构更清晰
- 便于代码的阅读与维护
4、art-template模板引擎
1、art-template是一个简约、超快的模板引擎,中文网站为:http://aui.github.io/art-template/zh-cn/index.html
2、art-template的安装:在浏览器访问http://aui.github.io/art-template/zh-cn/docs/installation.html页面,找到下载链接,鼠标右键选择另存为,下载到本地,然后通过script标签加载到网页上进行使用。
3、art-template模板引擎的使用步骤
- 导入art-template
- 定义数据
- 定义模板
- 调用template函数
- 渲染HTML结构
4、art-template的标准语法:art-template提供了{{}}这种语法格式,在{{}}内可以进行变量的输出、循环数组,这种语法在art-template中称为标准语法。
5、在 {{ }} 语法中,可以进行变量的输出、对象属性的输出、三元表达式输出、逻辑或输出、加减乘除等表达式的输出。
{{value}}
{{obj.key}}
{{obj['key']}}
{{a ? b: c}}
{{a || b}}
{{a + b}}
5、标准语法:原文输出:如果要输出的value值中,包含html标签结构,则需要使用原文输出语法,才能保证HTML标签被正常渲染。
{{@value}}
6、条件输出:要实现条件输出,可以在{{}}中使用if…else if…/if的方式,实现需求。
{{if value}} 按需输出的内容 {{if}}
{{if value1}} 按需输出的内容 {{else if value2}} 按需输出的内容 {{/if}}
7、循环输出:要实现循环,可以在{{}}中,通过each语法循环数组
- 当前循环的索引使用$index进行访问
- 当前循环项使用$value进行访问
{{each arr}}
{{$index}} {{$value}}
{{/each}}
8、过滤器:过滤器类似管道操作符,将上一个输出作为下一个的输入。
template.defaults.imports.filterName = function(value){
return 处理的结果
}
9、示例代码:
<!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>
<!-- 导入模板引擎 -->
<!-- 在window全局中,多了一个函数,叫做template('模板的id',需要渲染的数据对象) -->
<script src="./lib/template-web.js"></script>
<script src="./lib/jquery.js"></script>
</head>
<body>
<div id="container"></div>
<!-- 定义模板 -->
<!-- 模板的html结构,必须定义到script中 -->
<script type="text/html" id="tmpl-user">
<h1>{{name}}---{{age}}</h1>
{{@test}}
<div>
{{if flag == 0}}
flag的值为0
{{else flag == 1}}
flag的值为1
{{/if}}
</div>
<ul>
{{each hobby}}
<li>索引是:{{$index}},循环项是:{{$value}}</li>
{{/each}}
</ul>
<h3>{{regTime | dateFormat}}</h3>
</script>
<script>
//定义处理时间的过滤器
template.defaults.imports.dateFormat = function(date) {
var y = date.getFullYear();
var m = date.getMonth()+1;
var d = date.getDate();
return y + '-' + m + '-' + d;
}
//定义需要渲染的数据
var data = {name:'张三',age:20,test:'<h3>测试原文输出</h3>',flag:1,hobby:['吃','喝','学习'],regTime:new Date()};
//调用template函数
var htmlStr = template('tmpl-user',data)
console.log(htmlStr);
//渲染html结构
$('#container').html(htmlStr);
</script>
</body>
</html>
###5、模板引擎的原理
1、正则与字符串操作
1、exec()函数
1、exec()函数:用于检索字符串中的正则表达式的匹配,如果字符串中有匹配的值,则返回该匹配的值,否则返回null。
RegExpObject.exec(string)
2、示例代码:
<!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>
</head>
<body>
<script>
var str = 'hello';
var pattern1 = /x/;
var ret1 = pattern1.exec(str);
var pattern2 = /l/;
var ret2 = pattern2.exec(str);
console.log(ret1);
console.log(ret2);
</script>
</body>
</html>
2、正则表达式分组
1、正则表达式中 ( ) 包起来的内容表示一个分组,可以通过分组来提取自己想要的内容
2、示例代码:
<!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>
</head>
<body>
<script>
var str = '<div>我是{{name}}</div>';
var pattern = /{{([a-zA-Z]+)}}/;
var ret = pattern.exec(str);
console.log(ret);
</script>
</body>
</html>
3、字符串的replace函数
1、replace():用于在字符串中用一些字符替换另一些字符。
2、语法格式:
var ret = '111222333'.replace('111','abc');
3、示例代码:
<!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>
</head>
<body>
<script>
var str = '<div>我是{{name}}</div>';
var pattern = /{{([a-zA-Z]+)}}/;
var ret = pattern.exec(str);
str = str.replace(ret[0],ret[1]);
console.log(str); //<div>我是name</div>
</script>
</body>
</html>
4、多次replace
1、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var str = '<div>{{name}}今年{{ age }}岁了</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
// 第一次匹配
var res1 = pattern.exec(str);
str = str.replace(res1[0], res1[1]);
console.log(str);//<div>name今年{{ age }}岁了</div>
// 第二次匹配
var res2 = pattern.exec(str);
str = str.replace(res2[0], res2[1]);
console.log(str);//<div>name今年age岁了</div>
// 第三次匹配
var res3 = pattern.exec(str);
console.log(res3);//null
</script>
</body>
</html>
5、使用while循环replace
1、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var str = '<div>{{name}}今年{{ age }}岁了</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
var patternResult = null;
while (patternResult = pattern.exec(str)) {
str = str.replace(patternResult[0], patternResult[1]);
}
console.log(str);//<div>name今年age岁了</div>
</script>
</body>
</html>
6、replace替换为真值
1、示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var data = { name: '张三', age: 20 };
var str = '<div>{{name}}今年{{ age }}岁了</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
var patternResult = null;
while (patternResult = pattern.exec(str)) {
str = str.replace(patternResult[0], data[patternResult[1]]);
}
console.log(str);//<div>张三今年20岁了</div>
</script>
</body>
</html>
2、实现自定义目标引擎
1、实现步骤:
- 定义模板结构
- 预调用模板引擎
- 封装template函数
- 导入并使用自定义的模板引擎
2、示例代码:
<!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>
<script src="./lib/template-web.js"></script>
</head>
<body>
<div id="user-box"></div>
<script type="text/html" id="tmpl-user">
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{sex}}</div>
<div>住址:{{addr}}</div>
</script>
<script>
//定义数据
var data = {name:'张三',age:20,sex:'男',addr:'北京'};
//调用模板引擎
var htmlStr = template('tmpl-user',data);
//渲染html结构
document.getElementById('user-box').innerHTML = htmlStr;
</script>
</body>
</html>