Detect if child divs are wider than parent? - javascript

How can I detect if multiple child divs are wider than their parent? In this case, when they are wider, the rightmost one is displayed below the leftmost one. I have tried using js to check for an overflow (as described here: javascript css check if overflow), but it doesn't work.
Ultimately, I want to keep the rightmost div below its sibling and change its padding, but only when they are wider.
The code is basically this:
<div class='parent'>
<span>title</span><br />
<div class='child'>
Some content.
</div>
<div class='child'>
More content that sometimes doesn't fit.
</div>
</div>

not sure, but have you tried it?
var children = YourParentDiv.children;
for (var i = 0; i < children.length; i++) {
var child_width=children[i].offsetWidth;
var parent_width = children[i].parentElement.offsetWidth;
if (child_width>parent_width)
{console.log('wider');}
}

This will compare the child width and the parent width of your divs
$('.parent').children('.child').each(function() {
let $this = $(this);
console.log($this.width(), ' ', $('.parent').width());
if ($this.width() > $('.parent').width()) {
//add the padding you want
$this.css('padding-top', '10px');
}
})
.parent {
width: 500px;
}
.child {
background-color: green;
width: 700px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class='parent'>
<span>title</span>
<br />
<div class='child'>
Some content.
</div>
<div class='child'>
More content that sometimes doesn't fit.
</div>
</div>

Related

Get the elements that are overflowing

Is there anyway to find the elements that are overflowing outside of the div?
So you can edit them somehow, using JQuery for example?
I am trying to make it with an HTML table at the moment.
Check the javascript code to verify element is overflowing. This operation on large elements may be expensive.
const p = document.querySelector('.parent');
console.log('Overflow ' + (p.offsetHeight < p.scrollHeight));
.parent{
height: 50px;
border: 1px solid;
}
.child {
height: 20
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>

change width of array member when width is fixed with style

I have the following code:
JS/ANGULAR:
$scope.width = 10;
$scope.items = DATA taken from JSON about 2000 rows
CSS:
.theImage{width:100px}
.itemcontainer{width:100px}
<div class="container" id="container">
<div class="itemcontainer" ng-repeat="item in items" style="{{width}}px">
<div class="item">
<img class="theImage" src="http://...." />
</div>
</div>
</div>
So what happens here is that the width of the item container is set with code to 10 pixels wide (it overrules the CSS). This can be changed to any width no wider as 100px. So it all becomes like a accordion. This all works find, what i want to do is that when i hover over an 'array-member' the 'itemContainer' that this one becomes 100px wide. i tried doing it with this but can't get it to function;
$('.itemcontainer').hover(function () {
$(this).css("width", "100px");
console.log("WORKS")
});
I don't even get the 'works' in the console log, if i use a different element in my code it works fine. What would be a solution to make this one element change in size (AngularJS/Javascript/JQuery) ?
add this CSS.
.itemcontainer:hover{
width: 100px !important;
}
HTML:
<div class="container" id="container">
<div class="itemcontainer" ng-repeat="item in items" style="width:10px">
<div class="item">
<img class="theImage" src="http://...." />
</div>
</div>
</div>
CSS:
.itemcontainer { background: orange; }
JAVASCRIPT:
$('.itemcontainer').hover(function () {
$(this).css("width", "100px");
console.log("WORKS")
});
Combined code of Furkan added as the answer

hover over one div to show the nearest div of a certain class

i want to hover over one div and use jquery to find the nearest div by the name and to show that div.
<div class="entry">
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="somethingelse"></div>
<div class="footer"></div>
</div>
all the .footer classes will be hidden but i want to make it so that when i over over the .body class, only the nearest .footer class shows. [ meaning : if i hover over the first .body class, only the first .footer will be shown. ]
my current code isn't working and i'm starting to wonder if it's something wrong with it.
current jquery code :
$('.footer').hide();
$('.body').hover(function(){
$(this).closest('.footer').find('.footer').show();
});
While the problem is the same as this question, the reason is slightly different.
When you use .closest(".class") it's the equivalent of .parents().filter(".class").first() (or .last(), I don't recall exactly which way parents() works as that's what closest is for).
ie it goes up the tree
So $(".body").closest(".entry") would give you an element for your HTML.
In this case, you want siblings, but more specifically the next one. There's a jquery method .next() which looks like it's correct, but as detailed in the link above, this only gives the very next one (in your HTML this would be the date div) even if a filter is applied - so $(this).next(".footer") would give an empty set (as it's not .date).
The work around is:
$(this).nextAll(".footer").first()
Once you get this working, your will find that your hover does not work as expected as the footers are not hiding again - as you're using .hover rather than mouseenter mouseout, you just need to move the .hide() call inside the second event handler, giving:
// startup
$(".footer").hide();
// event
$(".body").hover(function() {
$(this).nextAll(".footer").first().show();
}, function() {
$(".footer").hide();
});
div > div { width: 100px; height: 10px }
.body { border: 1px solid red; }
.date { border: 1px solid blue; }
.footer { border: 1px solid green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry">
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="somethingelse"></div>
<div class="footer"></div>
</div>
$(this).closest('.footer')
You should start to use console.log() sometimes to check elements you would like to get. This does not find anything so nothing further to search and to show.
If you possibly can separate bodies and footers into containers you can do smth like
this.
Try to make use of nextUntil(".footer").next(); as below
$('.body').hover(function() {
$(this).nextUntil(".footer").next().show();
}, function() {
$(".footer").hide();
});
body {
font: 13px Verdana;
}
.footer {
display: none;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry">
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="somethingelse">somethingelse</div>
<div class="footer">footer</div>
</div>
IF your html is gonna keep those triads layout, you don't need jQuery for it.
Just use CSS to select the second div after the .body on hover
div{width:100px; height:100px; background-color:lime; margin:10px; float:left}
.body{background:yellow; clear:left;}
.footer{display:none;}
.body:hover + div + div{
display:block;
background:red;
}
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="date"></div>
<div class="footer"></div>
<div class="body"></div>
<div class="somethingelse"></div>
<div class="footer"></div>
The answer by freedomn-m offered a good explanation and good solution in case you want the nearest NEXT .footer, which seems to be the case from your example HTML.
However, if you want your request strictly, so you want exact NEAREST .footer, then his solution will not work for you. And I don't think there is a jQuery built-in functionality that can give you that, so you'll have to do it manually. Get the list of the children of the parent (don't use the siblings as they don't include the current element) and go through the list to calculate the distance from your current element using the indexes and then select the .footer that is really the nearest.
$('.body').hover(function() {
var children = $(this).parent().children();
var index = children.index(this);
var closest = children.length;
var footer = -1;
children.each(function(i, child) {
if (i !== index && $(child).hasClass("footer")) {
var distance = Math.abs(index - i);
if (distance < closest) {
closest = distance;
footer = i;
}
}
});
if (footer > -1)
children.eq(footer).show();
}, function() {
$(".footer").hide();
});
body {
font: 13px Verdana;
}
.footer {
display: none;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry">
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="somethingelse">somethingelse</div>
<div class="footer">footer</div>
</div>
If you don't care much about the performance, you can shorten the code a bit by selecting the list of .footer instead of the children of the parent, and then let jQuery give you the index of each of them. Not very efficient, but shorter code:
$('.body').hover(function() {
var index = $(this).index();
var closest = 9999;
var footer;
$(this).siblings(".footer").each(function(i, sibling) {
var distance = Math.abs(index - $(sibling).index());
if (distance < closest) {
closest = distance;
footer = sibling;
}
});
if (footer !== undefined)
$(footer).show();
}, function() {
$(".footer").hide();
});
body {
font: 13px Verdana;
}
.footer {
display: none;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry">
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="somethingelse">somethingelse</div>
<div class="footer">footer</div>
</div>
Inspired by freedomn-m's comment, we can also use the .prevAll() and .nextAll() methods to get the previous and next .footer siblings. These two methords return the siblings ordered by the closest, so we simply pick the first one of each list, subtract their indexes from our element's index (to find the distance), compare them together, and return the closest. This solution is also less efficient than the first one, but you may find the code easier to read:
$('.body').hover(function() {
var me = $(this);
var prev = me.prevAll(".footer").first();
var next = me.nextAll(".footer").first();
if (prev.length == 0)
next.show();
else if (next.length == 0)
prev.show();
else {
index = me.index();
if (Math.abs(prev.index() - index) < Math.abs(next.index() - index))
prev.show();
else
next.show();
}
}, function() {
$(".footer").hide();
});
body {
font: 13px Verdana;
}
.footer {
display: none;
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry">
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="date">date</div>
<div class="footer">footer</div>
<div class="body">body</div>
<div class="somethingelse">somethingelse</div>
<div class="footer">footer</div>
</div>

Make every two elements the same height

I have a container with a number of children that needs to be the same height, only in pairs of two tho.
for example the first and second element needs to be as high as the highest of the two and the third and forth need to be as high as whichever is highest, independent of the height of the first and second child.
My current code, which equals all children heights
$(document).ready(function(){
// Select and loop the container element of the elements you want to equalise
$('.parent').each(function(){
// Cache the highest
var highestBox = 0;
// Select and loop the elements you want to equalise
$('.child', this).each(function(){
// If this box is higher than the cached highest then store it
if($(this).height() > highestBox) {
highestBox = $(this).height();
}
});
// Set the height of all those children to whichever was highest
$('.child',this).height(highestBox);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='parent'>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content</div>
</div>
You're probably want to achieve grid-like behavior, it can be easily achieved without JavaScript using flexbox:
/* Purely for visual appearance */
.parent {
width: 300px;
}
.child {
background: linear-gradient(45deg, lightgreen, yellow);
padding: 5px;
box-sizing: border-box;
}
/* Actual logic */
.parent {
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.child {
flex: 1 1 50%;
}
<div class='parent'>
<div class='child'>a bit of text</div>
<div class='child'>very large amount of content to make height largest across all rows</div>
<div class='child'>a b c d e f g h i j k l m n o p q r s t u v w x y z</div>
<div class='child'>a b c</div>
</div>
Hope something like below you are looking for. May be using flex is simplest way of getting it done. Here i tried with some jquery.
$(document).ready(function() {
// Cache the highest
var highestBox = 0;
var loop = 1
// Select and loop the elements you want to equalise
$('.child', this).each(function() {
if (loop % 2 != 0) {
// If this box is higher than the cached highest then store it
highestBox = $(this).height();
if ($(this).next('.child').height() > highestBox) {
highestBox = $(this).next('.child').height();
}
// Set the height of all those children to whichever was highest
$(this).height(highestBox);
$(this).next('.child').height(highestBox);
}
loop++;
});
});
.child {
width: 50%;
float: left;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class='parent'>
<div class='child'>some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content</div>
<div class='child'>some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content
some dynamic content some dynamic content some dynamic content</div>
<div class='child'>some dynamic content</div>
<div class='child'>some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content</div>
<div class='child'>some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content some dynamic content</div>
<div class='child'>some dynamic content</div>
</div>

Prevent parent div from resizing when child div resizes

What I want to accomplish is after calling jQuery $().hide(), the animation to hide a child div on a current page and then show a new div in its place.
When I call the .hide(), the parent div resizes and I do not want that.
The parent has two divs in it, a text filled div, and the div in question so when I call the hide, only the text-only div remains. I want the height to remain the same because the new content is going to be the same height.
Here is what I have:
<div class="adminContent"> //Wrapper div, this should not change in height of 668px
<div class="adminTitle"> // Text only div, remains after .hide is called
Admin > Manage Class Roster
</div>
<div class="resetBody" id="manageClassBody1"> // Div that is being hidden/replaced
... // div contents
</div>
CSS
.adminContent {
background: #F7F7F7;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
min-height: 668px;
}
How should I have it so that its height is static after I hide the child div? Thanks!
EDIT: I want to do an in place swap of the two divs with an animation to switch between the two. I looked at the replaceWith() provided by jQuery but I'm not sure how to use it for my needs.
I would suggest using the animation features of JQuery to accomplish your task.
I created a sample JSBin for you.
Example:
$(document).on("click", "#togglebtn", function() {
var divs = $('.resetBody, .resetBody2');
var hiddenDiv = divs.filter(":not(:visible)");
var visibleDiv = divs.filter(":visible");
visibleDiv.fadeToggle({
complete: function() {
hiddenDiv.fadeToggle();
}
});
});
.adminContent {
background-color: lightgreen;
padding: 10px;
}
.resetBody {
background-color: #880000
}
.resetBody2 {
background-color: lightblue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="adminContent">//Wrapper div, this should not change in height of 668px
<div class="adminTitle">much text wow! much text wow! much text wow! much text wow! much text wow!
Admin > Manage Class Roster
</div>
<div class="resetBody">Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>
</div>
<div class="resetBody2" style="display:none">Div 2 is taller
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>
</div>
</div>
<div style="margin-top:10px;">
<button id="togglebtn">Toggle</button>
</div>

Categories

Resources