I set the width of a textarea to 100%, but now I need to know how many characters can fit in one row.
I'm trying to write a javascript function to auto-grow/shrink a textarea. I'm trying to keep from using jquery since I just need this one function.
My logic is to rows = textarea.value.split('\n'), iterate through rows and count += rows[i].length/textarea.cols, then count += rows.length, and finally textarea.rows = count. The only problem is that count is too large because textarea.cols is too small.
This function will set the height of the element (textarea, in your case) to the browser's default height. If that causes a scrollbar to appear, the height will be switched to the actually needed height.
function autoHeight(element){
element.style.height='auto';
element.style.height=element.scrollHeight+'px';
}
If you don't like the browser's default height, you can change that to some other default value of your own, of course.
Try this and enjoy:
var textarea = document.getElementById("YourTextArea");
var limit = 50; //height limit
textarea.oninput = function() {
textarea.style.height = "";
textarea.style.height = Math.min(textarea.scrollHeight, limit) + "px";
};
textarea {
width: 99%;
}
<textarea id="YourTextArea"></textarea>
Related
----------------------------------------------------
| This is my text inside a div and I want the overf|low of the text to be cut
----------------------------------------------------
Please note that I want the overflow to be removed, so the CSS ellipsis property would not work for me. So basically, I want that the text above to appear like this:
----------------------------------------------------
| This is my text inside a div and I want the overf|
----------------------------------------------------
How is this possible with pure JavaScript?
EDIT
I need a JavaScript function to crop the text because I need to count the characters of the visible text.
Okay, I didn't see the addendum to the question. Although I had previously said it wasn't possible to do this using JavaScript and a font that isn't fixed-width... it actually is possible!
You can wrap each individual character in a <span>, and find the first <span> that is outside the bounds of the parent. Something like:
function countVisibleCharacters(element) {
var text = element.firstChild.nodeValue;
var r = 0;
element.removeChild(element.firstChild);
for(var i = 0; i < text.length; i++) {
var newNode = document.createElement('span');
newNode.appendChild(document.createTextNode(text.charAt(i)));
element.appendChild(newNode);
if(newNode.offsetLeft < element.offsetWidth) {
r++;
}
}
return r;
}
Here's a demo.
You can do this with Javascript. Here is a function that counts the number of visible characters in an element, regardless of external css sheets and inline styles applied to the element. I've only tested it in Chrome, but I think it is cross browser friendly:
function count_visible(el){
var padding, em, numc;
var text = el.firstChild.data;
var max = el.clientWidth;
var tmp = document.createElement('span');
var node = document.createTextNode();
tmp.appendChild(node);
document.body.appendChild(tmp);
if(getComputedStyle)
tmp.style.cssText = getComputedStyle(el, null).cssText;
else if(el.currentStyle)
tmp.style.cssText = el.currentStyle.cssText;
tmp.style.position = 'absolute';
tmp.style.overflow = 'visible';
tmp.style.width = 'auto';
// Estimate number of characters that can fit.
padding = tmp.style.padding;
tmp.style.padding = '0';
tmp.innerHTML = 'M';
el.parentNode.appendChild(tmp);
em = tmp.clientWidth;
tmp.style.padding = padding;
numc = Math.floor(max/em);
var width = tmp.clientWidth;
// Only one of the following loops will iterate more than one time
// Depending on if we overestimated or underestimated.
// Add characters until we reach overflow width
while(width < max && numc <= text.length){
node.nodeValue = text.substring(0, ++numc);
width = tmp.clientWidth;
}
// Remove characters until we no longer have overflow
while(width > max && numc){
node.nodeValue = text.substring(0, --numc);
width = tmp.clientWidth;
}
// Remove temporary div
document.body.removeChild(tmp);
return numc;
}
JSFiddle Example
You're trying to force a CSS problem into JavaScript. Put the hammer away and get out a screwdriver. http://en.wiktionary.org/wiki/if_all_you_have_is_a_hammer,_everything_looks_like_a_nail
Solving the answer of character count is probably irrelevant if you take a step back. The last character could be only partially visible, and character count is drastically different given font size changes, the difference of width between W an i, etc. Probably the div's width is more important than the character count in the true problem.
If you're still stuck on figuring out the characters visible, put a span inside the div around the text, use the css provided in other answers to this question, and then in JavaScript trim one character at a time off the string until the span's width is less than the div's width. And then watch as your browser freezes for a few seconds every time you do that to a big paragraph.
try this, it requires a fixed width if that is ok with you: http://jsfiddle.net/timrpeterson/qvZKw/20/
HTML:
<div class="col">This is my text inside a div and I want the overf|low of the text to be cut</div>
CSS:
.col {
width:120px;
overflow: hidden;
white-space:nowrap;
}
.col { width:40px; overflow: hidden; white-space:nowrap; }
White-space: nowrap; is needed when the content has spaces.
Either way, long words in single lines do not appear. http://jsfiddle.net/h6Bhb/
I couldn't find any other questions asking the same thing, though that may be a problem with my search phrasing.
I'm trying to figure out how to find the largest width of all elements contained inside of a container div with a fixed width. So, in the image below, the black box is the container div with a fixed width. The red box represents the contents of the container div, which are subject to change. I want to find the width of the red box, using only the black box in js.
Here is a jsfiddle with what I've been working on/trying:
http://jsfiddle.net/w87k5/1/
the current jquery functions I've tried, with no success:
.width();
.innerWidth();
.outerWidth();
.scrollLeft();
Note: I do not know ANYTHING about the contents of this container. They could be any html element or mix of html elements, from divs to imgs to iframes. I could put a "red box" without a fixed width surrounding them. Overflow of the black box will be hidden.
Update: There could be any number of children in the container. Like this: http://jsfiddle.net/w87k5/3/
Update 2: I'm going to run benchmark speed tests on all of the answers to see which one is the fastest, and select one after that. Thanks for all your input!
Benchmarks:
I generated 1000 divs with a random width of inbetween 0 and 100, recorded the Date().getTime(), did the test, then recorded time again. Here are the results:
~2418 avg. milliseconds with the for loop for length. I might have messed this one up somehow?
for (var i = 1; i <= count; i++){
var q = $("#box :nth-child(" + i + ")").width();
if(q > box){
box = q;
}
}
~34.4 avg. ms for the .each loop.
~22.4 avg. ms for the .map function. (Chosen answer.)
If you need all nested elements can search with * selector which will return all descendent elements:
var widthArray=$('#box *').map(function(){
return $(this).outerWidth();
}).get();
var maxWIdth= Math.max.apply(Math, widthArray);
For just children:
var widthArray=$('#box').children().map(function(){....
You could use .each() to cycle though each child element.
jsFiddle example
var widths = [];
$('#box').children().each(function(i){
widths[i] = $(this).width();
});
alert(Math.max.apply(Math, widths));
Which will return the width of the child element with the largest width.
Get the number of children, and loop through to get the width of each
$(document).ready(function () {
var count = $("#box").children().length;
var h = 0;
for (var i = 1; i <= count; i++) {
max = $("#box :nth-child(" + i + ")").width();
var h = Math.max(max, h);
}
alert(h);
});
http://jsfiddle.net/JDVN3/1/
Please not that the index starts from 1 and not 0.
Check out: http://api.jquery.com/nth-child-selector/
I want to make a dynamic textarea, it should increase in rows as the content increase.
I am using this code:
$("#text_textarea").keyup(function(e) {
//splitting textarea value wrt '\n' to count the number of lines
if ($(this).val().lastIndexOf('\n')!=-1)
var x = $(this).val().split('\n');
$(this).attr( "rows" , x.length+1 );
});
But it fails when user continues to write without giving any new line \n (pressing Enter).
var keyUpTimeout = false; // Required variables for performance
var keyupTimer = 0;
$("#text_textarea").keyup(function(e) {
var cooldownTimeout = 500;
//Set the cooldown time-out. The height check will be executed when the user
// hasn't initiated another keyup event within this time
var ths = this;
function heightCheck(){
keyupTimer = false;
// Reset height, so that the textarea can shrink when necessary
ths.style.height = "";
// Set the height of the textarea
var newheight = this.scrollHeight + 2;
ths.style.height = newheight + "px";
}
if(keyupTimeout){ //Has a cooldown been requested?
clearTimeout(keyupTimer); //This+next line: Refresh cooldown timeout.
keyUpTimer = setTimeout(heightCheck, cooldownTimeout);
return; //Return, to avoid unnecessary calculations
}
// Set a cooldown
keyupTimer = setTimeout(heightCheck, cooldownTimeout);
keyupTimeout = true; //Request a cooldown
});
This piece of script will change the height of the textarea to fit the text inside.
Update
I have added an additional feature: To improve performance (changing the CSS height requires a significant amount of computer power), I have added a cooldown effect: The height check will only be executed when the user hasn't initiated a keyup event for 500 milliseconds (adjust this value to meet your wishes).
read this,
Textarea Height increase
TextAreaExpander (Demo)
autoResize Plugin
JQuery Elastic
You should use the attribute wrap='hard' on your textarea.
I write this code. what about it..
$("#text_textarea").keyup(function(e) {
var textarea_height = Number($(this).css('height').replace("px", ""))+4;
var scroll_height = this.scrollHeight;
if(textarea_height < scroll_height ){
$(this).css('height' ,"");
var x = Number(scroll_height) + 3;
if(x != $(this).height())
$(this).css("height", x+"px");
}
});
How do you find the current width of a <div> in a cross-browser compatible way without using a library like jQuery?
document.getElementById("mydiv").offsetWidth
element.offsetWidth (MDC)
You can use clientWidth or offsetWidth Mozilla developer network reference
It would be like:
document.getElementById("yourDiv").clientWidth; // returns number, like 728
or with borders width :
document.getElementById("yourDiv").offsetWidth; // 728 + borders width
All Answers are right, but i still want to give some other alternatives that may work.
If you are looking for the assigned width (ignoring padding, margin and so on) you could use.
getComputedStyle(element).width; //returns value in px like "727.7px"
getComputedStyle allows you to access all styles of that elements. For example: padding, paddingLeft, margin, border-top-left-radius and so on.
Another option is to use the getBoundingClientRect function. Please note that getBoundingClientRect will return an empty rect if the element's display is 'none'.
var elem = document.getElementById("myDiv");
if(elem) {
var rect = elem.getBoundingClientRect();
console.log(rect.width);
}
You can also search the DOM using ClassName. For example:
document.getElementsByClassName("myDiv")
This will return an array. If there is one particular property you are interested in. For example:
var divWidth = document.getElementsByClassName("myDiv")[0].clientWidth;
divWidth will now be equal to the the width of the first element in your div array.
Actually, you don't have to use document.getElementById("mydiv") .
You can simply use the id of the div, like:
var w = mydiv.clientWidth;
or
var w = mydiv.offsetWidth;
etc.
call below method on div or body tag onclick="show(event);"
function show(event) {
var x = event.clientX;
var y = event.clientY;
var ele = document.getElementById("tt");
var width = ele.offsetWidth;
var height = ele.offsetHeight;
var half=(width/2);
if(x>half)
{
// alert('right click');
gallery.next();
}
else
{
// alert('left click');
gallery.prev();
}
}
The correct way of getting computed style is waiting till page is rendered. It can be done in the following manner. Pay attention to timeout on getting auto values.
function getStyleInfo() {
setTimeout(function() {
const style = window.getComputedStyle(document.getElementById('__root__'));
if (style.height == 'auto') {
getStyleInfo();
}
// IF we got here we can do actual business logic staff
console.log(style.height, style.width);
}, 100);
};
window.onload=function() { getStyleInfo(); };
If you use just
window.onload=function() {
var computedStyle = window.getComputedStyle(document.getElementById('__root__'));
}
you can get auto values for width and height because browsers does not render till full load is performed.
How can I access the scrollHeight using mootools or some other property that contains the height so I can resize it to make an autogrow textarea?
Mootools offers a variety of Element 'dimension' functions that give you information on the scrollable and absolute element sizes. Full docs available here: http://mootools.net/docs/core/Element/Element.Dimensions
What you want to do is compare the return values of your element's getScrollSize() function to your element's getSize() function - in particular the 'y' member, which represents element and scrollable area height, respectively. Something along the lines of this should work:
var myElement = $('myElement'); // get a reference to your element
var scrollSize = myElement.getScrollSize(); // MooTools-specific function.
var elementSize = myElement.getSize(); // MooTools-specific function.
if (scrollSize.y > elementSize.y) {
// determine whether the scrollable area is greater than the dimensions
// of the element. If so, resize the element to match the scrollable area.
myElement.setStyle('height', scrollSize.y + 'px');
}
David Walsh created an excellent plugin for just this purpose:
http://davidwalsh.name/flext-textrea
Here's a simple method I'm using that expands but also contracts the textarea.
The issue you're always going to have is styling on the textare (padding/border).
The first thing to know is that getSize() will get the size of the textarea from absolute top to the absolute bottom, taking into account padding and borders. However, the actual style height of the text area .getStyle('height').toInt(), is the inside of the text box without padding and border. This is the part you need to be interested in as, when you set your height, it sets that, it doesn't set the full height of the textarea from absolute top to bottom.
Here's a working example, with a textarea that's styled (See Demo)
This will also resize the element correctly if you ran it inside domReady.
function expBox(el){
var e = $(el.id);
if(typeof(e._expBox) == "undefined"){
var v = e.value;
e.value = "";
var ss = e.getScrollSize();
var s = e.getSize();
var h = e.getStyle("height").toInt();
e._expBox = (s.y-h)-(s.y-ss.y);
e.value = v;
}
var k = event.keyCode || event.charCode;
if(k == 8 || k == 46){
e.setStyle("height","auto");
}
var ss = e.getScrollSize();
e.setStyle("height",(ss.y-e._expBox));
}
Demo:
http://jsfiddle.net/greatbigmassive/M6X5j/