使用getSelection来包装链接中的链接

时间:2013-05-15 20:36:17

标签: javascript getselection

我一直盯着这个问题已经有一段时间了,并没有设法找到一个有效的解决方案。

我正在使用Rangy库来确保Ranges的最佳支持。

目标

  1. 进行选择并使用链接进行换行。即使选择是在链接中。
  2. 完整选择已经链接的选择并将其替换为链接。
  3. 示例

    我想转换以下内容,其中|是一个选择范围。

      link to |add a link| to
    
    <a href="http://example.com">link to |add a link| to</a>
    

    预期

      link to |add a link| to
    
    <a href="http://example.com">link to</a> |<a href="http://example.com/pre">add a link</a>| <a href="http://example.com">to</a>
    

    Test Expectations Plnkr

    我感谢你的帮助。

    更新(2013-05-15 21:37 UTC):

    我有以下

    range = document.getSelection();
    link = document.createElement('a');
    link.href = "http://example.com/new";
    range.surroundContents(link);
    

    我还更新了plnkr tests

1 个答案:

答案 0 :(得分:0)

我设法找到了一个允许支持所有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');

see the tests and live code on plnkr.co