Показать исходную позицию div, когда пользователь перемещает div по странице - PullRequest
0 голосов
/ 23 октября 2019

У меня есть сортируемый список.

Когда пользователь перетаскивает элемент списка, я хотел бы стилизовать исходную позицию элемента, пока пользователь не перестанет перетаскивать.

В соответствии с этим: enter image description here

В этом случае в списке есть рамка вокруг пустого пространства, указывающая исходное положение «Польской весны».

Моя первоначальная идея заключалась в том, чтобы поместить контейнер div непосредственно за каждым элементом li. Однако, чтобы это работало, контейнерный div должен быть position:relative, а элементы li должны быть position:absolute, но для целей списка li элементы должны быть position:relative.

Вот мой соответствующий код:

import styled from '@emotion/styled';

const App = styled('div')`
    font-family: sans-serif;
    font-size: 1.5rem;
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;

    ul {
        margin: 0;
        padding: 0;
        list-style: none; !important
    }

    ul li {
        background-color: #D3D3D3;
        padding: 10px 20px;
        position: relative;
        //the line below does not work
        //position: absolute;
        display: flex;
        line-height: 1;
        list-style-type: none;
        border-style: solid;
        margin-top:10px;
        cursor: pointer 

    }
`;
const Container = styled('div')`
    background: red;
    border-color: coral;
    position: relative;
`;
class DragDropList extends React.Component {
*/ ....*/
onDragStart = (e, index) => {
        this.draggedItem = this.state.items[index];
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/html', e.target.parentNode);
        //e.dataTransfer.setDragImage(e.target.parentNode, 20, 20);
    };

    onDragOver = index => {
        const draggedOverItem = this.state.items[index];

        // if the item is dragged over itself, ignore
        if (this.draggedItem === draggedOverItem) {
            return;
        }

        // filter out the currently dragged item
        let order = this.state.order.filter(item => item !== this.draggedItem);

        // add the dragged item after the dragged over item
        order.splice(index, 0, this.draggedItem);

        this.setState({ order });
    };

    onDragEnd = index => {
        this.draggedIdx = null;
        // filter out the currently dragged item
        let items = this.state.order;
        this.setState({ items });
    };

    render() {
        return (
            <App>
                <main>
                    <ul>
                        {this.state.items.map((item, idx) => (
                            <div>
                                <Container>
                                    <li
                                        key={item + `idx`}
                                        onDragOver={() => this.onDragOver(idx)}
                                        draggable
                                        onDragStart={e =>
                                            this.onDragStart(e, idx)
                                        }
                                        onDragEnd={() => this.onDragEnd(idx)}
                                    >
                                        <div
                                            draggable
                                            onDragStart={e =>
                                                this.onDragStart(e, idx)
                                            }
                                            onDragEnd={() =>
                                                this.onDragEnd(idx)
                                            }
                                        >
                                            <span
                                                className="content"
                                                style={{ cursor: 'pointer' }}
                                            >
                                                {item}
                                            </span>
                                        </div>
                                    </li>
                                </Container>
                            </div>
                        ))}
                    </ul>
                </main>
            </App>
        );
    }
}

Вот песочница: https://codesandbox.io/s/black-dust-hqm2t?fontsize=14

1 Ответ

2 голосов
/ 23 октября 2019

Не уверен, что это лучший способ сделать это, но я изменил CSS перетаскиваемого элемента, сохранив перетаскиваемый индекс в состоянии и добавив простое условие для изменения className, если оно соответствует перетаскиваемому индексу. Для достижения точного эффекта, который вы разместили, может потребоваться немного больше хитрости CSS или другого условного рендеринга, но это должно охватывать основные функции.

Разветвленная песочница .

...