有没有办法防止contentEditable元素在光标到达底部时滚动?

时间:2012-02-04 21:20:33

标签: javascript html html5 scroll contenteditable

例如,我有一个contentEditable div,我可以输入它。当文本到达div的底部时,浏览器会自动滚动div,以便文本末尾和光标仍然可见。

如何阻止div滚动以使输入的文本超过div的底部,以便在键入时无法再看到光标?

我想要实现的行为就像在Photoshop中一样:当你制作一个文本框并输入太多时,光标会继续通过框底部,你无法看到你输入的内容。如果展开框,您将看到所有隐藏文本。

编辑2/7/2012 9:27 am:这就是我现在所拥有的,但它看起来很奇怪,因为在键盘事件后调整了滚动位置:http://jsfiddle.net/trusktr/hgkak/6/所以之前在keyup事件中,光标暂时放入视图中(对于每次击键)。我希望没有跳跃,并且光标保持在绿色div的末尾,当有多余的文本没有视图跳跃时(跳跃看起来像我的业余黑客:D)

5 个答案:

答案 0 :(得分:13)

让我们试试黑客:

  • 首先我们尝试阻止或恢复任何滚动
  • 每当用户按下某个键时,我们将元素的overflow属性转换为visible以避免滚动内容,但通过将其opacity设置为0来同时隐藏该元素。之后我们立即将overflow切换回hidden并再次显示该元素。
  • 为了避免闪烁,我们创建了一个可编辑元素的克隆(使用overflow: hidden)并在隐藏原始元素时显示此元素。

这里我们去(使用jQuery来方便DOM):

$(function() {

    var editableElement = $('#editable'), clonedElement;

    // Revert any scrolling                    
    editableElement.on("scroll", function(event) {
        editableElement.scrollTop(0);

        // Try to prevent scrolling completely (doesn't seem to work)
        event.preventDefault();
        return false;
    });

    // Switch overflow visibility on and off again on each keystroke.
    // To avoid flickering, a cloned element is positioned below the input area
    // and switched on while we hide the overflowing element.
    editableElement.on("keydown", function() {

        // Create a cloned input element below the original one
        if (!clonedElement) {
            var zIndex = editableElement.css('zIndex');
            if (isNaN(parseInt(zIndex, 10))) {
                zIndex = 10;
                editableElement.css({zIndex: zIndex});
            }    

            clonedElement = editableElement.clone();
            clonedElement.css({
                zIndex: zIndex-1,
                position: 'absolute',
                top: editableElement.offset().top,
                left: editableElement.offset().left,
                overflow: 'hidden',
                // Set pseudo focus highlighting for webkit
                // (needs to be adapted for other browsers)
                outline: 'auto 5px -webkit-focus-ring-color'
            });
            editableElement.before(clonedElement);
        } else {
            // Update contents of the cloned element from the original one
            clonedElement.html(editableElement.html());
        }

        // Here comes the hack:
        //   - set overflow visible but hide element via opactity.
        //   - show cloned element in the meantime
        clonedElement.css({opacity: 1});
        editableElement.css({overflow: 'visible', opacity: 0});

        // Immediately turn of overflow and show element again.
        setTimeout(function() {
            editableElement.css({overflow: 'hidden', opacity: 1});
            clonedElement.css({opacity: 0});
        }, 10);

    });
});

选中this jsFiddle以播放上述代码。

请注意,这可能不是一个完整的解决方案(我只尝试使用Safari,Chrome和Firefox),但对于经过测试的浏览器,它似乎可行。您可能希望对您的实现进行微调和优化(例如,焦点突出显示)。在jsFiddle示例中,我还关闭了拼写检查以避免闪烁标记。

答案 1 :(得分:3)

您需要父级div(A)和overflow:hidden;position:relative以及静态高度或最小高度。

在此父级中,您有子级div(B)contenteditable="true"style="position:absolute;width:100%;left:0;top:0"

div A的高度必须与integer * line-height of div B

相似

之后,您需要包含rangy和jQuery库

绑定div B keyup事件函数{

使用rangy在当前光标位置创建空span

从此范围获取offset().top,并将其与来自div A的offset().top + outerHeight()进行比较。如果第一个是大,那么第二个 - >你需要向下滚动div B.

向下滚动只需更改css top

上的当前+= line-height of div B

消灭空跨度。

(如果光标位置失败 - >您需要在创建跨度之前保存它并在销毁跨度后恢复光标位置)

}


此外,您需要使用箭头键模拟所有。在这种情况下,您需要在div B中的keyup上创建带event.which的开关选择器。键码为here

滚动光标位置是否在div A中的可见范围之外(算法类似于我上面所写的算法)


是的,这不是一种简单的方法,但它可以正常工作

答案 2 :(得分:2)

尝试设置style =“overflow:hidden;”在div上

答案 3 :(得分:2)

添加一个与底部重叠且具有更高z-index的Div?您可以使可编辑区域非常高,以免产生影响。然后你必须使覆盖div可拖动。

答案 4 :(得分:0)

很简单:

<div id="mydiv" contenteditable="true" style="width: 200px; height: 100px;"></div>


$(document).ready(function(){

    $("#mydiv").height(document.getElementById('mydiv').scrollHeight);

    $("#mydiv").keyup(function(){

        $(this).height(0).height(document.getElementById('mydiv').scrollHeight);

    });

});