ฉันจะพิมพ์ข้อความหลังจากเนื้อหาที่ถูกทิ้งได้อย่างไร

ฉันใช้องค์ประกอบที่ลากได้ของ jQuery UI เพื่อเพิ่มเนื้อหาที่แก้ไขได้

. รหัสนี้ใช้งานได้เพื่อค้นหาและฉันมีปัญหาเล็กน้อย ปัญหาคือเมื่อฉันทิ้งองค์ประกอบที่ลากได้เป็นคำสุดท้ายของย่อหน้า ฉันไม่สามารถพิมพ์ข้อความหลังจากที่องค์ประกอบที่หล่นไปนั้น

และปัญหาที่สองคือ ฉันต้องปิดการใช้งานตัวเลือก contentEditable จากคำ (ขยายด้วยตัวเลือกแบบถอดได้) เพื่อให้บรรลุว่าฉันจะเพิ่มโค้ดนี้ ($('.b').attr('contentEditable', false);) ภายใน $("p.given").blur เหตุการณ์ มันทำงานได้ดี ฉันต้องทำสิ่งเดียวกันเมื่อโหลดหน้าเว็บ ฉันจะทำมันได้อย่างไร? ฉันสามารถเพิ่มแอตทริบิวต์ contentEditable = false ซึ่งมีเพียงตัวเลือกที่ถอดออกได้เท่านั้น

หมายเหตุ: ฟังก์ชันปัจจุบันไม่สามารถหยุดได้

รหัสของฉันดังต่อไปนี้:

<link rel="stylesheet" href="http://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>
<style>
p.given {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
  display: flex;
  flex-wrap: wrap;
  cursor: pointer !important;

}

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;
}

.w ui-droppable{

cursor: pointer !important;
}

.w.b.ui-droppable {
  background: #FF8;
  color: #000;
}

.given.btn-flat {
  display: inline-block;
  padding: 0.25em 0.5em;
  border-radius: 1em;
  background: #A72020;
  color: #FFF;
  cursor: pointer;
}

.ui-draggable-dragging {
  background: #FFD700 !important;
}
</style>
<div class="row">
  <p id="doc_navc" 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">FirstName</span>
            <span class="given btn-flat white-text red lighten-1" rel="4">LastName</span>
          </div>
        </div>
      </div>
    </div>
  </section>
</div>

<input name="Go" id="btnPass" class="tstHeck" type="button" value="Go" onclick=""/>
<input name="Go" id="btnTxt" class="tstHeck" type="button" value="Go" onclick=""/>



<script language="javascript" type="text/javascript">

