Html : Text width is different than summation of its character's width - javascript

I need to calculate the text width without appending it to DOM.For this,i calculate and save each character's width i.e from (A-Z & a-z and other necessary characters).
Code :
function calculateCharactersWidth(){
for(var i=65;i<123;i++){
var x = $('<div style="float:left">').text(String.fromCharCode(i)).appendTo('#hiddenView');
charactersWidth[i] = x.width();
remHeight = x.height();
}
var x = $('<div style="float:left">').text(String.fromCharCode(45)).appendTo('#hiddenView');
charactersWidth[45] = x.width();
$('#hiddenView').empty();
}
and get each word's width like this
function getStringWidth(word){
var width=0;
for(var i=0;i<word.length;i++){
width=width+charactersWidth[word.charAt(i).charCodeAt(0)];
}
return width;
}
but when the word is appended to DOM. Its width differs from the calculated width.In some cases it differs by 3-4 px.
Even if we calculate it like this
// css font-weight:bold and font-size:14px
<div>Absin</div> width = 35.031
<div>A</div> width = 10.125
<div>b</div> width = 7.797
<div>s</div> width = 6.219
<div>i</div> width = 7
<div>n</div> width = 4.672
Added width = 35.831
This small difference creates a huge difference with array of words.So why is the difference and how can i make it work?

The kerning of the font is definitely messing up your calculation.
I am not sure why you'd need to do this, but why don't you print out your text in a hidden element and take the width of that?
function getStringWidth(word){
var x = $('<div style="float:left">').text(word).appendTo('#hiddenView');
return x.clientWidth;
}
This way you can also change the style, the font type and size, etc.

Related

How do I set the height of a css element based on the randomly generated height of another element?

I'm trying to create a consistent gap of 100px between two 'walls', one on the top of the screen 'wallTop' and one on the bottom 'wallBot', like in Flappy Bird. I've used Math.random on 'wallTop' to randomise the height of it in order to randomise the position of the gap, but how do I set the height of 'wallBot' to be based off of 'wallTop's randomised height?
Here's what I've tried
var wallGap = 100;
var wallTop = document.getElementById("wallTop");
var constant= (wallTop.height+wallGap);
$("#wallTop").css("height",Math.round(Math.random()*150+70)+"px");
$("#wallBot").css("height",450-constant+"px");
"450" is the height of the whole container, so I'm trying to find the remainder after subtracting 'wallTop' and 'wallGap', which will be the height of 'wallBot'.
Your constant won't change magically after having set a new height for wallTop (also note that wallTop.height will be undefined, since the element doesn't have the property height).
var wallGap = 100;
var wallSpace = 450 - wallGap;
var wallTop = $("#wallTop");
var wallBot = $("#wallBot");
wallTop.height(Math.round(Math.random()*150+70));
wallBot.height(wallSpace - wallTop.height());

div box size css show the value of auto

Help is really wanted here, I have a div surrounding a textarea, the div is auto sized, height and width, and I need to know what that auto value is. tried a little javascript, please see below:
function textAreaChange() {
var textboundary = document.getElementById("textarea");
textboundary.style.height = document.getElementById("heightx").innerHTML;
textboundary.style.width = document.getElementById("widthy").innerHTML;
}
fairly new to all this javascript so please be patient?
Thanks.
If you are looking at obtaining the height and width, based on wrapping of the text area, try one of the following:
var h = document.getElementById('someDiv').clientHeight;
var h = document.getElementById('someDiv').offsetHeight;
var h = document.getElementById('someDiv').scrollHeight;
clientHeight includes the height and vertical padding.
offsetHeight includes the height, vertical padding, and vertical borders.
scrollHeight includes the height of the contained document (would be greater than just height in case of scrolling), vertical padding, and vertical borders.
There are Widths that correspond to each Height.
You can do it like this :)
function textAreaChange() {
var textboundary = document.getElementById("textarea");
document.getElementById("heightx").innerHTML = textboundary.offsetHeight;
document.getElementById("widthy").innerHTML = textboundary.offsetWidth;
}
textAreaChange();
<textarea id="textarea" ></textarea>
<div id="heightx"></div>
<div id="widthy"></div>

How to set the font-size to 100% the size of a div?

