【问题标题】:Drag and drop <span> to paragraph using JQuery使用 JQuery 将 <span> 拖放到段落
【发布时间】:2020-02-01 13:39:21
【问题描述】:

我需要将&lt;span&gt; 拖放到&lt;p&gt;。我的代码有效,但我有 3 个问题,

  1. 当我通过键入某些内容(假设三个单词)编辑&lt;p&gt; 内容并将&lt;span&gt; 拖动到&lt;p&gt; 后,新键入的单词充当一个单词。所以不能在那些新输入的内容之间放置可拖动的组件。

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

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

为了整理第 3 期,我将&amp;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 日

我更新了问题,因为当我从代码生成可拖动组件&lt;span&gt; 时遇到问题。我生成的可拖动组件如下,它生成精细且能够拖放到&lt;p&gt;。但是当我单击&lt;p&gt; 并从&lt;p&gt;(这意味着在模糊事件中)在外部单击时,丢弃的组件没有显示关闭按钮。它显示为[Ameriaca] , [Qatatr] 为什么会这样?我怎样才能避免它。我在$(function() {}); 中调用了这个GetAllParameters()

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"这样的两个词和一个我识别出来的。当我在可编辑的&lt;p&gt; 中键入内容并单击&lt;p&gt; 的外部键入的单词时,这是一个大问题。请帮我解决这个问题

【问题讨论】:

  • @Rory McCrossan 你能看看这个

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


【解决方案1】:

您应该只根据您面临的实际问题提出实用、可回答的问题。喋喋不休的开放式问题会削弱我们网站的实用性,并将其他问题排在首页。

您的问题应该有合理的范围。如果你能想象一整本书都能回答你的问题,那你就问得太多了。

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

.on() 方法将事件处理程序附加到 jQuery 对象中当前选定的元素集。从 jQuery 1.7 开始,.on() 方法提供了附加事件处理程序所需的所有功能。

委托事件处理程序的优点是它们可以处理来自以后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委托事件处理程序来避免频繁附加和删除事件处理程序的需要。例如,此元素可以是模型-视图-控制器设计中视图的容器元素,或者如果事件处理程序想要监视 document 中的所有冒泡事件,则可以是 document。在加载任何其他 HTML 之前,document 元素在文档的 head 中可用,因此在此处附加事件是安全的,而无需等待文档准备好。

查看更多:.on()

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

这个方法是.on( "blur", handler )的快捷方式

当元素失去焦点时,会向元素发送模糊事件。本来这个事件只适用于表单元素,比如&lt;input&gt;。在最近的浏览器中,事件的域已扩展为包括所有元素类型。元素可能会通过键盘命令(例如 Tab 键)或通过鼠标单击页面上的其他位置而失去焦点。

查看更多:.blur()

【讨论】:

  • 但现在拖放后可拖动内容关闭X 不起作用。你能解释一下为什么吗?
  • 和下一个主要问题每次点击&lt;p&gt;内容并点击从&lt;p&gt;中删除的外部内容
  • @Adam 对.on() 稍作调整,点击回调正常触发。请参阅更新的代码。关于&lt;p&gt; 元素,我看不出你想说什么。当blur 事件被触发时,它确实会重新排列它,但那是它重新绘制所有新的&lt;span&gt; 元素。
  • 我的意思是当&lt;p&gt; blur 事件每次删除段落的第一个单词时。我想现在你可以清楚我在说什么了。一旦我单击段落的任何位置并单击段落外部,第一个单词就会删除。为什么会这样?
  • @Adam 这实际上不在问题的范围内。最有可能的是,正在应用另一个样式规则。我也没有 Windows 桌面,因此无法使用 IE 11 进行测试。请使用开发人员工具进一步调查,如果需要,请发布另一个问题。
【解决方案2】:

要解决第一个问题,您可以在用户每次输入文本或在文本区域散焦时“重新剪切”单词。我建议您在每次用户停止编辑文本区域或每次用户输入空格时重新映射/剪切您的文字(虽然这会更频繁地运行)。

如果您检测到一行中有多个(例如,使用正则表达式),则可以通过简单地循环文本并删除第二个问题来解决。

【讨论】:

  • 你能提供示例代码来排序吗?请注意我在这里使用的是

    而不是

  • 你可能真的想回去看看我对 TinyMCE 的建议:stackoverflow.com/questions/58161073/…
  • @Twisty 问题是先生,我不能使用 TinyMCE,不能使用这样的 3rd 方,你能告诉我如何解决,至少请帮我解决我提到的第一个问题,请先生
  • @Twisty 在这个答案stackoverflow.com/a/58193088/9512787 中,您建议我在特定活动中再次致电$("p.given").html(chunkWords($("p.given").text()));。不是很清楚,能不能给个完整的答案。请
猜你喜欢
  • 2020-01-31
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多