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

Is there a way to prevent a contentEditable element from scrolling when the cursor reaches the bottom?

本文关键字:contentEditable 滚动 元素 有没有 光标 底部      更新时间:2023-09-26

例如,我有一个contentEditablediv,我可以在其中键入。当文本到达div的底部时,浏览器会自动滚动div,使文本的末尾和光标仍然可见。

如何防止div滚动,使输入的文本越过div的底部,并且在键入时无法再看到光标?

我试图实现的行为就像在Photoshop中一样:当你制作一个文本框,并且键入太多时,光标会继续越过框的底部,你看不到你在键入什么。如果展开该框,您将看到所有隐藏的文本。

编辑日期:2012年7月2日上午9:27:这是我现在掌握的内容,但它看起来有问题,因为在按键事件后调整了滚动位置:http://jsfiddle.net/trusktr/hgkak/6/因此,在keyup事件之前,光标会被临时放置在视图中(对于每次击键)。我希望没有跳跃,并且当有多余的文本时,光标保持在绿色div的末尾下方,而视图没有跳跃(跳跃似乎是我的业余破解:d)

让我们试试破解:

  • 首先,我们试图阻止或恢复任何滚动
  • 每当用户按键时,我们都会将元素的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);
    });
});

检查这个jsFiddle来玩上面的代码。

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

您需要具有overflow:hidden;position:relative和静态高度或最小高度的父div(A)。

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

div A的高度必须类似于integer * line-height of div B


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

绑定div B keyup事件函数{

使用rangy在当前光标中创建空的span

从这个跨度中获取offset().top,并将其与div A中的offset().top + outerHeight()进行比较。如果第一个较大,则第二个->您需要向下滚动div B。

要向下滚动,只需更改+= line-height of div B 上的当前css top

销毁空跨度。

(如果光标位置失败->您需要在创建跨度之前预先保存,并在破坏跨度后恢复光标位置)

}


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

如果光标位置超出div A中的可见范围(算法类似于我上面写的),则滚动


是的,这不是一个简单的方法,但它有效

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

添加一个与底部重叠且z索引较高的div?您可以将可编辑区域设置得很高,以免产生差异。然后,您必须使覆盖div可拖动。

非常简单:

<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);
    });
});