Counting <ul> height with Javascript - javascript

Here's my situation. I have a sliding jquery menu like this: http://tympanus.net/codrops/2011/07/03/sliding-background-image-menu.
The code of menu is:
<div id="sbi_container" class="sbi_container">
<div class="sbi_panel" data-bg="images/1.jpg">
About
<div class="sbi_content">
<ul>
<li>Subitem</li>
<li>Subitem</li>
<li>Subitem</li>
</ul>
</div>
</div>
<div class="sbi_panel" data-bg="images/2.jpg">
...
</div>
CSS:
.sbi_content{
position:absolute;
border-top:2px solid #000;
bottom:90px;
left:0px;
width:100%;
background:transparent url(../images/pattern.png) repeat top left;
display:none;
overflow:hidden;
}
.sbi_content ul{
padding:10px;
}
.sbi_content ul a{
display:block;
color:#f0f0f0;
font-size:16px;
padding:4px 6px 4px 14px;
background:transparent url(../images/triangle.png) no-repeat 3px 50%;
opacity:0.9;
}
.sbi_content ul a:hover{
background-color:#000;
color:#fff;
-moz-box-shadow:1px 1px 5px #000;
-webkit-box-shadow:1px 1px 5px #000;
box-shadow:1px 1px 5px #000;
}
And here's a JavaScript piece I have a problem with:
$content.each(function(i) {
var $el = $(this);
// save each content's height (where the menu items are)
// and hide them by setting the height to 0px
var num = $el.find('ul li').size();
$el.data( 'height', num * 35 + 10 ).css( 'height', '0px' ).show();
});
I need to count a height of these <ul>.
That I'm doing now is counting how many there are <li> items, then multiply it by number of one's height (35) and adding a 10px for margin..
Everything would be ok, but when there is a realy long <li> item, it jumps to second row and problem is that this code doesn't count that second row height.
Any ideas how can I solve this problem?
Thank you.

You can use the scrollHeight property:
$("ul")[0].scrollHeight
For your specific case -
$content.find('ul')[0].scrollHeight

You can count the height of all the lis in the content using this:
var totalLiHeight = 0;
$el.find('ul li').each(function() {
var currentLiHeight = $(this).height();
totalLiHeight += currentLiHeight;
});
Then you can add the margin to that.

Related

replacing text on hover using javascript?

Here's my fiddle demo.
Is there any javascript code to keep changing the 'Z' when hover ?
For eg. when i hover over the Z, it disappears and E takes its position from the right,and E disappears to the left and P takes its place from the right similarly this process continues to form the word Zephyr.
and when the user moves the pointer away. it should come back to Z .
.initials {
position:absolute;
background:{color:main color};
background-image: url("http://static.tumblr.com/lxn1yld/Hnxnxaqya/space.gif");
color:white;
margin-top:20px;
padding-top:20px;
padding-bottom:20px;
width:60px;
text-align:center;
margin-left:20px;
font-size:20px;
letter-spacing:5px;
box-shadow:0px 2px 3px rgba(0,0,0,.15)
}
Take look to the code below. Hope this will help you. To increase/decrease speed of animation change the animate function's third parameter to your time. Here time is in ms.
$('.initials').mouseenter(function(){
for(var i=0; i<5; i++){
$('.letter:first').delay(500).animate({
marginLeft: '-=' + '70'
}, 300);
}
});
$('.initials').mouseleave(function(){
$('.letter:first').animate({
marginLeft: '0'
}, 1500);
});
.initials {
position:absolute;
background:{color:main color};
background-image: url("http://static.tumblr.com/lxn1yld/Hnxnxaqya/space.gif");
color:white;
padding-top:20px;
padding-bottom:20px;
width:60px;
text-align:center;
font-size:20px;
letter-spacing:5px;
box-shadow:0px 2px 3px rgba(0,0,0,.15);
overflow: hidden;
white-space: nowrap;
}
.letter{
width:60px;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="initials">
<div class="letter">Z</div>
<div class="letter">e</div>
<div class="letter">p</div>
<div class="letter">h</div>
<div class="letter">y</div>
<div class="letter">r</div>
</div>
JS Fiddle: http://jsfiddle.net/63utadgw/16/
It is possible using CSS Animation. You can see this How to move text using CSS animation?.
No need to use JavaScript

increase element width using jQuery or JS

So I have multiple elements with class name ml, all different widths because of different text contents (not set in CSS).
for example:
<li><a class="depth ml" title="">Login</a></li>
I would like to append a new width to all of them, +=5px of the element's inner width
I've tried doing this, using jQuery:
var elems = document.getElementsByClassName('ml');
for ( var i = 0; i < elems.length; i++ ) {
var num = 5;
var curr_width = elems[i].width();
elems[i].style.width=(curr_width+num)+'px';
}
Nothing happened.
I tried using offsetWidth and clientWidth
var curr_width = parseInt(elems[i].offsetWidth);
but it added almost 40px, which I don't know where those came from. There isn't even padding or margins on those elements.
I just want the element's inner width appended.
Can anyone suggest a solution, or see why the jQuery isn't working?
EDIT:
Here is the markup:
<body>
<div id="master_container">
<div class="container">
<div id="body">
<header>
<div id="homelink"></div>
<div id="links" class="topmenulist">
<ul id="nav" class="title">
<li><a class="depth ml" title="home">Home</a></li>
<li><a class="depth ml" title="BBTV1">BBTV1</a></li>
<li><a class="depth ml" title="BBTV">BBTV</a></li>
<li><a class="depth ml" title="About us" style="">About us</a></li>
</ul>
</div>
</header>
and the relevant CSS:
.depth {
position: relative;
font-size:25px;
text-decoration:none;
letter-spacing:2px;
text-transform:uppercase;
color: rgba(42,41,36,1.00);
}
.depth:before, .depth:after {
content: attr(title);
color: rgba(255,255,255,.1);
font-size:25px;
text-decoration:none;
letter-spacing:2px;
position: absolute;
}
.depth:before { top: 1px; left: 1px }
.depth:after { top: 2px; left: 2px }
/*_______________ NAVIGATOR _________________*/
#links {
position:relative;
left:469px;
top:80px;
width: 489px;
height:53px;
padding:0px;
padding-left:0px;
z-index:9999;
}
.topmenulist #nav {
list-style:none;
padding:0;
padding-top:10px;
}
.topmenulist #nav li {
float:left;
display:block;
position:relative;
text-indent:0px;
margin-left:0px;
}
.topmenulist #nav li a {
margin:0px;
padding:0px;
display:block;
font-size:25px;
text-decoration:none;
letter-spacing:2px;
text-transform:uppercase;
color:rgba(41,17,3,0.60);
text-wrap:suppress;
}
note: .ml has no css
Just to point out, you're using pure JS -which is very brave of you ;) anyway, with jQuery, you could try something like below:
$(window).load(function() {
$(".ml").each(function() { // this is kindof sugary way of doing for loop over array of elements - which is $(".ml")
var $this = $(this); // the current jQueried .ml element
var currentWidth = $this.width(); // get width of current element, width is a jQuery method: https://api.jquery.com/width/
var newWidth = currentWidth + 5; // increment the width
$this.width(newWidth); // pass in the new width as the parameter.
});
});
In your code:
var curr_width = elems[i].width();
resolve to an undefined value, because DOM object doesn't have width property (only jQuery object have this one).
So the next statement (curr_width+num) is incorrect because you want to add an undefined value with a number.