I have a div with a static size. Sometimes longer text than the div will be placed there. Is there anyway to achieve the text fitting the div width at all times through JavaScript alone? I am aware there are jQuery fixes but need a pure JS solution in this case.
Even if you have a link to a demo/tutorial that would be helpful, thanks.
Here you go, this should do what you want: JSFiddle
Basically the key here is to check the output.scrollHeight against output.height. Consider the following setup:
HTML:
<button onclick="addText(); resizeFont()">Click Me to Add Some Text!</button>
<div id="output"></div>
CSS:
div {
width: 160px;
height: 160px;
}
This creates a square div and fills it with a randomly long string of text via the addText() method.
function addText() {
var text = "Lorem ipsum dolor amit",
len = Math.floor(Math.random() * 15),
output = document.querySelector('#output'),
str = [];
for (; --len;)
str.push(text);
output.innerHTML = str.join(', ');
}
The magic lies in the resizeFont() function. Basically what this does is, once the text has been added, it sets the fontSize of the div to be equal to its own height. This is the base case for when you have a string of 1 character (i.e. the fontSize will equal the height). As the length of your string grows, the fontSize will need to be made smaller until the scrollHeight equals the height of the div
function resizeFont() {
var output = document.querySelector('#output'),
numRE = /(\d+)px/,
height = numRE.exec(window.getComputedStyle(output).height)[1],
fontSize = height;
// allow div to be empty without entering infinite loop
if (!output.innerHTML.length) return;
// set the initial font size to the height of the div
output.style.fontSize = fontSize + 'px';
// decrease the font size until the scrollHeight == height
while (output.scrollHeight > height)
output.style.fontSize = --fontSize + 'px';
}
The nice thing about this method is that you can easily attach an event listener to the resize event of the window, making the text dynamically resize as the user changes the window size: http://jsfiddle.net/QvDy8/2/
window.onload = function() {
window.addEventListener('resize', resizeFont, false);
}

Is it possible to get the width of the window in em units using javascript?

I'm looking for a reliable way to get the width of the window in em units using JavaScript. I was surprised to see that jQuery will only return a result in pixel measurements.
This seems to work:
$(window).width() / parseFloat($("body").css("font-size"));
Here's a solution that doesn't require jQuery, and doesn't require an explicit font-size declaration.
window.innerWidth / parseFloat(
getComputedStyle(
document.querySelector('body')
)['font-size']
)
For those who need it all put together, this code works for me:
<p>Window size: <span id="width_px"></span> pixels or <span id="width_ems"></span> ems</p>
<script>
window.onresize = function() {
document.getElementById("width_px").innerHTML = window.innerWidth;
document.getElementById("width_ems").innerHTML = window.innerWidth / parseFloat($("body").css("font-size"));
};
</script>
It's put together using the answer above added to the window-width test code found in the linked tutorial.
It's possible to calculate it, but em isn't a "simple" unit like px because it depends on a font selection (that is, a combination of typeface family, style (bold, italic, etc), and font size). Of course font size itself can be relative (e.g. if you give a font an em, ex, or percentage size then the computed px height for that font is derived from the parent element's size).
To get the em width of a page you could do the conversion like this (warning: psuedocode):
// For this to work reliably, size should be in px, pt, or mm.
function getWindowWidthInEm(fontFamily, style, size) {
var box = document.createElement("span");
box.innerText = "M";
box.style.fontFamily = fontFamily;
box.style.fontSize = size;
box.style.fontWeight = style is bold;
box.style.fontStyle = style is italic;
var body = document.getElementsByTagName("body")[0];
body.appendChild( box );
var emInPx = box.getComputedStyle().width;
body.removeChild( box );
var windowPx = window.width;
return windowx / emInPx;
}
Simple, since we know 1em = 16px
var window_width_em = 1/16 * window_width_px;

How to find actual rendered values of elements set to 'auto' using JavaScript

Suppose I have the following html, and no CSS
<div>
here is some content in this div. it stretches it out
<br />and down too!
</div>
Now I want to get the actual pixel width and height that the browser has rendered this div as.
Can that be done with JS?
Thank you.
Try getting a reference to your div and reading the offsetWidth and offsetHeight properties:
var myDiv = document.getElementById('myDiv');
var width = myDiv.offsetWidth; // int
var height = myDiv.offsetHeight;
offsetWidth/Height cumulatively measures the element's borders, horizontal padding, vertical scrollbar (if present, if rendered) and CSS width. It's the pixel values of the entire space that the element uses in the document. I think it's what you want.
If that is not what you meant, and you'd rather only the element's width and height (i.e. excluding padding, margin, etc) try getComputedStyle:
var comStyle = window.getComputedStyle(myDiv, null);
var width = parseInt(comStyle.getPropertyValue("width"), 10);
var height = parseInt(comStyle.getPropertyValue("height"), 10);
The values above will be the final, computed pixel values for the width and height css style properties (including values set by a <style> element or an external stylesheet).
Like all helpful things, this won't work in IE.
You say you are using jQuery. Well it's trivial now, and works cross-browser:
var width = $('div').css('width');
var height = $('div').css('height');
With jQuery you don't need the first part of this answer, it's all taken care of for ya ;)
One of the benefits of using a framework, like Prototype, is that the framework authors have usually sorted out the portability issues. Even if you don't use the framework, it can still be instructive to read. In the case of Prototype, the code for reading the dimensions of an element accounts for a Safari issue and allows you to read the width of an element that is not presently dislayed.
getDimensions: function(element) {
element = $(element);
var display = $(element).getStyle('display');
if (display != 'none' && display != null) // Safari bug
return {width: element.offsetWidth, height: element.offsetHeight};
// All *Width and *Height properties give 0 on elements with display none,
// so enable the element temporarily
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
},
For the jQuery framework, .height and .width do the job.

Categories

Resources