jQuery calculating 2 different HTML element attributes (height + margin-bottom) - javascript

I'm trying to get the height and the margin-bottom of a element, and count them up. But so far, i can only do this:
var sum = $('div').height() + 25);
That 25 i had to look up myself in the stylesheet at
div {
height: 75px;
margin-bottom: 25px;
}
How can i make this automaticly?
Because when i try:
var sum = $('div').height() + $('div').css('margin-bottom');
It isnt returning any value.

You're probably looking for http://api.jquery.com/outerheight/ which includes the margins, padding and borders (all which count towards the total height, along with the base height). Alternatively, you can use parseInt($('div').css('margin-bottom')) because the value is a css string that looks something like this: 100px. parseInt() would extract the 100 from that css, which is what you want.
In addition, you're kinda doing it wrong in general. Are you looking for the sum of all the heights of all the div elements? Or does your page have only one div?

$('div').css('margin-bottom') will have the px attached. Try and use something like parseInt()
var sum = $('div').height() + parseInt($('div').css('margin-bottom'), 10);
W

There are many 'div' elements in a document(usually).
You need a better selector for the one you want.
Fiddle for value in console.log
<div id="TestId" class="test"></div>
.test
{
height:40px;
margin:5px;
}
var tester = $("#TestId");
var eleHeight = tester.outerHeight();
var marginBottomHeight = tester.css('margin-bottom').replace("px", "")
console.log(eleHeight + parseInt(marginBottomHeight));

Related

How to reproduce the `.width()` jQuery behavior in pure JavaScript, without another library/framework

I know the method .width() from jQuery returns the element's width without padding, border and margin.
In the accepted answer Table with vertical scroll, in which I can't comment, such method is used to get the width of the td elements of the first row of the table.
One of the jsFiddle in the answer there can be used to see the values returned by the method.
I tried to reproduce the behavior with this piece of code:
let colunas = document.querySelector('.scroll tbody tr:first-child').children;
let colunasWidth = [];
for (let i = 0, length = colunas.length; i < length; i++) {
colunasWidth.push(colunas[i].offsetWidth);//Width/clientWidth
}
I tried the various widths (offsetWidth, width, clientWidth), none gave the same result as jQuery and then I tried to get the border and padding width to subtract from such various widths, but I can't think of a way to get the math or right properties right.
Is there a simple and straightfoward way to do it?
You want window.getComputedStyle and .getPropertyValue
What it does is, it gets the styles used and then gets the actual width value of the element.
Here's a jsfiddle to show you: http://jsfiddle.net/u9d27wno/1/
var jquerywidth = $("#container").width();
var jqueryishwidth = window.getComputedStyle(document.getElementById("container"));
var offsetWidth = document.getElementById('container').offsetWidth;
var clientWidth = document.getElementById('container').clientWidth;
var msg = "offsetWidth: " + offsetWidth + "<br>\n";
msg += "clientWidth: " + clientWidth + "<br>\n";
msg += "jQuery width: " + jquerywidth + "<br>\n";
msg += "jQueryish width: " + jqueryishwidth.getPropertyValue("width") + "<br>\n";
document.getElementById('msg').innerHTML = msg;
//alert(document.getElementById('msg').innerHTML);
Let me know if that's the solution you needed!
You can use element.clientWidth and getComputedStyle together, to obtain teh value you are looking for...
element.clientWidth
The Element.clientWidth property is zero for elements with no CSS or inline layout boxes, otherwise it's the inner width of an element in pixels. It includes padding but not the vertical scrollbar (if present, if rendered), border or margin.
window.getComputedStyle
The window.getComputedStyle() method returns an object that reports the values of all CSS properties of an element after applying active stylesheets and resolving any basic computation those values may contain.
function width(el){
// get element computed styles
let styles=getComputedStyle(el);
// remove the 'px' from the returned values
let paddingLeft = styles['padding-left'].slice(0,-2);
let paddingRight= styles['padding-right'].slice(0,-2);
// substract paddings from value returned by clientWidth, and return value
return el.clientWidth - paddingLeft - paddingRight;
}
// test
let w = width(document.getElementById('test'))
console.log( 'VanillaJS:' , w )
console.log( 'JQuery : ', $('#test').width())
#test{
border:10px solid red;
width:200px;
margin:10px;
padding:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
I'm 200px + <br>
10px padding + <br>
10px border +<br>
10px margin
</div>

How to find css unit for this number

I have a input type text
<input type="text">
Basically I am using javascript ClientRect to get caret details. ClientRect looks like this
[object ClientRect]
{
[functions]: ,
__proto__: { },
bottom: 540.7999877929687,
constructor: { },
height: 24,
left: 1034.5399169921875,
right: 1034.5399169921875,
top: 516.7999877929687,
width: 0
}
This is generated on everytext input.
left: 1034.5399169921875,
left: 1065.5399169921875,
left: 1078.5399169921875,
I want to convert this number to CSS units like px/%/rem/vh. So that I can put dynamic css. How to do it?
Try accessing the left position of your input and subtract the left position of your caret. This should give you an approximate width of the text in the input, if that's what you are looking for. You'll need to add an id or create a selector for your text input.
var inputElementRect = document.getElementById('YOURINPUTID').getBoundingClientRect()
var width = inputElementRect.left - caretRect.left
Those values are px by default .. so just add suffix as px to that value and use it.
<input type="text">
to get that value
let text = document.querySelector('input');
let values = text.getBoundingClientRect();
let top_value = values.top + 'px';
let bottom_value = values.bottom + 'px';
let width_value = values.width + 'px';
let height_value = values.height + 'px';
console.log('top: '+ top_value);
console.log('bottom: '+ bottom_value);
console.log('width: '+ width_value);
console.log('height: '+ height_value);
here properties other than width and height are relative to the view port ( top, bottom, left, right ) ,
so if scroll this values will changes ..
to get the perfect values even if scroll add this values with window.scrollX , window.scrollY or can use window.pageXOffset , window.pageYOffset
So if I understand the question correctly, you have position values for the cursor inside of the input and you want to convert it into different types of CSS units, presumably so you can do something to the input or related things
The first thing to understand is that ClientRect positions are relative to the viewport. So as vhutchinson pointed out, if you want the width of text you need to compare to the input's "left" value as defined by getBoundingClientRects. That's a good start, but if you're not just influencing left but also care about top, you need to account for scrolling. If your window/page is the only scrolling container, you should be able to do this simply by adding window.scrollY to top, and window.scrollX to left to understand your offset relative to the window.
All of these units are pixels by default... if you want to convert to rem it's pretty straightforward, 1 rem = the font-size of your root element, so to convert to rem you can do something like
var remBase = parseInt(window.getComputedStyle(document.body).getPropertyValue('font-size'), 10);
var remValue = (myComputedPixelValue / remBase) + "rem";
Doing VW is similar using the answer in Get the browser viewport dimensions with JavaScript for cross-browser window dimensions, you'd end up with something that looks like
var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var vwValue = (myComputedPixelValue / viewportWidth) + "vw";
Percentages are trickier, because you'd need to compute it based on the parent of the element you're applying the css value to, but the general idea follows the same principle.

How to check really width with "auto" value on css

I have a loop:
var takediv = document.getElementById('eye');
for(var i=0; i<categories.length; i++){
takediv.innerHTML +=^
'<img alt="'+(categories.length-i)+'" '+
'onclick="changef(this.alt)" '+
'src="mobile/img/pic/'+loc+"/mini/"+categories[categories.length-i-1][0]+'" '+
'style="cursor: pointer;"/>';
}
All images are having this css:
height: 80px;
width: auto;
And finally after loop I need to give the div this css
document.getElementById('eye').style.width
which will be sum of all inner img widhts
It is my first post here so sorry for mistakes.
Please help, and thanks!
You can use several approaches, for example getBoundingClientRect() which returns absolute values for position and width/height:
var width = document.getElementById('eye').getBoundingClientRect().width;
Just note it does not include border or padding, only the inner box.
Then there is getComputedStyle() - this will return a string suffixed with "px" so we also need to parse it using parseInt():
var width = parseInt(getComputedStyle(document
.getElementById('eye'))
.getPropertyValue("width"), 10);
Both returns size in pixels.
And as in #Rudi's answer, there is offsetWidth, and also clientWidth. This won't include margin.
Maybe you're looking for this:
var width = document.getElementById('eye').offsetWidth;

How to measure and set the width?

