Ajax:表单 模板引擎

Ajax:表单 & 模板引擎

    • form 表单
      • form 属性
    • Ajax操控表单
      • 事件监听
      • 阻止默认行为
      • 收集表单数据
    • 模板引擎
      • art-template
        • {{}}语法
        • 原文输出
        • 条件输出
        • 循环输出
        • 过滤器
      • 原理


form 表单

HTML中,可以通过<form>创建一个表单,收集用户信息。而采集到的信息想要发送给后端,此时就要与Ajax进行配合。

form 属性

在原生HMTL表单中,包含四个基本属性:

属性功能
action向何处提交表单内的数据url
method提交表单的方式getpost
enctype如何对表单数据编码
target打开action url的为止_blank_self
  • action

action的属性值往往是后端提供的一个url地址,这个地址接收并处理来自前端的数据。如果<form>没有指定该值,那么默认为当前页面的url

示例:

<form action="/login">
  <input type="account" name="account" />
  <input type="password" name="password" />
  <button type="submit">提交</button>
</form>

这是一个表单,指定action="/login"

输出结果:

请添加图片描述

可以看到,点击提交后,地址变成了/login?account=123456&password=54321,其中/login就是表单提交到的地址,而?后面是表单的参数。

这里有两个细节:

  1. 目标地址默认是在当前页面打开
  2. 表单的参数追加到了地址的末尾,说明默认是get请求
  • taget

taget指定在何处打开地址,刚刚打开地址是,是默认在当前页面打开,通过指定target就可以改变打开目标地址的方式。

  1. _blank:在新窗口打开
  2. _self:在当前窗口打开,默认值
  • method

刚刚发现,表单的提交方式默认为get,如果想要切换表单提交方式,可以通过method属性。

  1. get:以get形式发送请求,默认值
  2. post:以post形式发送请求

示例:

<body>
  <form action="/login" method="post" >
    <input type="account" name="account" />
    <input type="password" name="password" />
    <button type="submit">提交</button>
  </form>
</body>

此处把表单的提交方式改为post

提交表单后,查看控制台:

在这里插入图片描述

这次提交数据后,地址就是/login,表单的数据不再以?的形式追加到地址末尾。而在Payload窗口,可以看到表单数据accountpassword已经放在了请求的内部。

  • enctype

enctype用于指定表单数据的编码方式,其有三个可选值:

  1. application/x-www-form-urlencoded:在发送数据前编码所以的字符,默认值
  2. multipart/form-data:不对字符编码,如果表单内上传文件时,必须使用该选项,防止错误编码
  3. text/plain:空格转换为'+'字符,但是不对特殊字符编码,几乎不用

原生的HTML表单有很多缺点:

  1. 表单提交后,会发生页面跳转
  2. 表单提交后,会清空表单原有数据

想要处理这些问题,那就要引入JavaScriptAjaxJavaScript可以阻止默认行为,禁止页面进行跳转。但是这样也会阻止数据的提交,因此使用Ajax来进行表单数据提交,不再让表单自己提交数据。而且Ajax提交数据,不会清空表单的内容。


Ajax操控表单

事件监听

如果要在用户提交表单时,让Ajax立刻响应,代替表单的提交任务,此时就要对表单进行提交事件的事件监听。

只需要调用原先的jQuery接口即可:

$('form').submit(function(){})

$('form').on('submit', function(){})

以上两种方式,都可以实现对表单的提交事件的监听。


阻止默认行为

想要阻止默认提交行为,也很简单:

$('form').on('submit', function (e) {  
  e.preventDefault()
})

在回调函数中,添加是事件参数e,随后调用preventDefault方法阻止默认行为,这可以同时阻止提交行为和页面跳转。


收集表单数据

现在已经阻止了提交行为,接下来就要通过Ajax代替原先的提交行为了。在提交数据之前,就要先获取到表单的数据,这里jQuery封装了接口,可以一次性获取所有表单内容。

语法:

$('form').serialize()

注意:使用这个方法时,要确保表单的每个栏目都有name属性,否则无法获取到对应的栏目。

示例:

<form action="/login" id="f1">
  <input type="account" name="account" />
  <input type="password" name="password" />
  <button type="submit">提交</button>
</form>

<script>
  $(function () {
    $('#f1').on('submit', function (e) {
      e.preventDefault()
      var data = $(this).serialize()
      console.log(data)
    })
  })
</script>

输出结果:

在这里插入图片描述