$(function() {

document.addEventListener("mousemove", function() {
    var $draggable = $(".ui-draggable-dragging");
    if (!$draggable.length) return; // nothing is being dragged
    var $highlighted = $(".ui-state-highlight");
    if (!$highlighted.length || $($highlighted).index() > 0) return; // first word is not highlighted
    // Get center x coordinate of the item that is being dragged
    var dragX = $draggable.offset().left + $draggable.width() / 2;
    // Get center x coordinate of the first word in the paragraph
    var firstX = $highlighted.offset().left + $highlighted.width() / 2;
    // If draggable is more on the left side of the first word, then only the first word should be highlighted
    if ((dragX < firstX) === ($highlighted.length < 2)) return; // Situation is as it should be
    // Toggle the highlight on the second word of the paragraph
    $highlighted.first().next("span.w").toggleClass("ui-state-highlight");
});

   function chunkWords(p) {
   console.log("sasasa");
    var words = p.split(" "), b;
    for (var i = 0; i < words.length; i++) {
      if (/\[.+\]/.test(words[i])) {
        b = makeTextBox(words[i].slice(1, -1));
      } else {
        b = $("<span>").addClass("w").text(words[i]);
      }
      // do not pad the value with "&nbsp;" at this moment:
      words[i] = b.prop("outerHTML");
    }

    return words.join("&nbsp;"); // add the spaces here
  }


    function unChunkWords(tObj) {
    var words = "";
    $(tObj).contents().each(function (i, el) {
      if ($(el).hasClass("b")) {

        words += "[" + $(el).text() + "]";
      } else {
        words += $(el).text();
      }
    });

    return words.replace(/\s+/g, " ").trim();
  }




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

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

  function makeDropText(obj) {
    return obj.droppable({
        drop: function(e, ui) {
            var txt = ui.draggable.text();
            // Use proper jQuery to create a new span element
            var newSpan = $("<span>").addClass('w b').text(txt);
            // Determine if the element is being dropped on the first word, and only that one
            if (!$(".ui-state-highlight").last().index()) {
                $(this).before(newSpan, "&nbsp;"); // ...then prepend
            } else {
                $(this).after("&nbsp;", newSpan); // normal case
            }
            makeBtn(newSpan);
            makeDropText(newSpan);
            $("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"));
    $('.b').attr('contentEditable', false);
  });


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

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


</script>

person Adam    schedule 19.11.2019    source แหล่งที่มา


คำตอบ (1)


ฉบับที่ 1

หากต้องการอนุญาตให้พิมพ์ข้อความหลังองค์ประกอบที่ถูกดร็อป ให้เปลี่ยนบรรทัดนี้:

return words.join("&nbsp;");

to:

return words.join("&nbsp;") + "&nbsp;";

คุณยังอาจเพิ่มช่องว่างหลายช่อง เช่น + "&nbsp;&nbsp;&nbsp;" ซึ่งจะทำให้ค้นหาจุดที่สามารถใส่เครื่องหมายรูปหมวกได้ง่ายยิ่งขึ้น

ประเด็นที่ 2

ใช้ contenteditable = false กับ "ปุ่ม" ที่มีอยู่แล้วในข้อความเมื่อโหลดหน้า ให้เพิ่มบรรทัดที่คุณใช้อยู่แล้วในสคริปต์โหลด เช่น หลังบรรทัดนี้:

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

...จึงกลายเป็น:

$("p.given").html(chunkWords($("p.given").text()));
$('span.b').attr('contentEditable', false);

ข้อเสนอแนะเพิ่มเติม

ฉันพบว่ามันสับสนที่เคอร์เซอร์เป็นตัวชี้เมื่อวางเมาส์เหนือย่อหน้าที่แก้ไขได้ ฉันขอแนะนำให้ลบบรรทัดนี้ออกจากข้อกำหนด CSS สำหรับ p.given:

cursor: pointer !important;

และฉันจะเพิ่มคำจำกัดความ CSS นี้ ดังนั้นจึงมีความแตกต่างของเคอร์เซอร์เมื่อคุณวางเมาส์เหนือ "ปุ่ม":

p.given span.b {
  cursor: default;
}

ตัวอย่าง

$(function() {

  document.addEventListener("mousemove", function() {
    var $draggable = $(".ui-draggable-dragging");
    if (!$draggable.length) return; // nothing is being dragged
    var $highlighted = $(".ui-state-highlight");
    if (!$highlighted.length || $($highlighted).index() > 0) return; // first word is not highlighted
    // Get center x coordinate of the item that is being dragged
    var dragX = $draggable.offset().left + $draggable.width() / 2;
    // Get center x coordinate of the first word in the paragraph
    var firstX = $highlighted.offset().left + $highlighted.width() / 2;
    // If draggable is more on the left side of the first word, then only the first word should be highlighted
    if ((dragX < firstX) === ($highlighted.length < 2)) return; // Situation is as it should be
    // Toggle the highlight on the second word of the paragraph
    $highlighted.first().next("span.w").toggleClass("ui-state-highlight");
  });

  function chunkWords(p) {
    var words = p.split(" "),
      b;
    for (var i = 0; i < words.length; i++) {
      if (/\[.+\]/.test(words[i])) {
        b = makeTextBox(words[i].slice(1, -1));
      } else {
        b = $("<span>").addClass("w").text(words[i]);
      }
      // do not pad the value with "&nbsp;" at this moment:
      words[i] = b.prop("outerHTML");
    }

    return words.join("&nbsp;") + "&nbsp;"; // add the spaces here
  }


  function unChunkWords(tObj) {
    var words = "";
    $(tObj).contents().each(function(i, el) {
      if ($(el).hasClass("b")) {

        words += "[" + $(el).text() + "]";
      } else {
        words += $(el).text();
      }
    });

    return words.replace(/\s+/g, " ").trim();
  }

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

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

  function makeDropText(obj) {
    return obj.droppable({
      drop: function(e, ui) {
        var txt = ui.draggable.text();
        // Use proper jQuery to create a new span element
        var newSpan = $("<span>").addClass('w b').text(txt);
        // Determine if the element is being dropped on the first word, and only that one
        if (!$(".ui-state-highlight").last().index()) {
          $(this).before(newSpan, "&nbsp;"); // ...then prepend
        } else {
          $(this).after("&nbsp;", newSpan); // normal case
        }
        makeBtn(newSpan);
        makeDropText(newSpan);
        $("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.b').attr('contentEditable', false);

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

  $("p.given").blur(function() {
    var w = unChunkWords($(this));
    $(this).html(chunkWords(w));
    makeDropText($("p.given span.w"));
    $('.b').attr('contentEditable', false);
  });


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

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

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

p.given span.b {
  cursor: default;
  # add this
}

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;
}

.w ui-droppable {
  cursor: pointer !important;
}

.w.b.ui-droppable {
  background: #FF8;
  color: #000;
}

.given.btn-flat {
  display: inline-block;
  padding: 0.25em 0.5em;
  border-radius: 1em;
  background: #A72020;
  color: #FFF;
  cursor: pointer;
}

.ui-draggable-dragging {
  background: #FFD700 !important;
}
<div class="row">
  <p id="doc_navc" 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">FirstName</span>
            <span class="given btn-flat white-text red lighten-1" rel="4">LastName</span>
          </div>
        </div>
      </div>
    </div>
  </section>
</div>

<input name="Go" id="btnPass" class="tstHeck" type="button" value="Go" onclick="" />
<input name="Go" id="btnTxt" class="tstHeck" type="button" value="Go" onclick="" />

<link rel="stylesheet" href="http://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>

person trincot    schedule 19.11.2019
comment
ปัญหาที่ 2 ยังคงเกิดขึ้นหลังจากข้อเสนอแนะของคุณ ฉันคิดว่าฉันต้องเพิ่มแอตทริบิวต์ contentEditable = false ในขณะที่เพิ่มการเพิ่ม b class ฉันใส่มันไว้ในเหตุการณ์ p.given blur มันทำงานได้ดี ปัญหาคือเมื่อโหลดหน้าเว็บ - person Adam; 20.11.2019
comment
ฉันเพิ่มสิ่งนี้ var newSpan = $("<span contentEditable = 'false'>").addClass('w b').text(txt); และใช้งานได้เฉพาะเมื่อวางองค์ประกอบใหม่เท่านั้น แต่ต้องทำสิ่งเดียวกันสำหรับการโหลดครั้งแรก (ส่วนประกอบลดลงแล้ว) - person Adam; 20.11.2019
comment
ฉันแก้ไขมันด้วยการเพิ่มเหตุการณ์การคลิกเป็น ` $(p.given).click(function() { $('span.b').attr('contentEditable', false); }); ` นี่เป็นสิ่งที่ดี :) - person Adam; 20.11.2019
comment
ฉันทดสอบคำตอบก่อนที่จะเขียน ใช้งานได้: ปุ่มพิเศษเหล่านั้นได้รับ contentEditable: false ฉันเพิ่มตัวอย่างลงในคำตอบของฉันและตรวจสอบองค์ประกอบที่กำลังโหลดและมันก็เป็นเช่นนั้น ฉันไม่เข้าใจว่าทำไมคุณถึงบอกว่าประเด็นที่ 2 ยังคงเกิดขึ้น โปรดตรวจสอบตัวอย่างที่ฉันเพิ่ม และตรวจสอบว่า span Ipsum มีการตั้งค่าแอตทริบิวต์ contentEditable เป็น false ฉันยังไม่เข้าใจว่าคุณบอกว่าคุณแก้ไขได้อย่างไรโดยการเพิ่มเหตุการณ์การคลิก เนื่องจากไม่เกี่ยวข้องกับการโหลดหน้าเว็บ - person trincot; 20.11.2019
comment
ใช่ ฉันตรวจสอบแล้ว แต่ความช่วยเหลือของคุณมีมากสำหรับฉัน ขอบคุณสำหรับสิ่งทั้งหมดที่คุณทำเพื่อฉัน - person Adam; 20.11.2019