Как использовать ссылки в Medium Editor?

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

Проще говоря, вот некоторые HTML/JS, которые можно использовать для демонстрации проблемы:

HTML:

<html>
<head>
  <script src="//cdn.jsdelivr.net/medium-editor/latest/js/medium-editor.min.js"></script>
  <link rel="stylesheet" href="//cdn.jsdelivr.net/medium-editor/latest/css/medium-editor.min.css" type="text/css" media="screen" charset="utf-8">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/medium-editor/latest/css/themes/beagle.min.css" type="text/css">
</head>
<body>
  <div class='editable'>
    Hello world.  <a href="http://www.google.com">link</a>
  </div>
</body>
</html>

Javascript:

var editor = new MediumEditor('.editable');

Эта скрипка демонстрирует проблему (используя код выше).

  • Если вы наведите указатель мыши на ссылку, появится всплывающее окно.
  • Если вы нажмете на ссылку, ничего не происходит.
  • Если вы нажмете всплывающее окно, появится форма, где вы можете редактировать ссылку.

Мне кажется, что нажатие на ссылку должно привести меня туда, где ссылка href нацеливается. Единственный способ использовать ссылку - это щелкнуть правой кнопкой мыши и открыть либо в новой вкладке, либо в новом окне - что я не хочу просить моих пользователей.

Мне кажется, что в конфигурации мне не хватает чего-то простого (либо параметров предварительного просмотра привязки, либо параметров формы привязки). К сожалению, я этого не вижу.

В моем реальном приложении я не использую jQuery , но я использую angularjs , Если ответа строго среднего редактора не существует, я могу вернуться к использованию базового JS или всего, что предоставляет angularjs.

4 ответа

Решение

Что я действительно хотел, когда задавал вопрос, так это поведение, аналогичное Google Docs, в режиме "редактирования" ( как описано Нейтом Мельником). Я открыл проблему с трекером Medium Editor, и они решили не реализовывать ее как часть основного редактора среды, но отметили, что будут рады, если кто-то добавит эту функцию в качестве расширения.

Итак, я решил реализовать эту функциональность как расширение, как было предложено. Его можно найти как часть MediumTools 1. Проект все еще находится на очень ранних стадиях (например, я ничего не сделал для того, чтобы стиль выглядел лучше, или использовал лучшие практики минимизации, и т. Д., Но мы с радостью примем для этого запросы Pull)

Внутренности кода выглядят так:

var ClassName = {
  INNER: 'medium-editor-toolbar-anchor-preview-inner',
  INNER_CHANGE: 'medium-editor-toolbar-anchor-preview-inner-change',
  INNER_REMOVE: 'medium-editor-toolbar-anchor-preview-inner-remove'
}

var AnchorPreview = MediumEditor.extensions.anchorPreview;
GdocMediumAnchorPreview = MediumEditor.Extension.extend.call(
  AnchorPreview, {

    /** @override */
    getTemplate: function () {
      return '<div class="medium-editor-toolbar-anchor-preview">' +
        '  <a class="' + ClassName.INNER + '"></a>' +
        '  -' +
        '  <a class="' + ClassName.INNER_CHANGE + '">Change</a>' +
        '  |' +
        '  <a class="' + ClassName.INNER_REMOVE + '">Remove</a>' +
        '</div>';
    },

    /** @override */
    createPreview: function () {
      var el = this.document.createElement('div');

      el.id = 'medium-editor-anchor-preview-' + this.getEditorId();
      el.className = 'medium-editor-anchor-preview';
      el.innerHTML = this.getTemplate();

      var targetBlank =
          this.getEditorOption('targetBlank') ||
          this.getEditorOption('gdocAnchorTargetBlank');
      if (targetBlank) {
        el.querySelector('.' + ClassName.INNER).target = '_blank';
      }

      var changeEl = el.querySelector('.' + ClassName.INNER_CHANGE);
      this.on(changeEl, 'click', this.handleClick.bind(this));

      var unlinkEl = el.querySelector('.' + ClassName.INNER_REMOVE);
      this.on(unlinkEl, 'click', this.handleUnlink.bind(this));

      return el;
    },

    /** Unlink the currently active anchor. */
    handleUnlink: function() {
      var activeAnchor = this.activeAnchor;
      if (activeAnchor) {
        this.activeAnchor.outerHTML = this.activeAnchor.innerHTML;
        this.hidePreview();
      }
    }
  });

