How to get the height of the text inside of a textarea - javascript

I have a textarea with the the text Hello World. I would like to get the height of this text.
I've tried to use:
var element = document.getElementById('textarea');
var textHeight = element.innerHTML.offsetHeight;
and:
var textHeight = element.value.offsetHeight;
But these don't give the numbers of the text, but the height of the textarea element.

element.scrollHeight is probably worth investigating.
If I was going to approach this (and I've not tested this at all), I'd set the textarea's height to 1px measure the scroll height and then reset the textarea's height.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight

Create a span element, set Span's innerHTML to "Hello World".
Get the span's offsetHeight.
var span = document.createElement("span");
span.innerHTML="Hello World"; //or whatever string you want.
span.offsetHeight // this is the answer
note that you must set the span's font style to the textarea's font style.
Your example will NEVER work because innerHTML and value are both strings. String doesn't define offsetWidth.
If you wish to get the height of selected text inside of a textarea, use selectionStart/selectionEnd to find the selected text of the textarea.

In jQuery there is no scrollHeight, so it needs a little workaround. the solution would be:
var areaheight=$("textarea#element")[0].scrollHeight;
$("#element").height(areaheight);
or shorter:
$("#element").height($("#element")[0].scrollHeight)

You can use element.scrollHeight (just like Patrick answered) but it needs some corrections (I'm using jQuery in example):
1) if your textarea has padding, you need to substract it (top & bottom).
2) if element has already set height, you need to set it to zero (just for measure then set it back, else it returns this height + padding)
var h0 = $(element).height(); // backup height
$(this).height(0);
var h = $(this).get(0).scrollHeight - $(this).css('paddingTop').replace('px','')*1 - $(this).css('paddingBottom').replace('px','')*1; // actual text height
$(this).height(h0); // set back original height (or new height using h)
There is no need of extra span with same css as textarea.

For anyone using React:
const textarea_ref = useRef(null);
const [idealHeight,setIdealHeight] = useState(0);
const [inputValue,setInputValue] = useState("");
useLayoutEffect(() => { // useLayoutEffect TO AVOID FLICKERING
textarea_ref.current.style.height = '0px'; // NEEDS TO SET HEIGHT TO ZERO
const scrollHeight = textarea_ref.current.scrollHeight; // TO READ THE CORRECT SCROLL HEIGHT WHEN IT SHRINKS
textarea_ref.current.removeAttribute('style'); // REMOVE INLINE STYLE THAT WAS ADDED WITH 0px
setIdealHeight(scrollHeight + 2); // NEEDS TO ADD 2. I THINK IT'S BECAUSE OF THE BORDER
},[inputValue]);
return (
<textarea
// USE idealHeight STATE TO SET THE HEIGHT
value={inputValue}
onChange={onChange}
ref={textarea_ref}
/>
);
PS: It still flickers sometimes. At least in Chrome.

You can get the text height by getting the textarea scrollbar height
const textarea = document.getElementByTagName("textarea");
const height = textarea.scrollHeight;
console.log({ height });

http://www.quirksmode.org/dom/range_intro.html
sorry that I can't be of more help.
the problem with you example is that inline text does not have a height, it only has a line-height, for it to have a height it needs to be in display block mode, so that all the lines are added to a block of text, even then it all depends on the width of the box and the font-size, font-family etc.
what ItzWarty suggests is getting the text selection and putting it in a div that has the same font and width as the textarea, which has display block and allows you to get its height.

I am not sure whether I interpret your question correctly, but I personally needed to know the exact height of each line of text. The line-height property does not have the right value (for example, in Safari, it will be rounded to the closest value when actually printing text).
This is my workaround. You should have the following code somewhere at the beginning of the document.
// set one row in the textarea and get its height
element.rows = 1;
var height1 = parseFloat(window.getComputedStyle(element)["height"]);
// set two rows in the textarea and get its height
element.rows = 2;
var height2 = parseFloat(window.getComputedStyle(element)["height"]);
// Now, the line height should be the difference
var inputLineHeight = height2-height1;
The variable inputLineHeight should contain the correct value, in pixel.

Related

How to get full height (including margins) with window.getComputedStyle()?

I am trying to get the full height of a JSX element in ReactJS using window.getComputedStyle, however I'd like to get the full value, height+margin, but I couldn't find a way.
When I use only height I don't get the margin value.
window.getComputedStyle(productsContainerRef.current).height
I know I can get both values separetely and sum them, but is there a straightforward way to do that?
I am getting the element using a ref, so, it wouldn't be possible to use the event to aim the target element and get outerHeight.
Is there a way to do that using getComputedStyle?
One option is to add the margins to the refs current height.
Example:
const outerHeight = (el) => {
var height = el.offsetHeight;
var style = window.getComputedStyle(el);
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
return height;
};

Height of an element that is not rendert

