在您键入时设置内容可编辑元素的格式

发布于 2024-10-07 12:04:15 字数 414 浏览 0 评论 0原文

我基本上想做一些非常简单的事情:我希望用户输入一条推文,在 140 个字符之后,我希望将被截断的文本显示为灰色。 应该很简单,对吧?

我使用 contentEditable 属性进行格式设置。在 keyup 事件中,我检查文本是否太长,如果是这种情况,则将多余的字符移动到 中。然而,选择在途中丢失了。

我已经尝试过很多事情(包括这个),但没有任何效果 - 你能帮助我吗?我想如果你能给出一个可行的例子,这会对我有最大的帮助。

I basically want to do something very simple: I want the user to type in a tweet, and after 140 characters, I want the text that will be cut off to be greyed out. Should be simple, right?

I'm using the contentEditable property for the formatting. On the keyup event, I check if the text is too long, and move the extra chars into a <span> if this is the case. However, the selection gets lost on the way.

I've already tried many things (including this), but nothing worked - can you help me? I guess it would help me the most if you could give a working example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

山人契 2024-10-14 12:04:15

我接受这个是因为我感兴趣。这是一个令人烦恼的大量代码,但事实就是如此。我的新版本不使用 Rangy 的 saveSelection(),但使用其跨浏览器 Range 支持来实现 IE 兼容性。这里发布的代码太多,所以我只链接到 jsfiddle:http://jsfiddle。网/timdown/g7KJ5/9/

I took this on because I was interested. It's an annoyingly large amount of code, but that's just how it is. My new version doesn't use Rangy's saveSelection() but does use its cross-browser Range support for IE compatibility. It's too much code to post here, so I'll just link to the jsfiddle: http://jsfiddle.net/timdown/g7KJ5/9/

愚人国度 2024-10-14 12:04:15

我已经给乔伊发了电子邮件,但请看一下:

https://gist.github.com/746962

I emailed joey already, but give this a look:

https://gist.github.com/746962

暖伴 2024-10-14 12:04:15

我现在尝试了一种新方法,这就是我想到的:

$.fn.softlimit = function(maxChars, wrapElement, wrapAttributes) {
    var lastHTML, that = this[0];

    setInterval(function() {
        //Only trigger on change
        if (lastHTML == that.innerHTML) return;
        lastHTML = that.innerHTML;

        // Save the selection
        var savedSel = rangy.saveSelection();

        // Strip HTML and extract rangy markers
        var markers = [ ], text = '', htmlPos = 0;

        function escapeForHTML(text) {
            return text.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"');
        }

        function processNode(node) {
            if (node.nodeType == 3) 
                text += escapeForHTML(node.nodeValue);
            else if (node.nodeName == 'SPAN' && node.id && node.id.indexOf('selectionBoundary_') === 0)
                markers.push({ index: text.length, html: node.outerHTML });
            else
                for (var i = 0; i < node.childNodes.length; ++i)
                    processNode(node.childNodes[i]);
        }

        processNode(that);

        // Do formatting
        var getOffset, markerOffset = 0;

        if (text.length > maxChars) {
            var startTag = '<' + wrapElement + ' ' + wrapAttributes + '>';
            var endTag = '</' + wrapElement + '>';

            text = text.substr(0, maxChars) + startTag + text.substr(maxChars) + endTag;

            getOffset = function(index) {
                if (index > maxChars) return startTag.length;
                else return 0;
            };
        }
        else
            getOffset = function() { return 0; };

        // Re-inject markers
        for (var i = 0; i < markers.length; ++i) {
            var marker = markers[i];
            var index = marker.index + getOffset(marker.index) + markerOffset;

            text = text.substr(0, index) + marker.html + text.substr(index);
            markerOffset += marker.html.length;
        }

        that.innerHTML = text;

        // Restore the original selection 
        rangy.restoreSelection(savedSel);
    }, 20);

    return $(this);
};

感谢@Tim Down 提供的标记提示,这是关键的线索!

I've tried a new approach now and this is what I came up with:

$.fn.softlimit = function(maxChars, wrapElement, wrapAttributes) {
    var lastHTML, that = this[0];

    setInterval(function() {
        //Only trigger on change
        if (lastHTML == that.innerHTML) return;
        lastHTML = that.innerHTML;

        // Save the selection
        var savedSel = rangy.saveSelection();

        // Strip HTML and extract rangy markers
        var markers = [ ], text = '', htmlPos = 0;

        function escapeForHTML(text) {
            return text.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"');
        }

        function processNode(node) {
            if (node.nodeType == 3) 
                text += escapeForHTML(node.nodeValue);
            else if (node.nodeName == 'SPAN' && node.id && node.id.indexOf('selectionBoundary_') === 0)
                markers.push({ index: text.length, html: node.outerHTML });
            else
                for (var i = 0; i < node.childNodes.length; ++i)
                    processNode(node.childNodes[i]);
        }

        processNode(that);

        // Do formatting
        var getOffset, markerOffset = 0;

        if (text.length > maxChars) {
            var startTag = '<' + wrapElement + ' ' + wrapAttributes + '>';
            var endTag = '</' + wrapElement + '>';

            text = text.substr(0, maxChars) + startTag + text.substr(maxChars) + endTag;

            getOffset = function(index) {
                if (index > maxChars) return startTag.length;
                else return 0;
            };
        }
        else
            getOffset = function() { return 0; };

        // Re-inject markers
        for (var i = 0; i < markers.length; ++i) {
            var marker = markers[i];
            var index = marker.index + getOffset(marker.index) + markerOffset;

            text = text.substr(0, index) + marker.html + text.substr(index);
            markerOffset += marker.html.length;
        }

        that.innerHTML = text;

        // Restore the original selection 
        rangy.restoreSelection(savedSel);
    }, 20);

    return $(this);
};

Thanks to @Tim Down for the hint with the markers, that was the crucial clue!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文