可以拖拽, 靠边停靠, 效果图如下
代码如下:
注意: 代码中使用的图片未上传
DragAndDrop 组件:
- <template>
- <div class="drag" id="moveDiv"
- @mousedown="start($event)" @touchstart="start($event)"
- @mousemove="move($event)" @touchmove="move($event)"
- @mouseup="end($event)" @touchend="end($event)">
- <slot name="drag-cont"></slot>
- <div id="optionBall"></div>
- <div id="optionContent" v-show="optionContentShow">
- <span class="imgWrap" @click="gatewayOption" v-bind:style="{backgroundColor : this.$parent.whichOption?'#ff5b45':'#ffffff'}">
- <img v-bind:src="this.$parent.whichOption?require('../assets/img/SmartGateway_write.png'):require('../assets/img/SmartGateway.png')" width="24px" height="24px">
- </span>
- <span class="imgWrap" @click="alertOption" v-bind:style="{backgroundColor : !this.$parent.whichOption?'#ff5b45':'#ffffff'}">
- <img v-bind:src="!this.$parent.whichOption?require('../assets/img/alert_write.png'):require('../assets/img/alert.png')" width="24px" height="24px">
- </span>
- </div>
- </div><!--E 拖动组件 -->
- </template>
- <script>
- export default {
- name: "dragAndDrop",
- data() {
- return {
- position: {x: 0,y: 0}, // 鼠标点击的 x 轴和 y 轴的距离
- nx: '', // 鼠标当前距离元素的左侧距离
- ny: '', // 鼠标当前距离元素的顶部距离
- dx: '', // 元素距离左侧的距离
- dy: '', // 元素距离顶部的距离
- xPum: '', // 元素移动的 x 轴距离
- yPum: '', // 元素移动的 y 轴距离
- optionContentShow: true
- };
- },
- methods: {
- start(e){
- // 如果 touches 存在就说明是移动端
- // 否则为 pc 端直接获取事件源对象
- let touch = e.touches? e.touches[0] : e;
- this.position.x = touch.clientX;
- this.position.y = touch.clientY;
- this.dx = moveDiv.offsetLeft;
- this.dy = moveDiv.offsetTop;
- this.optionContentShow = true;
- },
- move(e){
- this.isDrop = true;
- if(this.isDrop){
- let touch = e.touches? e.touches[0] : e;
- this.nx = touch.clientX - this.position.x;
- this.ny = touch.clientY - this.position.y;
- this.xPum = this.dx+this.nx;
- this.yPum = this.dy+this.ny;
- moveDiv.style.left = this.xPum + "px";
- moveDiv.style.top = this.yPum + "px";
- document.addEventListener("touchmove",function(){
- event.preventDefault();
- },false);
- if(e.preventDefault){
- e.preventDefault();
- }else{
- Windows.event.returnValue == false;
- }
- }
- },
- end(e){
- let oWidth = moveDiv.offsetWidth; // Element Width
- let oWrapWidth = moveDiv.parentNode.offsetWidth; // Parent Element Width
- let oWrprapHeight = moveDiv.parentNode.offsetHeight; // Parent Element Height
- let sumWidth = moveDiv.offsetLeft + oWidth; // Element Left + Element Width
- let sumHeight = moveDiv.offsetTop + moveDiv.offsetHeight; // Element Top + Element Height
- // The Limit Deal
- if(moveDiv.offsetLeft <0) {
- moveDiv.style.left = 0;
- this.optionContentShow = false;
- moveDiv.style.left = "-30px";
- } else if(sumWidth> oWrapWidth){
- moveDiv.style.left = oWrapWidth - oWidth + 'px';
- // console.log("到最右边了");
- this.optionContentShow = false;
- moveDiv.style.left = "-30px";
- } else if(moveDiv.offsetTop <0) {
- moveDiv.style.top = 0;
- } else if(sumHeight> oWrprapHeight) {
- moveDiv.style.top = oWrprapHeight - moveDiv.offsetHeight + 'px';
- }
- document.onmousemove = null;
- document.onmouseup = null;
- },
- gatewayOption: function () {
- this.$parent.gatewayOption();
- },
- alertOption: function () {
- this.$parent.alertOption();
- },
- }
- };
- </script>
- <style scoped>
- .drag {
- width: 160px;
- height: 60px;
- position: absolute;
- left: 40px;
- bottom: 60px;
- z-index: 999;
- }
- #optionBall {
- width: 56px;
- height: 56px;
- position: absolute;
- background-color: #ff5b45;
- border-radius: 56px;
- z-index: 20;
- }
- #optionContent {
- width: 130px;
- height: 50px;
- background-color: #ff956b;
- position: absolute;
- left: 20px;
- margin-top: 3px;
- border-radius: 50px;
- z-index: 10;
- padding: 6px 0 6px 34px;
- box-sizing: border-box;
- }
- .imgWrap {
- display: inline-block;
- width: 38px;
- height: 38px;
- background-color: #ffffff;
- border-radius: 40px;
- padding: 8px;
- box-sizing: border-box;
- }
- .checked {
- background-color: #ff5b45;
- }
- </style>
父组件: subDevice.vue
- <template>
- <DragAndDrop></DragAndDrop>
- </template>
- <script>
- import DragAndDrop from "./DragAndDrop";
- export default {
- name: "subDevice",
- components: {DragAndDrop,InfiniteScroll},
- data() {
- return {
- whichOption: true
- }
- },
- methods:{
- gatewayOption: function () {
- this.whichOption = true;
- },
- alertOption: function () {
- this.whichOption = false;
- }
- }
- }
- </script>
来源: http://www.bubuko.com/infodetail-3355499.html