我的编程空间,编程开发者的网络收藏夹
学习永远不晚

小程序如何实现左滑抽屉菜单

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

小程序如何实现左滑抽屉菜单

这篇文章将为大家详细讲解有关小程序如何实现左滑抽屉菜单,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    在移动端,侧滑菜单是一个很常用的组件(通常称作 Drawer,抽屉)。因为现在手机屏幕太大,点击角落的菜单按钮明显不如在屏幕中间滑动方便。

    相比其他平台,小程序的组件库支持明显还不够完善,各个框架也还不太成熟。由于之前使用框架的过程中被各种神秘bug搞的头秃,还是用回了原生环境。

    最近研究了一下如何在原生框架中实现滑动抽屉菜单效果,本来以为很麻烦,结果发现其实只需要几十行代码,而且可以类比实现很多灵活的效果。感觉现在网上相关资料较少,因此在此分享一下。除了文中贴出的代码块,也可以点击链接在小程序开发工具中预览效果、查看代码片段。这里实现了三种常见效果,先看一下动图,下面将一一讲解代码实现。

    A 菜单在上层 

    小程序如何实现左滑抽屉菜单

    A2 菜单在上层,下层遮罩 

    小程序如何实现左滑抽屉菜单

    B 菜单在下层

    小程序如何实现左滑抽屉菜单

    WXS 响应事件

    手势控制菜单的原理很简单:小程序提供了一系列触摸手势触发的事件,包括触摸开始、移动、结束(touchstart, touchmove, touchend)等等。在这些事件上绑定自定义的事件响应函数,即可实现根据手势打开关闭菜单的操作。

    出于性能考虑,事件处理函数最好放在 WXS、而不是 JS 文件中。具体原理与小程序的运行环境有关,感兴趣的话可以去文末查看。WXS 是小程序的专用脚本语言(WXS 与 JS 的关系相当于 WXSS 与 CSS 的关系),语法和 JS 类似,有部分区别,比如:

    • 与 JS 隔离,不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API

    • 只能响应小程序内置组件的事件,不支持自定义组件的事件回调

    • 变量与函数默认为模块私有,通过 module.exports 对外暴露

    • 使用标签在 WXML 中引入使用(必须使用相对路径)

    wxs 文件和 wxml 文件中的基本写法如下:

    // index.wxsfunction touchStart(e, ins) {}function touchMove(e, ins) {}function touchEnd(e, ins) {}module.exports = {  touchstart: touchStart,  touchmove: touchMove,  touchend: touchEnd}<wxs module="drawer" class="lazy" data-src="./index.wxs"></wxs><view bindtouchstart="{{drawer.touchstart}}"      bindtouchmove="{{drawer.touchmove}}"       bindtouchend="{{drawer.touchend}}"></view>

    方案A

    页面结构和样式

    小程序如何实现左滑抽屉菜单

    这是最常见的抽屉菜单样式之一,滑动主体内容不动,菜单在上层显示。首先写出基本的 HTML 结构和 CSS 样式(省略了一些美观方面的样式表):

    <wxs module="drawer" class="lazy" data-src="./index.wxs"></wxs><view>  <view class="main" bindtouchstart="{{drawer.touchstart}}"    bindtouchmove="{{drawer.touchmove}}" bindtouchend="{{drawer.touchend}}">    <view>      右滑显示侧边菜单 方案A    </view>  </view>  <view class="drawer" data-drawerwidth="150">    <view class="drawer-item">drawerA</view>    <view wx:for="{{[1, 2, 3]}}" class="drawer-item">      <text>menu item {{item}}</text>    </view>  </view></view>

    WXML 中的几个重点:

    • 正确引入 wxs 模块(必须用相对路径)

    • 进行滑动手势时菜单是隐藏的,所以实际上是在主界面上进行滑动,所以三个滑动事件回调需要绑定在主体内容的 view 上面

    • 进行移动的是 .drawer 元素,需要设置好 class 属性方便获取

    • 抽屉元素的 data-drawerwidth 属性通过 dataset 传值给 wxs 脚本,规定了菜单的宽度,需要和样式保持一致

    WXSS 没啥好说的,写在注释里了:

    .main {  height: 100vh;  width: 100%;  position: absolute;}.drawer {  height: 100vh;  width: 150px;  position: absolute;  transition: transform 0.4s ease;   left: -150px;  }

    WXS 事件回调函数

    wxs 函数有两个入参

    • event 是小程序事件对象,并在此基础上多了触发事件的组件的实例 event.instance

    • ownerInstance 是触发事件的组件的父组件(页面)的实例

    wxs 中组件实例是封装好的 ComponentDescriptor 对象,能够操作组件的 dataset、设置 style、class 等,对于交互动画基本够用了。更多用法可参考文档。

    var wxsFunction = function(event, ownerInstance) {    var instance = ownerInstance.selectComponent('.classSelector') // 返回组件的实例    instance.setStyle({        "font-size": "14px" // 支持rpx    })    instance.getDataset()    instance.setClass(className)    return false // 不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault}

    WXS 脚本

    条件判断为主,逻辑没啥特别的,结合情景不难理解

    • 不要用 let, const 声明变量,会报错

    • 把设置 transform 属性 X 位移的代码简单封装一下,看起来更美观

    • judge point 类似于吸附效果,就是菜单划出来超过某一位置就自动把剩余部分打开

    var startmark = 0;var status = 0;  // 菜单开闭状态var JUDGEPOINT = 0.7;function touchStart(e, ins) {  var pageX = (e.touches[0] || e.changedTouches[0]).pageX;  startmark = pageX;}function touchMove(e, ins) {  var pageX = (e.touches[0] || e.changedTouches[0]).pageX;  var offset = pageX - startmark;  var drawerComp = ins.selectComponent('.drawer');  var drawerWidth = drawerComp.getDataset().drawerwidth;  if (offset > 0 && status == 0) {    setCompTransX(drawerComp, Math.min(drawerWidth, offset))  } else if (offset < 0 && status == 1) {    setCompTransX(drawerComp, Math.max(0, offset))  }}function touchEnd(e, ins) {  var pageX = (e.touches[0] || e.changedTouches[0]).pageX;  var offset = pageX - startmark;  var drawerComp = ins.selectComponent('.drawer');  var drawerWidth = drawerComp.getDataset().drawerwidth;  if (offset > 0 && status == 0) {    if (offset < drawerWidth * JUDGEPOINT) {      setCompTransX(drawerComp, 0);    } else {      setCompTransX(drawerComp, drawerWidth);      status = 1;    }  } else if (offset < 0) {    setCompTransX(drawerComp, 0);    status = 0;  }}function setCompTransX(comp, x) {  comp.setStyle({    transform: 'translateX(' + x + 'px)',  })}module.exports = {  touchstart: touchStart,  touchmove: touchMove,  touchend: touchEnd}

    遮罩层

    点击文首或文末链接在小程序开发工具中查看完整代码。

    遮罩层只需要在菜单和主容器之间增加一个 view 即可:

    <view class="main"></view><view class="mask" data-maxopacity="0.6"></view><view class="drawer" data-drawerwidth="150"></view>

    样式中很重要的是这个 pointer-events 属性,设置为 none 之后点击动作会穿透这个 view 达到下层。因为遮罩层不像抽屉是处在画面以外的,它虽然透明度为0,但实际上一直覆盖在 .main 上方,如果不加这个属性,所有对 .main 的点击操作都会点到 .mask 上面,那不管是滑动还是其他按钮都无效了。

    .mask {  height: 100vh;  width: 100%;  position: fixed;  transition: opacity 0.4s ease;  opacity: 0;  pointer-events: none;  background-color: #548CA8;}

    wxs 脚本也基本完全一致,只需要以相似的方法获取到 .mask 的实例以及 dataset 中的透明度参数,并在设置位移属性的同时设置遮罩层的透明度属性即可。

    function setDrawer(x) {  setCompTransX(drawerComp, x);  maskComp.setStyle({    opacity: x / drawerWidth * maskOpacity,  })}

    方案B

    点击文首或文末链接在小程序开发工具中查看完整代码。

    方案B 与方案A 的区别主要在于滑动时是主界面向右移动露出下层的菜单,其余各部分实现并无不同。这里只贴出主要差异的部分。

    因为移动的是 .main 元素,因此把宽度配置数据放到了该元素的标签中,这样可以少获取一个组件实例。

    <view class="drawer"></view><view class="main"       data-drawerwidth="150"       bindtouchstart="{{drawer.touchstart}}"      bindtouchmove="{{drawer.touchmove}}"       bindtouchend="{{drawer.touchend}}"></view>

    transition 动画属性也放在 .main 中,.drawer 的偏移不需要了。

    .main {  height: 100vh;  width: 100%;  position: absolute;  transition: transform 0.4s ease;}.drawer {  height: 100vh;  width: 150px;  position: absolute;}

    wxs 脚本中除了获取的组件不同外,连设置位移都不需要改。

    function touchMove(e, ins) {  var pageX = (e.touches[0] || e.changedTouches[0]).pageX;  var offset = pageX - startmark;  var mainComp = ins.selectComponent('.main');  var drawerWidth = mainComp.getDataset().drawerwidth;  if (offset > 0 && status == 0) {    setCompTransX(mainComp, Math.min(drawerWidth, offset))  } else if (offset < 0 && status == 1) {    setCompTransX(mainComp, Math.max(0, offset))  }}

    为什么要使用 WXS

    小程序在很多地方与 web 开发很像,但底层存在一些区别。网页中,渲染和脚本执行在同一个线程中执行(因此执行脚本可能会导致页面整个卡死);小程序在不同的线程中分别运行逻辑层(JS脚本)和渲染层(WXML和WXSS),线程间经由客户端(Native)进行通信。

    小程序如何实现左滑抽屉菜单

    因此,如果使用 JS 脚本响应事件,每次触发 touchmove 都会产生两次进程间通信(下图左所示),通信开销较大;同时“setData 渲染也会阻塞其它脚本执行”(文档这么说的,我也不知道为什么)。由于一次手势会触发巨量的 touchmove 事件,上述原因会造成动画的卡顿。

    而 WXS 函数运行在视图层,不存在上述问题(下图右所示)。

    小程序如何实现左滑抽屉菜单

    关于“小程序如何实现左滑抽屉菜单”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    小程序如何实现左滑抽屉菜单

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    小程序如何实现左滑抽屉菜单

    这篇文章将为大家详细讲解有关小程序如何实现左滑抽屉菜单,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在移动端,侧滑菜单是一个很常用的组件(通常称作 Drawer,抽屉)。因为现在手机屏幕太大,点击角落的菜
    2023-06-20

    Android怎么实现侧滑抽屉菜单

    这篇文章将为大家详细讲解有关Android怎么实现侧滑抽屉菜单,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。侧滑抽屉菜单 前言正文一、创建项目二、添加滑动菜单三、UI美化四、添加导航视图五、菜单分类六、动
    2023-06-14

    微信小程序如何实现点餐小程序左侧滑动菜单

    这篇文章主要讲解了“微信小程序如何实现点餐小程序左侧滑动菜单”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“微信小程序如何实现点餐小程序左侧滑动菜单”吧!效果图:一、初识scroll-view
    2023-07-02

    Android开源AndroidSideMenu实现抽屉和侧滑菜单

    AndroidSideMenu能够让你轻而易举地创建侧滑菜单。需要注意的是,该项目自身并不提供任何创建菜单的工具,因此,开发者可以自由创建内部菜单。核心类如下:/* * Copyright dmitry.zaicew@gmail.com D
    2022-06-06

    Android开发如何实现抽屉菜单

    这篇文章主要介绍Android开发如何实现抽屉菜单,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!实现效果点击菜单图表即可进入抽屉代码实现1、打开app/build.gradle文件,在dependencies闭包中添
    2023-06-25

    Flutter UI如何实现侧拉抽屉菜单

    小编给大家分享一下Flutter UI如何实现侧拉抽屉菜单,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!在移动开发中,我们可以通过底部导航栏、标签页或是侧边抽屉菜单来实现导航。这是在小屏幕上可以充分利用空间。我们设计不仅要
    2023-06-29

    Android实现自定义滑动式抽屉效果菜单

    在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自
    2022-06-06

    使用微信小程序实现滑动菜单效果

    使用微信小程序实现滑动菜单效果微信小程序作为一种快速开发并具有广泛应用的工具,为我们提供了多种实现滑动菜单效果的方法。本文将向您展示一种简单而实用的实现方式,帮助您在开发中轻松添加滑动菜单效果。准备工作在开始编码之前,我们需要先创建一个基本
    使用微信小程序实现滑动菜单效果
    2023-11-21

    uni-app制作小程序实现左右菜单联动效果

    这篇文章主要介绍了uni-app制作小程序实现左右菜单联动效果,实现步骤和思路都很简单,今天通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-16

    Android3D如何实现滑动菜单

    这篇文章主要介绍了Android3D如何实现滑动菜单,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。首先来讲一下这次的实现原理吧,其实传统的滑动菜单功能就是把菜单部分放在了下面
    2023-05-30

    Html+Css+Jquery如何实现左侧滑动拉伸导航菜单栏

    这篇文章主要介绍了Html+Css+Jquery如何实现左侧滑动拉伸导航菜单栏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。PC端移动端代码
    2023-06-09

    如何使用android实现左右侧滑菜单效果的方法

    这篇文章主要介绍了如何使用android实现左右侧滑菜单效果的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在android开发中,左右侧滑菜单的开发已成为我们现在开发的
    2023-05-30

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录