ajax学习第二天
1.form表单
属性 | 值 | 描述 |
---|
action | URL地址 | 规定当提交表单时,向何处发送表单数据 |
method | get或post | 规定以何种方式把表单数据提交到action URL |
enctype | application/x-www-form-urlencoded | 规定在发送表单数据前如何将其编码 |
target | _blank, _self, _parent, _top | 规定在何处打开action URL |
1.1target属性说明
- _blank:在新窗口打开
- _self:默认,在相同的框架中打开
- _parent,在父框架中打开(很少用)
- _top:在整个窗口打开:(很少用)
- framename:在指定的框架中打开
_blank 示例
| <!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> |
| <form action="/login" target="_blank"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| </body> |
| |
| </html> |

1.2 method属性说明
- get适合提交少量的,简单的数据(默认)(提供uRL地址形式提交,不安全)
- post适合用于提交大量的,复杂的或包含文件上传的数据
get示例
| <!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> |
| <form action="/login" target="_blank" method="GET"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| </body> |
| |
| </html> |

post 示例
| <!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> |
| <form action="/login" target="_blank" method="post"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| </body> |
| |
| </html> |

1.3 enctype 属性说明
值 | 描述 |
---|
application/x-www-form-urlencoded | 在发送前编码所有字符(默认) |
multipart/form-data | 不对字符编码,在使用包含文件上传控件的表单时,必须使用该值 |
text/plain | 空格转换为“+”加号,但不对特殊字符编码(很少用) |
1.4 action属性说明
| <!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> |
| <form action=""> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| </body> |
| |
| </html> |

| <!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> |
| <form action="/login"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| </body> |
| |
| </html> |

1.5 表单的同步提交
2. ajax提交表单数据
2.1 监听表单提交
| $("#form1").submit(function(e){}) |
| |
| $("#form2").on("submit",function(e){}) |
示例
| <!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/jquery.js"></script> |
| </head> |
| |
| <body> |
| <form action="/login" target="_blank" method="post" class="form1"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| |
| <script> |
| $(function() { |
| $(".form1").on("submit", function(e) { |
| console.log(e); |
| }) |
| }) |
| </script> |
| </body> |
| |
| </html> |

2.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/jquery.js"></script> |
| </head> |
| |
| <body> |
| <form action="/login" target="_blank" method="post" class="form1"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| |
| <script> |
| $(function() { |
| $(".form1").on("submit", function(e) { |
| alert("表单提交事件"); |
| console.log(e); |
| |
| |
| e.preventDefault(); |
| }) |
| }) |
| </script> |
| </body> |
| |
| </html> |

2.3 通过serialize()函数获取表单所有数据
| <!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/jquery.js"></script> |
| </head> |
| |
| <body> |
| <form action="/login" target="_blank" method="post" class="form1"> |
| <input type="text" name="user"> |
| <input type="password" name="psw"> |
| <input type="submit"> |
| </form> |
| |
| <script> |
| $(function() { |
| $(".form1").on("submit", function(e) { |
| |
| |
| |
| |
| e.preventDefault(); |
| |
| |
| var data = $(this).serialize(); |
| |
| console.log(data); |
| }) |
| }) |
| </script> |
| </body> |
| |
| </html> |

