拖拽列表

2022-03-12  本文已影响0人  苍老师的眼泪
drag.gif
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        .wrapper {
            width: 200px;
            box-sizing: border-box;
            margin: 10px 0;
            height: 50px;
            overflow: hidden;
        }

        [draggable="true"] {
            height: 50px;
            background-color: coral;
        }
    </style>

</head>

<body>
    <div id="test">
        <div class="wrapper">
            <div draggable="true">A</div>
        </div>
        <div class="wrapper">
            <div draggable="true">B</div>
        </div>
        <div class="wrapper">
            <div draggable="true">C</div>
        </div>
        <div class="wrapper">
            <div draggable="true">D</div>
        </div>
    </div>

    <script>
        var dragged

        function show_wrapper(target) {
            target.parentNode.style.border = "thick dashed gray"
        }

        function hidden_wrapper(target) {
            target.parentNode.style.border = ""
        }

        function set_draging_target(target) {
            target.style.opacity = '0.5'
        }

        function restore_draging_target(target) {
            target.style.opacity = ''
        }

        var created_wrapper = null

        function delete_created_wrapper() {
            if (created_wrapper && created_wrapper.childNodes.length == 0 && created_wrapper.parentNode) {
                created_wrapper.parentNode.removeChild(created_wrapper)
            }
        }

        function create_wrapper() {

            delete_created_wrapper()

            var wrapper = document.createElement('div')
            wrapper.className = 'wrapper'

            wrapper.style.border = "thick dashed gray"

            return wrapper
        }

        function isFrontOf(a, b) {
            if (a == null || b == null)
                return false

            if (a.nextSibling == b)
                return true

            return isFrontOf(a.nextSibling, b)
        }

        function isBehindOf(a, b) {

            if (a == null || b == null)
                return false

            if (a.previousSibling == b)
                return true

            return isBehindOf(a.previousSibling, b)
        }

        function pSibling(a, b) {
            if (b == null || b.previousSibling == null)
                return false

            if (a == b.previousSibling)
                return true

            if (b.previousSibling.nodeName == 'DIV')
                return false

            return pSibling(a, b.previousSibling)
        }

        function nSibling(a, b) {
            if (b == null || b.nextSibling == null)
                return false

            if (a == b.nextSibling)
                return true

            if (b.nextSibling.nodeName == 'DIV')
                return false

            return nSibling(a, b.nextSibling)
        }


        document.addEventListener("dragend", function (event) {

            restore_draging_target(dragged)
            hidden_wrapper(dragged)

        }, false);

        document.addEventListener('dragstart', event => {
            dragged = event.target

            set_draging_target(dragged)
            show_wrapper(dragged)

        })

        document.addEventListener('dragleave', event => {
            event.preventDefault()

            var leaved = event.target

            if (leaved == dragged || leaved == dragged.parentNode)
                return




        })

        document.addEventListener("dragover", function (event) {
            event.preventDefault();

            var dropped = event.target

            if (dragged == dropped)
                return

            if (!dropped.draggable)
                return

            var target_height = dropped.getBoundingClientRect().height

            var over_top_part = event.offsetY < target_height / 2
            var over_bottom_part = event.offsetY >= target_height / 2

            // 拖拽到下一个item的上半部分时
            if (pSibling(dragged.parentNode, dropped.parentNode))
                if (over_top_part) {
                    
                    return
                }

            // 拖拽到上一个item的下半部分时
            if (nSibling(dragged.parentNode, dropped.parentNode))
                if (over_bottom_part) {
                    
                    return
                }

            if (over_top_part) {

                var new_wrapper = create_wrapper()

                dropped.parentNode.parentNode.insertBefore(new_wrapper, dropped.parentNode)

                created_wrapper = new_wrapper

                
                dragged.parentNode.style.display = "none"
            }

            if (over_bottom_part) {

                var new_wrapper = create_wrapper()

                dropped.parentNode.parentNode.insertBefore(new_wrapper, dropped.parentNode.nextSibling)

                created_wrapper = new_wrapper


                dragged.parentNode.style.display = "none"
            }



        }, false)

        document.addEventListener("drop", function (event) {

            event.preventDefault();

            var dropped = event.target

            if (dropped == dragged)
                return

            if (created_wrapper && created_wrapper.parentNode) {

                dragged.parentNode.parentNode.removeChild(dragged.parentNode)

                created_wrapper.appendChild(dragged)

                created_wrapper = null

                return
            }

            if (dropped.className.indexOf('wrapper') == -1) {
                delete_created_wrapper()
                dragged.parentNode.style.display = ""
                return
            }


            var target_height = dropped.getBoundingClientRect().height


            var over_top_part = event.offsetY < target_height / 2
            var over_bottom_part = event.offsetY >= target_height / 2

            // 放置到下一个item的上半部分时
            if (pSibling(dragged.parentNode, dropped.parentNode))
                if (over_top_part) {
                    console.log('1')
                    return
                }

            // 放置到上一个item的下半部分时
            if (nSibling(dragged.parentNode, dropped.parentNode))
                if (over_bottom_part) {
                    console.log('2')
                    return
                }

            // 先移除原先位置的元素

            dragged.parentNode.parentNode.removeChild(dragged.parentNode)

            dropped.appendChild(dragged)

        }, false);

        document.addEventListener('dragenter', event => {
            event.preventDefault()

        })
    </script>
</body>

</html>
上一篇 下一篇

猜你喜欢

热点阅读