javascript - 使用 JQuery 将 <span> 拖放到段落中

标签 javascript jquery jquery-ui jquery-ui-draggable

我需要拖放<span><p> 。我的代码可以运行,但有 3 个问题,

  1. 当我编辑<p>时通过输入内容(假设三个单词)并拖动后<span><p>新输入的单词充当一个单词。因此不能在这些新输入的内容之间放置可拖动组件。

  2. 关闭后,添加的可拖动组件(通过点击 X )两个单词之间留有两个空格。

  3. 无法将可拖动组件作为段落的第 1 个单词放置。

为了解决第三个问题,我添加了 &nbsp;到该段落的第 1 段。并且已排序。

<p class="given" contenteditable="true">&nbsp; Lorem Ipsum is simply dummy</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 id="walkinDiv" 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>

更新时间:2019-10-22

我更新了问题,因为我在生成可拖动组件时遇到问题 <span>来自代码。我生成了可拖动组件,如下所示,它生成了良好且能够拖放到 <p> 的组件。 。但是当我点击 <p>然后单击 <p> 外部(这意味着在模糊事件中)丢弃的组件不显示关闭按钮。它显示为 [Ameriaca] , [Qatatr]为什么会出现这样的情况呢?我怎样才能避免它。我称之为GetAllParameters()里面$(function() {});

function GetAllParameters() {
    $.ajax({
        type: "POST",
        url: SERVER_PATH + '/service/TestService.asmx/GetAllParameters',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: GetAllNotificationParametersComplete,
        error: GetAllNotificationParameterFailed
    });
}

function GetAllNotificationParametersComplete(result, status) {
    NotificationParameters = JSON.parse(result.d);
    getTemplateparameters(NotificationParameters,'ShowIn');
}

function GetAllNotificationParameterFailed(result) {
    //console.log(result);
}


function getTemplateparameters(data,field) {

    var filtered = data.filter(function(item) {
         return item[field] == true;
    });
 populateTemplateParameters(filtered);
}

function populateTemplateParameters(data) {  
     var obj = data;
     var stringlist = "";
     $.each(obj, function (index, item) {
         stringlist = stringlist + ' <span class="given btn-flat white-text red lighten-1 parameter-wrapper">' +item.ParameterName+ '</span>';
     });
    $("#walkinDiv").html(stringlist);

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

  makeDropText($("p.given span.w"));
}

更新时间:2019-10-23

当可拖动组件有两个单词如 "Hello World" 时,就会出现前面提到的问题我发现了一件事。当我在可编辑的内部输入内容时<p>然后单击 <p> 的外部删除键入的单词。这是一个大问题。请帮我解决这个问题

最佳答案

You should only ask practical, answerable questions based on actual problems that you face. Chatty, open-ended questions diminish the usefulness of our site and push other questions off the front page.

Your questions should be reasonably scoped. If you can imagine an entire book that answers your question, you’re asking too much.

$(function() {
  function textWrapper(str, sp, btn) {
    if (sp == undefined) {
      sp = [0, 0];
    }
    var txt = "";
    if (btn) {
      txt = "<span class='w b'>" + str + "</span>";
    } else {
      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++) {
      var re = /\[.+\]/;
      if (re.test(words[i])) {
        var b = makeTextBox(words[i].slice(1, -1));
        words[i] = "&nbsp;" + b.prop("outerHTML") + "&nbsp;";
      } else {
        if (words[0].indexOf(".")) {
          words[i] = textWrapper(words[i], [1, 0]);
        } else {
          words[i] = textWrapper(words[i], [1, 1]);
        }
      }
    }
    return words.join("");
  }

  function unChunkWords(tObj) {
    var words = [];
    $(".w", tObj).each(function(i, el) {
      console.log($(el).text(), $(el).attr("class"));
      if ($(el).hasClass("b")) {
        words.push("[" + $(el).text().trim() + "]");
      } else {
        words.push($(el).text().trim());
      }
    });
    return words.join(" ");
  }

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

  function makeTextBox(txt) {
    var sp = $("<span>", {
      class: "w b"
    }).html(txt);
    makeBtn(sp);
    return sp;
  }

  function makeDropText(obj) {
    return obj.droppable({
      drop: function(e, ui) {
        var txt = ui.draggable.text();
        var newSpan = textWrapper(txt, [1, 0], 1);
        $(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()));

  $("p.given").on("click", ".b > .ui-icon", function() {
    $(this).parent().remove();
  });

  $("p.given").blur(function() {
    var w = unChunkWords($(this));
    console.log(w);
    $(this).html(chunkWords(w));
    makeDropText($("p.given span.w"));
  });

  $("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>

使用blur事件中,我们可以将包装的元素恢复为文本,然后用新内容再次将它们分块。为了维护按钮,我使用了 [] .

我用过.on().blur()由于特定原因。

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers.

Delegated event handlers have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated event handlers to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.

查看更多:.on()

这很重要,因为我们动态创建元素,并希望确保将回调委托(delegate)给这些元素,即使它们尚不存在。

This method is a shortcut for .on( "blur", handler )

The blur event is sent to an element when it loses focus. Originally, this event was only applicable to form elements, such as <input>. In recent browsers, the domain of the event has been extended to include all element types. An element can lose focus via keyboard commands, such as the Tab key, or by mouse clicks elsewhere on the page.

查看更多:.blur()

关于javascript - 使用 JQuery 将 <span> 拖放到段落中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58215677/

相关文章:

javascript - 错误 : [ngModel:numfmt] Expected `1` to be a number angularjs

javascript - FullCalendar v4 - fullCalendar 不是函数

jquery-ui - JQuery UI slider : set min and max with attributes

jquery ui 自动完成

javascript - Jquery UI Datepicker 注销和登录后不显示

JavaScript 匹配和替换;什么是最好的方法?

javascript - 如何在Electron上的React组件中导入CSS文件

javascript - 防止 Webapp 中的额外触摸

javascript - 如何获取滚动条内可见div的id

javascript - scrollTo TweenMax 不完全停在散列上