Jquery width 100% minus pixels - javascript

I'm trying to set the width on an elemrnt to 100% minus a variable in pixels.
My subtractWidth variable returns a dynamic value in pixels eg: 170
$('#chartTitle').each(function(i){
var elem = $(this);
var parent = $(elem).parent();
var next = $(parent).next();
var maxWidth = '100%';
var subtractWidth = next.width();
elem.width(maxWidth) - subtractWidth;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input id="chartTitle" />
</div>
<div> ... </div>
Am I mising something?
Any help or advice is appreciated - thank you in advance.

First apply the 100% width and then do the calculation based on the applied width.
Your problem is that in your line elem.width(maxWidth) - subtractWidth; elem is setting the maxWidth which is 100% but not subtracting it after.
calculate = function(){
var total = '50%';
var subtractWidth = $('#div1').width();
$('#div2').width(total)
$('#div2').width($('#div2').width() - subtractWidth);
}
div{
background-color: red;
height: 20px;
display: block;
width: 0px;
}
#div1{
width: 70px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1"></div>
<hr>
<div id="div2"></div>
<hr>
<button onclick="calculate()">calculate</button>

Related

How to get width and height of text not the span with display table-cell

How to find width and height of a text not the span's having display:table-cell. In side of a div with display:table.
<div style="display: table; width: 50px; height: 343.559px;"><span class="nodeText" style="display: table-cell;vertical-align: middle;text-overflow: ellipsis;font-family: Arial;font-size: 10px;font-style: normal;font-weight: normal;color: black;opacity: 1;">Desktop 1.43k (53.34%)</span></div>
Text width and height is
width is approx 45px
height is approx 35px
If you don't want the height of the span to be the height of the div (you want the space that the actual text takes up) you can extra wrap the text:
const span = document.querySelector("span>span");
console.log(
span.getBoundingClientRect()
)
<div style="display: table; width: 50px; height: 343.559px;">
<span class="nodeText" style="display: table-cell;vertical-align: middle;text-overflow: ellipsis;font-family: Arial;font-size: 10px;font-style: normal;font-weight: normal;color: black;opacity: 1;">
<span>Desktop 1.43k (53.34%)</span>
</span>
</div>
You can have a check for the div if it has a display:table then you can iterate through it and find the span with display:table-cell property.
let divs = document.querySelectorAll('div');
divs.forEach(div => {
if(div.style.display === 'table'){
let spans = document.querySelectorAll('span');
spans.forEach(spn => {
if(spn.style.display === 'table-cell'){
let theSpan = spn.getBoundingClientRect();
console.log(theSpan.width, theSpan.height);
}
});
}
})
Strange nobody recommended getBoundingClientRect:
fiddle
var span = document.getElementsByTagName("span")[0],
rect = span.getBoundingClientRect();
span.parentNode.nextElementSibling.textContent = "width: " + (rect.width|0)
+ "\nheight: " + (rect.height|0);
PS: I see that you meant the client area without the padding. And that was not clear in your question. Use 2 spans so that you end up with client areas.
HERE - width: 40 height: 32
https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth
https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
var $e = document.getElementById("e");
var $a = document.getElementById("a");
// Thses are for the span itself...
// Only inner width and padding
console.log($e.clientWidth,$e.clientHeight);
// also scrollbar if presented and ...
console.log($e.offsetWidth,$e.offsetHeight);
// get the width after any computing necessary
console.log( $e.getBoundingClientRect() );
var style = window.getComputedStyle( $e );
console.log( style.font );
// Now combine them to measure string in pixels
var $canvas= document.createElement("canvas");
var ctx = $canvas.getContext("2d");
ctx.font = style.font;
var txt = $e.innerText;
var measures = ctx.measureText(txt);
console.log( ctx.font );
console.log( measures );
$a.style.height = Math.ceil(measures.width / $e.clientWidth)
* parseInt(style.lineHeight) + 'px';
div, #e { position:relative; }
#a { display:block;width:3px;background:red; }
<!-- changed the size to fit in preview -->
<div style="display: table; width: 50px; height: 47px;"><span id="e" class="nodeText" style="display: table-cell;vertical-align: middle;text-overflow: ellipsis;font-family: Arial;font-size: 10px;font-style: normal;font-weight: normal;color: black;opacity: 1;">Desktop 1.43k (53.34%)</span>
<span style="display: table-cell;vertical-align: middle;">
<span id="a"></span>
</span>
</div>

How to get values of left/right/top/bottom properties in pixel using javascript?

I need to get the left/right/top/bottom property of the #test in px. My js code giving the property value as auto. How to get the value in px?
<div id="test">
<p>Dummy text</p>
</div>
#test{
position: absolute;
}
window.onload = function(){
var test = document.getElementById("test");
var left = window.getComputedStyle(test).getPropertyValue("left");
console.log(left); // auto
};
Use this code
window.onload = function(){
var test = document.getElementById("test");
var left = test.offsetLeft;
var right = test.offsetWidth - left;
var top = test.offsetTop;
var bottom = test.offsetHeight - top;
document.write("Left:" + left + "//");
document.write("Right:" + right + "//");
document.write("Top:" + top + "//");
document.write("Bottom:" + bottom);
};
#test{
position: absolute;
}
<div id="test">
<p>Dummy text</p>
</div>
use offsetLeft instead
test.offsetLeft
window.onload = function(){
var test = document.getElementById("test");
document.write(test.offsetLeft); // auto
};
#test{
position: absolute;
}
<div id="test">
<p>Dummy text</p>
</div>

element height() not adding + 200?

I would like to scroll to the end of the container. The element is having new items added via ajax on click, so I am recalculating its height each time I click to load more. The page scrolls fine but I would like to also add the navigation height in order to have the exact pixels. It looks like it is not adding + 224 tho
Html
lorem
New items are added via a click and ajax.
Css
nav {
height: 90px;
}
#container {
margin-top: 104px;
margin-bottom: 120px;
}
Jquery
var page = $("html, body");
var pos = $("#container").height() + 224;
page.animate({scrollTop: pos}, 1000);
I think you want something like this no ?
var page = $("html, body");
console.log($("#t").height());
var pos = $("#t").height() - 500;
console.log(pos);
page.animate({scrollTop: pos}, 1000);
div{
height: 1000px;
width: 50px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="t"></div>
you can use scrollIntoView for last added item
var j=0;
function Add(){
var item=null;
for(var i=0;i<20;i++){
j++
item= $('<div class="item">'+j+'</div>').appendTo("#container")
}
item[0].scrollIntoView()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" onclick="Add()" Value="Add" />
<div id="container"></div>

jQuery function that returns when a div touches another div upon scroll

how can I give an alert when one div hovers over another div upon scroll? here is a working example,
http://jsfiddle.net/uprosoft/Ek5Gy/267/
I cant find a jQuery code to go after though in-order to give an alert.
Code:
HTML
<div id="container">
<div id="div1">test</div>
<br>
<div id="div2"> another test</div>
</div>
CSS
#div1{
background: green;
position: fixed;
width: 100%;
}
#div2{
background: yellow;
position: relative;
width: 100%;
margin-top: 100px;
}
#container{
height: 1000px;
}
JQUERY ???
/* what jquery code goes here? to alert when the yellow div touches the green div upon scroll? */
Something like that should work:
$(window).scroll(function() {
var div1 = $("#div1");
var div2 = $("#div2");
var div1_top = div1.offset().top;
var div2_top = div2.offset().top;
var div1_bottom = div1_top + div1.height();
var div2_bottom = div2_top + div2.height();
if (div1_bottom >= div2_top && div1_top < div2_bottom) {
// overlapped
}
});​
DEMO: http://jsfiddle.net/Ek5Gy/280/
I know the question is for Jquery but either way, the same done with vanilla JS
function didDiv1TouchedDiv2() {
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
// Guard
if (div1 === undefined || div2 === undefined) return;
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
// We need to add the offsetHeight in order to include padding and border of element and get excact position
return div1Rect.top >= div2Rect.top + div2.offsetHeight;
}
window.addEventListener("scroll", didDiv1TouchedDiv2);

Set absolute height (offsetHeight) of HTML containers that use CSS padding, margin and border by Javascript

