Browse Source

fix: leftslip重写

yewenwen 5 years ago
parent
commit
a8960c3273

+ 194 - 0
src/packages/leftslip/backup.vue

@@ -0,0 +1,194 @@
+<template>
+    <div class="nut-leftslip">
+        <div class="nut-leftslip-item" ref="slipItem" :style="deleteSlider">
+            <div class="nut-leftslip-item-main" @touchstart="touchStart($event)" @touchmove="touchMove($event)"
+                @touchend="touchEnd($event)">
+                <slot name="slip-main"></slot>
+            </div>
+
+            <div class="nut-leftslip-item-btn">
+                <!-- <a @click.prevent="onlyDelClick($event)">删除</a> -->
+                <slot name="slipbtns">
+                    <a class="nut-delet-btn" @click.prevent="onlyDelClick($event)" v-if="onlyDelBtn">删除</a>
+                </slot>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+    export default {
+        name: 'nut-leftslip',
+        props: {
+            onlyDelBtn: {
+                type: Boolean,
+                default: false
+            },
+            btnSlipDel: {
+                type: Boolean,
+                default: false
+            }
+        },
+        data() {
+            return {
+                startX: 0,
+                startY: 0,
+                moveX: 0,
+                moveY: 0,
+                left: 0,
+                buttonWidth: 0,
+                disX: 0, //移动距离
+                deleteSlider: '', //滑动时的效果,使用v-bind:style="deleteSlider"
+                delBtnStyle: '' //单个删除键拖拽删除效果
+            };
+        },
+        mounted() {
+            this.$nextTick(() => {
+                if (this.onlyDelBtn) {
+                    return;
+                }
+                for (var slot of this.$slots.slipbtns) {
+                    this.buttonWidth = this.buttonWidth + slot.elm.offsetWidth;
+                }
+            });
+
+            window.addEventListener('scroll', this.handleScroll, true);
+        },
+        beforeDestroy() {
+            // 移除监听
+            window.removeEventListener('scroll', this.handleScroll, true);
+        },
+        methods: {
+            handleScroll() {
+                if (this.disX) {
+                    this.restSlide();
+                }
+            },
+            handleClick() {
+                this.restSlide();
+            },
+            onlyDelClick() {
+                //一键删除模式点击删除
+                this.$emit('oneDelete', this.$refs.slipItem);
+                this.restSlide();
+            },
+            touchStart(e) {
+                this.restSlide();
+                e = e || event;
+                //等于1时表示此时有只有一只手指在触摸屏幕
+                if (e.touches.length == 1) {
+                    this.startX = e.touches[0].clientX;
+                    this.startY = e.touches[0].clientY;
+                }
+            },
+            touchMove(e) {
+                e = e || event;
+                //获取当前滑动对象
+                let parentElement = e.currentTarget.parentElement;
+                //获取删除按钮的宽度,此宽度为滑块左滑的最大距离
+                let itemWd = this.$refs.slipItem.offsetWidth;
+                let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
+
+                if (e.touches.length == 1) {
+                    // 滑动时距离浏览器左侧实时距离
+                    this.moveY = e.touches[0].clientY;
+                    this.moveX = e.touches[0].clientX;
+                    if (Math.abs(this.moveY - this.startY) < 40) {
+                        //起始位置减去 实时的滑动的距离,得到手指实时偏移距离
+                        this.disX = this.startX - this.moveX;
+                        // console.log(this.disX);
+                        if (this.onlyDelBtn) {
+                            //单一删除,左滑一键删除
+                            if (this.disX < 0 || this.disX == 0) {
+                                this.deleteSlider = 'transform:translateX(0px)';
+                            }
+                            this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
+                            this.delBtnStyle = 'width:' + this.disX + 'px';
+                            parentElement.dataset.type = 1; //设置滑动展开隐藏标志位,左滑展开为1,右滑或复位为0
+                        } else {
+                            // 如果是向右滑动或者不滑动,不改变滑块的位置
+                            if (this.disX < wd / 4 || this.disX == 0) {
+                                this.deleteSlider = 'transform:translateX(0px)';
+                                parentElement.dataset.type = 0;
+                            } else if (this.disX > wd / 4) {
+                                parentElement.dataset.type = 1;
+                                this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
+                                // 最大也只能等于删除按钮宽度
+                                if (this.disX >= wd) {
+                                    // parentElement.dataset.type = 1;
+                                    if (wd >= itemWd) {
+                                        this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
+                                    } else {
+                                        this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            touchEnd(e) {
+                e = e || event;
+                let parentElement = e.currentTarget.parentElement;
+                let itemWd = this.$refs.slipItem.offsetWidth;
+                let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
+                if (e.changedTouches.length == 1) {
+                    let endY = e.changedTouches[0].clientY;
+                    if (Math.abs(this.startY - endY) < 40) {
+                        let endX = e.changedTouches[0].clientX;
+                        this.disX = this.startX - endX;
+                        // console.log('touchEndthis.disX:', this.disX);
+                        if (this.onlyDelBtn) {
+                            //单一按钮,左滑一键删除
+                            if (this.disX < 0 || this.disX == 0) {
+                                this.deleteSlider = 'transform:translateX(0px)';
+                                parentElement.dataset.type = 0;
+                            } else if (this.disX < itemWd - 20) {
+                                parentElement.dataset.type = 1;
+                                this.deleteSlider = 'transform:translateX(-50px);';
+                                this.delBtnStyle = ' width:0px;';
+                            } else {
+                                this.deleteSlider = 'transform:translateX(-' + itemWd + 'px);';
+                                this.delBtnStyle = ' width:' + itemWd + 'px;';
+                                parentElement.dataset.type = 1;
+                                this.onlyDelClick();
+                            }
+                        } else {
+                            //如果距离小于删除按钮的四分之一,强行回到起点
+
+                            if (this.disX < wd / 4) {
+                                parentElement.dataset.type = 0;
+                                this.deleteSlider = 'transform:translateX(0px)';
+                            } else {
+                                //大于一半 滑动到最大值
+                                parentElement.dataset.type = 1;
+                                if (wd >= itemWd) {
+                                    //按钮数不可超出整行宽度
+                                    this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
+                                } else {
+                                    this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
+                                }
+                            }
+                        }
+
+                        // console.log('touchEnd:dataset', parentElement.dataset.type);
+                    }
+                }
+            },
+            restSlide() {
+                let listItems = document.querySelectorAll('.nut-leftslip-item');
+
+                // 复位
+                for (let i = 0; i < listItems.length; i++) {
+                    listItems[i].style = 'transform:translateX(0' + 'px)';
+                    listItems[i].dataset.type = 0; //是否展开标志位默认0,左滑展开为1,右滑隐藏为0
+                }
+                if (this.onlyDelBtn) {
+                    let delBtns = document.querySelectorAll('.delbtn .trans');
+                    for (let j = 0; j < delBtns.length; j++) {
+                        delBtns[j].style = '';
+                    }
+                }
+            }
+        }
+    };
+</script>

File diff suppressed because it is too large
+ 104 - 90
src/packages/leftslip/demo.vue


+ 8 - 2
src/packages/leftslip/doc.md

@@ -24,7 +24,7 @@
 </div>
 ```
 
-### 单个按钮一键删除
+<!-- ### 单个按钮一键删除
 
 ```html
 <nut-leftslip onlyDelBtn @oneDelete="oneDel">
@@ -38,7 +38,7 @@ export default {
         par.remove();
     }
 };
-```
+``` -->
 
 ### 多个按钮
 
@@ -111,4 +111,10 @@ export default {
 | slip-main | 列表主内容自定义区域 | html    | -      |
 | slipbtns  | 左滑按钮自定义区域   | html    | -      |
 
+<!-- ## Prop
+
+| 字段 | 说明 | 类型 | 默认值
+|----- | ----- | ----- | ----- 
+| isClickClose | 点击不关闭 | Boolean | false -->
+
 

+ 4 - 4
src/packages/leftslip/leftslip.scss

@@ -5,11 +5,11 @@
         border-top: 1px solid #d8d8d8;
     }
     .slip-main {
-        padding: 10px;
+        padding: 15px 10px;
         position: relative;
         overflow: hidden;
         display: flex;
-        border-bottom: 1px solid #d8d8d8;
+        // border-bottom: 1px solid #d8d8d8;
         background: #fff;
     }
     .nut-leftslip-item {
@@ -40,7 +40,7 @@
             height: 100%;
         }
     }
-    .nut-delet-btn{
+    .nut-delet-btn {
         position: absolute;
         right: -50px;
         top: 0;
@@ -78,4 +78,4 @@
             text-align: center;
         }
     }
-}
+}

+ 72 - 113
src/packages/leftslip/leftslip.vue

@@ -1,15 +1,14 @@
 <template>
     <div class="nut-leftslip">
-        <div class="nut-leftslip-item" ref="slipItem" :style="deleteSlider">
+        <div class="nut-leftslip-item" ref="slipItem" :style="deleteSlider" :class="{'leftslip-open':isOpen}">
             <div class="nut-leftslip-item-main" @touchstart="touchStart($event)" @touchmove="touchMove($event)"
                 @touchend="touchEnd($event)">
                 <slot name="slip-main"></slot>
             </div>
 
-            <div class="nut-leftslip-item-btn">
-                <!-- <a @click.prevent="onlyDelClick($event)">删除</a> -->
+            <div class="nut-leftslip-item-btn" ref="right">
                 <slot name="slipbtns">
-                    <a class="nut-delet-btn" @click.prevent="onlyDelClick($event)" v-if="onlyDelBtn">删除</a>
+                    <!-- <a class="nut-delet-btn" @click.prevent="onlyDelClick($event)" v-if="onlyDelBtn">删除</a> -->
                 </slot>
             </div>
         </div>
@@ -26,7 +25,19 @@
             btnSlipDel: {
                 type: Boolean,
                 default: false
-            }
+            },
+            isMainSlide: {
+                type: Boolean,
+                default: true
+            },
+            isClickBack: {
+                type: Boolean,
+                default: true
+            },
+            // rightWidth: {
+            //     type: [Number, String],
+            //     default: 30
+            // }
         },
         data() {
             return {
@@ -38,7 +49,13 @@
                 buttonWidth: 0,
                 disX: 0, //移动距离
                 deleteSlider: '', //滑动时的效果,使用v-bind:style="deleteSlider"
-                delBtnStyle: '' //单个删除键拖拽删除效果
+                delBtnStyle: '', //单个删除键拖拽删除效果
+
+                pageWidth: null,
+                originalPos: 0,
+                originalLeft: 0,
+                oriRigWidth: 0,
+                isOpen: false,
             };
         },
         mounted() {
@@ -50,144 +67,86 @@
                     this.buttonWidth = this.buttonWidth + slot.elm.offsetWidth;
                 }
             });
+            this.pageWidth = document.documentElement.clientWidth
+            this.sliderEle = this.isMainSlide ? this.$refs.slipItem : this.$refs.right
 
-            window.addEventListener('scroll', this.handleScroll, true);
+            document.addEventListener('touchstart', this.handleRestet, false);
+            // window.addEventListener('scroll', this.handleRestet, true);
         },
         beforeDestroy() {
             // 移除监听
-            window.removeEventListener('scroll', this.handleScroll, true);
+            window.removeEventListener('touchstart', this.handleRestet, true);
         },
         methods: {
-            handleScroll() {
-                if (this.disX) {
+            handleRestet() {
+                var slip = document.getElementsByClassName('leftslip-open');
+                if (slip) {
                     this.restSlide();
                 }
             },
-            handleClick() {
-                this.restSlide();
-            },
             onlyDelClick() {
                 //一键删除模式点击删除
                 this.$emit('oneDelete', this.$refs.slipItem);
                 this.restSlide();
             },
             touchStart(e) {
-                this.restSlide();
-                e = e || event;
-                //等于1时表示此时有只有一只手指在触摸屏幕
-                if (e.touches.length == 1) {
-                    this.startX = e.touches[0].clientX;
-                    this.startY = e.touches[0].clientY;
-                }
+
+                this.originalPos = e.touches[0].pageX
+                const transform = this.sliderEle.style.transform
+                this.originalLeft = Number(transform ? transform.split('(')[1].split('px')[0] : 0)
+                this.oriRigWidth = this.originalLeft < 0 ? Number(this.$refs.right.style.width.split('px')[0]) : 0;
+                // console.log('startoleft2', this.sliderEle.style.transform, this.originalLeft, this.oriRigWidth)
             },
-            touchMove(e) {
-                e = e || event;
-                //获取当前滑动对象
-                let parentElement = e.currentTarget.parentElement;
-                //获取删除按钮的宽度,此宽度为滑块左滑的最大距离
-                let itemWd = this.$refs.slipItem.offsetWidth;
-                let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
 
-                if (e.touches.length == 1) {
-                    // 滑动时距离浏览器左侧实时距离
-                    this.moveY = e.touches[0].clientY;
-                    this.moveX = e.touches[0].clientX;
-                    if (Math.abs(this.moveY - this.startY) < 40) {
-                        //起始位置减去 实时的滑动的距离,得到手指实时偏移距离
-                        this.disX = this.startX - this.moveX;
-                        // console.log(this.disX);
-                        if (this.onlyDelBtn) {
-                            //单一删除,左滑一键删除
-                            if (this.disX < 0 || this.disX == 0) {
-                                this.deleteSlider = 'transform:translateX(0px)';
-                            }
-                            this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
-                            this.delBtnStyle = 'width:' + this.disX + 'px';
-                            parentElement.dataset.type = 1; //设置滑动展开隐藏标志位,左滑展开为1,右滑或复位为0
-                        } else {
-                            // 如果是向右滑动或者不滑动,不改变滑块的位置
-                            if (this.disX < wd / 4 || this.disX == 0) {
-                                this.deleteSlider = 'transform:translateX(0px)';
-                                parentElement.dataset.type = 0;
-                            } else if (this.disX > wd / 4) {
-                                parentElement.dataset.type = 1;
-                                this.deleteSlider = 'transform:translateX(-' + this.disX + 'px)';
-                                // 最大也只能等于删除按钮宽度
-                                if (this.disX >= wd) {
-                                    // parentElement.dataset.type = 1;
-                                    if (wd >= itemWd) {
-                                        this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
-                                    } else {
-                                        this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
-                                    }
-                                }
-                            }
-                        }
-                    }
+            touchMove(e) {
+                let moveDistance = e.touches[0].pageX - this.originalPos // >0 右滑,<0 左滑
+                if (moveDistance > 0 && this.originalLeft >= 0) { // 未向左边滑动时,不能右滑
+                    return false
                 }
+                this.doSlide(moveDistance / 2 + this.originalLeft) // 除以2来控制滑动速度
+
             },
             touchEnd(e) {
-                e = e || event;
-                let parentElement = e.currentTarget.parentElement;
-                let itemWd = this.$refs.slipItem.offsetWidth;
-                let wd = this.onlyDelBtn ? 40 : this.buttonWidth;
-                if (e.changedTouches.length == 1) {
-                    let endY = e.changedTouches[0].clientY;
-                    if (Math.abs(this.startY - endY) < 40) {
-                        let endX = e.changedTouches[0].clientX;
-                        this.disX = this.startX - endX;
-                        // console.log('touchEndthis.disX:', this.disX);
-                        if (this.onlyDelBtn) {
-                            //单一按钮,左滑一键删除
-                            if (this.disX < 0 || this.disX == 0) {
-                                this.deleteSlider = 'transform:translateX(0px)';
-                                parentElement.dataset.type = 0;
-                            } else if (this.disX < itemWd - 20) {
-                                parentElement.dataset.type = 1;
-                                this.deleteSlider = 'transform:translateX(-50px);';
-                                this.delBtnStyle = ' width:0px;';
-                            } else {
-                                this.deleteSlider = 'transform:translateX(-' + itemWd + 'px);';
-                                this.delBtnStyle = ' width:' + itemWd + 'px;';
-                                parentElement.dataset.type = 1;
-                                this.onlyDelClick();
-                            }
-                        } else {
-                            //如果距离小于删除按钮的四分之一,强行回到起点
+                // console.log('end')
+                const moveDistance = e.changedTouches[0].pageX - this.originalPos // >0 右滑,<0 左滑
+                let distance
+                if (!this.isClickBack && moveDistance === 0) { // 点击时不收起右侧
+                    return false
+                }
+                if ((-moveDistance) > 50) { // 向左滑动超过阙值时,右侧滑出固定距离
+                    distance = this.buttonWidth > this.pageWidth ? this.pageWidth * 0.8 : this.buttonWidth;
+                } else { // 向左滑动未超过阙值,或向右滑动时,回原位
+                    distance = 0
+                }
+                this.doSlide(-distance, true)
+                this.isOpen = true;
+                if ((-moveDistance) > 0) {
 
-                            if (this.disX < wd / 4) {
-                                parentElement.dataset.type = 0;
-                                this.deleteSlider = 'transform:translateX(0px)';
-                            } else {
-                                //大于一半 滑动到最大值
-                                parentElement.dataset.type = 1;
-                                if (wd >= itemWd) {
-                                    //按钮数不可超出整行宽度
-                                    this.deleteSlider = 'transform:translateX(-' + (itemWd - 40) + 'px)';
-                                } else {
-                                    this.deleteSlider = 'transform:translateX(-' + wd + 'px)';
-                                }
-                            }
-                        }
+                }
+                // console.log('touchEnd', distance);
+            },
 
-                        // console.log('touchEnd:dataset', parentElement.dataset.type);
-                    }
+            doSlide(distance, animate = false) {
+                this.sliderEle.style.transform = `translateX(${distance}px)`
+                this.$refs.right.style.width = -distance + 'px'
+                if (this.isMainSlide) {
+                    this.sliderEle.style.transition = animate ? 'transform .5s' : 'initial'
+                    this.$refs.right.style.transition = animate ? 'width .5s' : 'initial'
+                } else {
+                    this.sliderEle.style.transition = animate ? 'transform .5s, width .5s' : 'initial'
                 }
             },
+
             restSlide() {
-                let listItems = document.querySelectorAll('.nut-leftslip-item');
+                let listItems = document.querySelectorAll('.nut-leftslip-item.leftslip-open');
 
                 // 复位
                 for (let i = 0; i < listItems.length; i++) {
                     listItems[i].style = 'transform:translateX(0' + 'px)';
                     listItems[i].dataset.type = 0; //是否展开标志位默认0,左滑展开为1,右滑隐藏为0
+                    this.isOpen = false;
                 }
-                if (this.onlyDelBtn) {
-                    let delBtns = document.querySelectorAll('.delbtn .trans');
-                    for (let j = 0; j < delBtns.length; j++) {
-                        delBtns[j].style = '';
-                    }
-                }
+
             }
         }
     };