【问题标题】:How to use links in Medium Editor?如何在媒体编辑器中使用链接?
【发布时间】:2016-03-13 20:43:27
【问题描述】:

我一直在尝试出色的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');

这个fiddle 演示了这个问题(使用上面的代码)。

  • 如果您将鼠标悬停在链接上,则会出现一个弹出窗口。
  • 如果您单击该链接,则不会发生任何事情。
  • 如果您单击弹出窗口,则会出现一个表单,您可以在其中编辑链接。

在我看来,单击该链接应该会将我带到链接的href 所针对的任何地方。使用该链接的唯一方法是右键单击并在新选项卡或新窗口中打开——我不想让我的用户这样做。

我觉得我必须在配置中遗漏一些简单的东西(Anchor Preview OptionsAnchor Form Options)。不幸的是,我没有看到它。

在我的实际应用中,我使用jQuery,但我使用angularjs。如果不存在严格的 Medium Editor 答案,我可以回退到使用基本 JS 或 angularjs 提供的任何东西。

【问题讨论】:

  • 对不起,伙计。除非您禁用锚预览,否则单击该链接时似乎无法打开该链接。不过,您可以在他们的仓库中打开一个问题。
  • 在这个演示中https://yabwe.github.io/medium-editor/demo.html 同样的事情。
  • @Louy -- 是的,我想这可能就是我要做的 -- 尽管如果有人在接下来的 7 天内解决了这个问题,我会很乐意将赏金奖励给他们 ;-)
  • 我为他们创建了一个issue。我想我们会看到他们说什么。
  • 如果您按住 shift 或 control 并单击链接,它将在 firefox 中打开(控制新选项卡,移动新窗口)。在 IE 10 中,按住控件并单击弹出链接将起作用。在 Chrome 中,两者都不起作用

标签: javascript medium-editor


【解决方案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/

【讨论】:

  • 不错。这可能比我试图用 angular 做的更好。
  • 我会等待官方解决方案,它没有在所有浏览器/设备/等中测试...
  • @mgilson 谢谢。我想,在阅读了您在 Github 中打开的问题后,他们将讨论如何实现 Google Docs 中的链接功能。
  • 是的。我授予您赏金,因为如果我不授予它,那么没有人会受益,并且您在 cmets 中的建议(以及随后发布的解决方案)使我能够在他们讨论更永久的解决方案时创建一个可以通过的解决方案。如果他们没有创建更永久的解决方案,我可以自己通过扩展他们在文档中提到的锚预览插件来完成。再次感谢您帮助我解决这个问题!
【解决方案2】:

所以 medium-editor 是建立在对 contenteditable 元素的内置浏览器支持之上的。当您实例化 medium-editor 时,它会将 contenteditable=true 属性添加到您提供的任何元素中。

默认情况下,由于文本现在是可编辑的(contenteditable 属性使浏览器将其视为所见即所得的文本)浏览器不再支持单击链接进行导航。因此,medium-editor 并没有阻止这些链接点击的发生,浏览器本身就是将其作为使文本可编辑的一部分。

medium-editor 内置了与链接交互的扩展:

  • 锚扩展
    • 允许添加/删除链接
  • 锚预览扩展
    • 悬停链接时显示工具提示
    • 单击工具提示时,允许通过锚扩展编辑链接的 href

我认为编辑器的潜在目标是这里的误解。编辑器允许编辑文本,并且为了添加/删除/更新链接,您需要能够在不自动导航的情况下单击它。这就是我认为的“编辑”模式。

但是,编辑生成的 html 是有效的 html,如果您将该 html 放入不具有 contenteditable=true 属性的元素中,一切都会按预期工作。我认为这是“发布模式”

我查看了 word 或 google docs 之类的编辑器,您会看到类似的行为,当您编辑文档时,链接不仅会在您单击它们时离开,您必须实际选择导航它们单击链接后通过单独的操作。但是,在文档的“已发布”版本上,单击链接实际上会打开一个浏览器窗口并在那里导航。

我认为这确实是一个很好的建议,可以作为对现有锚预览扩展的增强。悬停链接时出现的工具提示可能有多个选项(即编辑链接 | 删除链接 | 导航到 URL)。

tldr;

通过内置的所见即所得支持 (contenteditable) 在浏览器中“编辑”文本时,链接无法在点击时导航。当不在“编辑”模式下时,链接将按预期工作。 这可以很好地增强媒体编辑器锚预览扩展。

【讨论】:

    【解决方案3】:

    根据 cmets 中 @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 是 Angular 的 $window 服务 -- 如果你不使用 angularjswindow 可以解决问题,我使用 angular.element 来简化事件监听器注册表,但是你可以用老式的方式(或使用你选择的 JS 框架)。

    【讨论】:

    • 好吧,它会起作用,但也许我们可以添加一个简单的选项。那么您的用户将如何编辑链接?
    • @j0k -- 如果您将链接悬停并单击弹出窗口,则该链接是可编辑的(基本上,它的可编辑方式与通常在媒体编辑器中可编辑链接的方式相同)。点击链接直接进入网站。
    【解决方案4】:

    当我问这个问题时,我真正想要的是在“编辑”模式 (as described by Nate Mielnik) 下类似于 Google Docs 的行为。我打开了一个issue on the Medium Editor tracker,他们决定不将其作为核心媒体编辑器的一部分来实现,但他们指出,他们很乐意有人将该功能添加为扩展。

    因此,我决定按照建议将该功能作为扩展来实现。它可以作为MediumTools1 的一部分找到。该项目仍处于非常早期的阶段(例如,我没有做任何事情来使样式看起来更好,或者使用更好的缩小实践等,但我们很乐意接受拉取请求)。

    代码的核心是这样的:

    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 的基本实现中借用了很多东西,但我将新的操作绑定到每个链接上。最后,我需要在单击“删除”时执行“取消链接”链接的操作,因此我为此添加了一个方法。使用 contenteditable 魔法(以确保它是浏览器撤消堆栈的一部分),取消链接方法可能会做得更好一些,但我没有花时间去弄清楚(尽管它会为任何有兴趣的人:-)。

    1目前,它是唯一的部分,但我希望这会在某个时候改变。 . .

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2022-09-24
      • 2016-03-30
      • 1970-01-01
      相关资源
      最近更新 更多