此时data就已经拿到了表单的内容,最后就可以通过Ajax进行发送了。


模板引擎

当从表单中拿到了大量的数据,此时可能就需要把这些数据重新渲染到页面上,如果对于原生的JavaScript或者jQuery,处理这个都是比较麻烦的,需要进行字符串拼接等操作,把数据拼接到标签的内部。

假设现在要渲染以下内容:

var data = {
  title: '<h3>用户信息</h3>',
  name: '张三',
  age: 18,
  isVIP: true,
  regTime: new Date(),
  hobby: ['HTML', 'HTTP', 'Linux']
}

渲染为如下结构:

在这里插入图片描述

如果只使用htmljQuery,那么就要从对象提取信息,然后一个一个通过.html方法把信息添加到页面中,对于最后一个hobby数组,还需要通过.each方法进行遍历,追加到页面中。

art-template

这很麻烦,模板引擎可以解决这个问题,以模板的形式,快速渲染大量的信息到网页。此处选用art-template模板引擎,可以到以下网址下载:

http://aui.github.io/art-template/zh-cn/docs/installation.html

只需要把template-web.js(gzip: 6kb)这个文件下载下来,并通过JavaScript的形式引入即可使用。

<script src="./template-web.js"></script>

导入art-template后,全局就会多出一个template方法,这就是模板引擎的核心方法。

示例:

首先,模板引擎的内容要定义在<script>标签内部:

<script type="text/html" id="tpl">
  <p>姓名: {{name}}</p>
  <p>年龄: {{age}}</p>
</script>

此处要制定type属性和id属性,默认情况下type="text/JavaScript",表示以JavaScript形式解析<script>内部的内容,此处改为text/html,表示以html形式解析内容。

随后就可以在内部编写html的代码了,在编写代码时,可以使用{变量名}}的形式来引入外部变量,这个变量会直接取对象中的值进行填入。

模板语法:

template('id', 对象)

此处的id是刚才<script>内部的属性id="tpl",而对象是要填充的对象,最后会返回格式化后的html字符串。

示例:

<script>
  var data = { name: '张三', age: 20}
  var htmlStr = template('tpl-user', data)
  $('#container').html(htmlStr)
</script>

