Getting heights of spans with jquery - javascript

I am trying to center a series of SPANs vertically inside their parent LIs.
The height values returned are all the same which means there must be something wrong with this code as some of the spans are on two lines.
Not sure if getting the height of an inline element (span) is a problem, any suggestions appreciated.
HTML:
<li class="nav-level-2-item">
<a href="">
<span class="menu-item">Text</span>
</a>
</li>
<li class="nav-level-2-item">
<a href="">
<span class="menu-item">Longer Text</span>
</a>
</li>
</ul>
JS:
$(document).ready(function () {
var navItem = $('li.nav-level-2-item');
navItem.each(function() {
var containerHeight = $('li.nav-level-2-item').height();
var spanHeight = $('span.menu-item').height();
alert(spanHeight)
$('span.menu-item').css('top', (containerHeight - spanHeight) / 2);
});
});

Making your span a block-level element will give it height:
<style> span.menu-item { display:block /* or inline-block */; } </style>
As an alternative, you could change the span to be one of the native block-level elements.

I'm not sure whether this is applicable to your code, but maybe you could avoid using jQuery altogether by making the <li> elements inline-block and centering them vertically:
li.nav-level-2-item
{
display: inline-block;
*display: inline; *zoom: 1; /* IE 6-7 hack */
vertical-align: middle;
}
Or another possible solution:
li.nav-level-2-item
{
display: table;
}
li.nav-level-2-item a
{
display: table-cell;
vertical-align: middle;
}
For additional CSS-only solutions, check out http://phrogz.net/css/vertical-align and http://www.vanseodesign.com/css/vertical-centering.

I'm not sure what the goal is, but I do have an answer for why the alert is always the same. You're iterating the li elements with .each(), but on each iteration, you aren't referencing the current item, so you always retrieve the height of the first matching element. Try this:
http://jsfiddle.net/5uwuQ/
$(document).ready(function () {
var navItem = $('li.nav-level-2-item');
navItem.each(function() {
var containerHeight = $(this).height();
var spanHeight = $('span.menu-item', this).height();
console.log(spanHeight)
});
});
Vertical centering of menu items is probably going to be easier by setting the line-height.

Related

how to shorten the breadcrumb when it appears in mobile website

