???? 作者简介,愚公搬代码
????《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,****博客专家,****商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。
????《近期荣誉》:2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。
????《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
????????欢迎 ????点赞✍评论⭐收藏
文章目录
- ????前言
- ????一、事件
- ????1.简单事件
- ????1.1 点击事件(Tap Event)
- ????1.2 输入事件(Input Event)
- ????1.3 表单提交事件(Submit Event)
- ????1.4 切换事件(Change Event)
- ????1.5 滑动事件(Scroll Event)
- ????2.事件参数
- ????3.事件传参
- ????3.1 通过 `data-` 属性传参
- ????3.2 通过 `` 传参
- ????3.3 使用 `bind` 传递参数
- ????3.4 在事件对象中传递自定义数据
- ????4.事件绑定
- ????4.1 WXML 文件
- ????4.2 JS 文件
- ????4.3 动态绑定条件
- ????4.4 WXML 文件中的条件绑定
- ????5.事件冒泡
- ????5.1 事件冒泡的具体过程
- ????5.2 阻止事件冒泡
- ????5.3 事件绑定类型
- ????6.互斥事件
- ????6.1 使用锁机制
- ????6.2 异步队列
- ????6.3 控制事件触发频率
- ????6.4 使用标志位
- ????6.5 mut-bind
- ????6.事件的捕获阶段
- ????7.事件对象
- ????感谢:给读者的一封信
????前言
在微信小程序中,事件是用户和程序之间交互的核心概念。通过事件,用户可以与小程序进行各种交互操作,例如点击按钮、输入文字、滑动屏幕等。以下是微信小程序中事件的概念和使用方法。
事件类型
-
触摸事件:包括触摸开始、触摸移动、触摸结束等,如
touchstart
、touchmove
、touchend
等。 -
鼠标事件:主要用于 PC 端小程序,如
click
、dblclick
等。 -
表单事件:与表单控件相关的事件,如
submit
、input
、focus
、blur
等。 -
媒体事件:与音视频控件相关的事件,如
play
、pause
、ended
等。 -
页面事件:与页面生命周期相关的事件,如
onLoad
、onReady
、onShow
、onHide
、onUnload
等。
事件绑定
在 WXML 中,通过 bind
或 catch
关键字来绑定事件处理函数。例如:
-
bindtap
:绑定点击事件。 -
bindinput
:绑定输入事件。
????一、事件
????1.简单事件
在微信小程序(WeChat Mini Programs)中,事件处理是实现用户交互的核心部分。
????1.1 点击事件(Tap Event)
点击事件是最常见的事件之一,可以用于按钮点击、图片点击等。
示例代码:
<!-- WXML -->
<view bindtap="handleTap">点击我</view>
- 1
- 2
// JS
Page({
handleTap: function() {
wx.showToast({
title: '你点击了我!',
icon: 'none'
});
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
????1.2 输入事件(Input Event)
输入事件用于处理用户在输入框中的输入操作。
示例代码:
<!-- WXML -->
<input bindinput="handleInput" placeholder="请输入内容"/>
- 1
- 2
// JS
Page({
data: {
inputValue: ''
},
handleInput: function(event) {
this.setData({
inputValue: event.detail.value
});
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
????1.3 表单提交事件(Submit Event)
表单提交事件用于处理用户提交表单时的操作。
示例代码:
<!-- WXML -->
<form bindsubmit="handleSubmit">
<input name="username" placeholder="用户名"/>
<button formType="submit">提交</button>
</form>
- 1
- 2
- 3
- 4
- 5
// JS
Page({
handleSubmit: function(event) {
const formData = event.detail.value;
wx.showModal({
title: '表单数据',
content: `用户名: ${formData.username}`,
showCancel: false
});
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
????1.4 切换事件(Change Event)
切换事件通常用于处理滑块或开关等组件的状态变化。
示例代码:
<!-- WXML -->
<switch bindchange="handleSwitchChange"/>
- 1
- 2
// JS
Page({
handleSwitchChange: function(event) {
wx.showToast({
title: event.detail.value ? '开关已打开' : '开关已关闭',
icon: 'none'
});
}
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
????1.5 滑动事件(Scroll Event)
滑动事件用于处理页面或某个区域的滚动操作。
示例代码:
<!-- WXML -->
<scroll-view bindscroll="handleScroll" style="height: 200px;" scroll-y>
<!-- 内容 -->
</scroll-view>
- 1
- 2
- 3
- 4
// JS
Page({
handleScroll: function(event) {
console.log('滚动位置:', event.detail.scrollTop);
}
})
- 1
- 2
- 3
- 4
- 5
- 6
????2.事件参数
在微信小程序中,事件参数是在事件触发时传递给事件处理函数的信息。这些参数通常包含关于事件的详细信息,例如事件类型、触发事件的元素、触摸点信息等。
以下是一些常见的事件参数:
-
event
: 主要的事件对象,包含以下属性和方法。-
type
: 事件类型,例如tap
、touchstart
、touchmove
、touchend
等。 -
timeStamp
: 事件生成时的时间戳。 -
target
: 触发事件的组件的相关信息,包含以下属性:-
id
: 触发事件的组件的ID。 -
dataset
: 触发事件的组件上绑定的data-
属性集合(例如data-foo="bar"
)。
-
-
currentTarget
: 当前处理事件的组件的相关信息,结构同target
。 -
detail
: 事件的详细信息,不同类型的事件会有不同的detail
数据。例如:- 对于
tap
事件,detail
包含x
和y
属性,表示触摸点相对于目标元素的坐标。 - 对于
input
事件,detail
包含value
属性,表示输入的内容。
- 对于
-
touches
: 当前所有触摸点的列表,每个触摸点包含以下信息:-
identifier
: 触摸点的标识符。 -
pageX
: 触摸点相对于页面的横坐标。 -
pageY
: 触摸点相对于页面的纵坐标。 -
clientX
: 触摸点相对于屏幕的横坐标。 -
clientY
: 触摸点相对于屏幕的纵坐标。
-
-
changedTouches
: 涉及本次事件的触摸点的列表,结构同touches
。
-
-
customData
: 通过bind
或catch
事件绑定方式传递的自定义数据(在WXML中使用data-
属性绑定)。
<!-- WXML -->
<view id="myView" data-foo="bar" bindtap="handleTap">点击我</view>
- 1
- 2
// JavaScript
Page({
handleTap(event) {
console.log(event);
console.log('事件类型:', event.type);
console.log('事件触发时间:', event.timeStamp);
console.log('触发元素ID:', event.target.id);
console.log('自定义数据:', event.target.dataset.foo);
console.log('触摸点信息:', event.touches);
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在这个示例中,当用户点击视图时,handleTap
函数会被调用,并且 event
对象会包含所有相关的事件参数。通过这些参数,你可以获取关于事件的详细信息,从而实现更复杂的交互逻辑。
????3.事件传参
在微信小程序中,事件传参是一个常见的需求,特别是在用户交互(如点击按钮、滑动等)时需要传递一些数据给事件处理函数。
????3.1 通过 data-
属性传参
微信小程序允许在组件上通过 data-
属性传递数据,这些数据会在事件对象的 中获取。
示例
<!-- 在 WXML 文件中 -->
<button bindtap="handleTap" data-id="123" data-name="item1">点击我</button>
- 1
- 2
// 在 JS 文件中
Page({
handleTap(event) {
const id = event.currentTarget.dataset.id;
const name = event.currentTarget.dataset.name;
console.log(id); // 输出: 123
console.log(name); // 输出: item1
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
????3.2 通过
传参
某些组件的事件对象中会包含 detail
属性,可以通过这个属性传递额外的信息。
示例
<!-- 在 WXML 文件中 -->
<slider bindchange="handleSliderChange"></slider>
- 1
- 2
// 在 JS 文件中
Page({
handleSliderChange(event) {
const value = event.detail.value;
console.log(value); // 输出滑块的值
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
????3.3 使用 bind
传递参数
使用 bind
方法可以在绑定事件时传递额外的参数。
示例
<!-- 在 WXML 文件中 -->
<button bindtap="handleTapWithArgs" data-id="123">点击我</button>
- 1
- 2
// 在 JS 文件中
Page({
handleTapWithArgs(event) {
const id = event.currentTarget.dataset.id;
this.someFunction(id, 'extraArg');
},
someFunction(id, extraArg) {
console.log(id); // 输出: 123
console.log(extraArg); // 输出: extraArg
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
????3.4 在事件对象中传递自定义数据
有些事件(如 form
的提交事件)会包含自定义的数据,可以通过 获取。
示例
<!-- 在 WXML 文件中 -->
<form bindsubmit="handleSubmit">
<input name="username" value="user1"/>
<button formType="submit">提交</button>
</form>
- 1
- 2
- 3
- 4
- 5
// 在 JS 文件中
Page({
handleSubmit(event) {
const formData = event.detail.value;
console.log(formData.username); // 输出: user1
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
????4.事件绑定
在微信小程序中,动态事件绑定是指在程序运行时,根据某些条件动态地为元素绑定事件处理函数。这在处理用户交互和动态内容时非常有用。
????4.1 WXML 文件
首先,在 WXML 文件中定义需要绑定事件的元素。这些元素通常会使用 wx:for
以循环的方式生成多个实例。
<view wx:for="{{items}}" wx:key="id" bindtap="handleTap" data-id="{{}}">
{{}}
</view>
- 1
- 2
- 3
????4.2 JS 文件
在 JS 文件中,定义数据和事件处理函数。
Page({
data: {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]
},
handleTap: function (event) {
const itemId = event.currentTarget.dataset.id;
console.log('Tapped item ID:', itemId);
// 根据itemId执行相应的逻辑
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
????4.3 动态绑定条件
如果需要根据某些条件动态地绑定或解绑事件,可以在 JS 文件中操作数据。
Page({
data: {
items: [
{ id: 1, name: 'Item 1', bindEvent: true },
{ id: 2, name: 'Item 2', bindEvent: false },
{ id: 3, name: 'Item 3', bindEvent: true }
]
},
onLoad: function () {
// 初始化时可能需要根据某些条件设置bindEvent
this.updateEventBindings();
},
updateEventBindings: function () {
this.setData({
items: this.data.items.map(item => {
// 假设我们根据某些条件来决定是否绑定事件
item.bindEvent = someCondition(item);
return item;
})
});
},
handleTap: function (event) {
const itemId = event.currentTarget.dataset.id;
console.log('Tapped item ID:', itemId);
}
});
function someCondition(item) {
// 返回一个布尔值,决定是否绑定事件
return item.id % 2 === 1; // 示例条件:ID为奇数的项绑定事件
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
????4.4 WXML 文件中的条件绑定
在 WXML 文件中使用条件渲染来动态绑定事件。
<view wx:for="{{items}}" wx:key="id">
<view wx:if="{{}}" bindtap="handleTap" data-id="{{}}">
{{}}
</view>
<view wx:else>
{{}}
</view>
</view>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这样,只有满足条件的元素会绑定 bindtap
事件处理函数。
????5.事件冒泡
在微信小程序中,事件冒泡是指事件从触发点(通常是一个较深层的子元素)逐级向上传递到父级元素,直到到达最顶层的祖先元素或者被某个中间层的元素拦截为止。这种机制类似于Web开发中的事件冒泡。
在微信小程序中,每个组件都有自己的事件处理函数。事件冒泡机制允许子组件的事件可以传递到父组件,这样父组件也可以对这些事件进行响应。
????5.1 事件冒泡的具体过程
-
事件触发:当用户在某个组件上触发一个事件时(例如点击事件
tap
)。 - 事件处理:该事件首先由触发事件的组件处理。
- 向上传递:如果该事件没有被阻止冒泡,它会继续向上传递到父组件,然后是父组件的父组件,依此类推,直到最顶层的组件。
????5.2 阻止事件冒泡
在微信小程序中,可以通过调用()
方法来阻止事件继续冒泡。
示例代码:
<!-- 页面结构 -->
<view bindtap="handleParentTap">
<view bindtap="handleChildTap" catchtap="handleChildTap">点击我</view>
</view>
- 1
- 2
- 3
- 4
// 页面逻辑
Page({
handleParentTap: function(event) {
console.log('父元素点击');
},
handleChildTap: function(event) {
console.log('子元素点击');
event.stopPropagation(); // 阻止事件冒泡
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在这个例子中,如果用户点击了<view>
标签内的子元素,由于调用了()
方法,事件不会冒泡到父元素上,所以不会触发handleParentTap
函数。
????5.3 事件绑定类型
微信小程序中提供了两种事件绑定:
- bind事件:默认会冒泡的事件。
- catch事件:阻止冒泡的事件。
例如:
-
bindtap
:绑定点击事件,并允许事件冒泡。 -
catchtap
:绑定点击事件,并阻止事件冒泡。
在实际开发中,可以根据需求选择适当的事件绑定方式来实现事件的处理和冒泡控制。
????6.互斥事件
在微信小程序开发中,互斥事件指的是多个事件或操作之间不能同时进行,必须确保它们在运行时不发生冲突。这种设计通常是为了避免资源竞争、数据不一致或者不可预测的行为。实现互斥事件的方式有很多,以下是一些常见的方法和注意事项:
????6.1 使用锁机制
锁可以确保某一时间只有一个事件或操作在执行。可以使用JavaScript内置的Promise机制来实现简单的锁机制。
let isLocked = false;
function someFunction() {
if (isLocked) {
return; // 已经有事件在进行,退出
}
isLocked = true; // 加锁
// 执行操作
setTimeout(() => {
// 操作完成,解锁
isLocked = false;
}, 1000);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
????6.2 异步队列
使用异步队列将事件排队并依次执行,确保不会同时执行多个事件。
let queue = [];
let isProcessing = false;
function processQueue() {
if (isProcessing || queue.length === 0) {
return;
}
isProcessing = true;
const task = queue.shift();
task().then(() => {
isProcessing = false;
processQueue();
});
}
function addToQueue(task) {
queue.push(task);
processQueue();
}
// 使用方法
addToQueue(() => new Promise(resolve => {
// 模拟异步操作
setTimeout(() => {
console.log("任务完成");
resolve();
}, 1000);
}));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
????6.3 控制事件触发频率
限制事件触发的频率,例如通过防抖(debounce)或者节流(throttle)来控制事件的触发。
防抖
防抖的原理是在一段时间内只执行最后一次操作。
function debounce(func, wait) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, arguments), wait);
};
}
const debouncedFunc = debounce(() => {
console.log("事件触发");
}, 300);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
节流
节流的原理是在一定时间间隔内只执行一次操作。
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
const throttledFunc = throttle(() => {
console.log("事件触发");
}, 300);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
????6.4 使用标志位
对于一些简单的互斥事件,可以使用标志位来实现。例如,按钮点击事件只能在上一次点击处理完成后才能触发下一次点击事件。
let isProcessing = false;
function handleClick() {
if (isProcessing) {
return;
}
isProcessing = true;
// 执行异步操作
setTimeout(() => {
console.log("按钮点击处理完成");
isProcessing = false;
}, 1000);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
通过这些方法,可以有效地控制微信小程序中的互斥事件,确保程序的稳定性和数据的一致性。
????6.5 mut-bind
在微信小程序开发中,mut-bind
是指多个事件绑定在同一个元素上时,这些事件是互斥的,也就是说,一个事件触发时,其他事件不会被触发。这在某些情况下可以用来避免事件冲突或者防止重复触发。
例如,在开发中,你可能会遇到需要同时监听 tap
、longpress
这类事件的情况。使用 mut-bind
可以确保在一个事件触发的情况下,另一个事件不会被触发。
下面是一个简单的示例,展示了如何在一个按钮上使用互斥事件:
<view class="container">
<button
mut-bind:tap="handleTap"
mut-bind:longpress="handleLongPress">
按钮
</button>
</view>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Page({
handleTap() {
console.log('Tap event');
},
handleLongPress() {
console.log('Long press event');
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在这个例子中,如果用户点击按钮,handleTap
会被触发;如果用户长按按钮,handleLongPress
会被触发。使用 mut-bind
可以确保在某一时刻只有一个事件被触发,从而避免多个事件冲突。
需要注意的是,mut-bind
需要在小程序基础库 2.9.1 或更高版本中使用。如果你在较低版本的小程序基础库中使用,可能会导致事件绑定失效或不如预期工作。你可以在 中设置最低基础库版本要求:
{
"miniprogramRoot": "miniprogram/",
"pluginRoot": "plugin/",
"setting": {
"miniprogramRoot": "miniprogram/",
"pluginRoot": "plugin/",
"es6": true,
"enhance": true,
"postcss": true
},
"compileType": "miniprogram",
"libVersion": "2.9.1",
"miniprogram": {
"minBaseLibVersion": "2.9.1"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
这样可以确保用户的基础库版本满足 mut-bind
的要求,从而确保事件互斥功能正常使用。
????6.事件的捕获阶段
在微信小程序中,事件捕获阶段是事件处理的一部分,它是指事件从最外层的祖先节点向目标节点传播的阶段。在这一阶段,事件会先被最外层的祖先节点捕获,然后逐层向内传播,直到到达目标节点。
微信小程序中的事件处理大致可以分为三个阶段:
- 捕获阶段(Capture Phase):事件从最外层的祖先节点开始,逐层向事件目标节点传播。
- 目标阶段(Target Phase):事件到达目标节点并触发目标节点上的事件处理器。
- 冒泡阶段(Bubble Phase):事件从目标节点开始,逐层向外传播到最外层的祖先节点。
在微信小程序中,可以在捕获阶段处理事件,通过在元素的事件绑定中指定 catch
或 bind
关键字来控制事件是否继续传播。bind
绑定的事件处理器不会阻止事件冒泡,而 catch
绑定的事件处理器会阻止事件冒泡。
要在捕获阶段处理事件,可以使用 capture-bind
或 capture-catch
,例如:
<view capture-bind:tap="handleTap">
<view>点击我</view>
</view>
- 1
- 2
- 3
在这个例子中,handleTap
函数会在捕获阶段被调用。
通过了解和使用捕获阶段,可以更好地控制事件流和事件处理的顺序,有助于实现更复杂的交互逻辑。
????7.事件对象
在微信小程序中,事件对象是指在事件处理函数中传递的参数,它包含了触发事件的相关信息。事件对象通常简称为 event
或 e
。事件对象的结构和属性可以根据不同的事件类型有所不同,但一般都包含以下一些常用属性:
-
type
:事件类型,例如tap
、input
等。 -
timeStamp
:事件生成时的时间戳。 -
target
:触发事件的组件的一些属性集合。 -
currentTarget
:当前组件的一些属性集合,与target
类似,但在冒泡过程中currentTarget
会变化。 -
detail
:事件的详细信息,不同的事件类型,detail
的内容会有所不同。例如,在input
事件中,包含输入框的内容。
-
touches
:触摸点信息的数组,包含所有当前处于触摸状态的触摸点信息。 -
changedTouches
:触摸状态发生改变的触摸点信息的数组。
具体的例子可以更好地理解事件对象的属性和用法。下面是一个简单的微信小程序事件处理函数示例:
Page({
data: {
// 一些页面数据
},
handleTap: function(event) {
console.log(event.type); // 输出 'tap'
console.log(event.timeStamp); // 输出时间戳
console.log(event.target); // 输出触发事件的组件信息
console.log(event.currentTarget); // 输出当前组件的信息
console.log(event.detail); // 输出事件的详细信息
}
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在上面的代码中,handleTap
是一个点击事件的处理函数,当用户点击某个组件时,这个函数会被调用,并且事件对象 event
会作为参数传递进来。通过访问 event
对象的各个属性,可以获取到关于这个点击事件的各种信息。
不同的事件类型(例如 tap
、input
、scroll
等)会有不同的 内容,具体的事件对象结构可以参考微信小程序官方文档来获取更多详细信息。
????感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。
再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”