Unable to retrieve Height from a toggleClass jQuery - javascript

I want to get the height of a class that is toggled. When a button is clicked, the class .category-menu-visible is added. If the class exists, then I want to get it's height. But when I alert menuHeight, it is 0.
Small scale JSFiddle example
Actual Code:
jQuery
jQuery('.topics-btn').click(function(){
jQuery('.category-menu-wrap').toggleClass('category-menu-visible');
if (jQuery('.category-menu-wrap').hasClass('category-menu-visible')){
var menuHeight = jQuery('.category-menu-visible').height();
alert(menuHeight);
jQuery('.sidebar .content-wrap').css('margin-top', menuHeight);
} else {
jQuery('.sidebar .content-wrap').css('margin-top', 0);
}
});
CSS:
.category-menu-wrap {
width:100%;
height:0px;
background-color:#F7D5B6;
overflow: hidden;
transition: height .5s cubic-bezier(.27,1.76,.95,1.19);
}
.category-menu-visible {
height: 70px;
transition: height .3s cubic-bezier(.27,1.76,.95,1.1);
}
Why can't it retrieve the height?

You need to wait till transition finishes.
Update:
There is a useful event transitionend to do it:
jQuery('.topics-btn').click(function(){
var $menu = jQuery('.category-menu-wrap');
$menu.toggleClass('category-menu-visible');
$menu.on("transitionend", function(){
if (jQuery('.category-menu-wrap').hasClass('category-menu-visible')){
var menuHeight = jQuery('.category-menu-visible').height();
alert(menuHeight);
jQuery('.sidebar .content-wrap').css('margin-top', menuHeight);
} else {
jQuery('.sidebar .content-wrap').css('margin-top', 0);
}
});
});
.category-menu-wrap {
height: 0;
}
.category-menu-visible {
height: 70px;
transition: height .3s cubic-bezier(.27,1.76,.95,1.1);
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button class='topics-btn'>Click</button>
<div class='category-menu-wrap'></div>

The problem you are having is the CSS transition. When you click the height is calculated but at that moment it is 0. After the transition it will have the 70px value. You need to get the height after the transition finishes.
In this example the transition duration is set to 0s.
jQuery('.topics-btn').click(function(){
jQuery('.category-menu-wrap').toggleClass('category-menu-visible');
if (jQuery('.category-menu-wrap').hasClass('category-menu-visible')){
var menuHeight = jQuery('.category-menu-visible').height();
alert(menuHeight);
jQuery('.sidebar .content-wrap').css('margin-top', menuHeight);
} else {
jQuery('.sidebar .content-wrap').css('margin-top', 0);
}
});
.category-menu-wrap {
width:100%;
height:0px;
background-color:#F7D5B6;
overflow: hidden;
transition: height 0s cubic-bezier(.27,1.76,.95,1.19);
}
.category-menu-visible {
height: 70px;
transition: height 0s cubic-bezier(.27,1.76,.95,1.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="topics-btn">.topics-btn</button>
<div class="category-menu-wrap"></div>
In this other example we rely on the transitionend event to get the height value:
jQuery('.topics-btn').click(function(){
jQuery('.category-menu-wrap').toggleClass('category-menu-visible');
});
jQuery('.category-menu-wrap').on('transitionend',function(){
if (jQuery('.category-menu-wrap').hasClass('category-menu-visible')){
var menuHeight = jQuery('.category-menu-visible').height();
alert(menuHeight);
jQuery('.sidebar .content-wrap').css('margin-top', menuHeight);
} else {
jQuery('.sidebar .content-wrap').css('margin-top', 0);
}
});
.category-menu-wrap {
width:100%;
height:0px;
background-color:#F7D5B6;
overflow: hidden;
transition: height 0.5s cubic-bezier(.27,1.76,.95,1.19);
}
.category-menu-visible {
height: 70px;
transition: height 0.5s cubic-bezier(.27,1.76,.95,1.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="topics-btn">.topics-btn</button>
<div class="category-menu-wrap"></div>

From the official docs
The value reported by .height() is not guaranteed to be accurate when the element or its parent is hidden. To get an accurate value, ensure the element is visible before using .height()
The problem here is exactly this: your .category-menu-visible is not visible. when JQuery looks for it. This is due to the transition property set with a duration on the toggled class.
Update (according to JSFiddle)
It appears that when toggling a class, the height isn't recognized on the toggled class unless a unit of measurement is specified.
This occurs even without the transition property.
Not working example - height: 70;
Working Example - height: 70px;

Related

Change different header styles at different scroll positions

I am trying to make a header for a website where the header changes to different colors at different positions on the page.
Trying to get blue color background for header if the page is scrolled down with less than 40 pixels. And then red color background for header if the page is scrolled down between 40 pixels and 100 pixels. And then when the page is moved completely up, the header background is a yellow color.
Edit 1:
In short, Trying to make a sticky header change colors at different positions of the scroll on a page.
Edit 2:
Tried a new way of putting conditions. Updated the below code with latest working sticky header.
My problem is, when the header goes to the top position, it doesn't change back to orange color
So far I have got this code.
JS Fiddle
jQuery(document).ready(function($){
var mywindow = $(window);
var transoffset = $('#stickyheaders').offset().top;
var mypos = mywindow.scrollTop();
mywindow.scroll(function() {
if (mypos > 40) {
if(mywindow.scrollTop() > mypos)
{
$('#stickyheaders').addClass('headerup');
}
else
{
if(mywindow.scrollTop() < 155) {
$('#stickyheaders').addClass('headertranspup');
} else {
//$('#stickyheaders').removeClass('headerup');
$('#stickyheaders').addClass('headerstyleup');
}
}
}
mypos = mywindow.scrollTop();
});
});
body { margin: 0; }
section {
height: 2000px;
padding-top: 100px; }
#stickyheaders{
background: orange;
-webkit-transition: transform 0.34s ease;
transition : transform 0.34s ease;
}
.headerup{
position: fixed;
top:0; left:0;
width: 100%;
background: orange !important;
//transform: translateY(-110px);
//adjust this value to the height of your header
}
.headerstyleup{
background-color: blue !important;
}
.headertranspup{
background-color: red !important;
}
.headertranpup{
background-color: yellow !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<section>
<div id="stickyheaders">This div will stick to the top</div>
</section>
The easiest solution for a problem like this is by assigning background-colour to the header directly in the element property using jquery rather than adding a new class with the same css property like background-colour in this case.
jQuery(document).ready(function($){
var mywindow = $(window);
var mypos = mywindow.scrollTop();
mywindow.scroll(function() {
if (mypos > 40) {
if(mywindow.scrollTop() > mypos)
{
$('#stickyheaders').addClass('headerup');
//$('#stickyheaders').addClass('headertranpup');
$('#stickyheaders').css("background-color","orange");
}
else
{
if(mywindow.scrollTop() < 75) {
$('#stickyheaders').removeClass('headerup');
$('#stickyheaders').css("background-color","transparent");
}
else
{
$('#stickyheaders').css("background-color","blue");
}
}
}
mypos = mywindow.scrollTop();
});
});
body { margin: 0; }
section {
height: 2000px;
padding-top: 100px; }
#stickyheaders{
-webkit-transition: transform 0.34s ease;
transition : transform 0.34s ease;
}
.headerup{
position: fixed;
top:0; left:0;
width: 100%;
adjust this value to the heigt of your header*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<section>
<div id="stickyheaders">This div will stick to the top</div>
</section>

how to change the color of the navbar after scrolling

I want my navbar to be transparent, but when the user scrolls a bit I want it to change to a solid color and I am using bootstrap for the navbar, I have done the code that is needed with javascript.
I had this javascript in my HTML file, but it doesn't seems to work and I don't really know why
<script>
var myNav = document.getElementById("mynav");
window.onscroll = function() {
use strict";
if (document.body.scrollTop >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
</script>
and I have also added the CSS code.
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
I don't know why it doesn't work, it is not displaying any errors, I have also manually put the class and it worked so the problem is from the js code and not the CSS.
Use scrollY property of Window object.
See the Snippet below:
var myNav = document.getElementById("mynav");
window.onscroll = function() {
if (window.scrollY >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
.main-container{
height: 1000px;
}
#mynav{
position: fixed;
background-color: gray;
height: 50px;
margin:0 auto;
top: 0;
bottom:0;
line-height: 50px;
padding:5px;
width: 100%;
}
<div class="main-container">
<div class="mynav" id="mynav">
Hello World! this is mynav
</div>
</div>
Try using window.scrollY instead of document.body.scrollTop.
if (window.scrollY >= 100)
You can also use document.documentElement.scrollTop. It's the html element that actually scrolls, not the body. Typically document.body.scrollTop will always be 0.

Pop out image html

I am developing a chrome extension which on any hover over an image it should popout a box over the image and the image should be zoomed to 1.5 times the original image.
So I started working on examples and found a similar example like this.
.zoomin img {
height: 200px;
width: 200px;
-webkit-transition: all 2s ease;
-moz-transition: all 2s ease;
-ms-transition: all 2s ease;
transition: all 2s ease;
}
.zoomin img:hover {
width: 300px;
height: 300px;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" title="All you need to know about CSS Transitions " />
</div>
But instead i need to create a box without zooming the image on hover. So in my exercise using this Using only CSS, show div on hover over <a> i have developed this.
main.js
div {
display: none;
}
img:hover + div {
display: block;
height : 200px;
width : 300px;
}
But the problem is that the size of the image should be dynamically adjusted based on the image we are hovering.
Is there a way to make this work when we hover over an image it should automatically make a div which should hold 1.5 times the dimensions of the image.Any suggestions.?Please help
I have included the screenshot below for reference.
img:hover div {
display: block;
var img = document.getElementById('imageid');
// get the image dimensions using this id
var width1 = img.clientWidth;
var height1 = img.clientHeight;
height : width * 1.5;
width : height * 1.5;
}
You need to just remove
+
because it selects immediate next div element to img.
I guess you should try:
img:hover ~ div
{
//your height and width goes here
}
I think this is the sort of thing you wanted.
I don't think you can do this with CSS only (though would love to be wrong)
I've done a for loop to add an event listener on for when you mouse over and off an image in .zoomin. Then it sets the image source accordingly.
var zoominSel = document.querySelectorAll(".zoomin img");
var zoomContSel = document.querySelector(".zoomcont img")
for (let i = 0; i < zoominSel.length; i++) {
zoominSel[i].addEventListener("mouseover", function(event) {
zoomContSel.setAttribute('src', event.target.getAttribute('src'));
zoomContSel.style.width = event.target.offsetWidth + "px";
zoomContSel.style.height = event.target.offsetHeight + "px";
zoomContSel.parentElement.style.top = event.target.offsetTop + "px";
zoomContSel.parentElement.style.left = (event.target.offsetLeft + event.target.offsetWidth + 2) + "px";
});
zoominSel[i].addEventListener("mouseout", function(event) {
zoomContSel.setAttribute('src', '');
});
}
body {
margin: 0;
}
.zoomin img {
max-width: 200px;
}
.zoomcont img[src=""] {
display: none;
}
.zoomcont {
z-index: 1000;
position: absolute;
transform: scale(1.5);
transform-origin: 0 0;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" />
</div>
<div class="zoomin">
<img src="http://usabilitygeek.com/wp-content/uploads/2013/07/free-fonts-for-commercial-personal-use.jpg" />
</div>
<div class="zoomcont">
<img src="" />
</div>
Hope you find this helpful.

CSS/JS: Animate Inline Element Upon Text Change

When an inline element's text changes, it is usually the case that its computed width or height changes as well.
Usually it's trivial to transition property changes with CSS, for example, adding a transition to change the background-color of an element upon hover.
However, inline element dimensions are really tricky. A simple transition property does not animate the change in computed width.
View example an by clicking here: https://jsfiddle.net/mz103/59s42ys4/ or viewing it below:
$("div").on("click", function() {
$(this).text("Although my width changes, it is not aniamted.");
});
div {
display: inline-block;
background-color: red;
padding: 8px 16px;
transition: width 0.3s; // Notice, this doesn't transition the width upon change.
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Click me.</div>
How, when the text of an inline element changes, can we animate those changes?
Here an Update: https://jsfiddle.net/ky3c5Lec/3/
$("div").on("click", function() {
//get the current Dimensions, as Start-value for the animation
var $this = $(this),
sw = $this.width(),
sh = $this.height();
$this.text("New text");
var tw = $this.width(),
th = $this.height();
$this.css({
//since jQuery.animate() doesn't have sth. like Tween.from()
//we have to reset the styles to the initial values
width: sw, height: sh
}).animate({
//and then animate
width: tw, height: th
}, function(){
//and when the animation is done, we clean up after ourselves
$this.css({
width: "", height: ""
});
})
});
You could try a little bit of jQuery animation:
function changeText(el) {
el.animate(
{
opacity: 0
},
{
duration: 'slow',
complete: function () {
$(this).text('New Text');
$(this).animate({opacity: 1}, 'slow');
}
});
}
Here is a fiddle.
I suppose that you will need two elements to achieve this elegantly:
$(".inner").on("click", function() {
var $this = $(this);
var $par = $this.parent();
$par.css({
width: $par.width()
});
$this.text("New text");
$par.css({
width: $this.outerWidth()
});
});
.inner {
display: inline-block;
padding: 8px 16px;
white-space: nowrap;
}
.outer {
display: inline-block;
transition: width 300ms ease-in-out;
background-color: red;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">Here's some text.</div>
</div>

How to 'slideUp' remaining portion of the div?

I have a div which I am showing just a portion of the top using absolute positioning and hidden overflow. When you hover over I want to show the remaining portion of the div. This div could be different total height based on the info inside.
https://jsfiddle.net/5abs1ocf/4/
.showAll {
bottom: 0px;
}
.showLittle {
top: 265px;
}
And the jQuery:
$(item).find('.info').toggleClass('showLittle showAll');
As you can see from this example, I have it working where it "pops" from one to the other. What I really want is for it to animate and "slide" up and down rather than just "popping" from one to the other.
Any suggestions?
Instead of using the top property use a negative bottom value:
.showLittle {
bottom: -105px;
}
And then use a transition:
.info {
transition: all .2s;
}
Demo: JSFiddle
An alternative way, if you want a dynamic height, is to use jQuery to calculate the offset:
var elementHeight = -($('.info').height() - 34);
console.log(elementHeight);
$('.showLittle').css('bottom', elementHeight);
And set the following CSS:
.showAll {
bottom: 0 !important;
}
Demo: JSFiddle
You don't need Javascript, just use CSS.
.info {
bottom: 0;
margin-bottom: -102px;
transition: margin 0.5s ease;
}
.tree:hover .info {
margin-bottom: 0;
}

Categories

Resources