Application of H5 dragging method in VUE

Keywords: Firefox IE Vue Windows

There are many pulling wheels on the Internet, but there are always some demands that the wheels can't meet. When the use of wheels can not meet their own needs, the use of H5 native dragging method has the following advantages:

  • api is rich and flexible to implement drag-and-drop requirements
  • It avoids the inconvenience of bug modification of wheel itself.

In order to make myself deeply understand the api, I simplified and implemented a drag-and-drop example in the vue project according to the requirement, which is also for your reference.

The requirements are as follows:

     

  • The left area field does not support sorting, but it can be dragged to the right to hierarchize, dimension, and contrast areas.
  • The left area field can also be dragged onto the first field that the dimension area has dragged, creating a hierarchical relationship that is displayed in the hierarchical area.
  • Fields dragged to dimensions and contrast areas support drag-and-drop exchanges, but cannot be dragged after the first field of a dimension generates a hierarchical relationship.
  • Fields in hierarchical areas do not support drag sorting

The code is as follows:

    //Part HTML
    <div style="margin-top: 100px;">
        <div class="drag-container">
            <p v-for="item in list"
               draggable="true"
               @dragstart="dragstart($event,item,'list')"
               @dragend="dragend($event,item)"
            >{{item.name}}</p>
        </div>
        <div class="drop-container">
            <p>Layered</p>
            <div class="drop-area" v-if="showLayer"
                @drop="drop($event,'layer')"
                @dragenter="dragenter"
                @dragover="dragover"
            >
                <p v-for="(item,index) in layer">
                    <span
                        draggable="true"
                        @dragstart="dragstart($event,item,'layer',index)"
                    >{{item.name}}</span>
                    <b v-if="index!=layer.length-1">-></b>
                </p>
            </div>
            <p>dimension</p>
            <div class="drop-area"
                 @drop="drop($event,'dimensions')"
                 @dragover="dragover">
                <span v-for="(item,index) in dimensions"
                      @drop="dropToItem($event,item)"
                      @dragover.prevent
                      draggable="true"
                      @dragstart="dragstart($event,item,'dimensions',index)"
                >{{item.name}}</span>
            </div>
            <p>Contrast</p>
            <div class="drop-area"
                 @drop="drop($event,'contrasts')"
                 @dragover="dragover">
                <span v-for="(item,index) in contrasts"
                      @dragover.prevent
                      draggable="true"
                      @dragstart="dragstart($event,item,'contrasts',index)"
                >{{item.name}}</span>
            </div>
        </div>
    </div><template>
    <div style="margin-top: 100px;">
        <div class="drag-container">
            <p v-for="item in list"
               draggable="true"
               @dragstart="dragstart($event,item,'list')"
               @dragend="dragend($event,item)"
            >{{item.name}}</p>
        </div>
        <div class="drop-container">
            <p>Layered</p>
            <div class="drop-area" v-if="showLayer"
                @drop="drop($event,'layer')"
                @dragenter="dragenter"
                @dragover="dragover"
            >
                <p v-for="(item,index) in layer">
                    <span
                        draggable="true"
                        @dragstart="dragstart($event,item,'layer',index)"
                    >{{item.name}}</span>
                    <b v-if="index!=layer.length-1">-></b>
                </p>
            </div>
            <p>dimension</p>
            <div class="drop-area"
                 @drop="drop($event,'dimensions')"
                 @dragover="dragover">
                <span v-for="(item,index) in dimensions"
                      @drop="dropToItem($event,item)"
                      @dragover.prevent
                      draggable="true"
                      @dragstart="dragstart($event,item,'dimensions',index)"
                >{{item.name}}</span>
            </div>
            <p>Contrast</p>
            <div class="drop-area"
                 @drop="drop($event,'contrasts')"
                 @dragover="dragover">
                <span v-for="(item,index) in contrasts"
                      @dragover.prevent
                      draggable="true"
                      @dragstart="dragstart($event,item,'contrasts',index)"
                >{{item.name}}</span>
            </div>
        </div>
    </div>
    //Part js
    export default {
        name: "drag",
        data(){
            return {
                dragItem:{},//Drag fields
                dragFrom:'',//Where does the drag start?
                dragIndex:'',//Index of dragged fields in an array
                dropIndex:'',//Index of fields put into place
                showLayer:false,//Whether to display layering
                isDropToItem:false,//Whether to drag to the dimension field for hierarchical operation
                layer:[],
                dimensions:[],
                contrasts:[],
                list:[
                    {
                        id:1,
                        name:'Full name'
                    },{
                        id:2,
                        name:'Gender'
                    },{
                        id:3,
                        name:'Age'
                    },{
                        id:4,
                        name:'Fraction'
                    }]
            }
        },
        methods:{
            //Drag and drop start
            dragstart(event,item,frm,index){
                console.log('------dragstart------')
                if(this.BrowserType().name == "FF"){
                    // Compatible with Firefox Browser, Firefox drag must carry data
                    console.log(event.dataTransfer.setData("imgInfo", event.target.id)); 
                }
                this.dragItem = item;
                this.dragFrom = frm;
                if(!isNaN(index)){
                    this.dragIndex = index;
                }
            },
            //Enter the drag area, trigger once when entering
            dragenter(event){
                console.log('------dragenter------')
            },
            //Triggered multiple times after entering the drag area
            dragover(event){
                event.preventDefault();
                var target = event.target;
                this.dropIndex = this.indexFn(target)
                var nodeName = target.nodeName;
                if(nodeName!='SPAN'){
                    this.dropIndex = -1;
                }
            },
            //Release the mouse to trigger after dragging
            drop(event,target){
                console.log('------drop------')
                var dragFrom = this.dragFrom;
                var dragItem = this.dragItem;
                var dragIndex = this.dragIndex;
                var dropIndex = this.dropIndex;
                if(this.isDropToItem){
                    return;
                }
                if(this.dragFrom == 'layer'){
                    this.layer.splice(dragIndex,1);
                }else if(this.dragFrom == 'dimensions'){
                    this.dimensions.splice(dragIndex,1);
                }else if(this.dragFrom == 'contrasts'){
                    this.contrasts.splice(dragIndex,1);
                }

                if(dragFrom == target && dropIndex>-1){
                    var targetArr = this[target];
                    targetArr.splice(dropIndex,0,dragItem);
                    return;
                }

                if(target == 'layer'){
                    this.layer.push(dragItem);
                }else if(target == 'dimensions'){
                    this.dimensions.push(dragItem);
                }else if(target == 'contrasts'){
                    this.contrasts.push(dragItem);
                }
            },
            //Triggered when dragged to the first field of the dimension
            dropToItem(event,item){
                console.log('------dropToItem------')
                if(this.dragFrom != 'list'){
                    this.isDropToItem = false
                    return;
                }else {
                    this.isDropToItem = true
                }
                if(this.showLayer){
                    this.layer.push(this.dragItem);
                }else{
                    this.showLayer = true;
                    this.layer.push(item);
                    this.layer.push(this.dragItem);
                }
            },
            //Triggered after the drag, whether or not the drag succeeded
            dragend(event,item){
                console.log('------dragend------')
                this.isDropToItem = false
            },
            //Determine the drag field so that it is used for sorting
            indexFn(el) {
                var index = 0;
                if (!el || !el.parentNode) {
                    return -1;
                }
                while (el && (el = el.previousElementSibling)) {
                    index++;
                }
                return index;
            },
            //Browser Judgment
            BrowserType(){
                var userAgent = navigator.userAgent; //Get the browser's userAgent string
                var isOpera = userAgent.indexOf("Opera") > -1; //Judging Opera Browser
                var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //Judging whether IE browser or not
                var isEdge = userAgent.indexOf("Windows NT 6.1; Trident/7.0;") > -1 && !isIE; //Edge Browser for IE
                var isFF = userAgent.indexOf("Firefox") > -1; //Determine whether Firefox browsers are available
                var isSafari = userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") == -1; //Determine whether Safari browser is available or not
                var isChrome = userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1; //Judging Chrome Browser

                if (isIE)
                {
                    var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
                    reIE.test(userAgent);
                    var fIEVersion = parseFloat(RegExp["$1"]);
                    return {name:"IE",num: fIEVersion};
                }//isIE end

                if (isFF) { return {name:"FF",num: "FF"};}
                if (isOpera) { return {name:"Opera",num: "Opera"};}
                if (isSafari) { return {name:"Safari",num: "Safari"};}
                if (isChrome) { return {name:"Chrome",num: "Chrome"};}
                if (isEdge) { return {name:"Edge",num: "Edge"};}
            }
        }
    }
/* css Part */
.drag-container{
    width: 100px;height: 500px;float: left; background-color: #BAB5F5;
    p{
        line-height: 40px; text-align: center; cursor: pointer;
    }
}
.drop-container{
    margin-left: 120px; float: left;height: 500px; width: 600px;
    p{
        color: #fff;line-height: 40px;
    }
    .drop-area{
        height: 80px; width: 600px; background-color: #4c72ff;padding: 10px;
        p{
            display: inline-block; margin: 0;
        }
        span{
            display: inline-block;min-width: 50px;line-height: 40px;margin-right: 5px;background-color: #5a3e99;text-align: center;cursor: pointer;
        }
    }
}

 

Posted by anita999 on Fri, 04 Oct 2019 08:59:00 -0700