GVKun编程网logo

【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流(前端中的事件流)

17

以上就是给各位分享【融职培训】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基础教程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可以获取到我们的事件目标,在这个例子中事件目标就是我们点击的按钮,而我们事件绑定的是按钮的容器,这样就可以将自己元素的事件委托给父级来处理。

四、课后练习

一、实现如下功能(阻止事件冒泡)

  1. 点击一个按钮,显示一个容器的盒子;
  2. 点击容器,容器背景颜色改变;
  3. 点击容器按钮 容器关闭;

二、实现水果列表,让后添加的元素也可以删除(事件委托);

三、通过上下左右按键控制元素移动;

 

【融职教育】在工作中学习,在学习中工作

【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程

【融职培训】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 模板引擎概述

【融职培训】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>

六、课后练习

制作一个登陆验证功能,具体要求如下所示

  1. 登录页填写用户名和密码(正确的用户名为:admin,密码为:123456)
  2. 输入正确的用户名和密码,跳转页面提示【登录成功】
  3. 输入错误的用户名和密码,跳转页面提示【登录失败】

 

【融职教育】在工作中学习,在学习中工作

【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法

【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法

一、指令

指令 (Directives) 是带有 v- 前缀的特殊属性,在此之前我们学习过的指令如下所示:

  • v-bind
  • v-on

本节我们将会介绍更多的 vue 指令。

二、条件判断

通过 v-ifv-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>

一个项目中,推荐使用统一的写法,本教程主要使用小写,并且用 - 链接单词。

组件传值

组件在嵌套的过程中,经常会遇到互相传递数据的情况,我们会在下一节讲解如何实现组件之间的数据传递。

五、课后练习

  1. 在单文件组件中实现一个图片切换效果,图片与数字列表都要使用列表展示。
  2. 用组件化的开发方式制作融职教育手机端的首页,组件名称如下所示:
    • Search
    • Swiper
    • Container
    • Menu

 

【融职教育】在工作中学习,在学习中工作

 

【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器

【融职培训】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 ]

功能如下所示

  1. 通过计数器选择购物清单数量
  2. 根据数量和单价计算总价

 

【融职教育】在工作中学习,在学习中工作

关于【融职培训】Web前端学习 第3章 JavaScript基础教程16 事件流前端中的事件流的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于【融职培训】Web 前端学习 第 3 章 JavaScript 基础教程 20 异步编程、【融职培训】Web 前端学习 第 5 章 node 基础教程 7 模板引擎概述、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 3 模板语法、【融职培训】Web 前端学习 第 7 章 Vue 基础教程 5 计算属性与侦听器等相关知识的信息别忘了在本站进行查找喔。

本文标签: