在 contenteditable 元素中插入链接 [英] Insert link in contenteditable element
问题描述
我正在开发一个简单的博客系统,我正在使用 contenteditable 以便用户可以设置文本格式.
I'm working on a simple blog system and I'm using contenteditable so that users can format the text.
到目前为止,一切都像一个魅力.
Up to now everything works like a charm.
接下来我想要的是用户可以在文本中添加超链接.
Next thing i want is that users can add a hyperlink in the text.
用户必须选择(部分)文本并点击链接按钮.之后会打开一个弹出窗口,用户应在其中输入链接地址.
The user have to select (part of) the text and click on the link button. After that a popup opens where users should enter the link address.
当用户点击接受按钮时,我想将链接添加到他们在 contenteditable 中选择的文本.
When the user clicks on the accept button I want to add the link to the text they selected in the contenteditable.
如何实现此功能,因为我不知道如何执行此操作?
How can I implement this functionality, since I have no clue how to do this?
我的网站:http://82.170.147.49/blog/3/alpha-release一个>
我网站的jsFiddle:http://jsfiddle.net/qhN9j/
jsFiddle of my site: http://jsfiddle.net/qhN9j/
推荐答案
document.execCommand()
在所有主流浏览器中为您做到这一点:
document.execCommand()
does this for you in all major browsers:
document.execCommand("CreateLink", false, "http://stackoverflow.com/");
要在显示链接对话框时保留选择,您可以使用以下功能:
To preserve the selection while your link dialog is displayed, you can use the following functions:
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
var ranges = [];
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
return ranges;
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(savedSel) {
if (savedSel) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSel.length; i < len; ++i) {
sel.addRange(savedSel[i]);
}
} else if (document.selection && savedSel.select) {
savedSel.select();
}
}
}
jsFiddle 示例:http://jsfiddle.net/JRKwH/1/
jsFiddle example: http://jsfiddle.net/JRKwH/1/
更新
获取创建的链接(如果有的话)是很棘手的.您可以使用我自己的 Rangy 库:
To get hold of the link(s) created (if any were created at all) is tricky. You could use my own Rangy library:
var sel = rangy.getSelection();
if (sel.rangeCount) {
var links = sel.getRangeAt(0).getNodes([1], function(el) {
return el.nodeName.toLowerCase() == "a";
});
alert(links.length);
}
... 或类似以下内容:
... or something like the following:
function getLinksInSelection() {
var selectedLinks = [];
var range, containerEl, links, linkRange;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
linkRange = document.createRange();
for (var r = 0; r < sel.rangeCount; ++r) {
range = sel.getRangeAt(r);
containerEl = range.commonAncestorContainer;
if (containerEl.nodeType != 1) {
containerEl = containerEl.parentNode;
}
if (containerEl.nodeName.toLowerCase() == "a") {
selectedLinks.push(containerEl);
} else {
links = containerEl.getElementsByTagName("a");
for (var i = 0; i < links.length; ++i) {
linkRange.selectNodeContents(links[i]);
if (linkRange.compareBoundaryPoints(range.END_TO_START, range) < 1 && linkRange.compareBoundaryPoints(range.START_TO_END, range) > -1) {
selectedLinks.push(links[i]);
}
}
}
}
linkRange.detach();
}
} else if (document.selection && document.selection.type != "Control") {
range = document.selection.createRange();
containerEl = range.parentElement();
if (containerEl.nodeName.toLowerCase() == "a") {
selectedLinks.push(containerEl);
} else {
links = containerEl.getElementsByTagName("a");
linkRange = document.body.createTextRange();
for (var i = 0; i < links.length; ++i) {
linkRange.moveToElementText(links[i]);
if (linkRange.compareEndPoints("StartToEnd", range) > -1 && linkRange.compareEndPoints("EndToStart", range) < 1) {
selectedLinks.push(links[i]);
}
}
}
}
return selectedLinks;
}
jsFiddle:http://jsfiddle.net/JRKwH/3/
这篇关于在 contenteditable 元素中插入链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!