javascript - Get contentEditable div height after typing a new char - Stack Overflow

I currently have a contentEditable div with a fixed width and a flexible height,that must be increased

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

The problem is that thought the following code,i'm getting the height of the contentEditable based on the last char typed,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"
     autoplete="off"
     onKeyPress="setInTitle();" <==CALL THE JS FUNCTION
></div>

So,i need through JAVASCRIPT,get the contentEditable height instantly after when a new char is typed,and if possible before the char bee rendered,like the scheme bellow:

KEYBOARD KEY PRESSED =>

JS GET THE HEIGHT OF THE CONTENTEDITABLEDIV WITH THE NEW CHAR =>

CHAR NOW BE RENDERED(This is just an simulation of course things won't get strictly like this)

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

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

The problem is that thought the following code,i'm getting the height of the contentEditable based on the last char typed,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"
     autoplete="off"
     onKeyPress="setInTitle();" <==CALL THE JS FUNCTION
></div>

So,i need through JAVASCRIPT,get the contentEditable height instantly after when a new char is typed,and if possible before the char bee rendered,like the scheme bellow:

KEYBOARD KEY PRESSED =>

JS GET THE HEIGHT OF THE CONTENTEDITABLEDIV WITH THE NEW CHAR =>

CHAR NOW BE RENDERED(This is just an simulation of course things won't get strictly like this)

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

Share Improve this question asked Jun 3, 2013 at 14:14 MateusMateus 2,6685 gold badges46 silver badges63 bronze badges 3
  • sorry, maybe i don't understand, are you asking the high of the div before the char is displayed inside the div but after the key is pressed? – Alessandro Gabrielli Commented Jun 3, 2013 at 19:14
  • Basically yes,exactly what you understood! – Mateus Commented Jun 3, 2013 at 22:22
  • Ok @Mateus Nunes , I replyed – Alessandro Gabrielli Commented Jun 3, 2013 at 22:25
Add a ment  | 

5 Answers 5

Reset to default 3

Considering that the height of the div won't increase before that the char appear, I can suggest you my workaround. You can fill with the typed letters another div by intercepting the event, then get the hight of this second div and finally, you can place the letter where it should be appear. This increase the input time.

You can test the script here

<script src="http://code.jquery./jquery-1.9.1.js"></script>
<script src="http://code.jquery./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"
     autoplete="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"
     autoplete="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>

If you attach the event handler to keyup rather than keydown you can fetch the height after render. You can't get the post-render height before it is rendered. What is the reason you're asking for that?

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"
     autoplete="off"
>type here</div>

Is this what you were after? Demo at http://jsfiddle/jksCt/

What if you kept a visbility: hidden DIV that duplicates the visible text with the same fixed width. Then you could attach an event to the onKeyDown event of the visible DIV, insert that character into the hidden DIV, get the new height of the hidden DIV, and then update the new height onto the visible DIV before the onKeyUp event is registered.

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

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

This is still done after rendering i think, though, but nearly instantly. The only way to do it before rendering is with a hidden element that duplicates all the styles and content of the element you need to measure.

Edit:

I'll correct myself. You don't need an extra element to measure the height. You could insert the pressed character to the same element, measure it and then remove the character. The tricky part is that you would need to take into account the caret position and current selection, both to insert the character and to restore the selection after measuring the element. Also note that pressing a key is not necessarily appending a character. If there is a selection it will overwrite it, removing content. You would also need to handle clipboard events, etc.

The solution I suggested here wouldn't handle the case where you edit content with the mouse (like, cut/copy/pasting from context menu for example). I suggest you look into the HTML5 input event, which might be a better candidate for this.

You could just use an editor that has this solved for you.

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

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

Here's instructions for getting a build of it together:

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

Or for the lazy, you can just use the build I ended up with:

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

You'd 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();

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744214266a4563478.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信