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
Related
Note that I'm not asking how to make a div the size of the "window" or "viewport" for which there are plenty of existing questions.
I have a web page of some height and width, and I'd like to add an empty, top-level div (i.e., not one containing the rest of the page) with a size exactly equal to the page's height and width. In practice, I also want it to be at least the size of the viewport.
I know I can do a one-time calculation of the height and width in JavaScript:
var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
But this value can change based on images loading, or AJAX, or whatever other dynamic stuff is going on in the page. I'd like some way of locking the size of the div at the full page size so it resizes dynamically and on-demand.
I have tried something like the following:
function resetFakeBg() {
// Need to reset the fake background to notice if the page shrank.
fakeBg.style.height = 0;
fakeBg.style.width = 0;
// Get the full page size.
var pageHeight = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var pageWidth = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
// Reset the fake background to the full page size.
fakeBg.style.height = pageHeight + 'px';
fakeBg.style.width = pageWidth + 'px';
}
// Create the fake background element.
fakeBg = setFakeBgStyle(document.createElement('div'));
document.body.appendChild(fakeBg);
// Keep resizing the fake background every second.
size_checker_interval = setInterval(resetFakeBg, 1000);
Limitations
This is for a Chrome extension, and I'd like to limit my modification of the page to adding this single div. This means that adding CSS to modify the height and width of the html and/or body tags is undesirable because it might have side-effects on the way the rest of the page is rendered.
In addition, I do not want to wrap the existing page in the div because that has the potential to break some websites. Imagine, for example, a site styled with the CSS selector body > div. I'd like my extension to break as few websites as possible.
WHY OH WHY WOULD I NEED TO DO THIS?
Because some people like to hold their answers hostage until they're satisfied that I have a Really Good Reason™ for wanting to do this:
This is for an accessibility-focused Chrome extension that applies a CSS filter across an entire page. Recent versions of Chrome (>= 45) do not apply CSS filters to backgrounds specified on the <html> or <body> tag. As a result, I have chosen to work around this limitation by copying the page's background onto a div with a very negative z-index value, so that it can be affected by the page-wide CSS filter. For this strategy to work, the div needs to exactly imitate the way the page background would appear to a user—by being the exact size of the document (and no larger) and at least filling the viewport.
setInterval() is your best friend in cases like this where you want the .height() and .width() of an element to be asynchronously specified all the time to something that can be dynamicly altered by user input and DOM tree changes. It is what I dub as a "page sniffer", and arguably, works better than $(document).ready if you are working in multiple languages (PHP, XML, JavaScript).
Working Example
You should get away with setting the width and height in the window resize function, you might wanna add it in a load function as well, when all data/images are loaded.
just add width=100%
e.g;-
Hello World
I think you must do it like this:
...
<body>
<script>
function height()
{var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);}
function width()
{var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);}
</script>
<div height="height()" width="width()">
</div>
</body>
...
I have a Element with the id="somID";
For Example:
Html:
<div id='somID' ></div>
Css :
#somID{ width:500px;height:500px}
and i have a class named : maximize.
So,
.maximize{width:100% !important; height:100% !important; }
Now dynamically i added the class .maximize to my div #somID
And after that i wanna get the width and height of my #somID by calling with its ID like,
$('#somID').width() or .height()
but i want to take the actual height of element that is defined in its ID but i get the .maximize in result not the height or width that is in #somID.
Any buddy have any idea ? That how to retrieve the height of div#somID if it contains .maximize ??
The problem is, there can be many, many selectors that are applied to a given element, with different specificities. There is no API that allows you to request a property from a selector in CSS - it simply wouldn't make much sense.
Having said that, you can create a hack to solve that issue:
function getOriginalDimensions(id) {
var $a = $("<div>", {id:id});
$("body").append($a);
var width = $a.width();
var height = $a.height();
$a.remove();
return {width:width, height:height};
}
console.log(getOriginalDimensions("somID")); // returns {width:500, height:500}
The above works with your example HTML and CSS.
JSFiddle
This basically creates an element with the same ID, appends it to the body, reads the dimensions and deletes it immediately. This is necessary because the div will have no size if it is just kept as a document fragment and not added to the DOM, because the CSS will not get applied.
In theory you could expand this function to make it work with other selectors.
However bear in mind this is a nasty hack and you should reconsider your approach.
A. Make your measurements and save them as .data attributes of the element :
var $el = $('#somID');
$el.data('original_dims', {
height: $el.height(),
width: $el.width()
}
B. Add class that changes the dimensions of the element :
$el.addClass('maximise');
C. Retrive the original dimensions whenever they are needed
var h = $el.data('original_dims').height;
var w = $el.data('original_dims').width;
I want to make horizontally scrollable container which will keep child elements on the y-line (width more that 100% of the screen).
If the data was fixed I would calculate it before rendering and setup the width of the container. The problem is that my data is dynamic, I don't know the number of the child elements that will be added and their width. So I decided to add them dynamic to the container DOM as a children, but when I try to get their width after appending, the result is 0. What I am doing wrong, or if you have a better idea how to do that I will be glad to see your way.
This is what I am doing now:
GalleryContainer.prototype.addItem = function(newItem) {
var newItemDiv = document.createElement('div');
newItemDiv.className = 'thumbnail';
content = document.createElement('img');
content.setAttribute('src', newItem);
newItemDiv.appendChild(content);
this.galleryDiv.appendChild(newItemDiv);
this.galleryArray.push(newItemDiv);
// width, offsetWidth, all properties are 0
console.log(newItemDiv.style.offsetWidth);
console.log($(content).css('width'));
console.log($(newItemDiv).innerWidth());
}
EDIT:
I made a jsfiddle example with my problem and in the demo the width is not 0, it's the actual size that i need, so I have to look deeper for the problem.
http://jsfiddle.net/valkirilov/QaHn7/1/
bellow code is working, maybe your newItemDiv is not append into HTML Document:
var newItemDiv = document.createElement('div');
newItemDiv.className = 'thumbnail';
$('body').append(newItemDiv);
// width, offsetWidth, all properties are 0
console.log(newItemDiv.style.offsetWidth);
console.log($(content).css('width'));
console.log($(newItemDiv).innerWidth());
I'm having a nightmare with a simple function!
I want it to:
read the height of a div with existing content in it
Update the div with the new content (supplied to the function)
Read the height the div should be, but set it to the original height.
Animate the div's height to adjust and fit the new content.
Code is as follows:
// function to display status content by animating the height of the status message
function slideStatus(content){
// get current height
var status_origheight = $("#status-message").height();
// insert new content
$("#status-message").html(content);
// get new height
var status_newheight = $("#status-message").height();
// set the height to the orig value, hiding overflow content
$("#status-message").height(status_origheight).css("overflow","hidden");
// animate the div to the new height
$("#status-message").animate({height:"+="+(status_newheight - status_origheight)+""}, 1000);
}
When i run this, it appears to ignore the fact that the content has changed, and just use the original height (therefore do no animation as it thinks the height has not changed).
Please help if you can!! It's driving me nuts.
Work for me. Your bug is likely elsewhere... http://jsfiddle.net/6aBfD/
UPDATE
http://jsfiddle.net/6aBfD/3/
But that only works once. The problem is that you are relying on an element to set it's own height and read from that. But after the first run, you lock the height to a specific value. The updated link has the correct working clode, click it multiple times. I added the following:
$("#status-message")
.css("overflow","visible")
.css("height", "auto");
Now when you read the height it will be it's natural height. Then set the oveflow and height again later to lock it back down to what you want.
Rob,
Try the following instead of .height():
var status_origheight = $("#status-message").css('height');
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.