Добавление div на лету, а затем перемещение его внутри квадратов

У меня есть следующий код, в котором синие цветные поля в левом тексте помещаются внутри квадратов после нажатия кнопки. В моем реальном коде это будет работать так: будет раскрывающийся список некоторых элементов, и я получу значения синих полей (например, H1 Text, H2 Text и т. д.) в зависимости от того, что выбрано пользователем из раскрывающийся список. Таким образом, в основном я буду динамически генерировать элементы div, связанные с синими прямоугольниками, и общее количество блоков (и значение внутри них) зависит от того, сколько значений возвращается в зависимости от выбора элемента из раскрывающегося списка. (Эта часть здесь не показана, и я просто жестко запрограммировал синие поля, поскольку это не имеет отношения к моему вопросу).

Мой вопрос: Если я захочу на лету создать дополнительные синие ящики, можно ли этого добиться? Например, я хочу создать синее поле со значением F6 Text в качестве значения и поместить его под синее поле с надписью G6 Text. Можно ли его создать? Это будет добавление такого нового div <div data-id = "13"><span data-id = "13" class = "words">F6 Text</span></div> чуть ниже <div data-id = "12"><span data-id = "12" class = "words">G6 Text</span></div> внутри <div id = "phrase">

Кроме того, я хотел бы создать просто пустое поле без какого-либо значения, поэтому, если у меня в div есть элементы до F6 Text, это будет выглядеть как <div data-id = "14"><span data-id = "12" class = "words"></span></div>.

Мне интересно, нужна ли мне где-нибудь кнопка, где мне нужно показать всплывающее диалоговое окно, спрашивающее пользователя, какое значение необходимо, а затем добавить div к приведенным выше элементам div, или есть ли лучший способ справиться с этим?

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

$(".words").draggable({
  revert: function (event, ui) {
    var bRevertingPhrase = this.closest("#drop-em");

    if (!bRevertingPhrase.length) {
      var phraseID = $(this).data("id");
      var phraseHomeID = $(this).parent().data("id");

      //If the child and parent ids don't match, we move the child to the correct parent
      if (phraseID !== phraseHomeID) {
        var correctCell = $("#phrase").find("div[data-id='" + phraseID + "']");
        correctCell.prepend(this);
      }
    }
    return !event;
  }
});
$("#drop-em > div").droppable({
  drop: function (ev, ui) {
    $(ui.draggable)
      .detach()
      .css({ top: 0, left: 0 })
      .appendTo($(this).find(".content:empty"));
    $("#move-text").addClass("disabled");
  }
});
$("#phrase > div").droppable({
  drop: function (ev, ui) {
    $(ui.draggable).detach().css({ top: 0, left: 0 }).prependTo(this);
  }
});

const myButton = document.querySelector("#move-text");
myButton.addEventListener(
  "click",
  () => {
    fill();
  },
  {
    once: true
  }
);

var reOrder = [];
function fill() {
  const cells = document.querySelectorAll("#phrase > div > span");
  var newLoc = "";

  myButton.classList.add("disabled");

  cells.forEach((cell, index) => {
    newLoc = document.querySelector(
      ".item:nth-child(" + reOrder[index] + ") .content "
    );
    newLoc.append(cell);
    newLoc.classList.add("moved");
  });
}
function reArrange() {
  var limit1 = 85;
  var limit2 = 91;

  for (let loop = 0; loop < 8; loop++) {
    for (let i = 0; i < 6; i++) {
      reOrder.push(limit1 + i);
    }
    limit1 = limit1 - 12;
  }
  for (let loop = 0; loop < 8; loop++) {
    for (let j = 0; j < 6; j++) {
      reOrder.push(limit2 + j);
    }
    limit2 = limit2 - 12;
  }
}
reArrange();
html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
body {
  counter-reset: columnCount 1 alphaCount cellCount;
}
h1 {
  text-align: center;
}
.wrap {
  display: flex;
  gap: 2rem;
  position:relative;
  padding-left:220px;
}

.grid {
  margin: auto;
  display: grid;
  flex: 1 0 0;
  grid-template-columns: repeat(12, 1fr);
  padding-top: 1.5rem;
}

.item {
  position: relative;
  background-color: #f9f9f9;
  border: 1px solid grey;
  aspect-ratio: 1/1;
  counter-increment: columnCount;
  min-width: 0;
  transition: background 1s ease;
}
.item:nth-of-type(12n + 1) {
  counter-increment: alphaCount;
}
.item:nth-of-type(12n + 1)::before {
  content: counter(alphaCount, upper-alpha);
  position: absolute;
  display: flex;
  align-items: center;
  top: 0;
  bottom: 0;
  left: -1.75rem;
  color: red;
  pointer-events: none;
}
.item:nth-of-type(n + 13)::after {
  display: none;
}
.item::after {
  content: counter(columnCount);
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  top: -1.75rem;
  color: red;
  pointer-events: none;
}
.content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  height: 100%;
  overflow: auto;
  color: #000;
  padding: 1rem;
  word-wrap: break-word;
  counter-increment: cellCount;
}

.words {
  cursor: move;
  transition: padding 0.5s ease;
}
.content:has(.ui-draggable-dragging) {
  overflow: visible;
}
.ui-droppable-active .content {
  overflow: visible;
}
.words.ui-draggable-dragging {
  background: blue;
  padding: 5px 10px;
  border-radius: 6px;
  z-index: 999;
  color: #fff;
  display: block;
  width: 50px;
  height: 50px;
  overflow: hidden;
}
#phrase {
  position:absolute;
  left:0;
  top:0;
  bottom:0;
  color: #fff;
  width:150px;
  overflow:auto;
  z-index: 2;
  display: flex;
  flex-direction: column;
  margin:1rem 0 .5rem;
}
#phrase > div {
  margin: 0 0 10px;
  width:150px;
  padding: 5px 10px;
  background: #007bff;
  border: 2px solid #007bff;
  border-radius: 6px;
  color: #fff;
}
#phrase > div:empty {
  background: #fff;
  border-style: dashed;
  padding: 0px 25px;
  min-height: 30px;
}

.moved {
  animation: fade 3s ease;
}
@keyframes fade {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
    background: red;
  }
}

.item .content::before {
  content: counter(cellCount);
  position: absolute;
  top: 2px;
  left: 2px;
  font-size: smaller;
  color: #666;
  border-radius: 50%;
  border: 1px solid red;
  background: white;
  width: 1.2rem;
  height: 1, 2rem;
  display: grid;
  place-items: center;
}

#move-text.disabled{
  cursor:none;
  pointer-events:none;
  opacity:0.5;
}
#phrase:has(.ui-droppable-active){
  overflow:visible;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<!-- You'd need to set up something different for touch devices though -->
<h1>Drag and drop example </h1>
<button id = "move-text" type = "button">Move Text Content!</button>
<div class = "wrap">
  <div id = "phrase">
    <!-- remove whitespace from  inside div html and then we can use :empty in css to change background -->
    <div data-id = "1"><span data-id = "1" class = "words">H1 Text</span></div>
    <div data-id = "2"><span data-id = "2" class = "words">H2 Text</span></div>
    <div data-id = "3"><span data-id = "3" class = "words">H3 Text</span></div>
    <div data-id = "4"><span data-id = "4" class = "words">H4 Text</span></div>
    <div data-id = "5"><span data-id = "5" class = "words">H5 Text</span></div>
    <div data-id = "6"><span data-id = "6" class = "words">H6 Text</span></div>
    <div data-id = "7"><span data-id = "7" class = "words">G1 Text</span></div>
    <div data-id = "8"><span data-id = "8" class = "words">G2 Text</span></div>
    <div data-id = "9"><span data-id = "9" class = "words">G3 Text</span></div>
    <div data-id = "10"><span data-id = "10" class = "words">G4 Text</span></div>
    <div data-id = "11"><span data-id = "11" class = "words">G5 Text</span></div>
    <div data-id = "12"><span data-id = "12" class = "words">G6 Text</span></div>
  </div>

  <div id = "drop-em" class = "grid">
    <div class = "item">
      <div class = "content"></div><!-- must have no spaces inside .content -->
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    <div class = "item">
      <div class = "content"></div>
    </div>
    

  </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) для оценки ваших знаний,...
0
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Можно динамически добавить еще один div, как показано в примере ниже. Я удалил сетку, так как ее не нужно демонстрировать. Я также сократил ваш код HTML и JavaScript до минимума.

Важная работа выполняется в прослушивателе событий addButton.

Существует несколько способов вычисления следующего идентификатора атрибута data-id. Я решил получить количество дочерних элементов div с идентификатором «фразы», ​​используя childElementCount, а затем добавить к нему 1.

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

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

Обратите внимание, что я снова вызываю функцию JQuery draggable() внутри прослушивателя событий с помощью:

$(".words").draggable();

чтобы добавить все правильные классы во вновь созданный синий ящик.

Этот метод должен дать вам представление о том, как подойти к остальной части вашей проблемы. Я уверен, что вы сможете получить текст синего поля из соответствующего элемента input.

$(".words").draggable();

const addButton = document.querySelector("#add-blue-box");

addButton.addEventListener(
  "click", () => {
    const phraseDiv = document.querySelector("#phrase");
    let nextId = phraseDiv.childElementCount + 1;
    const divElement = document.createElement("div");
    const spanElement = document.createElement("span");

    spanElement.textContent = "F6 Text";
    spanElement.setAttribute('data-id', nextId);
    spanElement.classList.add('words');

    divElement.appendChild(spanElement);
    divElement.setAttribute('data-id', nextId);

    phraseDiv.appendChild(divElement);

    $(".words").draggable();
  });
h1 {
  text-align: center;
}

.wrap {
  display: flex;
  gap: 2rem;
  position: relative;
  padding-left: 220px;
  height: 100vh;
}

#phrase {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  color: #fff;
  width: 150px;
  overflow: auto;
  z-index: 2;
  display: flex;
  flex-direction: column;
  margin: 1rem 0 .5rem;
}

#phrase>div {
  margin: 0 0 10px;
  width: 150px;
  padding: 5px 10px;
  background: #007bff;
  border: 2px solid #007bff;
  border-radius: 6px;
  color: #fff;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<h1>Drag and drop example </h1>
<button id = "add-blue-box" type = "button">Add Blue Box</button>
<div class = "wrap">
  <div id = "phrase">
    <div data-id = "1"><span data-id = "1" class = "words">H1 Text</span></div>
    <div data-id = "2"><span data-id = "2" class = "words">H2 Text</span></div>
    <div data-id = "3"><span data-id = "3" class = "words">H3 Text</span></div>
    <div data-id = "4"><span data-id = "4" class = "words">H4 Text</span></div>
    <div data-id = "5"><span data-id = "5" class = "words">H5 Text</span></div>
    <div data-id = "6"><span data-id = "6" class = "words">H6 Text</span></div>
  </div>
</div>

В качестве альтернативы, если вы действительно хотите сделать это с помощью JQuery (который представляет собой всего лишь библиотеку JavaScript), то одним из решений будет следующий фрагмент кода:

$(".words").draggable();

const addButton = document.querySelector("#add-blue-box");

addButton.addEventListener(
  "click", () => {
    let nextId = $("#phrase").children().length + 1;
    let text1 = "F6";
    let text2 = "Text";
    $("<div>", {
        "data-id": nextId
      })
      .append($("<span>", {
          "data-id": nextId,
          class: "words"
        })
        .text("Ln#" + text1 + " " + text2)
      ).appendTo($("#phrase"));
    $(".words").draggable();
  });
h1 {
  text-align: center;
}

.wrap {
  display: flex;
  gap: 2rem;
  position: relative;
  padding-left: 220px;
  height: 100vh;
}

#phrase {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  color: #fff;
  width: 150px;
  overflow: auto;
  z-index: 2;
  display: flex;
  flex-direction: column;
  margin: 1rem 0 .5rem;
}

#phrase>div {
  margin: 0 0 10px;
  width: 150px;
  padding: 5px 10px;
  background: #007bff;
  border: 2px solid #007bff;
  border-radius: 6px;
  color: #fff;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<h1>Drag and drop example </h1>
<button id = "add-blue-box" type = "button">Add Blue Box</button>
<div class = "wrap">
  <div id = "phrase">
    <div data-id = "1"><span data-id = "1" class = "words">H1 Text</span></div>
    <div data-id = "2"><span data-id = "2" class = "words">H2 Text</span></div>
    <div data-id = "3"><span data-id = "3" class = "words">H3 Text</span></div>
    <div data-id = "4"><span data-id = "4" class = "words">H4 Text</span></div>
    <div data-id = "5"><span data-id = "5" class = "words">H5 Text</span></div>
    <div data-id = "6"><span data-id = "6" class = "words">H6 Text</span></div>
  </div>
</div>

Этот ответ о Создание элемента div в jQuery, возможно, стоит прочитать.

Спасибо. Итак, добавление div можно сделать и с помощью jQuery, верно? Или он упустит некоторые детали, которые вы упомянули?` let html = "<div data-id = " + i + "><span data-id = " + i + ' class = "words">' + "Ln #" + text1 + " " + text2 + "</span></div>"; $("#phrase").append(html);`

Tan 08.03.2024 19:49

@Tan Ну, JQuery — это всего лишь библиотека JavaScript, поэтому должно быть много способов сделать то, что вы хотите, включая ваше предложение.

PeterJames 10.03.2024 11:34

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

Похожие вопросы

Запуск пользовательской функции в серверном компоненте с помощью Next JS App Router во время выполнения
Err Только простые объекты и несколько встроенных модулей можно передавать в клиентские компоненты из серверных компонентов. Классы или нулевые прототипы не поддерживаются
Можете ли вы добавитьWizardPage в программу удаления (QtInstallerFramework)?
Тест почтальона должен быть случайным с названием, содержащимся
Как исправить мой DataTable, чтобы stateSave работал правильно?
Могу ли я использовать локальный хост, созданный с помощью node.js, для хранения всех данных, представленных на моем веб-сайте? без SQL или какой-либо БД. Просто HTML
Файл GLB не загружается в Three.js
JS использует функцию внутри функции
Что вызывает эту странную ошибку горизонтального расстояния (?) между кнопками при добавлении элемента списка в неупорядоченный список через JavaScript?
Определить, показывает ли reportValidity() в настоящее время сообщение validityMessage в элементе DOM?