Как я могу ввести текст после удаления содержимого

Я использую перетаскиваемый компонент пользовательского интерфейса jQuery для добавления к редактируемому содержимому.

.Этот код работает, чтобы найти, и у меня есть небольшие проблемы. Проблема в том, что я удалил перетаскиваемый компонент как последнее слово абзаца. Я не могу набирать текст после этого удаленного компонента.

и вторая проблема заключается в том, что мне нужно отключить параметр 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. Я добавил фрагмент к своему ответу и проверил элемент при загрузке, и он есть. Я не понимаю, почему вы говорите, что вторая проблема все еще возникает. Пожалуйста, проверьте фрагмент, который я добавил, и убедитесь, что span Ipsum имеет атрибут contentEditable, установленный на false. Я также не понимаю, как вы говорите, что решили эту проблему, добавив событие клика, поскольку это не имеет ничего общего с загрузкой страницы. - person trincot; 20.11.2019
comment
Да, я проверил это, сэр, однако ваша помощь очень важна для меня. Спасибо за все, что вы для меня делаете. - person Adam; 20.11.2019