Display only one list item at the center of the <div> with overflow:hidden

I'm trying out a vertical ticker that displays a few text list items one after the other, but I need some help in positioning them.
You'll see a web ticker with two items. To display only one item at a time, I have to set 'overflow:hidden' in #tickerContainer.
However, the text in the ticker is not being positioned at the center of the ticker(As you see it is sitting at the bottom).
Also, when I remove 'overflow:hidden' from #tickerContainer, which is the whole ticker moving away from the top of the page?
Please help me fix this.
http://jsfiddle.net/nodovitt/NYhY4/2/
<div id="tickerContainer">
<ul id="ticker" class="js-hidden">
<li class="news-item">Item Number 1</li>
<li class="news-item">Item Number 2</li>
</ul>
</div>
The jQuery function:
<script>
function tick() {
$('#ticker li:first').slideUp(1000, function () {
$(this).appendTo($('#ticker')).slideDown(1000);
});
}
setInterval(function () {
tick()
}, 2000);
</script>
The CSS:
#tickerContainer {
background-color:white;
border-radius:15px;
text-align:center;
margin:10px;
box-shadow:0 0 8px black;
color:#2B7CD8;
font-size:50px;
width:500px;
height:100px;
overflow:hidden;
}
.news-item {
font-family:Times New Roman;
font-style:oblique;
}
#ticker li {
list-style-type:none;
}
You haven't put any specifications on your ticker id. So something like this http://jsfiddle.net/NYhY4/10/
#ticker {
padding:0px;
margin:0px;
padding-top:20px;
height:55px;
overflow:hidden;
}
Here is my answer as requested by OP
Add this css to your #ticker
#ticker {
margin: 0;
padding: 0;
line-height: 100px;
}
NOTE The line-height will always have to be the height of the #tickerContainer
You can see it here http://jsfiddle.net/NYhY4/3/
#ticker li {
list-style-type:none;
position: relative;
bottom:20px;
}
I didn't like the current item being hidden by seemingly "nothing" (the blank part of li box above the text) so I used this approach:
Remove the margins from the '#ticker'
set '#ticker' padding-top (.5em worked best for me)
set '#ticker li' padding-bottom to push the next item out of view (I used '1em' to be safe but '.5em' worked too)
The words didn't look perfectly centered so
set '#ticker li' line-height to '1em'
#ticker {
margin: 0;
padding-top: .5em;
}
#ticker li{
line-height: 1em;
padding-bottom: 1em;
list-style-type: none;
}
http://jsfiddle.net/JvuKU/2/
Note This depends on the font-size of the '#tickerContainer'. If you change the height or font-size of the '#tickerContainer', just adjust the values of '#ticker' padding-top and '#ticker li' padding-bottom.

