【问题标题】:Format contentEditable element as you type键入时格式化 contentEditable 元素
【发布时间】:2010-12-15 23:53:55
【问题描述】:

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

我正在使用 contentEditable 属性进行格式化。在keyup 事件中,我检查文本是否太长,如果是这种情况,将多余的字符移动到<span>。但是,选择会在途中丢失。

我已经尝试了很多方法(包括 this),但没有任何效果 - 你能帮帮我吗?如果你能举一个可行的例子,我想这对我的帮助最大。

【问题讨论】:

  • 当您尝试链接到的答案时,究竟是什么不起作用?有我们可以看到的例子吗?
  • 这是一个例子:jsfiddle.net/g7KJ5 我得到:Uncaught TypeError: Cannot read property 'previousSibling' of null
  • @Tim:如果你能解决这个问题,那就太棒了:-)
  • @eWolf:我知道问题出在哪里了,但是已经晚了,所以我明天再解释。
  • @Tim:好的,谢谢

标签: javascript html wysiwyg contenteditable


【解决方案1】:

我接受这个是因为我感兴趣。这是令人讨厌的大量代码,但事实就是如此。我的新版本没有使用 Rangy 的 saveSelection(),但使用了它的跨浏览器 Range 支持来实现 IE 兼容性。代码太多,这里就不贴了,我就直接链接到jsfiddle:http://jsfiddle.net/timdown/g7KJ5/9/

【讨论】:

  • 感谢您解决我的问题 - 不幸的是,您的解决方案似乎效果不佳。部分原因可能是 500ms 延迟造成的(真的有必要吗?),但有时它只是失去焦点。顺便说一句:我会将它用于 Chrome 扩展,因此不需要跨浏览器支持。
  • 我必须承认,我对它并不满意,也没有对它进行足够的测试。我认为,某种延迟通常是一个好主意,以防止打字时呆滞。我可能会尝试改进它。
  • 看看我在下面发布的答案 - 我现在用不同的方法解决了它。
【解决方案2】:

我已经给 joey 发了邮件,但是看看这个:

https://gist.github.com/746962

【讨论】:

    【解决方案3】:

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

    $.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('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;');
            }
    
            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 提供的标记提示,这是关键线索!

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 2011-06-16
      • 1970-01-01
      • 2015-07-30
      • 2011-06-10
      • 1970-01-01
      相关资源
      最近更新 更多