Перетащите шаблон с помощью JavaScript

После перетаскивания блока из левого контейнера в правый контейнер он удаляется из левого контейнера. Как предотвратить удаление из левого контейнера и несколько раз перетаскивать одно и то же?

Я пробовал с этим кодом, и он не работает для меня.

Необходимо достичь - он не должен удаляться после перетаскивания в правильный контейнер, он всегда должен быть там, чтобы перетаскивать несколько раз

const blocksData = [{
    id: 1,
    label: 'Test Content',
    htmlContent: '<h1>Test Content</h1>'
  },
  {
    id: 2,
    label: 'Test Content',
    htmlContent: '<h2>Test Content</h2>'
  },
  {
    id: 3,
    label: 'Test Content',
    htmlContent: '<h3>Test Content</h3>'
  },
  {
    id: 4,
    label: 'Test Content',
    htmlContent: '<button>Test Content</button>'
  },
];
const getDragAfterElement = (container, y) => {
  console.info("Test 1");
  const draggableElements = [...container.querySelectorAll('.block:not(.dragging)')]
  return draggableElements.reduce((closest, child) => {
    const box = child.getBoundingClientRect()
    const offset = y - box.top - box.height / 2
    if (offset < 0 && offset > closest.offset) {
      return {
        offset: offset,
        element: child
      }
    } else {
      return closest
    }
  }, {
    offset: Number.NEGATIVE_INFINITY
  }).element
}
const initiateHandler = () => {
  console.info("Test 2");
  const left = document.getElementsByClassName("left")[0];
  const handle = document.getElementById("handle");
  handle.draggable = true;
  handle.addEventListener("mousedown", (e) => {
    ismdwn = 1
    document.body.addEventListener('mousemove', (e) => mV(e, left))
    document.body.addEventListener('mouseup', (e) => end(e, handle))
  });
}
const onReady = () => {
  console.info("Test 3");
  initiateHandler();
  const drggableBlocksHolder = document.getElementById("blocks");
  blocksData.map((block) => {
    if (!document.querySelector("#blocks > div:nth-child(4)")) drggableBlocksHolder.innerHTML += `<div draggable = "true" class = "block" data-block = "${block.id}">${block.htmlContent}</div>`;
  });
  document.right = document.getElementsByClassName("right")[0];
  document.draggables = blocks.getElementsByClassName("block");
  document.draggable = document.querySelector('.dragging');
  for (let index = 0; index < document.draggables.length; index++) {
    const draggable = document.draggables[index];
    draggable.addEventListener('dragstart', () => {
      draggable.classList.add('dragging')
    });
    draggable.addEventListener('dragend', () => {
      draggable.classList.remove('dragging')
    });
  }
  document.right.addEventListener('dragover', (e) => {
    console.info("Test 4");
    e.preventDefault();
    document.draggables = blocks.getElementsByClassName("block");
    document.draggable = document.querySelector('.dragging');
    const afterElement = getDragAfterElement(document.right, e.clientY)
    if (afterElement == null) {
      id = document.draggable.getAttribute('data-block')
      document.draggable.innerHTML = blocksData[id - 1].htmlContent;
      document.right.appendChild(document.draggable)
    } else {
      document.right.insertBefore(document.draggable, afterElement)
    }
  });
};
const mV = (event, left) => {
  console.info("Test 5");
  if (ismdwn === 1) {
    left.style.flexBasis = event.clientX + "px"
  } else {
    end()
  }
}
const end = (e) => {
    console.info("Test 6");
    ismdwn = 0
    document.body.removeEventListener('mouseup', end)
    handle.removeEventListener('mousemove', mV)
  }
  (function() {
    console.info("Test 7");
    onReady()
  })();
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body,
html {
  position: relative;
}

.container {
  position: fixed;
  width: 100%;
  height: 100%;
  display: flex;
}

.container>.left {
  position: relative;
  height: 100%;
  border: 1px solid rgba(0, 0, 0, 0.2);
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 35%;
  min-width: 300px;
}

.container>.left>.blocks {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.container>.left>h4 {
  font-family: 'Roboto';
  font-weight: bold;
  margin: 10px auto;
  font-size: 18px;
  text-align: center;
}

.container>.left>.blocks>.block {
  width: 100%;
  padding: 10px 15px;
  margin-top: 5px;
  border: 1px solid rgba(0, 0, 0, 0.2);
  cursor: move;
}

.block.dragging {
  opacity: .5;
}

.container>.right {
  width: 100%;
  height: 100%;
  border: 1px solid rgba(0, 0, 0, 0.2);
  flex-grow: 0;
  flex-shrink: 1;
  overflow-x: auto;
}

.container>.handle {
  background-color: rgba(0, 0, 0, 0.4);
  content: '';
  width: 7px;
  cursor: col-resize;
  flex-grow: 0;
  flex-shrink: 0;
  margin: 0 0 0 auto;
}
<div class = "container">
  <div class = "left">
    <h4>Blocks</h4>
    <div class = "blocks" id = "blocks">
      <div draggable = "true" class = "block" data-block = "1">Test Block 1 H1</div>
      <div draggable = "true" class = "block" data-block = "2">Test Block 1 H2</div>
      <div draggable = "true" class = "block" data-block = "3">Test Block 1 H3</div>
      <div draggable = "true" class = "block" data-block = "4">Test Block 1 button</div>
    </div>
  </div>
  <div class = "handle" id = "handle"></div>
  <div class = "right"></div>
</div>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я надеюсь, это то, что вы хотели. Блок удалялся из-за метода appendChild. Я заменил ребенка, пытающегося быть добавленным к клону перетаскиваемого блока. Пожалуйста, дайте мне знать, если вам нужно что-то еще.

const blocksData = [{
    id: 1,
    label: 'Test Content',
    htmlContent: '<h1>Test Content</h1>'
  },
  {
    id: 2,
    label: 'Test Content',
    htmlContent: '<h2>Test Content</h2>'
  },
  {
    id: 3,
    label: 'Test Content',
    htmlContent: '<h3>Test Content</h3>'
  },
  {
    id: 4,
    label: 'Test Content',
    htmlContent: '<button>Test Content</button>'
  },
];
const getDragAfterElement = (container, y) => {
  console.info("Test 1");
  const draggableElements = [...container.querySelectorAll('.block:not(.dragging)')]
  return draggableElements.reduce((closest, child) => {
    const box = child.getBoundingClientRect()
    const offset = y - box.top - box.height / 2
    if (offset < 0 && offset > closest.offset) {
      return {
        offset: offset,
        element: child
      }
    } else {
      return closest
    }
  }, {
    offset: Number.NEGATIVE_INFINITY
  }).element
}
const initiateHandler = () => {
  console.info("Test 2");
  const left = document.getElementsByClassName("left")[0];
  const handle = document.getElementById("handle");
  handle.draggable = true;
  handle.addEventListener("mousedown", (e) => {
    ismdwn = 1
    document.body.addEventListener('mousemove', (e) => mV(e, left))
    document.body.addEventListener('mouseup', (e) => end(e, handle))
  });
}
const onReady = () => {
  console.info("Test 3");
  initiateHandler();
  const drggableBlocksHolder = document.getElementById("blocks");
  blocksData.map((block) => {
    if (!document.querySelector("#blocks > div:nth-child(4)")) drggableBlocksHolder.innerHTML += `<div draggable = "true" class = "block" data-block = "${block.id}">${block.htmlContent}</div>`;
  });
  document.right = document.getElementsByClassName("right")[0];
  document.draggables = blocks.getElementsByClassName("block");
  document.draggable = document.querySelector('.dragging');
  for (let index = 0; index < document.draggables.length; index++) {
    const draggable = document.draggables[index];
    draggable.addEventListener('dragstart', () => {
      draggable.classList.add('dragging')
    });
    draggable.addEventListener('dragend', () => {
      draggable.classList.remove('dragging')
      document.querySelector(".dragging").classList.remove("dragging")
    });
  }
  document.right.addEventListener('dragover', (e) => {
    console.info("Test 4");
    e.preventDefault();
    document.draggables = blocks.getElementsByClassName("block");
    document.draggable = document.querySelector('.dragging');
    const afterElement = getDragAfterElement(document.right, e.clientY)
    document.draggableClone = document.draggable.cloneNode(true)
    if (document.right.querySelector(".dragging") == undefined){
        if (afterElement == null) {
        id = document.draggable.getAttribute('data-block')
            document.draggableClone.innerHTML = blocksData[id - 1].htmlContent;
            document.right.appendChild(document.draggableClone)
        } else {
            document.right.insertBefore(document.draggableClone, afterElement)
        }
    }
  });
};
const mV = (event, left) => {
  console.info("Test 5");
  if (ismdwn === 1) {
    left.style.flexBasis = event.clientX + "px"
  } else {
    end()
  }
}
const end = (e) => {
    console.info("Test 6");
    ismdwn = 0
    document.body.removeEventListener('mouseup', end)
    handle.removeEventListener('mousemove', mV)
  }
  (function() {
    console.info("Test 7");
    onReady()
  })();
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body,
html {
  position: relative;
}

.container {
  position: fixed;
  width: 100%;
  height: 100%;
  display: flex;
}

.container>.left {
  position: relative;
  height: 100%;
  border: 1px solid rgba(0, 0, 0, 0.2);
  flex-grow: 1;
  flex-shrink: 0;
  flex-basis: 35%;
  min-width: 300px;
}

.container>.left>.blocks {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.container>.left>h4 {
  font-family: 'Roboto';
  font-weight: bold;
  margin: 10px auto;
  font-size: 18px;
  text-align: center;
}

.container>.left>.blocks>.block {
  width: 100%;
  padding: 10px 15px;
  margin-top: 5px;
  border: 1px solid rgba(0, 0, 0, 0.2);
  cursor: move;
}

.block.dragging {
  opacity: .5;
}

.container>.right {
  width: 100%;
  height: 100%;
  border: 1px solid rgba(0, 0, 0, 0.2);
  flex-grow: 0;
  flex-shrink: 1;
  overflow-x: auto;
}

.container>.handle {
  background-color: rgba(0, 0, 0, 0.4);
  content: '';
  width: 7px;
  cursor: col-resize;
  flex-grow: 0;
  flex-shrink: 0;
  margin: 0 0 0 auto;
}
<div class = "container">
  <div class = "left">
    <h4>Blocks</h4>
    <div class = "blocks" id = "blocks">
      <div draggable = "true" class = "block" data-block = "1">Test Block 1 H1</div>
      <div draggable = "true" class = "block" data-block = "2">Test Block 1 H2</div>
      <div draggable = "true" class = "block" data-block = "3">Test Block 1 H3</div>
      <div draggable = "true" class = "block" data-block = "4">Test Block 1 button</div>
    </div>
  </div>
  <div class = "handle" id = "handle"></div>
  <div class = "right"></div>
</div>

Получение этой ошибки -> Uncaught TypeError: невозможно установить свойства null (настройка «перетаскиваемый»)

Vcurl 08.05.2023 05:59

Можете ли вы быть более конкретным, так как это работает на фрагменте.

Cacci 08.05.2023 06:41

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

Vcurl 08.05.2023 06:56

Можете ли вы дать мне строку, которая вызывает эту ошибку.

Cacci 08.05.2023 07:02

этот -> handle.draggable = true;

Vcurl 08.05.2023 07:04

Вам не хватает html-элемента с классом "handle".

Cacci 08.05.2023 07:06

Наличие элемента HTML с классом «дескриптор»

Vcurl 08.05.2023 07:12

Что ж, эта строка выдает ошибку «Невозможно установить свойства нуля», что означает, что она не может найти дескриптор константы в DOM. Таким образом, у вас либо нет элемента с идентификатором «дескриптор», либо вы пытаетесь найти элемент с другим идентификатором. Это все, что я могу сделать, пока вы не опубликуете код, с которым работаете. Если это все еще не решит вашу проблему, дайте мне ссылку js.fiddle или codepen с вашим кодом.

Cacci 08.05.2023 07:16

Проверил еще раз, теперь работает нормально. Спасибо за своевременную помощь!!!

Vcurl 08.05.2023 07:26

Другие вопросы по теме