how to display list as table?

I have a list of items with different content floated left, I need to display them as a row.
<ul>
<li>small content..</li>
<li>medium Content..</li>
<li>large content..</li>
..
<!-- many item random contnet -->
</ul>
I would like to display the list items in a row.
row height depends on max height item in row,
How to get it?
Demo
Add display:table-cell so it acts as table column. remove float:left as well.
#contentpane{}
#contentpane li{
padding:10px;
width:80px;
border:1px solid #000;
display:table-cell
}
DEMO
CASE 2
In case you need it with auto height then use the below white-space:nowrap; method
ul#contentpane{
width:100%;
white-space:nowrap;
}
#contentpane li{
padding:10px;
width:80px;
border:1px solid #000;
height:auto;
display:inline-block;
white-space:normal !important;
}
DEMO 2 || DEMO (Vertically aligned to the top)
you should go with javascript to set clear:both to row overflow element.
var ch=$("#container").width();
var itemsPerRow=Math.floor(ch/102);
var itemsCount=$("#contentpane li").length;
var loopRound=Math.floor(itemsCount/itemsPerRow);
for(var i=1;i<loopRound+1;i++)
{
var nextFirstItem=i*itemsPerRow+1;
$("#contentpane li:nth-child("+ nextFirstItem +")").css({"clear":"both"});
}
demo
ul {
display: table-row;
}
ul > li {
display: table-cell;
}
Note that you should have a wrapper with display: table in order to built a complete table representation.
Set height to the li.
#contentpane{
}
#contentpane li{
float:left;
padding:10px;
width:80px;
height:180px;
overflow:auto;
display:table-cell;
border:1px solid #000;
}
FIDDLE
Try this one
var maxHeight = 0;
$("#contentpane li").each(function( index ) {
var height = $(this).height();
if(height > maxHeight){
maxHeight =height;
}
});
$("#contentpane li").css("height",maxHeight);
Fiddle Demo
Drop the float and use inline-block instead:
http://jsfiddle.net/CmkSb/10/
#contentpane li{
padding:10px;
width:80px;
display:inline-block;
vertical-align: text-top;
border:1px solid #000;
}

Function only works on second click, then works fine?

I am having trouble with a navigation menu I have created. Basically, the navigation consists of several tabs that is collapsible upon click a button and then expandable when you click that button again. When collapsed, the ends of the tabs are still visible, and when you hover over the tabs will go back out, and go back in when hovering out.
So I have the following navigation laid out:
<ul id="navigation">
<li>Name1</li>
<li>Name2</li>
<li>Name3</li>
<li id = "collapser">Collapse All</li>
</ul>
And I have the following jQuery/javascript laid out to do this:
$("#collapser").click(function(){
if($("#collapser").hasClass("clicked")){
$(function() {
$('#navigation a').stop().animate({'marginLeft':'-118px'},1000);
$('#navigation > li').hover(
function () {
$('a',$(this)).stop().animate({'marginLeft':'0px'},400);
},
function () {
$('a',$(this)).stop().animate({'marginLeft':'-118px'},400);
}
);
});
$("#collapser").removeClass("clicked");
$("#collapser").addClass("unclicked");
$("#collapser").html('Expand All')
}
else{
$(function() {
$('#navigation a').stop().animate({'marginLeft':'0px'},1000);
$('#navigation > li').hover(
function () {
$('a',$(this)).stop().animate({'marginLeft':'0px'},400);
},
function () {
$('a',$(this)).stop().animate({'marginLeft':'0px'},400);
}
);
});
$("#collapser").removeClass("unclicked");
$("#collapser").addClass("clicked");
$("#collapser").html('Collapse All')
}
})
The code works, but only when you click the link a second time. I can't seem to figure out what I did to make it work only after clicking it once already.
Any help would be appreciated, thank you very much!!
-Quintin
EDIT:
Here is the CSS for the navigation:
ul#navigation {
position: fixed;
margin: 0px;
padding: 0px;
font-size:14px;
top: 14px;
left: 0px;
list-style: none;
z-index:9999;}
ul#navigation li {
width: 100px;
}
ul#navigation li a {
display:block;
margin-bottom:3px;
width:126px;
padding:3px;
padding-left:15px;
background-color:#ffffff;
background-repeat:no-repeat;
background-position:center center;
opacity:0.7;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=60);
-moz-box-shadow: 0px 1px 3px #000;
-webkit-box-shadow: 0px 1px 3px #000;
}
ul#navigation .checked a{
color:#ffffff;
background-color:#000000;
}
You are verifying if your collapser div has or not the class clicked or unclicked, but you not initialize the div with some class. Adding the class clicked should adjust your effect:
<li id = "collapser" class='clicked'>Collapse All</li>
You can see it with this jsfiddle

Categories