3. 一个案例
3.1 bs3框架的一些知识点
单独的表单控件会被自动赋予一些全局样式。所有设置了 .form-control
类的 <input>
、<textarea>
和 <select>
元素都将被默认设置宽度属性为 width: 100%;
。
一个发表评论案例
| <!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> |
| <link rel="stylesheet" href="./lib/bootstrap.css"> |
| <style> |
| body { |
| padding: 15px; |
| } |
| |
| .list-group-item .badge:nth-child(1) { |
| background-color: orange !important; |
| } |
| |
| .list-group-item .badge:nth-child(2) { |
| background-color: skyblue !important; |
| } |
| </style> |
| |
| <script src="./lib/jquery.js"></script> |
| </head> |
| |
| <body> |
| |
| |
| |
| <div class="panel panel-primary"> |
| <div class="panel-heading"> |
| <h3 class="panel-title">发表评论</h3> |
| </div> |
| <form class="panel-body" id="addCmt"> |
| <p>评论人</p> |
| <input type="text" class="form-control person" name="username"> |
| <p>评论内容</p> |
| |
| <textarea id="input" class="form-control" rows="3" required="required" name="content"></textarea> |
| |
| <button type="submit" class="btn btn-primary" style="margin-top: 5px;">发表</button> |
| |
| |
| </form> |
| </div> |
| |
| |
| |
| <ul class="list-group"> |
| <li class="list-group-item"> |
| <span class="badge">评论时间:</span> |
| <span class="badge">评论人:</span> item |
| </li> |
| |
| </ul> |
| |
| <script> |
| var cmtlists = []; |
| getCmt(cmtlists); |
| |
| function getCmt(cmtlists) { |
| $.ajax({ |
| method: "GET", |
| url: "http://www.liulongbin.top:3006/api/cmtlist", |
| success: function(res) { |
| if (res.status === 200) { |
| cmtlists = res.data; |
| flesh(cmtlists); |
| } else { |
| alert("获取评论列表失败"); |
| } |
| } |
| }) |
| } |
| |
| |
| |
| function flesh(cmtlists) { |
| $("ul.list-group").html(""); |
| for (var i = 0; i < cmtlists.length; i++) { |
| var li = $('<li class="list-group-item"><span class="badge">评论时间:' + cmtlists[i].time + '</span><span class="badge">评论人:' + cmtlists[i].username + '</span> ' + cmtlists[i].content + '</li>'); |
| $("ul.list-group").append(li); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| $(function() { |
| $("#addCmt").on("submit", function(e) { |
| |
| e.preventDefault(); |
| |
| |
| |
| var adata = $(this).serialize(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| $.post("http://www.liulongbin.top:3006/api/addcmt", adata, function(res) { |
| if (res.status === 201) { |
| getCmt(cmtlists); |
| |
| $("#addCmt")[0].reset(); |
| } else { |
| alert("发表评论失败"); |
| } |
| }) |
| |
| }) |
| }) |
| </script> |
| |
| |
| </body> |
| |
| </html> |

4. 模板引擎
- 定义:根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面
- 图解

5.art-template模板引擎
5.1 有无引擎的对比
| <!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/jquery.js"></script> |
| </head> |
| |
| <body> |
| |
| <div id="title"></div> |
| <div>姓名:<span id="name"></span></div> |
| <div>年龄:<span id="age"></span></div> |
| <div>是否会员:<span id="isVip"></span></div> |
| <div>注册时间:<span id="regTime"></span></div> |
| <div> |
| <ul id="hobby"> |
| |
| </ul> |
| </div> |
| |
| <script> |
| |
| var data = { |
| title: '<h3>用户信息</h3>', |
| name: 'zs', |
| age: 20, |
| isVIP: true, |
| regTime: new Date(), |
| hobby: ['吃饭', '睡觉', '打豆豆'] |
| } |
| |
| $("#title").html(data.title); |
| $("#name").html(data.name); |
| $("#age").html(data.age); |
| $("#isVip").html(data.isVIP); |
| $("#regTime").html(data.regTime); |
| var temp = []; |
| $.each(data.hobby, function(i, ele) { |
| |
| temp.push("<li>" + ele + "</li>"); |
| }) |
| |
| $("#hobby").append(temp.join(' ')); |
| </script> |
| </body> |
| |
| </html> |
| <!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/jquery.js"></script> |
| |
| <script src="./lib/template-web.js"></script> |
| |
| |
| </head> |
| |
| <body> |
| |
| <div class="con"></div> |
| |
| |
| <script type="text/html" id="tep-user"> |
| |
| <div id="title"> {{@title}} </div> |
| <div>姓名:<span id="name">{{name}}</span></div> |
| <div>年龄:<span id="age">{{age}}</span></div> |
| <div>是否会员:<span id="isVip">{{isVIP}}</span></div> |
| <div>注册时间:<span id="regTime">{{regTime}}</span></div> |
| <div> |
| <ul id="hobby"> |
| {{each hobby}} |
| <li>{{$value}}</li> |
| {{/each}} |
| </ul> |
| </div> |
| </script> |
| |
| |
| <script> |
| var data = { |
| title: '<h3 id="1">用户信息</h3>', |
| name: 'zs', |
| age: 20, |
| isVIP: true, |
| regTime: new Date(), |
| hobby: ['吃饭', '睡觉', '打豆豆'] |
| } |
| |
| |
| var htmlstr = template("tep-user", data); |
| |
| $(".con").html(htmlstr); |
| </script> |
| </body> |
| |
| </html> |
- 效果图(一样的效果图),这里数据少,体现不出渲染引擎的优点

5.2 渲染引擎的使用
- 导入art-template
- 定义数据
- 定义模板
- 调用template函数
- 渲染HTML结构
5.3 art-template的标准语法
| {{value}} //变量输出 |
| {{obj.key}} //对象属性的输出 |
| {{obj['key']}} //对象属性的输出 |
| {{a ? b : c}} //三元运算符的输出 |
| {{a || b}} //逻辑表达式输出 |
| {{a + b}} //加减乘除输出 |
5.3.1 原文输出
- 如果要输出的value值中包含HTML结构,则需要原文输出,才能使HTML结构被渲染
5.3.2 条件输出
| {{if value}} 满足条件输出的内容{{/if}} |
| |
| //多分支输出 |
| {{if value1}} 输出满足value1成立的内容{{else if v2}} |
| 输出v2满足内容{{/if}} |
5.3.3 循环输出
- 通过each语法循环数组,
i
n
d
e
x
代
表
索
引
号
,
index代表索引号,
index代表索引号,value代表值
| {{each arr}} |
| {{$index}} {{$value}} |
| {{/}} |
5.3.4 过滤器

| template.defaults.imports.filterName=function(value){/*return处理的结果*/} |
示例
| <!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/jquery.js"></script> |
| |
| <script src="./lib/template-web.js"></script> |
| |
| |
| </head> |
| |
| <body> |
| |
| <div class="date"></div> |
| |
| |
| |
| <script type="text/html" id="temp"> |
| <h3>{{date | filterName}}</h3> |
| </script> |
| |
| <script> |
| |
| |
| template.defaults.imports.filterName = function(date) { |
| var year = date.getFullYear(); |
| var month = date.getMonth() + 1; |
| var day = date.getDate(); |
| |
| return year + "-" + month + "-" + day; |
| } |
| |
| |
| |
| var data = { |
| date: new Date() |
| } |
| |
| |
| |
| var htmlStr = template("temp", data); |
| |
| $(".date").html(htmlStr); |
| </script> |
| |
| |
| </body> |
| |
| </html> |

获取新闻案例
| <!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> |
| <link rel="stylesheet" href="./assets/news.css" /> |
| <script src="./lib/jquery.js"></script> |
| <script src="./lib/template-web.js"></script> |
| </head> |
| |
| <body> |
| |
| <div id="news-list"> |
| |
| </div> |
| |
| |
| <script type="text/html" id="model"> |
| |
| |
| {{each data}} |
| <div class="news-item"> |
| <img class="thumb" src="http://www.liulongbin.top:3006{{$value.img}}" alt="" /> |
| <div class="right-box"> |
| <h1 class="title">{{$value.title}}</h1> |
| <div class="tags"> |
| {{each $value.tags }} |
| <span>{{$value}}</span>{{/each}} |
| </div> |
| <div class="footer"> |
| <div> |
| <span>{{$value.source}}</span> |
| <span>{{$value.time|timeFilter}}</span> |
| </div> |
| <span>评论数:{{$value.cmtcount}}</span> |
| </div> |
| </div> |
| </div> |
| |
| {{/each}} |
| </script> |
| |
| <script> |
| |
| |
| |
| template.defaults.imports.timeFilter = function(time) { |
| |
| var time1 = new Date(time); |
| var year = time1.getFullYear(); |
| var month = time1.getMonth() + 1; |
| var date = time1.getDate(); |
| var h = parseInt(time1.getHours()); |
| h = h < 10 ? '0' + h : h; |
| var m = parseInt(time1.getMinutes()); |
| m = m < 10 ? '0' + m : m; |
| var s = parseInt(time1.getSeconds()); |
| s = s < 10 ? '0' + s : s; |
| |
| return year + '-' + month + '-' + date + ' ' + h + ':' + m + ':' + s; |
| |
| } |
| |
| |
| |
| getDate(); |
| var data = []; |
| |
| function getDate() { |
| |
| $.get("http://www.liulongbin.top:3006/api/news", function(res) { |
| if (res.status === 200) { |
| |
| |
| |
| |
| for (var i = 0; i < res.data.length; i++) { |
| res.data[i].tags = res.data[i].tags.split(','); |
| } |
| |
| var htmlstr = template("model", res); |
| |
| console.log(htmlstr); |
| |
| |
| $("#news-list").html(htmlstr); |
| |
| } else { |
| alert("获取新闻列表失败"); |
| } |
| }) |
| } |
| </script> |
| |
| </body> |
| |
| </html> |

6.正则表达式(模板引擎原理刨析)
6.1 基本语法
| RegExpObject.exec(string) |
- 如果字符串中有表达式的值,则返回该匹配值,否则返回null
示例
| <!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 pattern = /o/; |
| |
| var pattern2 = /m/; |
| |
| console.log(pattern.exec(str)); |
| console.log(pattern2.exec(str)); |
| </script> |
| </body> |
| |
| </html> |

6.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]+)}}/; |
| |
| console.log(pattern.exec(str)); |
| </script> |
| </body> |
| |
| </html> |

