繁体   English   中英

修改contenteditable div中的文本而不重置插入符(光标)位置

[英]Modify text in a contenteditable div without resetting the caret (cursor) position

我试图/any thing in here/<b>/any thing in here/</b>中的/any thing in here/替换任何/any thing in here/任何实例,因为在一个可信的div中进行了更改。

我当前的实现工作正常,但是在每个按键时,插入符被移动到div的开头,使得实现无法使用。 在替换div的内容时是否有某种方法可以保持插入位置?

$('.writer').on('keyup', function(e) {
     $(this).html($(this).html().replace(/\/(.*)\//g, '<b>\/$1\/<\/b>'));
});

尝试演示

    $('#writer').on('keyup', function(e) {
        var range = window.getSelection().getRangeAt(0);
        var end_node = range.endContainer;
        var end = range.endOffset;
        if(end_node != this){
            var text_nodes = get_text_nodes_in(this);
            for (var i = 0; i < text_nodes.length; ++i) {
                if(text_nodes[i] == end_node){
                    break;
                }
                end += text_nodes[i].length;
            }
        }
        var html = $(this).html();
        if(/\&nbsp;$/.test(html) && $(this).text().length == end){
            end = end - 1;
            set_range(end,end,this);
            return;
        }
        var filter = html.replace(/(<b>)?\/([^<\/]*)(<\/b>)?/g, '\/$2');
        console.log(filter);
        filter = filter.replace(/(<b>)?([^<\/]*)\/(<\/b>)?/g, '$2\/');
        console.log(filter);
        filter = filter.replace(/(<b>)?\/([^<\/]*)\/(<\/b>)?/g, '<b>\/$2\/<\/b>');
        console.log(filter);
        if(!/\&nbsp;$/.test($(this).html())){
            filter += '&nbsp;';
        }
        $(this).html(filter);
        set_range(end,end,this);

    });

    $('#writer').on('mouseup', function(e) {
        if(!/\&nbsp;$/.test($(this).html())){
            return;
        }
        var range = window.getSelection().getRangeAt(0);
        var end = range.endOffset;
        var end_node = range.endContainer;
        if(end_node != this){
            var text_nodes = get_text_nodes_in(this);
            for (var i = 0; i < text_nodes.length; ++i) {
                if(text_nodes[i] == end_node){
                    break;
                }
                end += text_nodes[i].length;
            }
        }
        if($(this).text().length == end){
            end = end - 1;
            set_range(end,end,this);
        }
    });

    function get_text_nodes_in(node) {
        var text_nodes = [];
        if (node.nodeType === 3) {
            text_nodes.push(node);
        } else {
            var children = node.childNodes;
            for (var i = 0, len = children.length; i < len; ++i) {
                var text_node
                text_nodes.push.apply(text_nodes, get_text_nodes_in(children[i]));
            }
        }
        return text_nodes;
    }

    function set_range(start, end, element) {
        var range = document.createRange();
        range.selectNodeContents(element);
        var text_nodes = get_text_nodes_in(element);
        var foundStart = false;
        var char_count = 0, end_char_count;

        for (var i = 0, text_node; text_node = text_nodes[i++]; ) {
            end_char_count = char_count + text_node.length;
            if (!foundStart && start >= char_count && (start < end_char_count || (start === end_char_count && i < text_nodes.length))) {
                range.setStart(text_node, start - char_count);
                foundStart = true;
            }
            if (foundStart && end <= end_char_count) {
                range.setEnd(text_node, end - char_count);
                break;
            }
            char_count = end_char_count;
        }

        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM