图文并茂演示小程序movable-view的可移动范围
前言
开发过小程序的同学可能对这两个内置组件并不陌生,他们配合用来实现在页面中可以拖拽滑动,其中:
movable-area
表示元素可移动的区域,它决定元素移动的区域范围movable-view
表示可移动的视图容器,它决定了什么元素可以移动
使用上要求movable-view
必须是movable-area
的直接子节点,否则不能移动。
这两个组件对于比较常规的可拖拽移动产品需求可以轻松应对,但是针对一些稍微复杂的需求,可能需要对他们的用法原理要进一步掌握理解。
重新认识movable-area和movable-view
在微信小程序官网介绍movable-area时,有过这样的一段提示:
tip
: 当 movable-view 小于 movable-area 时,movable-view的移动范围是在 movable-area 内;tip
: 当 movable-view 大于 movable-area 时,movable-view的移动范围必须包含movable-area(x轴方向和 y 轴方向分开考虑)
上面两个组件比较大小是基于各自的尺寸大小而言的,也就是对应矩形的区域面积而言。
其实官网上面对二者关系的说明不是太详细,有很多情况需要区分开;本人在项目做了不同的尝试,下面是总结的不同情况,有不对的地方还请大家斧正。
movable-area和movable-view的一方完全包含另一方
针对movable-area
和movable-view
其中一方的尺寸大小可以完全覆盖另一方的尺寸大小时,其移动范围表现比较好理解。
例如下图为movable-view
的尺寸完全覆盖movable-area
的区域时,movable-view
的可以移动范围演示图:
movable-view
不管怎么移动都要完全包含住movable-area
,也就是说movable-area
不能超出movable-view
的区域范围;反之亦然。
那么大家有没有想过,若不满足一方能完全包含另一方,也就是二者区域存在交叉时,movable-view
的移动范围是怎么表现的呢?
movable-area与movable-view区域交叉
所谓区域交叉,是指一方不能完全覆盖另一方时,二者区域有部分重叠;针对这种情况其表现是有差异,这时movable-view
的移动范围就要针对x轴方向和 y 轴方向分开考虑。
总结来说:
二者交叉时,不看
movable-area
与movable-view
的区域谁大谁小,而是看movable-view
宽高值最大的那个方向。
举个例子:movable-view
的width比其height大,因为其跟movable-area
区域交叉,那么两个不同方向的最大移动范围表现:
- 水平方向:
movable-view
的width要完全包含movable-area
的width - 垂直方向:
movable-view
的height要被movable-area
的包含覆盖
如下移动演示图:
movable-area区域大小为0,而movable-view不为0
movable-view
的区域大于0,而movable-area
的面积为0的在移动过程会有怎样的表现呢?
首先,看下movable-area
区域为0的两种形式:
movable-area
组件的width和height都为0movable-area
组件的width和height其中只有一个为0
那么在这两种情况下,movable-view
的移动范围是什么呢,思考几秒钟。
其实,针对movable-area
的宽高都为0的情况,可以将上图的黑色正方块想象成一个尺寸为0的一个点,只不过在界面不会展示,但是其位置还在对应位置,那么movable-view
就是围绕该不可见点的位置移动,不能超过这个范围,如下图所示,为了方便展示将该点位置用红色点表示。
针对movable-area
的width和height任一个为0的情况,与二者同时为0将其想象一个点的情况主要区别是,可以将movable-area
想象其为一条不可见的直线,它也不会在界面展示,但是它决定了movable-view
移动范围,我们以width为0,height不为0的情况来说明movable-view
的移动范围,如下图演示:
movable-area与movable-view区域大小同时为0
首先介绍本节前说明一下:
moable-view
为0不代表不能移动,例如其子元素有尺寸,依然可以移动- 在二者区域都为0的情况下,页面是不会展示对应元素的,下图以演示目的会将其画出来表示其在页面的位置
movable-area
或者movable-view
区域为0的情况,有两种情况:要么元素的width和height都为0,或者二者不同时为0。
下面我们来介绍下movable-view
在其width和height不同时为0情况下(同时为0不会有移动的元素)的移动范围,该前提下要区分movable-area
区域为0的情况。
movable-area
的宽高同时为0,movable-view
的width不为0,height为0的情况(height不为0 的情况类似)。
movable-area
的宽高不同时为0- 若
movable-area
和movable-view
的width都不为0,或者height都不为0,其表现如下图演示:
movable-area
的有width为0,height不为0,而movable-view
的width不为0,height为0的情况移动范围演示如下图,相反的情况类似;
- 若
由上面的演示可以得知:
movable-area
和movable-view
同时为0的情况,跟二者区域不为0且存在交叉的情况下表现类似。
movable-view的子元素内容超过其尺寸
movable-area
和movable-view
元素必须设置width和height,但是有时我们movable-view
的子元素内容超过其设置的宽高,这时其表现如何呢?
先说结论:
拖拽滑动元素的移动范围是由
movable-area
和movable-view
元素决定的,与movable-view
的子元素尺寸没有关系。
也就是说,movable-area
和movable-view
的宽高一旦设置后,移动范围就固定了,如下图所演示。
movable-view决定可拖动元素
要实现元素可拖动,至少要满足:
- 可拖动元素必须通过
movable-view
设置 movable-view
必须为movable-area
的直接子元素
说明一下,可以在movable-area
中设置多个movable-view
表示设置多个可滑动的块,例如这文章# 微信小程序基于movable-area实现DIY T恤/logo定制实现的拖动。
实现一个卡片多段式拖动
例如有一个产品需求屏幕内一个卡片支持多段式滑动,例如下图所示的三段式:
要求:页面数据初始化后卡片移动到h2的为位置,用户手动拖动到h2 ~ h1的中间位置靠上时,卡片移动到h1的位置,中间位置靠下的话还是移动到h2的位置,h1~h0之间的移动后卡片位置策略与h2 ~ h1一样。
一个实现思路:可以借鉴上面讨论的movable-area
和movable-view
区域都为0,但是二者存在交叉的情况,具体实现:
movable-area
设置其区域尺寸为width为0,height为100vhmovable-view
设置其区域尺寸width为100vw,height为0movable-view
的子元素内容即为卡片的展示内容
这样,movable-view
在垂直方向的移动范围就是movable-area
的高度范围,相当于在垂直方向,movable-area
的长度大于movable-view
,所以后者的移动范围不能超出前者。
wxml的结构如下所示:
<movable-area
style="width: 0; height: 100vh;"
>
<movable-view
direction="vertical"
y="{{offsetY}}"
style="width: 100vw; height: 0;"
bindchange="onChange"
bind:touchend="onTouchEnd"
bind:touchcancel="onTouchEnd"
>
<view class="movable-content">
<view class="card">
...
</view>
</view>
</movable-view>
</movable-area>
可以在movable-view
的change事件中收集卡片滑动后的y方向的偏移值,在触摸事件的结束最后统一计算卡片的最终滑动偏移量值。
Page({
// 下面的h0、h1、h2、100vh 分别表示需求要求设置的卡片多段式滑动范围
data: {
offsetY: h2,
segs: [{
value: h0,
mix_value: h0,
max_value: (h0 + h1)/2
}, {
value: h1,
mix_value: (h0 + h1)/2,
max_value: (h1 + h2)/2
}, {
value: h2,
mix_value: (h1 + h2)/2,
max_value: 100vh
}]
},
...
onChange(event) {
if (event.detail.source) {
this._offsetY = event.detail.y
}
},
onTouchEnd() {
const y = this._offsetY;
const idx = this.segs.findIndex(item => {
return (
y >= item.min_value && y <= item.max_value
);
});
if (idx !== -1) {
this.setData({
offsetY: this.segs[idx].value
})
}
}
})
图文并茂演示小程序movable-view的可移动范围的更多相关文章
- 关于微信小程序获取view的动态高度填坑
wx.createSelectorQuery().select('#box').boundingClientRect(function (rect) { width = rect.width heig ...
- mPaaS 小程序架构解析 | 实操演示小程序如何实现多端开发
对于 mPaaS 小程序开发框架,想必读者们并不陌生.它源自于支付宝小程序框架,继承了易开发性.跨平台性及 Native 性能,不仅帮助开发者实现面向自有 App 投放小程序,还可快速构建打包,覆盖支 ...
- 小程序获取view元素的高度
页面wxml <!--page/index/index.wxml--> <view id='demo'> <text>哈哈哈哈哈</text> < ...
- 【微信小程序】view顶部固定或底部固定 + scroll-view中的元素view也可以使用position:fixed;固定选中元素位置
1.顶端固定核心代码如下: <view class="page__hd" style="position:fixed; top:0;width: 750rpx;&q ...
- 微信小程序将view动态填满全屏
一.在app.js利用官方方法获取设备信息,将获取到的screenHeight.windowHeight度量单位统一由rpx换算为px 注:官方文档给出 [rpx换算px (屏幕宽度/750) ][ ...
- 关于小程序去除view/navigator 点击后默认阴影效果
hover:class :定义容器在被触发时的样式 通常无用,但若不去除则影响用户体验: 为避免被覆盖,约定在wxss底部添加class,比如: <!-- wxml --> <na ...
- 微信小程序 -- scroll view
效果图:横向滚动和纵向滚动 scroll view使用方法文档,前面已经介绍查找文档方法,此处不再赘述 一.横向滚动 创建一个页面scroll-nav 然后,在.wxml文件中排版 <!--水平 ...
- 一个小时快速搭建微信小程序教程
「小程序」这个划时代的产品发布快一周了,互联网技术人都在摩拳擦掌,跃跃欲试.可是小程序目前还在内测,首批只发放了 200 个内测资格(泪流满面).本以为没有 AppID 这个月就与小程序无缘了,庆幸的 ...
- 一个小时快速搭建微信小程序
「小程序」这个划时代的产品发布快一周了,互联网技术人都在摩拳擦掌,跃跃欲试.可是小程序目前还在内测,首批只发放了 200 个内测资格(泪流满面).本以为没有 AppID 这个月就与小程序无缘了,庆幸的 ...
随机推荐
- 在vue-cli中安装scss,且可以全局引入scss的步骤
简历魔板__个人简历模板在线生成 在写vue的css样式时,觉得需要css预处理器让自己的css更加简洁.适应性更强.可读性更佳,更易于代码的维护,于是在vue-cli脚手架采用scss.写过的人都知 ...
- 用 Python 远程控制 Windows 服务器,太好用了!
在很多企业会使用闲置的 Windows 机器作为临时服务器,有时候我们想远程调用里面的程序或查看日志文件 Windows 内置的服务「 winrm 」可以满足我们的需求 它是一种基于标准简单对象访问协 ...
- K8S面试应知必回
目录 面试不要不懂装懂,不会就是不会,不可能每个人都接触过所有的知识! 1. 基础问题 1.1 Service是怎么关联Pod的?(课程Service章节) 1.2 HPA V1 V2的区别 1.3 ...
- 论文解读《Deep Attention-guided Graph Clustering with Dual Self-supervision》
论文信息 论文标题:Deep Attention-guided Graph Clustering with Dual Self-supervision论文作者:Zhihao Peng, Hui Liu ...
- 被迫开始学习Typescript —— class
TS 的 class 看起来和 ES6 的 Class 有点像,基本上差别不大,除了 可以继承(实现)接口.私有成员.只读等之外. 参考:https://typescript.bootcss.com/ ...
- leetcode 142. Linked List Cycle II 环形链表 II
一.题目大意 https://leetcode.cn/problems/linked-list-cycle-ii/ 给定一个链表的头节点 head ,返回链表开始入环的第一个节点. 如果链表无环,则 ...
- 关于我开发tinymce的自由表单、病历插件这件事
项目地址:https://gitee.com/zhao-xuhang/tinymce 1.前期准备 这是个vue2项目所以要使用vue-cli (虽然开发tinymce插件和这个没关系) 1. 使用n ...
- Navicat破解激活流程
Navicat Navicat Premium 是一套数据库开发工具,让你从单一应用程序中同时连接 MySQL.MariaDB.MongoDB.SQL Server.Oracle.Postg ...
- 【SSM框架】Spring笔记 --- 事务详解
1.Spring的事务管理: 事务原本是数据库中的概念,在实际项目的开发中,进行事务的处理一般是在业务逻辑层, 即 Service 层.这样做是为了能够使用事务的特性来管理关联操作的业务. 在 Spr ...
- python3在使用类基础时,遇到错误TypeError: module.**init**() takes at most 2 arguments (3 given)
python3在使用类基础时,遇到错误TypeError: module.init() takes at most 2 arguments (3 given) 1.原因:直接导入的py文件,而没有导入 ...