当我使用javascript更新文本时,光标移动到文本的开头 [英] Cursor moves to beginning of text when I update text with javascript

查看:166
本文介绍了当我使用javascript更新文本时,光标移动到文本的开头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用contenteditable来允许用户编辑网页上的信息,但有些字段有长度要求,我希望他们知道什么时候达到了这个要求,所以我改变了文本的颜色当它们重新变成红色时被砍掉。

I'm using contenteditable to allow users to edit information on the webpage, but some fields have a length requirement, and I want them to know when they've hit that requirement, so I change the color of the text that will be chopped off when they hit return to red.

问题是当使用JavaScript更改文本时,浏览器会将光标移动到字符串的前面。有谁知道我可以防止这种行为的方式?据我所知,这是所有浏览器中的一个问题。

The issue is that when the text is changed with JavaScript, the browser moves the cursor to the front of the string. Does anyone know of a way I can prevent this behavior? As far as I can tell this this is an issue in all browsers.

这是一个JSFiddle。

$(element).keypress(function (event) {
    if ($(element).text().trim().length > maxChars) {
        $(element).html($(element).text().trim().substr(0, maxChars) +
            "<span class=red>" + $(element).text().trim().substr(maxChars) + "</span>");
    }
});


推荐答案

感谢harsha和Tim Down我终于得到了这个工作并修复了Firefox不允许空间的问题,并且它运行良好。我能找到的唯一不可预期的行为是它弄乱了浏览器的撤消历史记录,但除此之外它的效果非常好。

Thanks to harsha and Tim Down I finally got this to work and also fixed the issue where Firefox doesn't allow spaces, and it works quite well. The only non-expected behavior I could find was that it messes up the browser's undo history but other than that it works very well.

我已经在每个浏览器中测试但是IE,但我不明白为什么它不适用于较新的IE版本。它需要使用输入事件,因此它不适用于旧版浏览器。我也不知道它如何处理换行符,因为我在我的应用程序中删除它们。

I've tested in every browser but IE, but I don't see why it wouldn't work in newer IE versions also. It requires use of the input event though, so it wouldn't work in older browsers. I also don't know how it handles line breaks because I strip them in my app.

首先,你需要这段代码由Tim Down编写的

First, you need this code written by Tim Down somewhere in your file.

var saveSelection, restoreSelection;
var endSpaceIndex = -1;

if (window.getSelection && document.createRange) {
    saveSelection = function(containerEl) {
        var range = window.getSelection().getRangeAt(0);
        var preSelectionRange = range.cloneRange();
        preSelectionRange.selectNodeContents(containerEl);
        preSelectionRange.setEnd(range.startContainer, range.startOffset);
        var start = preSelectionRange.toString().length;

        return {
            start: start,
            end: start + range.toString().length
        }
    };

    restoreSelection = function(containerEl, savedSel) {
        var charIndex = 0, range = document.createRange();
        range.setStart(containerEl, 0);
        range.collapse(true);
        var nodeStack = [containerEl], node, foundStart = false, stop = false;

        while (!stop && (node = nodeStack.pop())) {
            if (node.nodeType == 3) {
                var nextCharIndex = charIndex + node.length;
                if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                    range.setStart(node, savedSel.start - charIndex);
                    foundStart = true;
                }
                if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                    range.setEnd(node, savedSel.end - charIndex);
                    stop = true;
                }
                charIndex = nextCharIndex;
            } else {
                var i = node.childNodes.length;
                while (i--) {
                    nodeStack.push(node.childNodes[i]);
                }
            }
        }

        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
} else if (document.selection) {
    saveSelection = function(containerEl) {
        var selectedTextRange = document.selection.createRange();
        var preSelectionTextRange = document.body.createTextRange();
        preSelectionTextRange.moveToElementText(containerEl);
        preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
        var start = preSelectionTextRange.text.length;

        return {
            start: start,
            end: start + selectedTextRange.text.length
        }
    };

    restoreSelection = function(containerEl, savedSel) {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(containerEl);
        textRange.collapse(true);
        textRange.moveEnd("character", savedSel.end);
        textRange.moveStart("character", savedSel.start);
        textRange.select();
    };
}

在某处你还需要以下代码。它使用jQuery,所以如果你没有,你将不得不摆脱下面的例子中的jQuery。这需要绑定到输入事件,因为Firefox与调用 keyup 和<$ c时非常不一致$ C>按键。这就解决了Firefox不允许空间的问题。这太乱了。但话说回来,显然浏览器支持 contenteditable

Somewhere you also need the following code. It uses jQuery, so if you don't have that you'll have to get rid of the jQuery in the example below. This needs to be bound to the input event, as Firefox is very inconsistent with when it calls keyup and keypress. This is what fixes the issue with Firefox not allowing spaces. It's pretty messy. But then again, apparently so is browser support for contenteditable.

// Provided `element` is the element that you want to modify while the user changes it.
$(element).bind('input', function() {
    var savedSel = saveSelection(element);
    if (endSpaceIndex > -1 && $(element).text().substr(endSpaceIndex) != " " 
        && savedSel.end == $(element).text().length && savedSel.end == savedSel.start) {
            $(element).html($(element).text().substr(0, endSpaceIndex) + " " + $(element).text().substr(endSpaceIndex));
            endSpaceIndex = -1;
            savedSel.end = savedSel.start = $(element).text().length;
    }

    // Here, change the element however you want to. 
    // For example, I add a 'red' class around the text that will be chopped off

    restoreSelection(element, savedSel);
    var fullText = $(element).text();
    if (fullText.substr(fullText.length - 1) == " ") {
        endSpaceIndex = fullText.length - 1;
    }
}

此外我最初将此标记为dupli cate,但我不再认为它是重复的,因为它修复了Firefox不允许空格的问题。希望这有助于其他人!

Also I originally marked this as a duplicate, but I no longer think it's a duplicate because it fixes this issue with Firefox not allowing spaces. Hope this helps someone else!

这篇关于当我使用javascript更新文本时,光标移动到文本的开头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