可拖動模組控制元件

mazhenxiao發表於2019-01-02

可拖動模組控制元件


/**
 * @name 移動模組
 * @class move
 * @template  {el:移動模組class,parent:"移動模組id"}
 *  new Move({
      el: "RCBlock", //className
     parent: "RContainer" //id
     }); //獲取頁面
 */
class move { 
    constructor({ el = "", parent = "" }) {
        
         this.move = false;
        this.tar = "";
        this.x=this.y=this.width=this.height=this.left=this.top=this.pleft=this.ptop,this.pwidth,this.pheight=0;
        this.className = el;
        this.Z = document.createElement("div");
        this.Z.className = "Z";
        this.opt = [];
        this.dom = null;
        this.parent = document.querySelector("#"+parent);
        this.init();
        this.setT = null;
        this.time = 0;
        this.titleHeight = 35;
        this.checkd = true;
        this.setT2 = null;
    }
    init() { 
    
        if (!this.parent || !this.className) {
            console.log("引數錯誤");
            return
        }
        
        document.addEventListener("mousemove", this.mousemove.bind(this), false);
        document.addEventListener("mousedown", this.mousedown.bind(this), false);
        document.addEventListener("mouseup", this.mouseup.bind(this), false);

    }
    find(el) { 
        if (!el||el == document) { console.log("檢查點選元素是否為類明,或該類是否存在");return null}
        if ((el.className || "").includes(this.className)) {
            return el;
        } else if (el.parentNode) { 
           return this.find(el.parentNode)
        }
    }
 
    mousedown(event) {
        
        if (event.button > 0||!this.checkd) { return }
        this.tar = this.find(event.target);
        
        if (!this.tar || event.layerY >= this.titleHeight) {
            return
        }
       
        this.tar.classList.add("moveActive");
        let self = this.tar.getBoundingClientRect();
        let pa = this.parent.getBoundingClientRect();
        this.move = true;
        this.left = self.left;
        this.top = self.top;
        this.x = event.layerX;
        this.y = event.layerY;
        this.width = self.width;
        this.height = self.height;
        this.pwidth = pa.width;
        this.pheight = pa.height;
        this.pleft = pa.left;
        this.ptop = pa.top;
        this.parent.classList.add("active");

        Object.assign(this.tar.style, {
            position: "fixed",
            left:this.left+"px",
            top:this.top+"px",
            width:this.width+"px",
            height: this.height + "px",
            zIndex: 100
        })
        //this.parent.appendChild(this.Z);
        Object.assign(this.Z.style, { width: this.width + "px", height: this.height + "px" });
        this.tar.before(this.Z);
          this.resetXY();
    }
    mousemove(event) {
        if (!this.move) { return }
        let x = event.pageX, y = event.pageY;
        x = x - window.scrollX-this.x;
        y = y - window.scrollY-this.y;
        Object.assign(this.tar.style, {
            left: x + "px",
            top: y + "px"
        });
        this.EventMove(x, y);
        
    }
    mouseup(event) {
        if (!this.move) { return}
        this.move = false;
        this.tar.removeAttribute("style");
        this.parent.classList.remove("active");
        this.tar.classList.remove("moveActive");
        this.parent.replaceChild(this.tar, this.Z);
        //this.parent.removeChild(this.Z);
        this.resetXY();
    }
    EventMove(x, y) {
        if (!this.checkd) { return false}
        let th = this;
        let { left, top } = this.tar.getBoundingClientRect();
        let l = left - this.pleft;
        let t = top - this.ptop;
        let first, last,currentLast = false;
       // console.log(this.opt);
       let current =  this.opt.filter(d => { 
            let startx = d.left, endx = startx + d.width;
           let starty = d.top, endy = starty + d.height;
           
          // console.log(l + ":" + startx + "||" + l + ":" + endx);
           if (l > startx && l < endx && t > starty && t < endy) {
               first = last = false;
               return true
           }
            return false;
       })[0]
      
        
        if (!current) { return }
       // console.log(current);
        //設定是否一個元素
        if (current.el.previousSibling == null) {
           
            first = true;
            last = false;
        } else if (current.el.nextSibling == null) { 
        //設定是否最後一個元素
            first = false;
            last = true;
        }
        
        //設定惰性替換選中
        if (this.setT) {
            clearTimeout(this.setT)
        }
         
        this.setT = setTimeout(() => {
            if (first) {
                this.parent.prepend(this.Z);
                 this.writerXY();
            } else if (last) {
                this.parent.append(this.Z);
                 this.writerXY();
            } else{ 
                let node = current.el.nextSibling;
                
                if (node && node.className.includes(this.className)) {
                    this.parent.insertBefore(this.Z, node);
                    this.writerXY();
                } else { 
                    let node = current.el.previousSibling;
                    this.parent.insertBefore(node,this.Z);
                }
                
                
            }
            
        },this.time)
      

    }
    sibling() { 
        return this.parent.childNodes.map(d => {
            if (d.n.nodeType === 1) {
                return d;
            }
        });
         

    }
    /**
     *@name 初始化位置
     */
    resetXY() { 
        this.opt = [];
        this.parent.childNodes.forEach((el, ind) => {
            if (el.className != this.className||el.nodeType!==1) { return}
            let { left, top,width,height } = el.getBoundingClientRect();
            this.opt.push({ id: ind, el, left:left-this.pleft, top:top-this.ptop,width,height });
        });
       // console.log(this.opt);
    }

    /**
     *@name 位置重定向
     */
    writerXY() { 
        this.opt = this.opt.map(d => { 
            let { left, top, width, height } = d.el.getBoundingClientRect();
            Object.assign(d, {
                left: left - this.pleft,
                top: top - this.ptop,
                width, height
            })
            return d;
        })
        let self = this;
        self.checkd = true;
        // if (this.setT2) {
        //     clearTimeout(this.setT2)
        // }
        // this.setT2 = setTimeout(() => {
        //     self.checkd = true
        // })
    }
}
export default move;
複製程式碼

相關文章