我设法找到了一个支持所有 3 个场景的解决方案。
rangy.createModule('SafeWrapLink', function(api, module) {
var surroundSelectionWithLink;
surroundSelectionWithLink = (function(href) {
var after, afterLink, afterLinkHref, before, beforeLink, beforeLinkHref, currentLink, fullText, link, par, parNode, range, selectionText;
range = document.getSelection().getRangeAt(0);
selectionText = range.toString();
if (range.commonAncestorContainer.nodeName !== "#text") {
beforeLinkHref = range.commonAncestorContainer.childNodes[0].getAttribute('href');
afterLinkHref = range.commonAncestorContainer.childNodes[2].getAttribute('href');
par = range.commonAncestorContainer;
parNode = par;
} else {
par = range.commonAncestorContainer.parentNode;
currentLink = par.getAttribute('href');
parNode = par.parentNode;
}
fullText = par.innerText;
before = fullText.match(new RegExp("^(.*)" + selectionText))[1];
after = fullText.match(new RegExp(selectionText + "(.*)$"))[1];
// Build link for before selection
beforeLink = document.createElement('a');
beforeLink.href = beforeLinkHref || currentLink;
beforeLink.innerText = before;
// Build link to insert
link = document.createElement('a');
link.href = href;
link.innerText = selectionText;
// Build link for after selection
afterLink = document.createElement('a');
afterLink.href = afterLinkHref || currentLink;
afterLink.innerText = after;
// Append the links in order
if (beforeLink.innerText.length > 0) {
parNode.appendChild(beforeLink);
}
parNode.appendChild(link);
if (afterLink.innerText.length > 0) {
parNode.appendChild(afterLink);
}
// remove old linking
if (par === range.commonAncestorContainer) {
par.removeChild(par.childNodes[0]);
return par.removeChild(par.childNodes[1]);
} else {
return parNode.removeChild(par);
}
});
return api.util.extend(api, {
surroundSelectionWithLink: surroundSelectionWithLink
});
});
然后在进行选择后调用以下
rangy.surroundSelectionWithLink('http://www.example.com/added');
在 plnkr.co 上查看测试和实时代码