I would like to make sub-navigation to measure its parents width and then set its own width accordingly. At the moment every sub-navigation (.primary-navigation ul ul) gets an individual class (customWidth-0 + i). Then using this class I measure its parent's width and set the width minus the padding. It's all working nice and fine, but I'm learning and I'd like to shorten the script. I was trying to loop this, use "this", but seem to get stuck at every point. It would be nice to learn to do this in a proper, robust way. Any help is very much appreciated. Thanks.
jQuery(document).ready(function( ) {
jQuery(".primary-navigation ul ul").each(function(i) {
i = i+1;
jQuery(this).addClass("customWidth-0" + i);
});
a = jQuery(".customWidth-01").prev().parent().width();
b = jQuery(".customWidth-02").prev().parent().width();
c = jQuery(".customWidth-03").prev().parent().width();
d = jQuery(".customWidth-04").prev().parent().width();
jQuery(".customWidth-01").css("width", a-31);
jQuery(".customWidth-02").css("width", b-31);
jQuery(".customWidth-03").css("width", c-31);
jQuery(".customWidth-04").css("width", d-31);
});
I took your look and added my code after commenting your sections out and got the same thing.
<script type="text/javascript">
jQuery(document).ready(function( ) {
jQuery(".primary-navigation ul ul").each(function(i) {
i = i+1;
var _this = jQuery(this), w = _this.parents('ul').width();
_this.css("width", (w-31)+"px");
//jQuery(this).addClass("customWidth-0" + i);
console.log(i);
});
/*
a = jQuery(".customWidth-01").prev().parent().width();
b = jQuery(".customWidth-02").prev().parent().width();
c = jQuery(".customWidth-03").prev().parent().width();
d = jQuery(".customWidth-04").prev().parent().width();
jQuery(".customWidth-01").css("width", a-31);
jQuery(".customWidth-02").css("width", b-31);
jQuery(".customWidth-03").css("width", c-31);
jQuery(".customWidth-04").css("width", d-31);
*/
});
</script>
It will find the div above given ul and take its width take off 31px and then apply it to given elements below. The LI elements inside of the UL will already have a 100% width and conform to that standard. If you wanted to you could just apply a position: relative; on the LIs of the .primary-navigation and then position: absolute; left: 0; top: ~20px; (top is a little skewed according to your em size.. This will do the same thing except it won't wrap your children and make it look weird.
If you gave me an exact image of what you wanted your menu to look like (not using javascript or anything maybe a designed version??) I could probably do a better job as this is still kinda hard to answer. Hopefully the code I provided helps you if not leave another comment and let me know if you have questions.
Below line is old answer.
Set a variable
var _this = jQuery(this), w = _this.parent().parent().width();
_this.css("width", (w-31)+"px");// just to be safe added px use w/e or leave blank it assumes it
This should work for you the same as you have it in the foreach.
you could also use .parents('ul')
w = _this.parents('ul').width();
function() {
$('.primary-navigation').children('li').each(
function(index) {
var parentWidth = $(this).width();
$(this).children('ul').width(parentWidth/2);
}
);
Is this what you are looking for? now all the sub menu is 1/2 of parent. you need to fix it to your specific need.
DEMO http://jsfiddle.net/La07pvf2/

Can a DIV's CSS attribute be changed dynamically by javascript just by knowing it's class?

I have this div:
<div class="galleria-info" style="">
<div class="galleria-info-text">
<div class="galleria-info-title" style="">#test</div>
</div>
</div>
And I have this CSS for it:
.galleria-info {
width: 100%;
top: 290px;
left: 330px;
z-index: 10;
position: absolute;
}
What I would like to do is somehow thru javascript change the left attribute of the galleria.info div dynamically so that based on the length of the text for #test i can position the div far enough left to make room for it on screen.
I write different information where the word #test is at in the HTML dynamically and it doesn't have an ID only class.
Any clues or help will be mega-appreciated!
document.getElementsByClassName('galleria-info')[0].style.left = '300px'; // or whatever you want
You have two questions; I have two answers.
Getting by Classname
getElementById() gets the element by its id, getElementsByTagName()[] gets the element by tag name, and to get it by class name, use:
document.querySelectorAll("galleria-info")
Setting the Position
Sorry I used getElementById and getElementsByTagName instead of querySelectorAll.
right Attribute
Wouldn't a right attribute be more appropriate? You could get the width of the body (or container) and subtract however much you want from that instead.
var body_width = document.getElementsByTagName('body')[0].style.width;
var body_width = parseFloat(body_width);
document.getElementById('galleria-info').style.right = (body_width - 600) + "px";
Fixed-Width Font
But, if you are using a fixed-width font, then you can get the length of the string, multiply by the width of each character, and then set style.left to that minus the max distance it can reach (i.e. 300px.)
var str_length = document.getElementById('galleria-info').innerHTML.length;
var str_length = str_length * 10; // Or whatever the fixed width is
document.getElementById('galleria-info-text').style.left = (300 - str_length) + "px";
Wrapper
This doesn't use JavaScript, which, in my opinion, is a good thing because users can disable JavaScript. You can have a wrapper div around the original div that has the following CSS:
#galleria-info-wrapper {
width:300px;
text-align:right;
}
#galleria-info {
text-align:left;
}

Categories

Resources