删除输入#光标以外的所选(突出显示的元素)

时间:2011-10-03 20:49:44

标签: javascript

我有这个功能可以删除所选的(光标)突出显示的元素:

function deleteSelection() {
    if (window.getSelection) {
        // Mozilla
        var selection = window.getSelection();
        if (selection.rangeCount > 0) {
            window.getSelection().deleteFromDocument();
            window.getSelection().removeAllRanges();
        }
    } else if (document.selection) {
        // Internet Explorer
        var ranges = document.selection.createRangeCollection();
        for (var i = 0; i < ranges.length; i++) {
            ranges[i].text = "";
        }
    }
}

我真正想要做的是删除所有以光标突出显示的元素,输入#cursor元素除外。

编辑:

所以我想说如果用光标突出显示这些元素:

<span>a</span>
<span>b</span>
<input type='text' id = 'cursor' />
<span>c</span>
<span>d</span>

在密钥上,此功能不应删除<input> ...仅<span>

2 个答案:

答案 0 :(得分:1)

Phew,这比预期的要难一点!

这是代码,我在IE8和Chrome 16 / FF5中进行了测试。我曾经测试的JSFiddle可用here。 AFAIK,这可能是你获得的最佳性能。

我用于Moz的文档:SelectionRangeDocumentFragment。 IE:TextRange

function deleteSelection() {
    // get cursor element
    var cursor = document.getElementById('cursor');

    // mozilla
    if(window.getSelection) {
        var selection = window.getSelection();
        var containsCursor = selection.containsNode(cursor, true);

        if(containsCursor) {
            var cursorFound = false;
            for(var i=0; i < selection.rangeCount; i++) {
                var range = selection.getRangeAt(i);
                if(!cursorFound) {                 
                    // extracts tree from DOM and gives back a fragment
                    var contents = range.extractContents();
                    // check if tree fragment contains our cursor
                    cursorFound = containsChildById(contents, 'cursor');
                    if(cursorFound) range.insertNode(cursor); // put back in DOM
                }
                else {
                    // deletes everything in range
                    range.deleteContents();
                }
            }  
        }
        else {
            selection.deleteFromDocument();
        }
        // removes highlight   
        selection.removeAllRanges();
    }
    // ie
    else if(document.selection) {
        var ranges = document.selection.createRangeCollection();
        var cursorFound = false;
        for(var i=0; i < ranges.length; i++) {
            if(!cursorFound) {
                // hacky but it will work
                cursorFound = (ranges[i].htmlText.indexOf('id=cursor') != -1);
                if(cursorFound)
                    ranges[i].pasteHTML(cursor.outerHTML); // replaces html with parameter
                else
                    ranges[i].text = '';
            }
            else {
                ranges[i].text = '';
            }
        }
    }
}

// simple BFS to find an id in a tree, not sure if you have a 
// library function that does this or not
function containsChildById(source, id) {
    q = [];
    q.push(source);

    while(q.length > 0) {
        var current = q.shift();
        if(current.id == id)
            return true;

        for(var i=0; i < current.childNodes.length; i++) {
            q.push(current.childNodes[i]);
        }
    }

    return false;
}

答案 1 :(得分:1)

我建议删除你想要保留的元素,使用Range的extractContents()方法提取选择内容,然后使用范围的insertNode()方法重新插入要保留的元素。

对于IE&lt; 9,它不支持DOM Range,代码比较复杂,所以为了简单起见,你可以使用我的Rangy库,它还增加了方便的方法,例如Range的containsNode()方法。

现场演示:http://jsfiddle.net/DFxH8/1/

代码:

function deleteSelectedExcept(node) {
    var sel = rangy.getSelection();
    if (!sel.isCollapsed) {
        for (var i = 0, len = sel.rangeCount, range, nodeInRange; i < len; ++i) {
            range = sel.getRangeAt(i);
            nodeInRange = range.containsNode(node);
            range.extractContents();
            if (nodeInRange) {
                range.insertNode(node);
            }
        }
    }
}

deleteSelectedExcept(document.getElementById("cursor"));
相关问题