如何在 Medium Editor 中使用链接?
How to use links in Medium Editor?
我一直在尝试优秀的Medium Editor。我一直遇到的问题是我似乎无法将 links 转换为 "work"。
最简单的,这里有一些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 演示了问题(使用上面的代码)。
- 如果将鼠标悬停在 link 上,会出现一个弹出窗口。
- 如果您单击 link,什么也不会发生。
- 如果单击弹出窗口,将出现一个表单,您可以在其中编辑 link。
在我看来,单击 link 应该会将我带到 link 的 href
所定位的任何位置。使用 link 的唯一方法是右键单击并在新选项卡或新选项卡中打开 window -- 我不想让我的用户这样做。
我觉得我一定是在配置中遗漏了一些简单的东西(Anchor Preview Options or the Anchor Form Options)。很遗憾,我没有看到它。
在我的实际应用中,我不是使用jQuery
,而是使用angularjs
。如果不存在严格的 Medium Editor 答案,我可以退回到使用基本 JS 或 angularjs 提供的任何东西。
根据评论中@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
服务 -- 如果您不使用 angularjs
,window
可以做到这一点,我使用 angular.element
来简化事件侦听器注册表,但您可以使用 old-fashioned 方式(或使用您选择的 JS 框架)。
我找到了如何绑定事件。
这是完整的事件列表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)}})
因此 medium-editor 建立在 built-in 浏览器支持 contenteditable
元素之上。当您实例化 medium-editor 时,它会将 contenteditable=true
属性添加到您提供的任何元素中。
默认情况下,由于文本现在是可编辑的(contenteditable
属性使浏览器将其视为所见即所得文本),浏览器不再支持单击 link 进行导航。因此,medium-editor 并没有阻止这些 link 点击的发生,浏览器本身就是这样做的,作为使文本可编辑的一部分。
medium-editor 内置了与 link 交互的扩展:
- 锚扩展
- 允许 adding/removing links
- anchor-preview 分机
- 悬停 link
时显示工具提示
- 单击工具提示时,允许通过锚扩展编辑 link 的 href
我觉得小编的目的就是这里的误会。编辑器允许编辑文本,为了 add/remove/update link,您需要能够单击它而不会自动离开。这就是我认为的 'edit' 模式。
但是,由于编辑而产生的 html 是有效的 html,如果您将 html 放在一个没有 [= 的元素中11=] 属性,一切都会按预期工作。我认为这是 'publish mode'
我查看像 word 或 google 文档这样的编辑器,您会看到类似的行为,当您编辑文档时,links 不会在您单击时离开在它们上,您必须在单击 link 后实际选择通过单独的操作来导航它们。但是,在文档的 'published' 版本中,单击 link 实际上会打开浏览器 window 并导航到那里。
我认为这确实是一个很好的建议,作为对现有 anchor-preview 扩展的增强。悬停 link 时出现的工具提示可能有多个选项(即编辑 Link | 删除 Link | 导航至 URL)。
tldr;
当 'editing' 文本在浏览器中通过 built-in 所见即所得支持 (contenteditable
) 时,Link 无法在单击时导航。当不处于 'edit' 模式时,links 将按预期工作。
这可以很好地增强 medium-editor anchor-preview 扩展。
当我问这个问题时,我真正想要的是在 "edit" 模式下类似于 Google Docs 的行为(). I opened an issue on the Medium Editor tracker 他们决定不将其作为核心的一部分来实现中型编辑器,但他们指出,他们很乐意有人将该功能添加为扩展。
因此,我决定按照建议将该功能作为扩展来实现。它可以作为 MediumTools1 的一部分找到。该项目仍处于非常早期的阶段(例如,我没有做任何事情来使样式看起来更好,或者使用更好的缩小实践等。但我们很乐意为此接受 Pull Requests)。
代码的内容如下所示:
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();
}
}
});
作为解释,我只是使用 medium 的原型继承风格 "subclass" original/builtin AnchorPreview
扩展。我重写 getTemplate
方法以将额外的 link 添加到标记中。然后我从 getPreview
的基本实现中借鉴了很多,但我将新的操作绑定到每个 link 中。最后,我需要在单击 "Remove" 时对 "unlinking" 和 link 执行操作,因此我为此添加了一个方法。 unlink 方法可能可以使用 contenteditable magic 做得更好(以确保它是浏览器撤消堆栈的一部分),但我没有花时间去弄明白(尽管它会使对任何感兴趣的人来说都是一个很好的 Pull Request :-).
1目前,这只是 的一部分,但我希望这会在某个时候改变。 . .
我一直在尝试优秀的Medium Editor。我一直遇到的问题是我似乎无法将 links 转换为 "work"。
最简单的,这里有一些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 演示了问题(使用上面的代码)。
- 如果将鼠标悬停在 link 上,会出现一个弹出窗口。
- 如果您单击 link,什么也不会发生。
- 如果单击弹出窗口,将出现一个表单,您可以在其中编辑 link。
在我看来,单击 link 应该会将我带到 link 的 href
所定位的任何位置。使用 link 的唯一方法是右键单击并在新选项卡或新选项卡中打开 window -- 我不想让我的用户这样做。
我觉得我一定是在配置中遗漏了一些简单的东西(Anchor Preview Options or the Anchor Form Options)。很遗憾,我没有看到它。
在我的实际应用中,我不是使用jQuery
,而是使用angularjs
。如果不存在严格的 Medium Editor 答案,我可以退回到使用基本 JS 或 angularjs 提供的任何东西。
根据评论中@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
服务 -- 如果您不使用 angularjs
,window
可以做到这一点,我使用 angular.element
来简化事件侦听器注册表,但您可以使用 old-fashioned 方式(或使用您选择的 JS 框架)。
我找到了如何绑定事件。
这是完整的事件列表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)}})
因此 medium-editor 建立在 built-in 浏览器支持 contenteditable
元素之上。当您实例化 medium-editor 时,它会将 contenteditable=true
属性添加到您提供的任何元素中。
默认情况下,由于文本现在是可编辑的(contenteditable
属性使浏览器将其视为所见即所得文本),浏览器不再支持单击 link 进行导航。因此,medium-editor 并没有阻止这些 link 点击的发生,浏览器本身就是这样做的,作为使文本可编辑的一部分。
medium-editor 内置了与 link 交互的扩展:
- 锚扩展
- 允许 adding/removing links
- anchor-preview 分机
- 悬停 link 时显示工具提示
- 单击工具提示时,允许通过锚扩展编辑 link 的 href
我觉得小编的目的就是这里的误会。编辑器允许编辑文本,为了 add/remove/update link,您需要能够单击它而不会自动离开。这就是我认为的 'edit' 模式。
但是,由于编辑而产生的 html 是有效的 html,如果您将 html 放在一个没有 [= 的元素中11=] 属性,一切都会按预期工作。我认为这是 'publish mode'
我查看像 word 或 google 文档这样的编辑器,您会看到类似的行为,当您编辑文档时,links 不会在您单击时离开在它们上,您必须在单击 link 后实际选择通过单独的操作来导航它们。但是,在文档的 'published' 版本中,单击 link 实际上会打开浏览器 window 并导航到那里。
我认为这确实是一个很好的建议,作为对现有 anchor-preview 扩展的增强。悬停 link 时出现的工具提示可能有多个选项(即编辑 Link | 删除 Link | 导航至 URL)。
tldr;
当 'editing' 文本在浏览器中通过 built-in 所见即所得支持 (contenteditable
) 时,Link 无法在单击时导航。当不处于 'edit' 模式时,links 将按预期工作。 这可以很好地增强 medium-editor anchor-preview 扩展。
当我问这个问题时,我真正想要的是在 "edit" 模式下类似于 Google Docs 的行为(
因此,我决定按照建议将该功能作为扩展来实现。它可以作为 MediumTools1 的一部分找到。该项目仍处于非常早期的阶段(例如,我没有做任何事情来使样式看起来更好,或者使用更好的缩小实践等。但我们很乐意为此接受 Pull Requests)。
代码的内容如下所示:
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();
}
}
});
作为解释,我只是使用 medium 的原型继承风格 "subclass" original/builtin AnchorPreview
扩展。我重写 getTemplate
方法以将额外的 link 添加到标记中。然后我从 getPreview
的基本实现中借鉴了很多,但我将新的操作绑定到每个 link 中。最后,我需要在单击 "Remove" 时对 "unlinking" 和 link 执行操作,因此我为此添加了一个方法。 unlink 方法可能可以使用 contenteditable magic 做得更好(以确保它是浏览器撤消堆栈的一部分),但我没有花时间去弄明白(尽管它会使对任何感兴趣的人来说都是一个很好的 Pull Request :-).
1目前,这只是 的一部分,但我希望这会在某个时候改变。 . .