在CKEditor内的tekst上设置选择

时间:2014-02-14 15:27:18

标签: ckeditor selection

我在CKEditor(3.6)中选择文本时遇到问题。由于我们使用纯文本,我不知道如何正确使用范围选择器。

CKEditor的HTML代码:

<body spellcheck="false" class="rf-ed-b" contenteditable="true">
<br>
Cross those that apply:<br>
<br>
<br>
[«dummy»] If he/she is tall<br>
<br>
[«dummy»] If he/she is a male<br>
<br>
[«dummy»] If he/shi is a minor<br>
<br>
Specialties:<br>
<br>
[«dummy»] «Write here the specialties if known»<br>
<br>
<br>
«You are now done with filling in this form»<br>
</body>

按键'CRTL + N'我想进入下一个可填写的地点:
    «[标号]»

我试过像:

var editor = CKEDITOR.instances['MyEditor'];
var findString = '«';
var element = editor.document.getBody();
var ranges = editor.getSelection().getRanges();
var startIndex = element.getHtml().indexOf(findString);
if (startIndex != -1) {
    ranges[0].setStart(element.getFirst(), startIndex);
    ranges[0].setEnd(element.getFirst(), startIndex + 5);
    editor.getSelection().selectRanges([ranges[0]]);
}

错误: 例外:索引或大小为负数或大于允许的数量

虽然完全条纹下来它有点工作:

var editor = CKEDITOR.instances['MyEditor'];
var ranges = editor.getSelection().getRanges();
var startIndex = 10;
if (startIndex != -1) {
    ranges[0].setStart(element.getFirst(), startIndex);
    ranges[0].setEnd(element.getFirst(), startIndex + 5);
    editor.getSelection().selectRanges([ranges[0]]);
}

这里它在第一行选择第5到第10个字符。

我使用了以下来源:

example on Stackoverflow

Another stackoverflow example

CKEditor dom selection API

我可以找到使用html节点的所有解决方案。

如何设置'«'到下一个'»'

的选择范围

1 个答案:

答案 0 :(得分:0)

我设法解决了这个问题。同时我还将CKeditor升级到4.0。 这不应该对解决方案产生影响。

JS中有很多代码。 在我的键绑定上,我调用以下JS函数:getNextElement() 在此解决方案中,它还在光标后面搜索,这使得可以逐步执行多个查找结果。 此外,视图也会滚动到下一个搜索结果

var textNodes = [], scrollTo=0,ranges = [];

    function getNextElement(){
        var editor =null;           
        ranges = [];
            // I dont know the ID of the editor, but i know there is only one the page
        for(var i in CKEDITOR.instances){
            editor = CKEDITOR.instances[i];
        }
        if(editor ==null){
            return;
        }
        editor.focus();
        var startRange = editor.getSelection().getRanges()[0];
        var cursorData ="",cursorOffset=0,hasCursor = false;
        if(startRange != null && startRange.endContainer.$.nodeType == CKEDITOR.NODE_TEXT){
            cursorOffset = startRange.startOffset;
            cursorData = startRange.endContainer.$.data;
            hasCursor = true;
        }

        var element;
        element = editor.document.getBody().getLast().getParent();
        var selection = editor.getSelection();

        // Recursively search for text nodes starting from root.
        textNodes = [];
        getTextNodes( element );
        var foundElement = false;
        foundElement = iterateEditor(editor,hasCursor,cursorData,cursorOffset);
        if(!foundElement){
            foundElement =iterateEditor(editor,false,"",0);
        }

        if(foundElement){
            // Select the range with the first << >>.
            selection.selectRanges( ranges );
            jQuery(".cke_wysiwyg_frame").contents().scrollTop(scrollTo);
        }
    }

    function iterateEditor(editor,hasCursor,cursorData,cursorOffset){
        var foundElement = false;
        var rowNr = 0;
        var text, range;
        var foundNode = false;
        if(!hasCursor){
            foundNode = true;
        }
        // Iterate over and inside the found text nodes. If some contains
        // phrase "<< >>", create a range that selects this word.
        for (var i = textNodes.length; i--; ) {
            text = textNodes[ i ];
            if ( text.type == CKEDITOR.NODE_ELEMENT && text.getName() == "br" ){
                rowNr++;
            } else if ( text.type == CKEDITOR.NODE_TEXT ) {
                var sameNode = false;
                if(text.$.data == cursorData){
                    foundNode = true;
                    sameNode = true;
                }
                if(foundNode){
                    var startIndex = -1;
                    var endIndex = 1;
                    if(sameNode){
                        // Check inside the already selected node if the text has multiple hits on the searchphrase
                        var indicesStart = getIndicesOf('\u00AB', text.getText());
                        var indicesEnd = getIndicesOf('\u00BB', text.getText());
                        for (var j = indicesStart.length; j--; ) {
                            if(indicesStart[j] > cursorOffset){
                                startIndex = indicesStart[j];
                                endIndex = indicesEnd[j];
                            }
                        }
                    } else{
                        startIndex = text.getText().indexOf( '\u00AB' );
                        endIndex = text.getText().indexOf( '\u00BB' );
                    }

                    if ( startIndex > -1 && (!sameNode || startIndex > cursorOffset)) {
                        range = editor.createRange();
                        range.setStart( text, startIndex );
                        foundElement = true;
                        // calculate the height the window should scroll to focus the selected element
                        scrollTo = (rowNr)*20;
                    }
                    if ( endIndex > -1 && foundElement ) {
                        range.setEnd( text, endIndex+1 ); 
                        ranges.push( range );
                        return true;
                    }
                }
            }
        }
    }

    function getIndicesOf(searchStr, str) {
        var startIndex = 0, searchStrLen = searchStr.length;
        var index, indices = [];
        while ((index = str.indexOf(searchStr, startIndex)) > -1) {
            indices.push(index);
            startIndex = index + searchStrLen;
        }
        return indices;
    }

    function getTextNodes( element ) {
        var children = element.getChildren(), child;
        for ( var i = children.count(); i--; ) {
            child = children.getItem( i );
            textNodes.push( child );
        }
    }