I want to do something like setting offsetHeight (offsetHeight is a read only property) - fit 3 div ("d1", "d2", "d3") into one container ("c"):
<!DOCTYPE HTML>
<html>
<body>
<style type="text/css">
.c {
background-color:#FF0000;
overflow:hidden;
}
.d {
left:10px;
border:9px solid black;
padding:13px;
margin:7px;
background-color:#FFFF00;
}
</style>
<div class="c" id="c">
<div id="d1" class="d">text text text</div>
<div id="d2" class="d">text text text</div>
<div id="d3" class="d">text text text</div>
</div>
<script type='text/javascript'>
var h=600;
var hd = Math.floor(h/3);
var c = document.getElementById("c");
var d1 = document.getElementById("d1");
var d2 = document.getElementById("d2");
var d3 = document.getElementById("d3");
c.style.height=h +"px";
d1.style.height=hd +"px";
var hd2 = (2 * hd - d1.offsetHeight) +"px";
d1.style.height=hd2;
d2.style.height=hd2;
d3.style.height=hd2;
</script>
</body>
</html>
but - first: the boxes doesn’t fit perfect :-( and secondly the style is bad. Do you have a idea how to fit the 3 div ("d1", "d2", "d3") into one container ("c")?
=> also I dont know how to read the css properties "padding" and "margin"
alert(d1.style.paddingTop);
doesn't work (maybe because it is defined by css-class and not direct)
Thank you :-)
Best regards Thomas
Which browser your using and what DOCTYPE you have determines the default box model for block elements. Usually, the default is content-box, which means that the padding, border, and margin all add to the height/width, so you'll need to factor that into your calculations if you have the box model as content-box.
Another options is, you can change the box model to border-box using the box-sizing CSS property. This means that the padding and border are included in the height and width, and only the margin adds to them. In my opinion, this box model is usually a more convenient one for doing what I want, so I usually end up switching.
Reference:
https://developer.mozilla.org/En/CSS/Box-sizing
https://developer.mozilla.org/en/CSS/box_model
After some testing I figure out this solution:
(works with: Opera, Firefox and Google Chrome)
(box-sizing: doesn't work on Firefox when used JavaScript?!)
<!DOCTYPE HTML>
<html>
<body>
<style type="text/css">
.c {
background-color:#FF0000;
overflow:hidden;
margin:0px;
padding:0px;
}
.d {
left:10px;
border:13px solid black;
padding:7px;
margin-bottom:13px;
margin-top:4px;
background-color:#FFFF00;
}
</style>
<div class="c" id="c">
<div id="d1" class="d">text text text</div>
<div id="d2" class="d">text text text</div>
<div id="d3" class="d">text text text</div>
</div>
<script type='text/javascript'>
///////////////////////////////////////////
// see: http://stackoverflow.com/questions/1601928/incrementing-the-css-padding-top-property-in-javascript
function getStyle(elem, name) {
if (elem.style[name]) {
return elem.style[name];
}
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
else if (document.defaultView && document.defaultView.getComputedStyle) {
name = name.replace(/([A-Z])/g, "-$1");
name = name.toLowerCase();
s = document.defaultView.getComputedStyle(elem, "");
return s && s.getPropertyValue(name);
}
else {
return null;
}
}
///////////////////////////////////////////
var c = document.getElementById("c");
var d1 = document.getElementById("d1");
var d2 = document.getElementById("d2");
var d3 = document.getElementById("d3");
var paddingY = parseInt(getStyle(d1, 'paddingTop'),10) + parseInt(getStyle(d1, 'paddingBottom'), 10);
var marginTop = parseInt(getStyle(d1, 'marginTop'),10);
var marginBottom = parseInt(getStyle(d1, 'marginBottom'),10);
var marginMax = Math.max(marginTop, marginBottom);
var borderY = parseInt(getStyle(d1, 'borderTopWidth'),10) + parseInt(getStyle(d1, 'borderBottomWidth'), 10);
var h=600;
var count=3;
var hd = Math.floor((h-marginMax*(count-1) - marginTop - marginBottom - (paddingY + borderY) *count) / count) ;
c.style.height=h +"px";
d1.style.height=hd +"px";
d2.style.height=hd +"px";
d3.style.height=hd +"px";
</script>
</body>
</html>

Categories