when i view my website in mobile with lot of filters, the breadcrumb length becomes too large. so i want to replace all the li tags that are behind the second last li. that means all the li except first, last and last-1 li need to be replaced with dots.
Anybody can help me fix this with jquery, javascript, or css?
<ul class="left">
<li class="active">Airways</li>
<li>Trauma</li>
<li>Medical</li>
<li>OB | Peds</li>
<li>Patient Assessment</li>
<li>Proprietary</li>
<li>Trauma</li>
<li>Medical</li>
<li>OB | Peds</li>
<li>Patient Assessment</li>
<li>Proprietary</li>
</ul>
This is just example code i have added here.
You can try with jquery like this. Basically if it is a smaller width device, and if it is not first, last or second last child, the text of the link tag is replaced by '..' .
<script>
$(document).ready(function () {
if (window.matchMedia("(max-width: 767px)").matches)
{
// The viewport is less than 768 pixels wide
console.log("This is a mobile device.");
$('ul.left li').each(function() {
$this = $(this); // cache $(this)
if (! $this.is(':first-child') && ! $this.is(':nth-last-child(2)') && ! $this.is(':last-child') ) {
$this.find('a').text("..");
}
});
}
});
</script>
This is my first answer on stack overflow, hope this is what you want this is the codepen link
https:// codepen.io/vatzkk/pen/yLYMJeG
HTML
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<ul class="left" id="bread">
<li class="active">Airways</li>
<li id="dropdown" style="display:none">
<div class="dropdown" >
<i class="dropbtn">...</i><i class="fas fa-caret-down"></i>
<div class="dropdown-content" id="dropdown-list">
</div>
</div>
</li>
<li>Trauma</li>
<li>Medical</li>
<li>OB | Peds</li>
<li>Patient Assessment</li>
<li>Proprietary</li>
<li>Trauma</li>
<li>Medical</li>
<li>OB | Peds</li>
<li>Patient Assessment</li>
<li>Proprietary</li>
</ul>
Javascript
//you can add your conditions over here
document.getElementById("dropdown").style.display="block";
var arr=[...document.getElementById("bread").children];
var dropdownItems=arr.slice(2,-2);
dropdownItems.map(item=>{
document.getElementById("bread").removeChild(item);
document.getElementById("dropdown-list").appendChild(item);
});
Pure CSS Working example: https://jsfiddle.net/3o8vuwd6/2/
First give your list a class
<ul class="left breadcrumblist">
CSS:
/* This is just to give it some styling as you haven't given any */
.breadcrumblist li {
list-style: none;
display: inline-block;
padding-right: 0.5em;
}
.breadcrumblist li + li::before{
content: "/";
padding-right: 0.5em;
}
/* adjust to your breakpoint. 9999 just so it works on large screen as an example */
#media only screen and (max-width: 9999px) {
/* hide all */
.breadcrumblist li{
display: none;
}
/* show first and last */
.breadcrumblist li:first-child,
.breadcrumblist li:last-child{
display: inline-block;
}
/* add ... to the end of the first one */
.breadcrumblist li:first-child::after{
content: "...";
padding-left: 0.5em;
}
/* fiddle with the content we added in styling */
.breadcrumblist li + li::before{
content: "";
padding-right: 0;
}
}
Thank you all for your guidance and finally i made something work according to my requirement and also i want to share it here because in case in future if someone looks for the same issue he or she can be benefited from this. This is also from the modifications that all you have just posted above.
<ul class="left" id="bread_cumb">
$(document).ready(function(){
if (window.matchMedia("(max-width: 767px)").matches)
var width = $(window).width();
if (width < 720) {
$('#bread_cumb li:not(:first-child):not(:nth-child(2)):not(:last-
child):not(:nth-last-child(2))').html('<span style="margin-
left:7px;margin-right:7px;"> ... </span>');
var last =$('#bread_cumb li:last-child').text();
var re = /^([A-Za-z0-9_'",.!##$%^&*()-+=?/\|:]+)[\s,;:]+([a-z]+)/i;
var m = re.exec(last);
$('#bread_cumb li:last-child').html('<a>'+m[1]+' '+m[2]+'...</a>');
}
});
Thanks all for your valuable ideas.

Animate <ul> height when adding/removing floated <li>s not in the last row

I have a ul containing floated li elements of variable width that wrap around inside of a container into multiple rows. I am removing li elements from the ul, and would like the height of the container to animate to accommodate the potential removal of a row.
If I am removing from the last row, I am handling this by animating the height of the li to zero before removing it.
The problem arises when I remove an element from a row other than the last row, and it vacates enough space to pull all of the elements in the last row into the previous row. Since I'm not removing an element in the last row, my li height animation doesn't do anything, causing a jump in the height of the ul and container when that last row is vacated.
Is there a way to handle this or am I stuck with this jump in this special case?
For example:
https://jsfiddle.net/d4v5kyty/1/
EDIT: My solution is posted below and here is a working fiddle: https://jsfiddle.net/x3qt0m89/1/
If you do not need to remove the elements from the DOM I would advise you to add a transition property to the LI elements and "remove" them by making them hidden on the canvas.
I've create this jsFiddle with an example that goes like this:
The normal HTML:
<!-- Just to remove the elements on the demo -->
<button class="js_removable">
Remove last item
</button>
<ul class="transitionable">
<li class="removable width-1">Content</li>
<li class="removable width-2">Content</li>
<li class="removable width-3">Content</li>
<li class="removable width-4">Content</li>
<li class="removable width-5">Content</li>
<li class="removable width-3">Content</li>
<li class="removable width-2">Content</li>
<li class="removable width-5">Content</li>
</ul>
The CSS would include the floated elements with variable width and the ul as their parent:
.transitionable {
width: 100%;
background-color: black;
overflow: hidden;
}
.removable {
float: left;
height: 50px;
border: 1px solid;
transition: all 0.5s ease-in-out;
}
.removable.hidden {
height: 0px;
/* you can further remove it from the dom with the visibility property, this is just for demo reasons */
}
.width-1 {
width: 25%;
background-color: white;
}
/* ... rest of the variables widths */
And the JS to remove the elements:
$('.js_removable').click(function () {
// Select only the not hidden elements .removable:not(.hidden)
$('.removable:not(.hidden)').last().addClass('hidden');
// You can further remove it from DOM if necessary after the animation ends
});
It's hard to really give a definitive answer since you didn't provide your code, but from what it sounds like, you're just missing some transitions. Try adding transition codes to the container and <ul>, and see what happens.
I ended up using jQuery to solve this issue by applying inline styles to the container when the page loads, and then after appending to removing from the ul calculating its height and animating the container to the height of the ul, like so:
JS:
var container = $('.container');
container.attr('style','height:' + $('.container').css('height') + ';');
var animateContainer = function () {
var ulHeight = $(container.find('ul')).css('height');
container.animate({'height': ulHeight}, 250);
}
$('.js_removable').click(function () {
$('.removable:not(.hidden)').first().addClass('hidden');
setTimeout(function(){
animateContainer();
}, 1000)
});
because there is a delay in this happening, there is a time when the ul can be larger than the container (if appending to the ul). I had no problem with this, and just added overflow: hidden; to the container to clean up the effect.
Not sure if this is the best method, but it works well for my purposes.
Here is a working fiddle: https://jsfiddle.net/x3qt0m89/1/

How to use Jquery to remove an overflowing element?

Pretty simple problem, but I can't find a solution. This plugin claims to do it, but I can't get it to work on my site at all, not as a called script, not inline, nothing. So, I have two columns of divs, the ones on one side larger than the other. I have set it up so the second column container will match the height of the first (which is determined elsewhere and thus varies) and set it to overflow:hidden, but what I want to do do is to remove the overflowing divs entirely so it always ends on the last complete div. Here's the fiddle: https://jsfiddle.net/bw2v39ru/2/
This is the JS to equalize the heights $('.row2').css('height', $('.row1').height()+'px');
In that example, only two of he block2 spans should be visible and the overflowing ones removed completely instead of leaving half a block.
Try this: https://jsfiddle.net/bw2v39ru/9/
Besides the code below - you will have to e.g. insert a <br style="clear:both;" /> in the parent DIV since the children has float: left
$('.row2').css('height', $('.row1').height());
var maxHeight = $("#main").outerHeight();
$("#main span").each(function() {
var elm = $(this);
if (elm.offset().top + elm.height() > maxHeight)
elm.remove();
});
as promised, here is my answer. Custom build jsfiddle from pure JavaScript.
https://jsfiddle.net/www139/vjgnsrpg/
Here is a code snippit for you. It assumes that all of your block2 elements have a fixed height. Also I changed the .row1 and .row2 classes to ids to make the solution easier to create. Feel free to change it back but remember to use document.getElementsByClassName('class')[i] instead.
//make sure you execute this script onload inside a jquery document ready or window.onload
//get the rendered height of both rows
//enter margin for blocks here
//this also assumes that the height of your block1 and block2 elements are fixed
var margin = 5;
var rowOneHeight = document.getElementById('row1').offsetHeight;
//get height of block2 element including vertical margin (multiplied twice)
var blockTwoHeight = document.getElementById('row2').getElementsByClassName('block2')[0].offsetHeight + 2 * margin;
var howManyBlocksCanFit = Math.floor(rowOneHeight / blockTwoHeight);
var numberOfBlocks = document.getElementById('row2').getElementsByClassName('block2').length;
for (var i = 0; i != numberOfBlocks - howManyBlocksCanFit; i++) {
document.getElementById('row2').removeChild(document.getElementById('row2').lastElementChild);
}
#main {
width: 240px;
}
#row1 {
float: left;
}
#row2 {
float: right;
overflow: hidden;
}
.block1 {
display: block;
margin: 5px;
width: 100px;
height: 50px;
border: 1px solid red;
}
.block2 {
display: block;
margin: 5px;
width: 100px;
height: 100px;
border: 1px solid red;
}
<div id="main">
<div id="row1">
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
<span class="block1"></span>
</div>
<div id="row2">
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
<span class="block2"></span>
</div>
</div>
Hope this helps you, please tell me if there was something I didn't understand in your question to improve my answer.
I programmed it for you, this works after your existing JS code line:
var row2 = $('div.row2'),
block2elements = row2.children('span.block2');
// Function to use also for other situations
function calculateElementsHeight(elements) {
var height = 0;
$.each(elements, function(i, elementRaw ){
height += $(elementRaw).height();
})
return height;
}
for(var i = 0; block2elements.length > i; i++) {
block2elements = row2.children('span.block2'); // Get new state of the block2 elements
if(row2.height() < calculateElementsHeight(block2elements)) {
block2elements.last().remove();
}
}

