6

我目前有一个 contentEditable div,宽度固定,高度灵活,必须根据用户输入的长度增加或减少。

问题是想到下面的代码,我得到了基于最后输入的字符的 contentEditable 的高度,这是我的代码:

<!-- THE JS FUNCTION THE GETS THE DIV CALLED title HEIGHT-->
function setInTitle() {

        var titleHeight = document.getElementById('title').offsetHeight;

}

<!-- THE DIV CALLED title -->
<div
     id="title"
     class="title"
     contenteditable="true"
     style="font-family: Helvetica; font-size:18px; font-weight:bold; background-color:#fff; color:#000; -webkit-tap-highlight-color:rgba(0,0,0,0); margin:14px;"
     autocapitalization="off"
     autocorrection="off"
     autocomplete="off"
     onKeyPress="setInTitle();" <==CALL THE JS FUNCTION
></div>

所以,我需要通过 JAVASCRIPT,在输入新字符后立即获取 contentEditable 高度,如果可能的话,在呈现字符之前,如下面的方案:

键盘按键 =>

JS 使用新的 CHAR 获得 CONTEDITABLEDIV 的高度 =>

CHAR NOW BE RENDERED(这只是一个模拟,当然事情不会像这样严格)

这可以做到吗?任何想法将不胜感激,在此先感谢!

4

5 回答 5

3

考虑到 div 的高度在字符出现之前不会增加,我可以建议你我的解决方法。您可以通过拦截事件将键入的字母填充到另一个 div,然后获取第二个 div 的高度,最后,您可以将字母放在应该出现的位置。这增加了输入时间。

你可以在这里测试脚本

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<style type="text/css">

#title {
    border: 1px #3399FF solid;
    min-height:50px;
    width:100px;
    word-wrap:break-word;
}
#title2 {
    filter:alpha(opacity=20);
    opacity:0.2;
    border: 1px #3399FF solid;
    min-height:50px;
    width:100px;
    word-wrap:break-word;
}
</style>
</head>
<body>

<!-- THE DIV CALLED title -->
<div
     id="title"
     class="title"
     contenteditable="true"
     style="font-family: Helvetica; font-size:18px; font-weight:bold; background-color:#fff; color:#000; -webkit-tap-highlight-color:rgba(0,0,0,0); margin:14px;"
     autocapitalization="off"
     autocorrection="off"
     autocomplete="off"
></div>
<div
     id="title2"
     class="title"
     contenteditable="true"
     style="font-family: Helvetica; font-size:18px; font-weight:bold; background-color:#fff; color:#000; -webkit-tap-highlight-color:rgba(0,0,0,0); margin:14px;"
     autocapitalization="off"
     autocorrection="off"
     autocomplete="off"
></div>
<div id="a"></div>
</body>
<script>

var slowl = 400 //updating time
var lastts = "";//last timestamp value
$("#title").on('keydown keyup change keypress', function(e) {//catch the event
    e.preventDefault();//stop the event
    if(e.timeStamp-lastts < slowl){//try prevent keypress abuse
        return false;
    }
    lastts = e.timeStamp;
    var html=$('#title').text();
    console.log(e);
    if(e.charCode!=0){//all browsers
        char = e.charCode;
    }else{
        char = e.keyCode;
    }
    content = $('#title').text()+String.fromCharCode(char); //prepare content
    $('#title2').text(content);
    var height = $('#title').height();
    $('#a').html(height);
    setTimeout("$('#title').text($('#title2').text());",slowl);//normalize the sitation

});
</script>
</html>
于 2013-06-03T22:22:56.830 回答
1

如果您将事件处理程序附加到keyup而不是您可以在渲染keydown获取高度。在渲染之前,您无法获得渲染后高度。你问这个的原因是什么?

js

var output = document.getElementById('output');
var title = document.getElementById('title');

title.addEventListener("keyup", function (e) {
    output.innerHTML = title.offsetHeight;
});

//initialize
output.innerHTML = title.offsetHeight;

html

<div>Height of #title is: <span id="output">...</span>px</div>
<div
     id="title"
     class="title"
     contenteditable="true"
     autocapitalization="off"
     autocorrection="off"
     autocomplete="off"
>type here</div>

这就是你所追求的吗?演示在http://jsfiddle.net/jksCt/

于 2013-06-10T08:40:39.917 回答
0

您可以使用为您解决此问题的编辑器。

goog.Editor.SeamlessField 有这个解决的跨浏览器:

http://closure-library.googlecode.com/git/closure/goog/demos/editor/seamlessfield.html

以下是一起构建它的说明:

http://b9dev.blogspot.com/2013/06/getting-started-with-google-closure-on.html

或者对于懒惰的人,你可以使用我最终得到的构建:

http://brass9.com/downloads/editor.min.js

你会像这样使用它:

// Work with a tag with id=editor
var editor = new Editor('editor');

// Make contentEditable
editor.makeEditable();

// Get the HTML contents of the tag
editor.getCleanContents();
于 2013-06-14T20:18:30.380 回答
0

您可以使用具有 0 延迟的 setTimeout 几乎立即检索高度:

<div
     id="title"
     class="title"
     contenteditable="true"
     autocapitalization="off"
     autocorrection="off"
     autocomplete="off"
     onkeypress="setTimeout(function() { var height = document.getElementById('title').offsetHeight; console.log(height); }, 0)"
>type here</div>

不过,我认为这仍然是在渲染之后完成的,但几乎是立即完成的。在渲染之前执行此操作的唯一方法是使用隐藏元素,该元素复制您需要测量的元素的所有样式和内容。

编辑:

我会纠正自己。您不需要额外的元素来测量高度。您可以将按下的字符插入同一元素,对其进行测量,然后删除该字符。棘手的部分是您需要考虑插入符号位置和当前选择,既要插入字符又要在测量元素后恢复选择。另请注意,按下一个键并不一定要附加一个字符。如果有选择,它将覆盖它,删除内容。您还需要处理剪贴板事件等。

我在此处建议的解决方案无法处理使用鼠标编辑内容的情况(例如,从上下文菜单中剪切/复制/粘贴)。我建议您查看 HTML5 输入事件,这可能是一个更好的候选者。

于 2013-06-14T19:31:26.420 回答
0

如果您保持可见性怎么办:隐藏的 DIV 以相同的固定宽度复制可见文本。然后您可以将一个事件附加到可见 DIV 的 onKeyDown 事件,将该字符插入隐藏 DIV,获取隐藏 DIV 的新高度,然后在注册 onKeyUp 事件之前将新高度更新到可见 DIV 上。

于 2013-06-09T10:22:29.537 回答