HTML5 Drag and Drop - No transparency?

后端 未结 12 1895
青春惊慌失措
青春惊慌失措 2020-12-05 02:00

When I drag and drop an element on my page the element becomes \"ghosted\". Basically it gets some transparency value.

Is there some way to make it opacity: 1;

12条回答
  •  一个人的身影
    2020-12-05 02:27

    As others have suggested, you will need some sort of mechanism that will:

    1. Hide the element that is being dragged.
    2. Make a clone of the element that is being dragged.
    3. Put the clone in place of the element that is being dragged.
    4. Listen to the drag event to position the clone element.

    In practise, looks like this:

    function Drag (subject) {
        var dative = this,
            handle,
            dragClickOffsetX,
            dragClickOffsetY,
            lastDragX,
            lastDragY;
    
        subject.draggable = true;
    
        dative.styleHandle(subject);
    
        subject.addEventListener('dragstart', function (e) {    
            handle = dative.makeHandle(subject);
    
            dragClickOffsetX = e.layerX;
            dragClickOffsetY = e.layerY;
    
            this.style.opacity = 0;
        });
    
        subject.addEventListener('drag', function (e) {
            var useX = e.x,
                useY = e.y;
    
            // Odd glitch
            if (useX === 0 && useY === 0) {
                useX = lastDragX;
                useY = lastDragY;
            }
    
            if (useX === lastDragX && useY === lastDragY) {
                return;
            }
    
            dative.translate(useX - dragClickOffsetX, useY - dragClickOffsetY, handle, subject);
    
            lastDragX = useX;
            lastDragY = useY;
        });
    
        subject.addEventListener('dragend', function (e) {
            this.style.opacity = 1;
    
            handle.parentNode.removeChild(handle);
        });
    };
    
    /**
     * Prevent the text contents of the handle element from being selected.
     */
    Drag.prototype.styleHandle = function (node) {
        node.style['userSelect'] = 'none';
    };
    
    /**
     * @param {HTMLElement} subject
     * @return {HTMLElement}
     */
    Drag.prototype.makeHandle = function (subject) {
        return this.makeClone(subject);
    };
    
    /**
     * Clone node.
     * 
     * @param {HTMLElement} node
     * @return {HTMLElement}
     */
    Drag.prototype.makeClone = function (node) {
        var clone;
    
        clone = node.cloneNode(true);
    
        this.styleClone(clone, node.offsetWidth, node.offsetHeight);
    
        node.parentNode.insertBefore(clone, node);
    
        return clone;
    };
    
    /**
     * Make clone width and height static.
     * Take clone out of the element flow.
     *
     * @param {HTMLElement} node
     * @param {Number} width
     * @param {Nubmer} height
     */
    Drag.prototype.styleClone = function (node, width, height) {
        node.style.position = 'fixed';
        node.style.zIndex = 9999;
        node.style.width = width + 'px';
        node.style.height = height + 'px';
        node.style.left = '-9999px';
    
        node.style.margin = 0;
        node.style.padding = 0;
    };
    
    /**
     * Used to position the handle element.
     * 
     * @param {Number} x
     * @param {Number} y
     * @param {HTMLElement} handle
     * @parma {HTMLElement} subject
     */
    Drag.prototype.translate = function (x, y, handle, subject) {
        handle.style.left = x + 'px';
        handle.style.top = y + 'px';
    };
    

    Start with attaching an element:

    new Drag(document.querySelector('.element'));
    

    And you have a working drag and drop with full control over the looks of the draggable element. In the above example, I clone the original element to use it as the handle. You can extend the Drag function to customise the handle (e.g. use image to represent the draggable element).

    Before you get too excited, there are couple of things to consider:

    • WHATWG Drag and Drop does not work with mobile, HTML5 Drag & Drop for Mobile
    • There is no way to capture the "handle release" event, See the link for the solution: How to get mouseup event after native drag event?.

    Update:

    I have written a library for touch enabled implementation of WHATWG drag and drop mechanism, https://github.com/gajus/pan.

提交回复
热议问题