Переместить курсор за интервал в редактируемом контенте - PullRequest
1 голос
/ 31 марта 2020

Я создаю систему ввода тегов для конструктора шаблонов. Прямо сейчас я пытаюсь помочь своему редактору «узнать» разницу между обычным текстом и форматированным текстом, потому что сейчас я делаю это так, как если бы я использовал шорткоды WordPress, где шаблонный элемент был бы похож на [shortcode] Но проблема в том, что я прямо сейчас сталкиваюсь с тем, что курсор моего div включает в себя любой текст, введенный после вставленного шорткода в стилизованный div.

$(function() {
  /**
   * Position tracking.
   */
  class PositionTracker {
    constructor(start, end) {
      this.start = start;
      this.end = end;
    }
  }

  /**
   * Variable insert selector
   * @type {jQuery|HTMLElement}
   */
  const $selector = $("#variableSelector");
  /**
   * Message content editor
   * @type {jQuery|HTMLElement}
   */
  const $body = $("#bodyContent");
  /**
   * Message Recorder
   * @type {jQuery|HTMLElement}
   */
  const $recorder = $('#bodyRecorder');


  /**
   * Position of cursor
   * @type {PositionTracker}
   */
  const position = new PositionTracker(0, 0);

  $selector.on('change', function() {
    let content = $body.html();
    let tag = $('<span>', {
      class: 'text-tag',
      text: $(this).val().toString()
    });
    $body.append(tag);
  });
  $body.on('input mousedown mouseup mouseout', function() {
    $recorder.val($(this).html);
    let selection = window.getSelection();
    position.start = selection.anchorOffset;
    position.end = selection.focusOffset;
  });

});
.text-editor {
  background: #fff;
  margin: 1rem 0;
  padding: 10px 8px;
  font: inherit;
  font-size: 1.15em;
  line-height: 1.35;
  color: #000;
  border: solid 1px rgba(6, 26, 45, 0.65);
  box-shadow: inset 2px 2px 6px rgba(4, 24, 39, 0.35);
}

.text-editor:focus {
  outline: none;
}

.text-editor[contenteditable=true]:empty:before {
  color: darkgray;
  content: attr(placeholder);
  pointer-events: none;
  display: block;
  /* For Firefox */
}

.text-editor.body {
  min-height: 170px;
}

.text-tag {
  background: rgba(0, 195, 255, 0.1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input name="content" type="hidden" id="contentRecoreder" required="required">
  <div id="bodyContent" contenteditable="true" class="content-body text-editor" placeholder="Hi [customer-name], this is [my-name] with [my-company]. We can do that job for just [quote-price]. If you have any questions, call or text us at [my-phone]"></div>

  <label>Variables</label>
  <select name="variables" id="variableSelector">
    <option value="empty">(choose one)</option>
    <option value="[customer-name]">Customer Name</option>
    <option value="[my-name]">My Name</option>
    <option value="[my-company]">My Company</option>
    <option value="[my-price" ]>Quote Price</option>
    <option value="[my-phone]">My Phone</option>
  </select>

  <button type="submit">Save</button>
</form>

1 Ответ

0 голосов
/ 31 марта 2020

Могут быть и другие способы добиться этого, но одним простым способом будет добавить атрибут contenteditable к вашему элементу span и установить его значение на false - отметив, что это необходимо сделать после того, как вы его заполнили ваше shortcode значение.

Обратите внимание, что, хотя это не «перемещает курсор», оно предотвращает ввод текста, введенного после вставленного шорткода, в стилизованный интервал. Что, когда вы думаете об этом, вероятно, то, что вы на самом деле хотите - иначе ваши shotcode теги будут доступны для редактирования, просто нажав на них печатая.

например

$(function() {
  /**
   * Position tracking.
   */
  class PositionTracker {
    constructor(start, end) {
      this.start = start;
      this.end = end;
    }
  }

  /**
   * Variable insert selector
   * @type {jQuery|HTMLElement}
   */
  const $selector = $("#variableSelector");
  /**
   * Message content editor
   * @type {jQuery|HTMLElement}
   */
  const $body = $("#bodyContent");
  /**
   * Message Recorder
   * @type {jQuery|HTMLElement}
   */
  const $recorder = $('#bodyRecorder');


  /**
   * Position of cursor
   * @type {PositionTracker}
   */
  const position = new PositionTracker(0, 0);

  $selector.on('change', function() {
    let content = $body.html();
    let tag = $('<span>', {
      class: 'text-tag',
      text: $(this).val().toString()
    });
    // prevent editing of the span content
    tag.attr('contenteditable', false);
    $body.append(tag);
  });
  $body.on('input mousedown mouseup mouseout', function() {
    $recorder.val($(this).html);
    let selection = window.getSelection();
    position.start = selection.anchorOffset;
    position.end = selection.focusOffset;
  });

});
.text-editor {
  background: #fff;
  margin: 1rem 0;
  padding: 10px 8px;
  font: inherit;
  font-size: 1.15em;
  line-height: 1.35;
  color: #000;
  border: solid 1px rgba(6, 26, 45, 0.65);
  box-shadow: inset 2px 2px 6px rgba(4, 24, 39, 0.35);
}

.text-editor:focus {
  outline: none;
}

.text-editor[contenteditable=true]:empty:before {
  color: darkgray;
  content: attr(placeholder);
  pointer-events: none;
  display: block;
  /* For Firefox */
}

.text-editor.body {
  min-height: 170px;
}

.text-tag {
  background: rgba(0, 195, 255, 0.1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input name="content" type="hidden" id="contentRecoreder" required="required">
  <div id="bodyContent" contenteditable="true" class="content-body text-editor" placeholder="Hi [customer-name], this is [my-name] with [my-company]. We can do that job for just [quote-price]. If you have any questions, call or text us at [my-phone]"></div>

  <label>Variables</label>
  <select name="variables" id="variableSelector">
    <option value="empty">(choose one)</option>
    <option value="[customer-name]">Customer Name</option>
    <option value="[my-name]">My Name</option>
    <option value="[my-company]">My Company</option>
    <option value="[my-price" ]>Quote Price</option>
    <option value="[my-phone]">My Phone</option>
  </select>

  <button type="submit">Save</button>
</form>

Редактировать (см. Комментарии):

showing multiple tags

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...