javascript - 如何使用 jQuery 拖放段落元素

标签 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>标签。

最佳答案

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

$(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”按钮来删除它。

关于javascript - 如何使用 jQuery 拖放段落元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58189136/

相关文章:

javascript - jquery 适用于主体,但不适用于其他元素

php - 使用 mysqli_query 进行 json 表单验证

jquery - 浏览器未观察到 data-* 的更改,CSS 属性选择器属性未呈现

javascript - 使用 javascript 从图像数组更改 img 标签 src。骰子游戏

javascript - 如何选择元素的第 n 个子元素?

javascript - 首先填充底行的 HTML - 审美原因

javascript - 如何逐步构建和拆除 JavaScript 对象?

javascript - 基本 jQuery .data() 调用返回未定义

jquery - native iOS 网络应用程序 + jquery 移动。保存当前应用程序状态

html - 选择框文本卡在 FF 中的框顶部