We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Demo gist地址 👈
做web开发经常会遇到列表操作, 如果不涉及移动端, 那么在列表上放几个按钮, 用户点击就完事了, 如果是移动端, 受限于屏幕宽度, 操作按钮太多会影响布局, 所以在移动端列表的滑动操作比较常见.
做原生开发, 系统可能给列表提供了基本的删除等功能, 那么网页应该如何实现呢?
本文以地址管理为demo, 用react实现, 其实不管是什么框架, 涉及到的大部分都是 web 的接口.
demo用到了coroutine, 使用协程方便管理一系列事件 (event flow).
2件事要处理: 滑动 和 布局
滑动事件需要被监听, 应该在列表的每一个item上设置监听, 每个item处理滑动事件.
如果是 mobile 监听这三个事件:
否则监听这几个:
在生命周期开始时候监听这几个事件:
startupTouchEvent() { const current = ReactDOM.findDOMNode(this); current.addEventListener('touchstart', this.moveLoop); current.addEventListener('touchend', this.moveLoop); current.addEventListener('touchmove', this.moveLoop); } 复制代码
其中 this.moveLoop 是:
this.moveLoop
this.moveLoop = coroutine(function*() { let e = {}; while (e = yield) { if (e.type === 'touchstart') { // trace position const startX = e.touches[0].clientX; while (e = yield) { if (e.type === 'touchmove') { // trace position // console.log('touchmove', e); const movedX = e.changedTouches[0].clientX; const deltaX = movedX - startX; // console.log('moved', deltaX); if (deltaX <= 0) { that.moveMask(deltaX); } } if (e.type === 'touchend') { const endX = e.changedTouches[0].clientX; const deltaX = endX - startX; // console.log('end', deltaX); if (deltaX >= -40) { that.closeMaskIfNeeded(); } else { that.openMask(); } break; } } } } }) 复制代码
这里用到了 corutine.
首先当手指放到 item 上时, 记录位置 startX = e.touches[0].clientX;.
startX = e.touches[0].clientX;
当手指滑动时获取此时的位置 e.changedTouches[0].clientX, 减去初始位置 deltaX = movedX - startX;, 如果 deltaX 小于0, 那么此时是左滑, 进行 UI 上的操作, 将上层 div 左移 deltaX.
e.changedTouches[0].clientX
deltaX = movedX - startX;
deltaX
div
当手指离开屏幕时候, 记录此时位置并获取与初始位置的差值 deltaX = endX - startX, 判断 deltaX, 如果滑动距离太小(40px)或者向右滑, 那么就关掉展开的 div, 如果滑动距离够长, 那么就完全展开 div.
deltaX = endX - startX
<div className="address-swipe-wrapper"> <div className="swiper-operation-btns"> <button style={{ backgroundColor: '#7EA1D6' }} onClick={onEdit}> 编辑 </button> <button style={{ backgroundColor: 'red' }} onClick={onDelete}> 删除 </button> </div> <div className="address-item" onClick={onClick} style={{ left, position: 'relative', transition: 'all 250ms', }}> {selected && <img className="address-item-selected-icon" src={require('../img/check.png')} alt="选中" /> } <div className="address-content"> <div>{`${name} ${mobile}`}</div> <div>{provinceName+cityName+districtName+detailedAddress}</div> </div> </div> </div> 复制代码
几个操作按钮是绝对布局被盖在 address-item 内容的下面, 当滑动或者展开时候 address-item 会左移 left 距离, 它是 relative 布局.
left
为了让滑动有动效, 可以添加 transition: 'all 250ms'.
transition: 'all 250ms'
openMask() { this.setState({ left: -160 }); } moveMask(deltaX) { this.setState({ left: deltaX }); } closeMaskIfNeeded() { this.setState({ left: 0 }); } 复制代码
不会, 经过pc和手机(ios/android)尝试, 滑动时候不会触发 address-item 的选中, 并没发现会冲突, 除非你写 evt.preventDefault().
evt.preventDefault()
给 window 添加监听事件:
window
window.addEventListener('touchstart', this.closeMaskIfNeeded); 复制代码
在 PC 上表现良好, 但是在 mobile 上表现异常. 所以移到 TODO 里待解决.
The text was updated successfully, but these errors were encountered:
No branches or pull requests
预览
前言
Demo gist地址 👈
做web开发经常会遇到列表操作, 如果不涉及移动端, 那么在列表上放几个按钮, 用户点击就完事了, 如果是移动端, 受限于屏幕宽度, 操作按钮太多会影响布局, 所以在移动端列表的滑动操作比较常见.
做原生开发, 系统可能给列表提供了基本的删除等功能, 那么网页应该如何实现呢?
本文以地址管理为demo, 用react实现, 其实不管是什么框架, 涉及到的大部分都是 web 的接口.
demo用到了coroutine, 使用协程方便管理一系列事件 (event flow).
原理
2件事要处理: 滑动 和 布局
滑动
滑动事件需要被监听, 应该在列表的每一个item上设置监听, 每个item处理滑动事件.
如果是 mobile 监听这三个事件:
否则监听这几个:
在生命周期开始时候监听这几个事件:
其中
this.moveLoop
是:这里用到了 corutine.
首先当手指放到 item 上时, 记录位置
startX = e.touches[0].clientX;
.当手指滑动时获取此时的位置
e.changedTouches[0].clientX
, 减去初始位置deltaX = movedX - startX;
, 如果deltaX
小于0, 那么此时是左滑, 进行 UI 上的操作, 将上层div
左移deltaX
.当手指离开屏幕时候, 记录此时位置并获取与初始位置的差值
deltaX = endX - startX
, 判断deltaX
, 如果滑动距离太小(40px)或者向右滑, 那么就关掉展开的div
, 如果滑动距离够长, 那么就完全展开div
.布局
几个操作按钮是绝对布局被盖在 address-item 内容的下面, 当滑动或者展开时候 address-item 会左移
left
距离, 它是 relative 布局.为了让滑动有动效, 可以添加
transition: 'all 250ms'
.其他几个方法
小结
会不会手势滑动与点击冲突?
不会, 经过pc和手机(ios/android)尝试, 滑动时候不会触发 address-item 的选中, 并没发现会冲突, 除非你写
evt.preventDefault()
.如何实现点击空白关掉?
给
window
添加监听事件:在 PC 上表现良好, 但是在 mobile 上表现异常. 所以移到 TODO 里待解决.
TODO
参考
The text was updated successfully, but these errors were encountered: