如何使用带有段落元素的jQuery拖放

时间:2019-10-01 16:44:10

标签: javascript jquery html jquery-ui jquery-ui-draggable

我需要使用JQuery UI创建可自定义的段落。

这是我的代码。

$(document).ready(function() {
  var given = $("p.given").text();

  var new_given = given.replace(/blank/g, '  <div class="blanks"></div>  ');
  $("p.given").html(new_given);

  function updateDroppables() {
    $("div.blanks").droppable({
      accept: "span.given",
      classes: {
        "ui-droppable-hover": "ui-state-hover"
      },
      drop: function(event, ui) {
        var dragedElement = ui.draggable.text();
        var dropped = ui.draggable;
        console.log(dropped);
        dropped.hide();
        console.log(dragedElement);
        $(this).replaceWith(
          " <span class='answers'><b class='blue-text' rel='" +
          ui.draggable.attr("rel") +
          "'>" +
          dragedElement +
          "</b> <a href='#' class='material-icons cancel md-16'>highlight_off</a></span> "
        );
      }
    });
  }

  updateDroppables();

  $("span.given").draggable({
    helper: "clone",
    revert: "invalid"
  });

  $(document).on("click", "a.cancel", function(e) {
    e.preventDefault();
    var rel = $(this).prev().attr('rel');
    console.log(rel);

    $(this)
      .parent()
      .replaceWith("<div class='blanks'></div>");
    updateDroppables();
    $('.btn-flat[rel=' + rel + ']').show();
  });
});
div.blanks {
  display: inline-block;
  min-width: 50px;
  border-bottom: 2px solid #000000;
  color: #000000;
}

div.blanks.ui-droppable-active {
  min-height: 20px;
}

span.answers>b {
  border-bottom: 2px solid #000000;
}

span.given {
  margin: 5px;
}
<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>
<p><b><i>In the text below some words are missing. Drag words from the box below to the appropriate place in the text. To undo an answer choice, drag the word back to the box below the text.</i></b></p>

<div class="row">
  <p class="given">
    He wants to get a better [blank] and earn more money. Managers set objectives, and decide [blank] their organization can achieve them. A defect can be caused [blank] negligen ce by one of the members of a team.
  </p>
</div>

<div class="divider"></div>
<br>
<div class="section">
  <section>
    <div class="card blue-grey ">
      <div class="card-content white-text">
        <div class="row">
          <div class="col s12">

            <span class="given btn-flat white-text red lighten-1" rel="1">the Santee, thDakota</span>
            <span class="given btn-flat white-text red lighten-1" rel="2">America</span>

            <span class="given btn-flat white-text red lighten-1" rel="3">Qatar</span>

            <span class="given btn-flat white-text red lighten-1" rel="4">Philippines</span>

          </div>
        </div>
      </div>
    </div>
  </section>
</div>

这可行,但是问题在于上面的代码中可拖动组件只能添加到[blank]区域。我需要在段落<p>中的任何位置添加可拖动组件,该怎么做?这是code pen sample,您可以播放并查看以上代码的工作原理

很简单,我将上述代码更改如下,

$("p.given").droppable({
  accept: "span.given",
  classes: {
    "ui-droppable-hover": "ui-state-hover"
  }

,但将整个段落<p>替换为拖动的组件。如何将可拖动组件添加到<p>标记的任何位置。

2 个答案:

答案 0 :(得分:2)

由于要完成的事情很多,因此需要准备很多东西。这是一个非常粗糙的例子。

$(function() {
  function textWrapper(str, sp) {
    if (sp == undefined) {
      sp = [
        0,
        0
      ];
    }
    var txt = "<span class='w'>" + str + "</span>";
    if (sp[0]) {
      txt = "&nbsp;" + txt;
    }
    if (sp[1]) {
      txt = txt + "&nbsp;";
    }
    return txt;
  }

  function chunkWords(p) {
    var words = p.split(" ");
    words[0] = textWrapper(words[0], [0, 1]);
    var i;
    for (i = 1; i < words.length; i++) {
      if (words[0].indexOf(".")) {
        words[i] = textWrapper(words[i], [1, 0]);
      } else {
        words[i] = textWrapper(words[i], [1, 1]);
      }
    }
    return words.join("");
  }

  function makeBtn(tObj) {
    var btn = $("<span>", {
      class: "ui-icon ui-icon-close"
    }).appendTo(tObj);
    btn.click(function(e) {
      $(this).parent().remove();
    });
  }

  function makeDropText(obj) {
    return obj.droppable({
      drop: function(e, ui) {
        var txt = ui.draggable.text();
        var newSpan = textWrapper(txt, [1, 0]);
        $(this).after(newSpan);
        makeBtn($(this).next("span.w"));
        makeDropText($(this).next("span.w"));
        $("span.w.ui-state-highlight").removeClass("ui-state-highlight");
      },
      over: function(e, ui) {
        $(this).add($(this).next("span.w")).addClass("ui-state-highlight");
      },
      out: function() {
        $(this).add($(this).next("span.w")).removeClass("ui-state-highlight");
      }
    });
  }

  $("p.given").html(chunkWords($("p.given").text()));

  $("span.given").draggable({
    helper: "clone",
    revert: "invalid"
  });

  makeDropText($("p.given span.w"));
});
p.given {
  display: flex;
  flex-wrap: wrap;
}

p.given span.w span.ui-icon {
  cursor: pointer;
}

div.blanks {
  display: inline-block;
  min-width: 50px;
  border-bottom: 2px solid #000000;
  color: #000000;
}

div.blanks.ui-droppable-active {
  min-height: 20px;
}

span.answers>b {
  border-bottom: 2px solid #000000;
}

span.given {
  margin: 5px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row">
  <p class="given" contenteditable="true">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>

<div class="divider"></div>
<div class="section">
  <section>
    <div class="card blue-grey ">
      <div class="card-content white-text">
        <div class="row">
          <div class="col s12">
            <span class="given btn-flat white-text red lighten-1" rel="1">the Santee, thDakota</span>
            <span class="given btn-flat white-text red lighten-1" rel="2">America</span>
            <span class="given btn-flat white-text red lighten-1" rel="3">Qatar</span>
            <span class="given btn-flat white-text red lighten-1" rel="4">Philippines</span>
          </div>
        </div>
      </div>
    </div>
  </section>
</div>

这将获取<p>中的当前文本,并用不间断空格包装每个单词。它尝试遵守句子语法。

现在,每个单词都被包裹起来,然后我们就可以将每个单词都放下。假设一个单词将落在前一个单词上,并突出显示将在其间插入的两个单词。删除后,将创建一个新的<span>并将其附加到目标之后。我添加了一个“ x”按钮将其删除。

答案 1 :(得分:0)

  1. 用单词创建数组。
  2. 创建新片段:https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment#JavaScript
  3. 使用forEach()迭代数组,并使用append的每个单词<span data-index="indexNumber">arrayWord</span>进行分段。
  4. 迭代之后,将片段追加到您的<p>
  5. 然后用单独的单词获得句子。
  6. 向每个span元素添加data-dropped-value属性。
  7. on drop拖动的元素,您将更新跨度,它将为data-dropped-value="your dragged value"
  8. 然后您可以将此值附加到此范围。

  1. 在拖放时将文本附加到跨度,将其悬停。
  2. 不需要