Insert link in contenteditable element

前端 未结 5 1687
灰色年华
灰色年华 2020-12-04 11:26

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

5条回答
  •  被撕碎了的回忆
    2020-12-04 12:23

    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 example: http://jsfiddle.net/JRKwH/1/

    UPDATE

    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/

提交回复
热议问题