6.3 replace函数将{{(分组内容)}}替换成分组内容
| <!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]+)}}/; |
| |
| console.log(pattern.exec(str)); |
| |
| var result = pattern.exec(str); |
| |
| str = str.replace(result[0], result[1]); |
| |
| console.log(str); |
| </script> |
| </body> |
| |
| </html> |

6.3.1 多次replace
| <!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}}年龄{{ age }}</div>"; |
| |
| |
| |
| |
| |
| |
| var pattern = /{{\s*([a-zA-Z]+)\s*}}/; |
| var result; |
| |
| while ((result = pattern.exec(str)) !== null) { |
| console.log(result); |
| str = str.replace(result[0], result[1]); |
| } |
| |
| console.log(str); |
| </script> |
| </body> |
| |
| </html> |

6.4 通过正则实现模板引擎的效果
| <!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 data = { |
| name: '张三', |
| age: 18 |
| } |
| |
| |
| |
| var str = '<div>姓名:{{ name }}年龄:{{ age }}</div>'; |
| |
| |
| |
| var pattern = /{{\s*([a-zA-Z]+)\s*}}/; |
| |
| |
| var result; |
| |
| while (result = pattern.exec(str)) { |
| str = str.replace(result[0], data[result[1]]); |
| } |
| |
| console.log(str); |
| </script> |
| </body> |
| |
| </html> |

6.5 自定义一个模板引擎
| <!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> |
| |
| |
| <div id="box"> |
| |
| </div> |
| |
| |
| <script type="text/html" id="my-tep"> |
| <div>姓名:{{name }}</div> |
| <div>年龄:{{ age }}</div> |
| <div>性别:{{sex }}</div> |
| <div>住址:{{ address}}</div> |
| </script> |
| |
| <script> |
| |
| |
| function template(id, data) { |
| var tep = document.getElementById(id); |
| |
| var str = tep.innerHTML; |
| |
| var pattern = /{{\s*([a-zA-Z]+)\s*}}/; |
| |
| var result; |
| while (result = pattern.exec(str)) { |
| str = str.replace(result[0], data[result[1]]); |
| } |
| |
| return str; |
| } |
| |
| |
| |
| var data = { |
| name: '张三', |
| age: 18, |
| sex: '男', |
| address: '北京' |
| } |
| |
| |
| var htmlstr = template("my-tep", data); |
| |
| var box = document.getElementById("box"); |
| box.innerHTML = htmlstr; |
| </script> |
| </body> |
| |
| </html> |
- 效果图

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!