以上就是给各位分享【融职培训】Web前端学习第3章JavaScript基础教程16事件流,其中也会对前端中的事件流进行解释,同时本文还将给你拓展【融职培训】Web前端学习第3章JavaScript基础
以上就是给各位分享【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流,其中也会对前端中的事件流进行解释,同时本文还将给你拓展【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程、【融职培训】Web 前端学习 第 5 章 node 基础教程 7 模板引擎概述、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:- 【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流(前端中的事件流)
- 【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程
- 【融职培训】Web 前端学习 第 5 章 node 基础教程 7 模板引擎概述
- 【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法
- 【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器
【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流(前端中的事件流)
一、绑定事件
想要给一个元素绑定事件,我们有两种方法:使用内联事件或事件监听器。在之前的课程中,我们一直使用的是内联事件来为元素绑定事件,例如一个按钮的点击事件,代码如下
btn.onclick = function(){} //绑定鼠标单击事件
我们还可以用使用事件监听器为元素绑定事件,代码如下
btn.addEventListener("click",function(){});
下面我们用两种方法为按钮绑定事件
1 <button id="btn1">按钮1</button> 2 <button id="btn2">按钮2</button> 3 <script> 4 var btn1 = document.querySelector("#btn1"); 5 var btn2 = document.querySelector("#btn2"); 6 7 btn1.onclick = function(){ 8 console.log("我是按钮1"); 9 } 10 11 btn2.addEventListener("click",function(){ 12 console.log("我是按钮2"); 13 }) 14 </script>
两种方法都能实现相同的效果,能成功的为按钮绑定了点击事件,但区别是使用addEventLitener可以无限制的为元素绑定事件,而内联事件后面的会覆盖前面的
1 var btn1 = document.querySelector("#btn1"); 2 var btn2 = document.querySelector("#btn2"); 3 4 btn1.onclick = function(){ 5 console.log("我是按钮1"); 6 } 7 btn1.onclick = function(){ 8 console.log("我是按钮1,第二次绑定"); 9 } 10 11 btn2.addEventListener("click",function(){ 12 console.log("我是按钮2"); 13 }) 14 15 btn2.addEventListener("click",function(){ 16 console.log("我是按钮2,第二次绑定"); 17 })
第一个按钮第二次绑定的事件覆盖了第一次绑定的事件,第二个按钮两次绑定的事件都能被触发。
二、事件冒泡与事件捕获
接下来我们用事件监听器为三个div元素绑定点击事件,最外层的div宽高是300px,中间的div宽高都是200px,最内层的div宽高都是100px,那么思考一下,点击最内层的div,事件会如何触发,是只触发最内层的div,还是从内到外依次触发,还是从外到内依次触发
1 <div> 2 <div> 3 <div></div> 4 </div> 5 </div> 6 7 var box1 = document.querySelector(".box1"); 8 var box2 = document.querySelector(".box2"); 9 var box3 = document.querySelector(".box3"); 10 11 box1.addEventListener("click",function(){ 12 console.log("我是box1") 13 }) 14 box2.addEventListener("click",function(){ 15 console.log("我是box2") 16 }) 17 box3.addEventListener("click",function(){ 18 console.log("我是box3") 19 })
通过上面的例子我们可以看到,事件是从最内层开始触发,然后依次向外,输出的顺序是box3-box2-box1。导致这种顺序的原因是因为:事件流有事件捕获阶段和事件冒泡阶段,事件捕获阶段是从最外层元素开始一层一层进入到事件目标(也就是我们点击的那个元素),到达事件目标后,进入事件冒泡阶段,事件从最内层流向最外层,事件默认情况下在冒泡阶段触发,所以我们看到的是先输出box3,最后输出box1。
我们也可以将事件设置为捕获阶段触发,代码如下
1 box1.addEventListener("click",function(){ 2 console.log("我是box1") 3 },true) 4 box2.addEventListener("click",function(){ 5 console.log("我是box2") 6 },true) 7 box3.addEventListener("click",function(){ 8 console.log("我是box3") 9 },true)
只要在添加事件方法中添加第三个参数为true,事件就会在捕获阶段被触发,这样输出的顺序就变成了box1-box2-box3。但是在日常开发中,我们几乎不用做此修改,让事件在冒泡阶段触发就可以了。
三、事件委托
利用事件流的原理,我们可以实现事件委托,事件委托可以简单的理解为将子级的事件委托给父级来处理,我们先来看一个简单的例子
1 <div> 2 <button>按钮1</button> 3 <button>按钮2</button> 4 </div>
网页中有两个按钮,他们的父级是一个div标签,现在我们希望给这两个按钮绑定事件,当我们点击按钮的时候输出按钮的文本内容,按照我们之前学过的知识,可以有如下写法
1 //第一种写法 2 var btn1 = document.querySelector(".btn1"); 3 var btn2 = document.querySelector(".btn2"); 4 btn1.addEventListener("click",function(){ 5 console.log(this.innerHTML) 6 }) 7 btn2.addEventListener("click",function(){ 8 console.log(this.innerHTML) 9 })
这种方法简单易懂,但是存在重复,两个按钮触发事件执行的代码完全一样,我们可以获取到所有按钮,再通过遍历绑定事件
1 //第二种写法 2 var btnArray = document.querySelectorAll("button"); 3 for(var i = 0;i<btnArray.length;i++){ 4 btnArray[i].addEventListener("click",function(){ 5 console.log(this.innerHTML) 6 }) 7 }
通过遍历我们优化了代码,但是仍然存在问题,首先,如果按钮的数量特别多,每一个按钮都绑定依次事件会非常影响程序的性能,其次,就算不考虑性能,通过这种方法绑定事件,如果使用js新增了一个按钮,这个按钮因为初始化的时候没有绑定事件,所以无法点击。为了解决上述问题,我们可以使用事件委托的方式来实现上面的功能
1 var btnBox = document.querySelector(".btnBox"); 2 btnBox.addEventListener("click",function(event){ 3 var target = event.target; //通过事件对象获取事件目标 4 console.log(target.innerHTML); 5 })
在事件监听函数中,我们可以在形参的位置获取到事件对象event,事件对象中包含了事件相关的信息,通过event.target可以获取到我们的事件目标,在这个例子中事件目标就是我们点击的按钮,而我们事件绑定的是按钮的容器,这样就可以将自己元素的事件委托给父级来处理。
四、课后练习
一、实现如下功能(阻止事件冒泡)
- 点击一个按钮,显示一个容器的盒子;
- 点击容器,容器背景颜色改变;
- 点击容器按钮 容器关闭;
二、实现水果列表,让后添加的元素也可以删除(事件委托);
三、通过上下左右按键控制元素移动;
【融职教育】在工作中学习,在学习中工作
【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程
一、同步与异步
异步: 可以多条任务线去执行程序,一条任务卡顿不影响其他任务。
二、回调函数
三、promise 对象
在 ES2015 中新加入了 Promise 对象,Promise 对象用来解决异步问题,关于异步问题,我们会在第 8 章详细讲解,本章只要概括性地了解 Promise 对象的语法即可,创建一个 Promise 对象的语法如下所示:
1 // resolve的作用是把异步获取的数据结果传递出来。 2 let getData = new Promise((resolve) => { 3 let data = "string data"; 4 resolve(data); 5 })
Promise 构造函数的参数是一个函数,而函数的形参 resolve 同样也是一个函数,调用 resolve 可以将数据从 promise 对象中传递出来。
四、async 函数
async 函数
async 函数与 Promise 对象结合使用,可以优雅地处理异步问题,声明 async 函数的语法如下所示:
1 async function fun(){ 2 //async函数内部可以使用await关键字 3 }
我们用一个实际的案例来讲解 async 函数与 Promise 对象的用法。
在 Promise 对象的示例中,我们用 resolve 函数将数据传递出来之后,然后可以用 async 函数中的 await 关键字接收数据,完整的实例代码如下所示。
1 let getData = new Promise((resolve) => { 2 let data = "string data"; 3 resolve(data); 4 }) 5 6 async function showData(){ 7 let data = await getData; 8 console.log(data) 9 } 10 11 showData();
await 后面跟着一个 Promise 对象,可以获取到 Promise 对象内部 resolve 传递出来的数据,这这里需要注意的是:
await 关键字必须写在 async 函数内部。
【融职教育】在工作中学习,在学习中工作
【融职培训】Web 前端学习 第 5 章 node 基础教程 7 模板引擎概述
一、模板引擎概述
上一节我们通过 Koa 创建了一个 web 服务器,并可以根据用户请求路径的不同响应不同的页面,但是每一个页面的内容都是通过字符串的方式给送给浏览器的,这样的开发方式并不友好,我们更希望直接发送 html 页面。
模板引擎可以解决这个问题,通过模板引擎,可以直接设置响应的 html 页面,并且可以把后台数据绑定到模板中,然后发送给客户端。
目前市面上有很多模板引擎,这里我们选择一个功能完善,又容易上手的模板引擎:nunjucks
二、安装 nunjucks
在 koa 框架下安装 nunjucks 需要两个第三方模块
- koa-views:负责配置 koa 的模板引擎
- nunjucks:下载模板引擎
执行命令安装这两个模块
1 cnpm install --save koa-views 2 cnpm install --save nunjucks
三、配置模板引擎
1 //server.js 2 const Koa = require("koa"); 3 const nunjucks = require("nunjucks"); 4 const views = require("koa-views"); 5 const app = new Koa(); 6 app.use(views(__dirname + ''/views'', { 7 //将使用nunjucks模板引擎渲染以html为后缀的文件。 8 map: { html: ''nunjucks'' } 9 })); 10 app.use(async ctx => { 11 //render方法渲染模板,第二个参数可以给模板传递参数 12 await ctx.render("index",{title:"我的第一个模板"}) 13 }) 14 app.listen(3000, () => { 15 console.log("server is running"); 16 }) 17 18 <!-- views/index.html --> 19 <!DOCTYPE html> 20 <html lang="en"> 21 <head> 22 <meta charset="UTF-8"> 23 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 24 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 25 <title>{{title}}</title> 26 </head> 27 <body> 28 <h1>hello world</h1> 29 </body> 30 </html>
四、结合路由渲染模板
结合上一节路由的内容,制作一个有两个页面的网站,功能如下:
核心功能代码如下所示:
1 router.get(''/'', async (ctx, next) => { 2 await ctx.render(''index'',{ 3 title:"欢迎来到融职教育" 4 }) 5 }); 6 7 router.get(''/docs'', async (ctx, next) => { 8 await ctx.render(''data'', { 9 title: ''融职教育'', 10 desc:''让学习更高效'' 11 }) 12 });
五、处理表单数据
表单概述
在网页重构的课程中,我们已经了解了表单的基本样式,本节我们讲解如何通过表单向后台发送数据,首先看两个 form
标签的属性。
- action 属性:指定表单提交数据的路径
- method 属性:指定表单提交数据的请求方法,请求方法包括 get、post。
form
标签设置完成之后,要对表单空间进行设置
- input.name 属性:指定数据传输的字段
- input.type=“submit”:指定提交按钮,点击后提交表单数据
获取 get 请求的数据
直接通过 ctx.query
可以获取 get 请求的数据,实例代码如下所示:
1 //获取get请求的参数 2 router.get("/form", async ctx => { 3 await ctx.render("form") 4 }) 5 router.get("/data", async ctx => { 6 let username = ctx.query.username; 7 await ctx.render("data",{usr:username}) 8 })
若需要获取 post 请求的数据,需要安装第三方模块 koa-parser
来解析 post 请求,实例代码如下所示:
1 <form action="/data"> 2 <input type="text" name="username"> 3 <input type="submit" value="提交数据"> 4 </form> 5 6 const Koa = require("koa"); 7 const parser = require(''koa-parser'') 8 const app = new Koa(); 9 app.use(parser()); 10 //获取post请求的参数 11 router.get("/form", async ctx => { 12 await ctx.render("form") 13 }) 14 router.post("/data", async ctx => { 15 let username = ctx.request.body.username; 16 await ctx.render("data",{usr:username}) 17 }) 18 19 <form action="/data" method="POST"> 20 <input type="text" name="username"> 21 <input type="submit" value="提交数据"> 22 </form>
六、课后练习
制作一个登陆验证功能,具体要求如下所示
- 登录页填写用户名和密码(正确的用户名为:admin,密码为:123456)
- 输入正确的用户名和密码,跳转页面提示【登录成功】
- 输入错误的用户名和密码,跳转页面提示【登录失败】
【融职教育】在工作中学习,在学习中工作
【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法
一、指令
指令 (Directives) 是带有 v-
前缀的特殊属性,在此之前我们学习过的指令如下所示:
- v-bind
- v-on
本节我们将会介绍更多的 vue 指令。
二、条件判断
通过 v-if
和 v-show
指令可以控制元素的显示与隐藏,区别如下:
v-if=''false''
:不会渲染 DOM,查看元素不可见。v-show=''false''
:会渲染 DOM,查看元素可见,但是样式为display:none;
下面我们通过事件来控制元素的可见性。
1 <div> 2 <button @click="showOrNot">显示与隐藏</button> 3 <h2 v-if="isShow">hello world</h2> 4 <h2 v-show="isShow">hello world</h2> 5 </div> 6 7 export default { 8 data(){ 9 return { 10 isShow:true 11 } 12 }, 13 methods:{ 14 showOrNot(){ 15 this.isShow = !this.isShow; 16 } 17 } 18 }
三、显示列表
显示列表的功能在 web 应用中是非常常见的,例如文章列表、博客列表,学生列表等等,可以使用 v-for
指令将数据绑定在列表中,实例代码如下所示:
1 <template> 2 <ul> 3 <li v-for="fruit in fruits">{{fruit}}</li> 4 </ul> 5 </template> 6 7 <script> 8 export default { 9 data(){ 10 return { 11 fruits:["香蕉","苹果","鸭梨"] 12 } 13 } 14 } 15 </script>
v-for="fruit in fruits
中的 fruit 是 fruits 中的元素,fruits 是 data 中的数据,此数据是一个数组,fruit 则是数组中的元素。
可以通过下面的方式获取索引值
1 <li v-for="fruit,index in fruits"> 2 <p>名称:{{fruit}}</p> 3 <p>索引:{{index}}</p> 4 </li>
在开发的过程中,经常会遇到这种情况,数据集合的每一个元素并不是简单的字符串,而是对象,我们同样可以使用 v-for
执行遍历所以元素以及元素的属性。
示例代码如下所示:
1 export default { 2 data(){ 3 return { 4 students:[ 5 {name:"小明",age:2}, 6 {name:"小亮",age:3}, 7 {name:"小红",age:4}, 8 ] 9 } 10 } 11 } 12 13 <table> 14 <thead> 15 <th>序号</th> 16 <th>姓名</th> 17 <th>年龄</th> 18 </thead> 19 <tbody> 20 <tr v-for="student,index in students"> 21 <td>{{index + 1}}</td> 22 <td>{{student.name}}</td> 23 <td>{{student.age}}</td> 24 </tr> 25 </tbody> 26 </table>
上述代码将一个学生列表数据放在了表格元素内。
四、组件嵌套
组件命名
自定义组件一般在 components
目录中创建,命名用大驼峰的方式。
接下来我们创建两个组件,分别命名如下:
- Hello
- HelloWorld
如果首字母小写切与 html 标签重名,程序会报错。
注册组件
通过下面的代码,可以将外部组件引入到当前组件
1 import Hello from "@/components/Hello" 2 import HelloWorld from "@/components/HelloWorld" 3 export default { 4 components:{ 5 Hello, 6 HelloWorld 7 } 8 }
在 template
中,组件的标签不区分大小写,切驼峰命名的组件可以使用 -
链接。
1 <div> 2 <hello></hello> 3 <Hello></hello> 4 <HelloWorld></HelloWorld> 5 <Hello-world></Hello-World> 6 </div>
一个项目中,推荐使用统一的写法,本教程主要使用小写,并且用 -
链接单词。
组件传值
组件在嵌套的过程中,经常会遇到互相传递数据的情况,我们会在下一节讲解如何实现组件之间的数据传递。
五、课后练习
- 在单文件组件中实现一个图片切换效果,图片与数字列表都要使用列表展示。
- 用组件化的开发方式制作融职教育手机端的首页,组件名称如下所示:
- Search
- Swiper
- Container
- Menu
【融职教育】在工作中学习,在学习中工作
【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器
一、计算属性
计算属性中定义的值可以直接绑定在表达式中。如果某些值需要通过计算才能得到,那使用计算属性就再合适不过了。
1 <template> 2 <div> 3 <h1>{{fullTitle}}</h1> 4 <h2>{{title}}</h2> 5 </div> 6 </template> 7 8 export default { 9 data(){ 10 return { 11 title:"hello world" 12 } 13 }, 14 computed:{ 15 fullTitle(){ 16 return "融职教育-" + this.title 17 } 18 } 19 }
在上面的示例代码中 fullTitle
的值是通过 title
属性计算而来,所以可以通过 computed
获得计算的结果,并绑定到表达式中。
但是这个例子并没有说服力,我们还可以用很多其他方法来实现这个功能,那我们再来制作一个计数器效果,让 computed
属性发挥它的作用。
1 <template> 2 <div id="app"> 3 <div>单价{{price}}</div> 4 <div> 5 <button @click="sub">-</button> 6 <span>{{count}}</span> 7 <button @click="add">+</button> 8 </div> 9 <div>总价:{{totalPrice}}</div> 10 </div> 11 </template>
我们在之前的实例中,在 data 属性中定义了三个变量:price、count、totalPrice。
利用计算属性可以简化这个示例:
1 export default { 2 name: ''app'', 3 data(){ 4 return { 5 name:"xiaoming", 6 count:0, 7 price:15 8 } 9 }, 10 computed:{ 11 totalPrice(){ 12 return this.count * this.price 13 } 14 }, 15 methods:{ 16 add(){ 17 this.count++ 18 }, 19 sub(){ 20 this.count-- 21 } 22 } 23 }
二、侦听属性
侦听属性可以实时监控一个属性的变化,如果这个值发生变化了,可以执行某些操作,我们用侦听器来改写上面的计数器功能,示例代码如下所示
1 export default { 2 name: ''app'', 3 data(){ 4 return { 5 name:"xiaoming", 6 count:0, 7 price:15 8 } 9 }, 10 watch:{ 11 count(newValue,oldValue){ 12 console.log(newValue) 13 console.log(oldValue) 14 this.totalPrice = newValue * this.price 15 }, 16 }, 17 methods:{ 18 add(){ 19 this.count++ 20 }, 21 sub(){ 22 this.count-- 23 } 24 } 25 }
三、计算属性与侦听属性对比
如果关注的是一个变量的结果,使用计算属性;如果关注一个变量的改变会导致一系列行为,使用侦听属性。
四、课后练习
使用表格制作一个购物清单,商品列表数据如下
1 [ 2 {"name":"香蕉","price":3.14}, 3 {"name":"苹果","price":2.25}, 4 {"name":"鸭梨","price":6} 5 ]
功能如下所示
- 通过计数器选择购物清单数量
- 根据数量和单价计算总价
【融职教育】在工作中学习,在学习中工作
关于【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流和前端中的事件流的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程、【融职培训】Web 前端学习 第 5 章 node 基础教程 7 模板引擎概述、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器等相关知识的信息别忘了在本站进行查找喔。
本文标签: