1.form表单
form表单的属性: form
: action
| target
| method
| enctype
action
: url
- action属性用来规定提交表单时,向何处发送表单的数据。当提交表单后,页面会立即跳转到指定的url地址
- action属性的值是后端提供的url,这个url专门负责接收表单提交过来的数据
- 如果未指定action属性值,默认值为当前页面的url
target
: _self(默认)
| _blank
- target属性用来规定以什么方式打开action url
- _self: 当前窗口打开
- _blank:新窗口中打开
method
: get(默认)
| post
- method属性用来规定以何种方式把表单数据提交到action url
- get: 以
url的形式
提交(get适合用来提交少量的
、简单的
数据) - post: 以
隐秘的方式
提交(post适合用来提交大量的
、复杂的
或包含文件上传
的数据) - 实际开发中
<form>
表单的post提交方式用得最多,很少用get。例如登录
、注册
、添加数据
等,都是用post方式。
enctype
: application/x-www-urlencoded(默认)
| multipart/form-data | text/plain
- application/x-www-urlencoded: 在发送前
编码
所有字符 - multipart/form-data: 不对字符编码(在使用
文件
上传控件的表单时,必须使用该值) - text/plain: 空格转换为"
+
"号,但不对特殊字符编码(很少用)
在使用form表单通过点击submit
按钮,触发表单提交的操作,从而使页面跳转到action url的行为,叫做表单的同步提交
。
同步提交的缺点:
- form表单同步提交后,整个页面会发生跳转,跳到指定的action url,用户体验很差
- 表单同步提交后,页面之前的状态和数据会丢失
我们可以让表单
只负责采集数据
,Ajax
负责将数据提交
到服务器。
2.监听表单提交事件
// 方式1:
$("#form1").submit(function () {
alert('监听到了表单提交')
e.preventDefault()
})
// 方式2:
$("#form1").on("submit", function () {
alert('监听到表单提交事件')
e.preventDefault()
})
当监听到表单提交事件后,可以使用serialize()
快速的获取到form表单中的数据
const data = $("#form1").serialize()
- serialize()可以快速获取表单的数据(必须为每个表单元素
添加name
属性)
2.模板引擎
模板引擎可以根据我们指定的模板结构
和数据
,自动生成一个完整的HTML页面
。
模板引擎的好处:
- 减少了字符串的拼接操作
- 使代码结构更清晰
- 使代码更易于阅读与维护
art-template
是一个简约、超快的模板引擎。
官网地址: http://aui.github.io/art-template/zh-cn/index.html
1.模板引擎的基本使用
在这里我们使用模板引擎将数据渲染到页面。
(1)导入art-template
<script src="lib/template-web.js"></script>
- 导入art-template后,在window全局,多了一个函数
template()
(2)定义需要渲染的数据
const data = { name: '张三', age: 18 }
(3)定义模板
<script type="text/html" id="tpl">
<h3>{{name}} ---- {{age}}</h3>
</script>
(4)调用template函数
template('模板',需要渲染的数据对象)
const htmlStr = template('tpl', data)
(5)渲染HTML结构
$("#container").html(htmlStr)
- 将数据渲染到id为container的盒子中
2.art-template标准语法
art-template提供了{{}}
这种语法格式,在{{}}内可以进行变量输出或循环数组等操作,这种{{}}语法在art-template中称为标准语法。
在{{}}语法中,可以进行变量的输出
,对象属性的输出
,三元表达式的输出
,逻辑或输出
,加减乘除
等表达式输出。
如:
{{value}}
{{obj.key}}
{{obj['key']}}
{{a ? b : c}}
{{a || b}}
{{a + b}}
标准语法-原文输出
{{@ value}}
- 如果要输出的
value
值中,包含了html标签结构,则需要使用到原文输出,才能保证HTML标签被正常渲染
标准语法-条件输出
/*
{{if value}} 按需输出的内容 {{/if}}
{{if value1}} 按需输出的内容 {{else if value2}} 按需输出的内容 {{/if}}
*/
- 如果要实现条件输出,则可以在
{{}}
中使用if..else if../if
的方式,进行按需输出
标准语法-循环输出
{{each 数组}}
{{$index}} {{$value}}
{{/each}}
- 如果要实现循环输出,则可以在{{}}内,通过
each
语法循环数组,当前循环的索引使用$index
访问,当前循环项使用$value
进行访问
标准语法-过滤器
{{value | fiterName}}
|
是过滤器管道操作符,它的上一个输出作为下一个输入value
输出的结果作为fiterName
的输入(value的值作为过滤器处理函数的参数)
//定义过滤器的基本语法
template.defaults.imports.fiterName = function (value) { return 处理的结果}
- 过滤器最后一定要
return
一个值
模板引擎标准语法使用示例:
(1).导入art-template
<script src="lib/template-web.js"></script>
<script src="lib/jquery.min.js"></script>
<div id="container"></div>
(2).定义需要渲染的数据
const data = {
name: '张三',
age: 18,
test: '<h3>原文输出测试 </h3>',
flag: 1,
hobby: ['唱歌', '跳舞', '打游戏'],
getTime: new Date()
}
(3).定义模板
<script type="text/html" id="tpl">
<h3>{{name}} ---- {{age}}</h3>
{{@ test}}
<div>
{{if flag === 0}}
flag的值为0
{{else if flag === 1}}
flag的值为1
{{/if}}
</div>
<ul>
{{each hobby}}
<li> 当前索引号:{{$index}},当前循环项:{{$value}}</li>
{{/each}}
</ul>
<h3>
{{getTime | dateFormat}}
</h3>
</script>
// 定义处理时间的过滤器
template.defaults.imports.dateFormat = function (time) { // getTime作为参数传到过滤器处理函数中
const dt = new Date(time)
const year = dt.getFullYear()
const month = dt.getMonth() + 1
const date = dt.getDate()
return year + '-' + month + '-' + date // 返回处理过的新值,传入到 {{getTime | dateFormat}}中
}
(4).调用template函数
const htmlStr = template('tpl', data)
(5).渲染HTML结构
$("#container").html(htmlStr)
3.模板引擎的核心
1.正则表达式提取分组
- 正则表达式中
()
包起来的内容表示一个分组
,可以通过分组来提取
自己想要的内容
。
如下我们需要提取{{}}
中的name
:
正则提取分组
const str = '<div>我是{{name}}</div>'
const exp = /{{([a-zA-Z]+)}}/
const res = exp.exec(str)
console.log(res) // ['{{name}}', 'name', index: 7, input...]
字符串replace()操作
let str = '<div>我是{{name}}</div>'
const exp = /{{([a-zA-Z]+)}}/
const expRes = exp.exec(str)
// console.log(expRes) ['{{name}}', 'name', index: 7...]
str = str.replace(expRes[0], expRes[1])
console.log(str) // <div>我是name</div>
- 提取分组得到的结果用str.replace()替换
字符串多次replace()操作
let str = '<div>{{name}}今年{{ age }}岁了</div>'
const exp = /{{\s*([a-zA-Z]+)\s*}}/ // \s*表示可以有多个空白字符
// 第一次匹配
const res1 = exp.exec(str)
// console.log(res1) // ['{{name}}', 'name', index: 5...]
str = str.replace(res1[0], res1[1])
console.log(str) // <div>name今年{{ age }}岁了</div>
// 第二次匹配
const res2 = exp.exec(str)
// console.log(res2) // ['{{ age }}', 'age', index: 11...]
str = str.replace(res2[0], res2[1])
console.log(str) // <div>name今年age岁了</div>
// 第三次匹配
const res3 = exp.exec(str)
console.log(res3) // null
- 当匹配的结果为null时,说明所有的东西都已匹配完
可以使用while循环进行replace()操作
let str = '<div>{{name}}今年{{ age }}岁了</div>'
const exp = /{{\s*([a-zA-Z]+)\s*}}/
let expRes = null
while (expRes = exp.exec(str)) {
str = str.replace(expRes[0], expRes[1])
}
console.log(str) // <div>name今年age岁了</div>
- 使用while循环简化replace的多次操作
replace()替换为真值
data = { name: '张三', age: 20 } // 数据
let str = '<div>{{name}}今年{{ age }}岁了</div>' // 模板
const exp = /{{\s*([a-zA-Z]+)\s*}}/
let expRes = null
while (expRes = exp.exec(str)) {
str = str.replace(expRes[0], data[expRes[1]]) // data['name'] data['age']
}
console.log(str) // <div>张三今年20岁了</div>
- 以上其实就是
模板引擎的核心代码
,用到了正则提取然后字符串的replace()操作
2.调用自己定义的模板引擎
<script src="lib/my_template.js"></script>
<div id="box"></div>
<!-- 1.定义模板结构 -->
<script type="text/html" id="tpl-user">
<div>姓名:{{name}}</div>
<div>年龄:{{ age }}</div>
<div>性别:{{ gender}}</div>
<div>住址:{{address }}</div>
</script>
<script>
// 2.预调用模板引擎
// 定义数据
const data = { name: '张三', age: 18, gender: '男', address: '北京' }
// 调用模板引擎
const htmlStr = template("tpl-user", data)
// 渲染html结构
document.getElementById('box').innerHTML = htmlStr
</script>
在my_template中定义好自己的模板引擎
// 封装template函数
function template(id, data) {
let str = document.getElementById(id).innerHTML
const exp = /{{\s*([a-zA-z]+)\s*}}/
let expRes = null
while ((expRes = exp.exec(str))) {
str = str.replace(expRes[0], data[expRes[1]])
}
return str
}