在对象data中,包含nameage两个属性,这刚好和之前指定的{{name}}{{age}}相匹配。随后调用template('tpl, data),表示用data这个对象值,去填充模板tpl的内容,此时就会返回一个html格式的字符串,直接把字符串填入目标容器即可。

<div id="container"></div>
<script type="text/html" id="tpl-user">
  <p>姓名: {{name}}</p>
  <p>年龄: {{age}}</p>
</script>

<script>
  var data = { name: '张三', age: 20}
  var htmlStr = template('tpl-user', data)
  $('#container').html(htmlStr)
</script>

输出结果:

在这里插入图片描述

这样就实现了快速渲染对象的内容到html中。


{{}}语法

刚才已经见过{{}}的基本功能了,其实就是把对象中命名相匹配的内容,直接填充到html中,其实它还支持很多种语法格式:

{{value}}
{{obj.key}}    // 获取对象值
{{obj['key']}} // 获取对象值
{{a ? b : c}}  // 三元表达式
{{a || b}}     // 逻辑判断
{{a + b}}      // 算数运算

原文输出

如果输出的内容是一个字符串,并且字符串中包含html标签,如果希望这个标签被渲染,需要使用原文输出

{{@ value}}

在值前面加一个@符号即可。

示例:

<div id="container"></div>
<script type="text/html" id="tpl">
  <p>姓名: {{@ name}}</p>
  <p>年龄: {{age}}</p>
</script>

<script>
  var data = { name: '<li>张三</li>', age: 20}
  var htmlStr = template('tpl', data)
  $('#container').html(htmlStr)
</script>

输出结果:

在这里插入图片描述

通过{{@ name}}<li>标签就被正常解析了。


条件输出

有时候,可能需要在输出时进行条件判断,比如说如果某个用户是VIP,要额外输出VIP的剩余时间。而如果他不是VIP,这个内容就不用输出。对于这种情况,可以使用条件输出来完成。

语法:

{{if value}} 输出内容 {{/if}}

{{if value}} 输出内容1 {{else}} 输出内容2 {{/if}}

{{if value1}} 输出内容1 {{else if value2}} 输出内容2 {{/if}}

示例:

<script type="text/html" id="tpl">
  <p>姓名: {{name}}</p>
  <p>年龄: {{age}}</p>
  {{if isVip}} 
    <p> VIP剩余时间: {{time}} </p>
  {{else}}
    <p> 不是VIP </p>
  {{/if}}
  <hr>
</script>

在模板中,通过{{if isVip}}来判断该用户是不是VIP,并选择不同的输出结果。

填入以下两个对象:

<script>
  var zs = { 
    name: '张三',
    age: 20,
    isVip: true,
    time: 100
  }

  var ls = { 
    name: '李四',
    age: 25,
    isVip: false,
    time: null
  }

  var htmlStr1 = template('tpl', zs)
  var htmlStr2 = template('tpl', ls)
  $('#container').html(htmlStr1 + htmlStr2)
</script>

示例中,张三VIP,而李四不是,最后这两者渲染出来的结果就不一样:

在这里插入图片描述


循环输出

如果输出的目标是一个数组,可以通过循环输出来遍历所有的数组元素。

语法:

{{each arr}}
	{{$index}} {{$value}}
{{/each}}

其中arr是被遍历的数组,而$index是下标,$value是元素值。

示例:

<script type="text/html" id="tpl">
  <p>姓名: {{name}}</p>
  <p>年龄: {{age}}</p>
  <ul>
    {{each hobby}} 
      <li> {{$value}} </li>
    {{/each}}
  </ul>
</script>

<ul>内部,通过循环遍历所有的hobby,并通过{{$value}}拿到元素值,渲染到li中。

给张三加上hobby属性:

<script>
  var zs = { 
    name: '张三',
    age: 20,
    hobby: ['HTML', 'HTTP', 'Linux']
  }
  var htmlStr = template('tpl', zs)
  $('#container').html(htmlStr)
</script>

输出结果:

在这里插入图片描述

这样就可以快速遍历所有的数组成员了。


过滤器

如果说,对象中的元素并不是直接填写到页面中的,而是要经过一定的处理之后在填入。比如说商品价格,可能要乘以某个值后,以打折的价格显示在页面中,这就需要引入过滤器

{{value | filterName }}

其中value是要处理的值,这个值会交给filterName 函数处理,函数返回值会最为最终结果填入模板。

过滤器函数并不是直接就可以调用原生的函数,而是要导入到模板中:

template.defaults.imports.filterName = function(value){ 函数体 }

现在张三对象内容如下:

var zs = { 
  name: '张三',
  age: 20,
  hobby: ['HTML', 'HTTP', 'Linux'],
  startYear: 2023
}

此处的startYear表示入学年份,最终渲染到页面中时,希望输出学年: 入学年份 ~ 毕业年份,此时可以交给一个过滤器处理:

template.defaults.imports.graduate = function(value){
   return value + " ~ " + (value + 4)  
  }

过滤器graduate 会进行一个字符串拼接,虽然value是数字类型,但是中间的" ~ "是一个字符串,最终整个返回值就是一个字符串,毕业年份是入学年份的四年后。

在模板中,把startYear 输入到过滤器:

<script type="text/html" id="tpl">
  <p>姓名: {{name}}</p>
  <p>年龄: {{age}}</p>
  <ul>
    {{each hobby}} 
      <li> {{$value}} </li>
    {{/each}}
  </ul>
  <p>
    学年: {{ startYear | graduate }}
  </p>
</script>

此处{{ startYear | graduate }}就是在处理数据。

输出结果:

在这里插入图片描述


原理

其实模板引擎的原理非常简单,就是正则表达式匹配,随后替换元素值即可。

art-template为例,其所有占位符格式都是{{}},那么正则就可以写为:

let pattern = /{{([a-zA-Z]+)}}/

首先通过最外层的{{}}进行占位符得到匹配,内层一个()进行分组匹配,提取出具体的信息,[a-zA-Z]+表示提取任意多个字母。

比如对于字符串<div>{{name}}</div>,通过以上正则就可以得到name这个值。

var str = '<div>{{name}}</div>'
var pattern = /{{([a-zA-Z]+)}}/

var result = pattern.exec(str)
console.log(result)

输出结果:

在这里插入图片描述

可以看到,最后正则返回一个数组,第一个元素是匹配成功的字符串,第二个元素是提取出来的分组值。

当提取到变量名后,就要去对象中拿到对于的变量,并替换原先的占位符,替换通过replace方法完成:

'string'.replace('子串', '替换值')

比如说"helloworld".replace("world", "linux"),就会返回字符串"hellolinux"

let obj = {
  name: "张三"
}

var str = '<div>{{name}}</div>'
var pattern = /{{([a-zA-Z]+)}}/

var patternResult = pattern.exec(str)
str = str.replace(patternResult[0], obj[patternResult[1]])
console.log(str)

patternResult[0]是被匹配的字符串,也就是{{name}}patternResult[1]是提取到的分组,也就是name。只需要把原字符串str{{name}}替换为obj['name']即可,也就是str.replace(patternResult[0], obj[patternResult[1]])

输出结果:

在这里插入图片描述

这样就完成了元素的替换。

当整个字符串中有多个{{xxx}},可以使用一个循环进行匹配:

let patternResult = null;
while (patternResult = pattern.exec(str)) {
	str = str.replace(patternResult[0], obj[patternResult[1]])
}

pattern.exec匹配不到{{}}时,就会返回一个null,循环就会结束,整个模板字符串被完全替换为对象的值,最后得到一个可以直接渲染的html字符串。


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

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

相关文章

基于centos7.9搭建在线购物网站

mall 搭建数据库配置Java配置jar包 一款模仿天猫的在线购物网站&#xff0c;基于centos7.9搭建 搭建数据库 官网下载软件包后上传 基于centos7.9搭建mysql5.6.42 [rootmysql02 ~]# ls anaconda-ks.cfg init.sh MySQL-5.6.42-1.el7.x86_64.rpm-bundle.tar解压 tar -xf My…

Python 自动化运维:Python基础知识

Python 自动化运维&#xff1a;Python基础知识 目录 &#x1f4ca; Python 基础复习 数据类型、控制结构与常用函数面向对象编程&#xff08;OOP&#xff09;与类的使用函数式编程概念与 lambda 表达式异常处理与日志记录的基本实践 1. &#x1f4ca; Python 基础复习 数据…

【论文阅读】Tabbed Out: Subverting the Android Custom Tab Security Model

论文链接&#xff1a;Tabbed Out: Subverting the Android Custom Tab Security Model | IEEE Conference Publication | IEEE Xplore 总览 “Tabbed Out: Subverting the Android Custom Tab Security Model” 由 Philipp Beer 等人撰写&#xff0c;发表于 2024 年 IEEE Symp…

word技巧:如何禁止复制word文件内容?

在文档管理与协作的复杂环境中&#xff0c;确保文档内容的完整性和安全性至关重要。Microsoft Word作为一款广泛使用的文字处理软件&#xff0c;提供了强大的限制编辑功能&#xff0c;允许用户控制对文档内容的修改权限&#xff0c;有效防止未经授权的更改。本文将深入解析Word…

LabVIEW如何学习数据结构和算法

作为LabVIEW程序员&#xff0c;在学习数据结构和算法时&#xff0c;由于LabVIEW以图形编程为主&#xff0c;与传统编程语言的学习方式有些不同。因此&#xff0c;理解算法思想并将其在LabVIEW中实现是关键。 ​ 1. 夯实编程基础概念 LabVIEW与文本编程语言在实现逻辑上的方式…

Maven项目报错:invalid LOC header (bad signature)

文章目录 Maven项目报错&#xff1a;invalid LOC header (bad signature)1. Maven项目加载或Pom.Xml刷新后仍出现如下错误2. 解决方法 Maven项目报错&#xff1a;invalid LOC header (bad signature) 1. Maven项目加载或Pom.Xml刷新后仍出现如下错误 错误提示&#xff1a; in…

方形件排样优化与订单组批问题探析

方形件排样优化与订单组批问题是计算复杂度很高的组合优化问题&#xff0c;在工业工程中有很广泛的应用背景。为实现个性化定制生产模式&#xff0c;企业会选择订单组批的方式&#xff0c;继而通过排样优化实现批量切割&#xff0c;加工完成后再按照不同客户需求进行分拣&#…

高质量短视频素材平台推荐

在当今短视频内容日益增长的时代&#xff0c;拥有高质量的素材显得尤为重要。以下是一些值得关注的短视频素材平台&#xff0c;它们各具特色&#xff0c;适合不同需求的创作者。 蛙学网 蛙学网专注于提供高质量的短视频素材&#xff0c;适合各种创作需求。虽然该平台需要订阅&a…

DerpNStink: 1渗透测试

靶机&#xff1a;DerpNStink: 1 <https://www.vulnhub.com/entry/derpnstink-1,221/> 攻击机&#xff1a;kail linux 2024 目标&#xff1a;获得4个flag 1,将两台虚拟机网络连接都改为NAT模式&#xff0c;并查看靶机的MAC地址 2&#xff0c;攻击机上做主机扫描发现靶机 靶…

#HarmonyOS:页面和自定义组件生命周期

页面生命周期 即被Entry装饰的组件生命周期 onPageShow&#xff1a;页面每次显示时触发一次&#xff0c;包括路由过程、应用进入前台等场景。onPageHide: 页面每次隐藏时触发一次&#xff0c;包括路由过程、应用进入后台等场景。onBackPress: 当用户点击返回按钮是触发 组件…

自定义类型:联合和枚举【上】

自定义类型&#xff1a;数组&#xff0c;结构体&#xff0c;联合体&#xff0c;枚举。前面一些我们已经讲过了&#xff0c;接下来我们讲联合体和枚举。 一.联合体 1.联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同…

网络搜索引擎Shodan(2)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 声明&#xff1a;本文主要用作技术分享&#xff0c;所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险&#xff0c;并遵循相关法律法规。 感谢泷…

(南京观海微电子)——GH7006-01_HKC_B3-PV043WVQ-N80_MIPI_LVDS_RGB原理及代码介绍

1. 原理 2. 代码 /**************************************************/ // Model - GV050WVQ-N82 // IC - GH7006 // Width - 800 // Height - 480 // REV: - V01 // DATA - 20240621 // INTERFACE- LV…

4.1.2 网页设计技术

文章目录 1. 万维网&#xff08;WWW&#xff09;的诞生2. 移动互联网的崛起3. 网页三剑客&#xff1a;HTML、CSS和JavaScriptHTML&#xff1a;网页的骨架CSS&#xff1a;网页的外衣JavaScript&#xff1a;网页的活力 4. 前端框架的演变基于CSS的框架基于JavaScript的框架基于MV…

质量漫谈一

我知道很多同学看到这类问题&#xff0c;第一反应想要去寻找的就是作为测试角色&#xff0c;应该要如何如何去做&#xff1f;但是今天这里作为质量第一篇&#xff0c;不打算按照这样单角度去写&#xff0c;这类同学可以就此打住&#xff0c;如果在意的话&#xff0c;可关注后续…

excel斜线表头

检验数据验证对象 鼠标放在检验数据 验证对象中间&#xff0c;altenter 之后空格 选中格子&#xff0c;右键单元格格式&#xff0c; 完成 如果是需要多分割&#xff0c;操作一样&#xff0c;在画斜线的时候会有区别&#xff0c;在插入里面用直线画斜线即可 在表格插入的时…

采用Excel作为可视化设计器的开源规则引擎 NopRule

决策树和决策矩阵是业务人员可以直观理解的复杂IF-ELSE逻辑表达形式&#xff0c;也是规则引擎中最常用、最有用的部分。常见的规则引擎如Drools虽然提供了更加丰富的功能特性集&#xff0c; 特别是所谓的RETE算法可以用于高效复用多次重复出现的表达式片段&#xff0c;但在实际…

xxl-job java.sql.SQLException: interrupt问题排查

近期生产环境固定凌晨报错&#xff0c;提示 ConnectionManager [Thread-23069] getWriteConnection db:***,pattern: error, jdbcUrl: jdbc:mysql://***:3306/***?connectTimeout3000&socketTimeout180000&autoReconnecttrue&zeroDateTimeBehaviorCONVERT_TO_NUL…

Windows自带录屏好用吗?四大录屏工具轻松实现高效录屏!

Windows系统自带的录屏工具其实就是Xbox Game Bar。今天&#xff0c;除了这个工具&#xff0c;我还会为大家推荐几款实用录屏工具&#xff0c;让大家轻松实现高效录屏&#xff01; 福昕录屏软件 直达链接&#xff1a;www.foxitsoftware.cn/REC/ 操作教程&#xff1a;立即获取…

本地缓存库分析(一):golang-lru

文章目录 本地缓存概览golang-lru标准lrulru的操作PutGet 2q&#xff1a;冷热分离lruPutGet expirable_lru&#xff1a;支持过期时间的lruPutGet过期 总结 本地缓存概览 在业务中&#xff0c;一般会将极高频访问的数据缓存到本地。以减少网络IO的开销&#xff0c;下游服务的压…