How to get div's content height

My div has a styling position:absolute, and as a result, it doesn't expand if the content is higher than it's height.
Therefore, I thought that a solution would be if I find what the is the actual content's height, and assign the height to the div with the position:absolute styling.
Any idea how to do it? or maybe an idea how to make an absolute div to expand according to its content.
Thanks in advance!
Element.scrollHeight should do the job.
Here's an awful way to get the height of the container. We're basically cloning the whole div, setting the position so that it has height, checking that height, and then removing it:
$(function () {
var clone = null;
alert( clone = $('.test').clone().css('position', 'static').appendTo(".container").height());
clone.remove();
});
Here's the fiddle: http://jsfiddle.net/vPMDh/1/
It should expand even if being absolute.
check you don't have a height: xxpx
if so, change it to min-height
As you've said "it doesn't expand if the content is higher than it's height." I guess you have a fixed height set on it.. if you do need this for some reason try using min-height instead.
Have a look at this fiddle.
<div class="classname">
Some content....
<p style="clear:both">&nbsp</p>
</div>
use a clearfix hack. heres the link
and add clearfix to you div
example
in your style sheet
<style>
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
</style>
...
and in your div add clearfix the class
<div class="clearfix">
//some html tags
</div>
Thanks for contributing your question. If you use this:
$(document).ready(function(){
var x = $("#container").height();
alert(x);
//if not works then
var y = $("#container").outerHeight();
alert(y);
});
I think it is easy as clean code to find the height of any div if you do not apply the div's height too.
similar solution to #MattDiamant, but with vanilla JS and without creating a clone:
function getDivHeight(posAbsoluteDiv) {
const heightBackup = posAbsoluteDiv.style.height;
posAbsoluteDiv.style.height = 'auto';
const contentHeight = posAbsoluteDiv.getBoundingClientRect().height;
posAbsoluteDiv.style.height = heightBackup;
return contentHeight;
}

