Странное поведение перетаскивания div

#javascript #html

#javascript #HTML

Вопрос:

Я пытаюсь выполнить многократное div перетаскивание, которое может динамически добавлять больше divs или удалять некоторые.

В первый раз это работает просто отлично, но если я попытаюсь запустить функцию снова, она ведет себя странно.

  • Он перемещается путем перетаскивания в любом месте, а не только в заголовке, как раньше.
  • Все перемещения выполняются до последнего div.
  • Больше не могу писать в текстовой области.

 var applyDrag = () => {
    Array.prototype.slice.call(document.querySelectorAll(".contentCon")).forEach(e=>{
        
        e.querySelector("h1").onmousedown = null;
        dragElement(e);
        console.log(e.querySelector("h1").innerText);
    });
}

applyDrag();

var moveRoom = document.querySelector(".mainCon");

function dragElement(elmnt) {
    elmnt.style.background = "blue";   
    var dragEl = elmnt.querySelector("h1");
    dragEl.style.cursor = "move";
    console.log(dragEl.innerText);
    var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    if (moveRoom) {
        moveRoom.onmousedown = dragMouseDown;
    } else {
        dragEl.onmousedown = dragMouseDown;
    }

    function dragMouseDown(e) {
        console.log(dragEl);
        e = e || window.event;
        e.preventDefault();
        pos3 = e.clientX;
        pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        document.onmousemove = elementDrag;
    }

    function elementDrag(e) {
        e = e || window.event;
        e.preventDefault();
        pos1 = pos3 - e.clientX;
        pos2 = pos4 - e.clientY;
        pos3 = e.clientX;
        pos4 = e.clientY;
        elmnt.style.top = (elmnt.offsetTop - pos2)   "px";
        elmnt.style.left = (elmnt.offsetLeft - pos1)   "px";
    }

    function closeDragElement() {
        document.onmouseup = null;
        document.onmousemove = null;
    }
}  
 <body>
    <div class="mainCon">
        <div class="contentCon" id="mainCode" style="position: absolute;"> 
            <h1>Main block</h1>
            <button onclick="applyDrag()">Submit</button>
            <br>
            <textarea cols="10" rows="10" spellcheck="false">Click the "Submit" button to run the Drag and Drop function again.
Internal code not applied.</textarea>
        </div>

        <div class="contentCon" style="position: absolute;"> 
            <h1>Exit log</h1>
            <br>
            <textarea id="ExitLog" cols="10" rows="10" spellcheck="false" readonly style="cursor: auto; width: 300;">Internal code not applied.</textarea>
        </div>
    </div>
</body>  

Комментарии:

1. Ваш код и ваше объяснение довольно запутанны. Какую функцию вы имеете в виду в «запустить функцию снова»? applyDrag не похоже, что он был разработан для запуска несколько раз. Код представляет собой странную смесь нового стиля ( querySelector ) и древнего стиля ( e || window.event и присваивания событиям on... свойств вместо addEventListener ). Более того, есть современный API перетаскивания: developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API

Ответ №1:

пожалуйста, замените эти строки в функции dragElement.

 if (moveRoom) {
    moveRoom.onmousedown = dragMouseDown;
}
else {
    dragEl.onmousedown = dragMouseDown;
}
  

и просто сделайте это

dragEl.onmousedown = dragMouseDown;

он работает при первом запуске, потому что при первом вызове moveRoom имеет значение null, что при выполнении другой части и функции onmousedown правильно назначается dragEl, но при втором запуске оно не равно null, а функция onmousedown назначается элементу moveRoom.