Get contentEditable div height after entering new char

I currently have a contentEditable div with a fixed width and a flexible height, which should be increased or decreased according to the length of the user input.

The problem is that in the following code, I get the contentEditable height based on the last char, this is my code:

<!-- 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> 

So, I need through JAVASCRIPT to immediately get the height of the contentEditable after the new char is introduced, and, if possible, before the char is displayed, for example, the diagram below:

KEYBOARD KEYBOARD =>

JS GET HEIGHT OF CONTENT INTERACTION WITH NEW char =>

CHAR NOW turns out (This is just a simulation, of course, things will not look strictly like that)

It can be done? Any ideas would be appreciated, thanks in advance!

+6
source share
5 answers

Given that the height of the div will not increase until char appears, I can offer you a workaround. You can fill out another div with the typed letters, intercepting the event, then get the height of this second div, and finally, you can put the letter where it should appear. This increases input time.

You can test the script here

 <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> 
+3
source

If you attach an event handler to keyup rather than keydown , you can get the height after rendering. You cannot get the height of the post-render before rendering it. Why are you asking for this?

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> 

Is that what you were? Demo at http://jsfiddle.net/jksCt/

+1
source

What to do if you saved viscosity: a hidden DIV that duplicates visible text with the same fixed width. You can then attach the event to the onKeyDown event of the visible DIV, insert this symbol into the hidden DIV, get the new height of the hidden DIV, and then update the new height to the visible DIV before registering the onKeyUp event.

0
source

You can get the height almost instantly using setTimeout with a delay of 0:

 <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> 

This is still done after rendering, but I think, but almost instantly. The only way to do this before rendering is to have a hidden element that duplicates all the styles and contents of the element you need to measure.

Edit:

I will correct myself. You do not need an additional element for measuring height. You can insert the pressed character into the same element, measure it, and then delete the character. The tricky part is that you will need to consider the position of the carriage and the current selection, both for inserting a character and for restoring a selection after measuring an element. Also note that pressing a key does not necessarily add a character. If there is a choice, he will overwrite it, deleting the content. You will also need to handle clipboard events, etc.

The solution I proposed here will not handle the case when you edit the content with the mouse (for example, cut / copy / paste from the context menu, for example). I suggest you study the HTML5 input event, which may be the best candidate for this.

0
source

You can simply use the editor that solved it for you.

goog.Editor.SeamlessField has this cross-browser enabled:

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

Here are the assembly instructions:

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

Or for the lazy, you can just use the assembly in which I ended up:

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

You would use it like:

 // 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(); 
0
source

Source: https://habr.com/ru/post/946416/


All Articles