Center image on jQuery Slider in HTML

I have an jQuery Content Slider. But i have an problem, where tall images is stretch. Isn't it possible to center the image. Some says that i need to set the overflow to hidden. But it doesn't make any differences.
Best regard Morten Starck
The html code:
<ul class="bxslider">
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/4fac343a-5d4b-4aab-8205-f57f165bc484_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/7bdfb0cc-47ec-4afa-9fc7-aa2cbb9d43a0_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/aad1d457-285d-42e3-8e68-e243bd2988d4_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" src="http://billeder.edc.dk/edcmedia/2012/04-April/04/768fda69-af61-4322-a60b-012040d78384_Size687x458.jpg"/></li>
<li>
<img id="propImageSliderLarge" onload="FixImages(true)" src="http://www.blog.designsquish.com/images/uploads/victorian-flatbush-old-hous_thumb.jpg" /></li>
And the Javascript:
<script type="text/javascript">
$('.bxslider').bxSlider({
pagerCustom: '#bx-pager'
});
</script>
and the CSS code:
#propImageSliderLarge {
width: 530px;
height: 400px;
overflow: hidden;
position: relative;
}
There're two things you're doing wrong here. First, you're using the same ID for multiple elements, this isn't valid. I think you intended to use CSS classes. Second, you're setting the width and height attributes of the IMG tag, when in fact you should set these attributes on the container (in this case the LI). Try the following:
Change your markup to this
<li class="propImageSliderLarge">
<img src="http://billeder.edc.dk/edcmedia/2012/04-April/04/4fac343a-5d4b-4aab-8205-f57f165bc484_Size687x458.jpg"/>
</li>
Change your CSS to this
.propImageSliderLarge {
width: 530px;
height: 400px;
overflow: hidden;
position: relative;
text-align: center; /* this will centre your image in the LI */
}
Update the image dimension if larger than LI container
This script assumes variables set for containerWidth and containerHeight so just set these to whatever your LI container size is and it'll resize the images to the max constraints of the container so you can see the entire image.
function resizeImage(img) {
var imgWidth = parseInt($(img).width());
var imgHeight = parseInt($(img).height());
if (imgWidth > containerWidth || imgHeight > containerHeight) {
$(img).width(containerWidth);
$(img).height(containerHeight);
}
}​
First, change the attribute id to attribute class. Id means Identifier, and as the name goes, two things cannot have same identifier. To center the images, give an id to ul tag and add following css:
text-align: center;
Try this...not sure if it'll work.
you can run the slider in onload and check it out.
<script type="text/javascript">
$(document).ready(function(){
$('.bxslider').bxSlider({
mode: 'fade',
captions: true
});
});
</script>
otherwise, you can use anyone suitable slider in http://bxslider.com/examples

Categories

Resources