I found this question to get the height of an element that has not height Attribute. But is it possible to get or calculate the height before it is rendert?
for example I have this Code:
var element = createElement("div");
element.style.width = "20px";
element.innerHTML = "XXXXXXXXXXXXXXXXXXXXXXXXX";
If I know the fontsize and other stuff like padding etc. , is it possible to get the height it would have if it gets rendert?
I need this because I need to know how heigh the element is before it gets rendert to change things that happens after that.

How can I get text dimensions?

This snippet gives the width of the "theDiv", which equals to the width of the page:
<div id="theDiv">This is some text</div>
<script>
var rect = document.getElementById("theDiv").getBoundingClientRect();
alert("width of text is (not): " + rect.width);
</script>
Is there any way to get the width (and height) of the actual text in the div?
note: I'm developing a chrome extension that analyzes web-pages - I cannot change the dom and the css, meaning I cannot use span instead of div or change the style of the element.
You can use a Range to measure text. For example:
var range = document.createRange();
range.selectNodeContents(document.getElementById("theDiv"));
var rect = range.getBoundingClientRect();
document.getElementById("out").innerHTML = "width of text is: " + rect.width;
<div id="theDiv">This is some text</div>
<div id="out"></div>
If you can't change the dom then you could make theDiv inline-block via CSS:
#theDiv {
display: inline-block
}
Ok, in this case you could create virtual element, append it to the dom, calculate dimensions and then remove it from dom:
// fetch source element and his content
var div = document.getElementById("theDiv"),
text = div.innerHTML;
// create virtual span to calculate dimestions
var span = document.body.appendChild(document.createElement('span'));
span.innerHTML = text,
rect = span.getBoundingClientRect();
alert(rect.width);
// remove virtual span from the DOM
document.body.removeChild(span);
Getting an element's text's width by itself isn't possible without the use of an extra (inline, usually invisible) element, as far as I know, or could tell.
For those others who arrive here without OP's restrictions though, it is possible using only JS and without affecting the page's flow at all.
var target = ... // Whichever element's text's width you wish to measure
var ruler = document.createElement("span");
ruler.style.position = "absolute"; // remove from the page's flow
ruler.style.visibility = "hidden"; // and totally stop it from being rendered
// copy font-size, font-family and the text itself
ruler.style.fontSize = target.style.fontSize;
ruler.style.fontFamily = target.style.fontFamily;
ruler.innerHTML = target.innerHTML;
// add to the document so that the styles get applied, allowing us to discover its width
document.body.appendChild(ruler);
var textWidth = ruler.offsetWidth;
// and then promptly remove again from the document
document.body.removeChild(ruler);
You can use clientWidth or offsetWidth
Use var offsetWidth =element.offsetWidth;
the difference is offsetWidth includes border width, clientWidth does not

offsetWidth returns wrong width in css animated block under Chrome

I'm trying to make a kind of "news bar" on a web page.
The bar use a CSS animation, and the text content is refreshed on each iteration using ajax to retrieve data from an RSS feed.
My problem is that the content length may vary, so I want to set the size of the font used to display the text small enough to display all the content.
I then use this function to resize the text content:
function resize(content /*content div*/, maxHeight/*bar height*/, maxWidth /*bar width*/) {
content.parentNode.style.fontSize = maxHeight + 'px';
var totalwidth = content.offsetWidth;
if (totalwidth > maxWidth) {
content.parentNode.style.fontSize = (maxHeight * maxWidth / totalwidth) + 'px';
}
}
It sometimes works on first iteration, but after it returns totally wrong values (like 36) for totalWidth.
If I put a breakpoint on the 'if' line the debugger display a coherent value (like 4320) for content.offsetWidth.
How can I fix this ?
I've found the solution.
I have to set the content as "inline-block".
If content display is set as "block" its offsetWidth vary with the css animation.

Calculating html element (div) width with javascript/dojo?

Normally when you have a div created in html. You can check its width with offsetWidth or style.width (if declared). However if the innerHTML is changed such that the width of the div is also change, neither of those functions work (not sure, but they haven't in my cases).
some code:
var div = document.createElement("div");
div.innerHtml = "asdfasdfasdfasdfsdfasdfasdfad";
alert(div.style.width); // this is nothing
alert(div.offsetWidth); // this is 0
How do you get the width of the div above?
I realize this is an old question, but for the many people landing here from google I'll provide it.
This is the way to do it in dojo 1.7+. With the geometry module you can get and set the width of the content (not including padding or border). This ignores box-sizing.
require(['dojo/dom-geometry'], function(domGeom) {
var myDivNode = dojo.query('div')[0];
var contentBox = domGeom.getContentBox(myDivNode);
alert(contentBox.w);
// This is how to set width/height
domGeom.setContentSize(myDivNode, {w: 100, h: 100});
});
Source: https://dojotoolkit.org/reference-guide/1.7/dojo/contentBox.html
you can't get width value of element that wasn't appended to document.
so you should append it to page, than you can get width,
here is a working demo

Categories

Resources