В качестве объяснения я просто использую среду прототипного наследования среды, чтобы "подклассить" оригинал / встроенный AnchorPreview расширение. Я отменяю getTemplate Способ добавления дополнительных ссылок в разметку. Тогда я много позаимствовал из базовой реализации getPreview, но я связал новые действия с каждой из ссылок в зависимости от обстоятельств. Наконец, мне нужно было выполнить действие для "отсоединения" ссылки при нажатии "Удалить", поэтому я добавил метод для этого. Метод unlink, вероятно, можно было бы сделать немного лучше, используя contenteditable magic (чтобы убедиться, что он является частью стека отмены браузера), но я не тратил время на то, чтобы это выяснить (хотя это сделало бы хороший Pull Request для кому интересно:-).

1 В настоящее время это единственная часть, но я надеюсь, что она изменится в какой-то момент. , ,

Я нашел, как связать событие.

Вот полный список событий https://github.com/yabwe/medium-editor/blob/master/CUSTOM-EVENTS.md

Попробуйте изменить свой код на

var editor = new MediumEditor('.editable')
    .subscribe("editableClick", function(e){if (e.target.href) {window.open(e.target.href)}})

https://jsfiddle.net/fhr18gm1/

Таким образом, редактор среднего уровня построен поверх встроенной поддержки браузера для contenteditable элементы. Когда вы создаете экземпляр среднего редактора, он добавит contenteditable=true приписать любой элемент (ы), которые вы предоставили.

По умолчанию, так как текст теперь редактируемый (contenteditable Атрибут заставляет браузер воспринимать его как текст WYSIWYG) браузер больше не поддерживает нажатие на ссылки для навигации. Таким образом, редактор среднего уровня не блокирует эти щелчки по ссылкам, а браузеры делают это по сути как часть редактирования текста.

medium-editor имеет встроенные расширения для взаимодействия со ссылками:

  • расширение якоря
    • позволяет добавлять / удалять ссылки
  • расширение предварительного просмотра
    • показывает всплывающую подсказку при наведении ссылки
    • при нажатии всплывающей подсказки позволяет редактировать ссылку на ссылку через расширение якоря

Я думаю, что основной целью редактора является недоразумение здесь. Редактор позволяет редактировать текст, и чтобы добавлять / удалять / обновлять ссылки, вы должны иметь возможность щелкать по нему без автоматической навигации. Это то, что я считаю режимом редактирования.

Однако html, созданный в результате редактирования, является действительным html, и если вы возьмете этот html и поместите его в элемент, который НЕ имеет contenteditable=true атрибут, все будет работать как положено. Я думаю об этом как "режим публикации"

Я смотрю на редакторов, как Word или Google Docs, и вы видите похожий тип поведения, при котором, когда вы редактируете документ, ссылки не просто уходят, когда вы нажимаете на них, вы фактически должны выбрать для навигации по ним действие после нажатия на ссылку. Однако в "опубликованной" версии документа, щелкнув ссылку, вы фактически откроете окно браузера и перейдете туда.

Я думаю, что это делает хорошее предложение как расширение существующего расширения предварительного просмотра. Возможно, всплывающая подсказка, появляющаяся при наведении на ссылку, может иметь несколько параметров (например, "Редактировать ссылку | Удалить ссылку | Перейти к URL").

tldr;

Ссылки не доступны при щелчке при "редактировании" текста в браузере с помощью встроенной поддержки WYSIWYG (contenteditable). Когда режим не находится в режиме редактирования, ссылки будут работать как положено. Это могло бы стать хорошим дополнением к расширению anchor-preview среднего редактора.

Отработав некоторые идеи от @Valijon в комментариях, я смог заставить его работать, используя следующий код:

var iElement = angular.element(mediumEditorElement);

iElement.on('click', function(event) {
  if (
      event.target && event.target.tagName == 'A' &&
      event.target.href && !event.defaultPrevented) {
    $window.open(event.target.href, '_blank');
  }
});

Я думаю, что ключ в том, что, очевидно, редактор позволяет событию распространяться на элементы предка, поэтому я смог просто прослушать щелчок по элементу редактора верхнего уровня.

Вот, $window угловой $window сервис - если вы не используете angularjs , window сделал бы трюк, и я использовал angular.element упростить реестр слушателей событий, но вы могли бы сделать это старомодным способом (или использовать JS-фреймворк по вашему выбору).

Другие вопросы по тегам