Flickering CSS and Javascript dropdown - javascript

Here is the HTML for my menu:
<div class="navLink four">
<div>
this
<div class="subMenu">
link
link
</div>
</div>
</div>
I've got this jQuery to show and hide my menu:
$('.navLink div').hover(
function () {
$('.navLink div .subMenu').css({'display': 'none'});
$(this).find('.subMenu:first').slideDown();
},
function () {
$('.navLink div .subMenu').css({'display': 'block'});
$(this).find('.subMenu:first').slideUp();
}
);
And this CSS:
.navLink .subMenu {
display: none;
position: absolute;
}
.navLink > div:hover .subMenu {
display: block;
}
But the dropdown flikers a lot when you hover over it, I think I need some preventDefault() or something in my javascript.

Here's a JSfiddle to show the problem: http://jsfiddle.net/V5H3A/
Here is the solution: http://jsfiddle.net/jdfqW/1/
You need to stop the animation like so:
$('.navLink div').hover(
function () {
$('.navLink div .subMenu').css({'display': 'none'});
$(this).find('.subMenu:first').stop().slideDown();
},
function () {
$('.navLink div .subMenu').css({'display': 'block'});
$(this).find('.subMenu:first').stop().slideUp();
}
);
For even less lines of code you can do this http://jsfiddle.net/jdfqW/2/:
CSS:
.navLink .subMenu {
display: none;
position: absolute;
}
Javascript:
$('.navLink div').hover(
function () {
$(this).find('.subMenu:first').stop().slideToggle();
}
);
OR if you're SUPER adventurous you can do it all with only CSS3 like so http://jsfiddle.net/jdfqW/3/:
CSS
.navLink .subMenu {
height: 0px;
overflow: hidden;
position: absolute;
-webkit-transition:height 0.5s ease;
-moz-transition:height 0.5s ease;
transition:height 0.5s ease
}
.navLink:hover .subMenu {
height: 20px;
}

$('.navLink div a:first').mouseenter(function () {
$(this).next('.subMenu').slideDown(200);
}).mouseleave(function () {
$(this).next('.subMenu').slideUp(200);
});
Without any flickering ---> http://jsfiddle.net/WK7We/

use stop()... this will stop the running animation which i assume is causing the flickering...
$(this).find('.subMenu:first').stop().slideDown();
$(this).find('.subMenu:first').stop().slideUp();

Working jsFiddle Demo
Use .stop() method before .slideUp() and .slideDown():
$('.navLink div').hover(
function () {
$('.navLink div .subMenu').css({'display': 'none'});
$(this).find('.subMenu:first').stop().slideDown();
// HERE --------------------- ^
},
function () {
$('.navLink div .subMenu').css({'display': 'block'});
$(this).find('.subMenu:first').stop().slideUp();
// HERE --------------------- ^
}
);
References:
.stop() - jQuery API Documentation
Stop the currently-running animation on the matched elements.

Related

How to hide menu for mobiles by default? Using Javascript

I have a website with side-bar menu. Menu is by default visible. If i click close-btn. Menu is hidden. That works
I would like make menu by default visible for desktops and by default hidden for mobiles.
.side-bar {
background: #1b1a1b;
backdrop-filter: blur(15px);
width: 250px;
height: 100vh;
position: fixed;
top: 0;
z-index: 50;
left: 0px;
overflow-y: auto;
transition: 0.6s ease;
transition-property: left;
}
.side-bar.non-active {
left: -250px;
}
.side-bar.active {
left: 0px;
}
The window.innerWidth < 850 works but i'm not sure if there is something better. 850px i use for #media queries.
$(document).ready(function () {
//jquery for toggle sub menus
$(".sub-btn").click(function () {
$(this).next(".sub-menu").slideToggle();
$(this).find(".dropdown").toggleClass("rotate");
});
//jquery for expand and collapse the sidebar
if (window.innerWidth > 850) {
$(".close-btn").click(function () {
$(".side-bar").addClass("non-active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("non-active");
$(".menu-btn").css("visibility", "hidden");
});
}
else {
$(".side-bar").css("left", -250);
$(".close-btn").click(function () {
$(".side-bar").addClass("active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("active");
$(".menu-btn").css("visibility", "hidden");
});
}
});
The issue is propably in $(".side-bar").css("left", -250); because in the DOM i can see it as inline style and after click nothing happen. Only .menu-btn disappers.
Is there another way how to set "reverse" logic for mobiles please? Or maybe just easy fix this i hope little bug?
I tried set oposite style for left: -250px; to left:0; via following logic but without any positiv result..
Use this instead:
if (window.matchMedia('(max-width: 850)').matches) { ... }
else { ... }
This uses css media query in JavaScript without any frameworks.

Changing the hide show toggle effect?

I have an element that works just fine with the following code. It's an object #obj1 that is hidden when loading the page, but appears when clicking on #obj2.
#obj1{
position:fixed;
width:100px;
bottom:180px;
right:100px;
display:none;
}
$("#obj1").hide();
$("#obj2").show();$('#obj2').toggle(function(){
$("#obj1").slideDown(function(){});
},function(){
$("#obj1").slideUp(function(){});
});
but I would like to have it like this:
$("#obj1").css({"opacity": "0","bottom": "180"})
$("#obj2").toggle(
function () {
$("#obj1").animate({"opacity": "1","bottom": "140"}, "slow");
},function () {
$("#obj1").animate({"opacity": "0","bottom": "180"}, "slow");
});
I would like it to fade in, but how do I add the animation to the first script? (animation ex: .animate({"opacity": "1","bottom": "140"}, "slow");)
Here is a super simple demo of fading in an element using CSS. You can use jQuery to add the class through a click event.
// HTML
<div id="myId" class="hide">
This is div with myId
</div>
// CSS
.hide {
display: none;
}
.myId {
animation: fadein 2s;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
// JQUERY
$("#myId").removeClass("hide").addClass("myId");
You can see a working demo here. You'll just have to modify it to trigger on click of obj2 or where you like
EDIT - As per your comment above I have edited the pen, so now the element will be hidden on page load and then the class will be removed and the animation class added.
You would be best keeping the styles within css, and just using js to change the state (add/remove a class). The way you have the javascript is passable, but it'd be better for the class to be toggled based on itself so they can't accidentally get out of sync:
$('#obj2').on('click',function(e){
e.preventDefault();
if($('#obj1').hasClass('js-on'))
$('#obj1').removeClass('js-on');
else
$('#obj1').addClass('js-on');
});
#obj1{
position:absolute;
width:100px;
bottom:10px;
right:20px;
opacity: 0;
background-color: yellow;
padding: 1em;
transition: .5s opacity, .5s bottom;
}
#obj1.js-on {
opacity: 1;
bottom: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="obj2" href="#">Click me</a>
<div id="obj1">Hi</div>
$(document).ready(function() {
$("#obj1").hide();
$("#obj2").show();
});
$('#obj2').toggle(function(){
$("#obj1").slideToggle();
});
This will show obj1 by sliding when obj2 is pressed. To have it fade in instead Try,
$("#obj2").click(function () {
$("#obj1").fadeToggle("slow","swing");
This toggles obj1 fading in and out.
reference:
http://api.jquery.com/fadetoggle/
Slightly confused by the question, but here's my attempt at an answer: hope it helps
$(".obj1").click(function(){
$(".obj2").css('opacity', 0)
.slideDown('slow')
.animate(
{ opacity: 1 },
{ queue: false, duration: 'slow' }
);
});
.obj1 {
display: inline-block;
padding: 10px;
background: lightgrey;
}
.obj2 {
height: 100px;
width: 100px;
background: red;
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="obj1">click me</div>
<div class="obj2"></div>

How to animate the ajax/json response?

This is my piece of HTML code
<div class='qna_div'>
<div class="q_div"></div>
<div class="a_div"></div>
</div>
I make a Ajax request and get a json response for every click by the user and i append the q_div and a_div using the jquery function
$('.q_div').append(data.question);
$('.a_div').append(data.answer);
I have css keyframe animation on both q_div and a_div to come from right to left of the screen. But the animation works only on the first load of the page and not on the 'append' function for the json response. I am new to css and animations. help me out for the responsive animations
animation in css3 code:
.q_div {
animation: q_ani 2s;
}
#keyframes q_ani {
from{margin-left: 50px;}
to{margin-left: default;}
}
a possible solution using css animation
$(function() {
var cssAnimationEnd = "webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend";
$('.click').click(function() {
$('.q_div, .a_div').addClass("animate").one(cssAnimationEnd , function() {
$('.q_div, .a_div').removeClass("animate");
});
});
})
.q_div.animate {
animation: q_ani 2s;
}
.a_div.animate {
animation: q_ani 2s;
}
#keyframes q_ani {
from {
margin-left: 150%;
}
to {
margin-left: default;
}
}
/*for test purpose*/
.q_div,
.a_div {
position: relative;
height: 20px;
width: 500px;
background: #ddd;
margin-top: 10px;
}
.qna_div {
padding: 20px;
width: 500px;
background: #333;
}
body {
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">go</button>
<div class='qna_div'>
<div class="q_div"></div>
<div class="a_div"></div>
</div>
You should delete and add .q_div class each time you need animation appear
You could use jquery to animate your divs. Put this code in the success ajax callback:
// First put your divs to the right
$('.q_div, .a_div').css('right','0');
// Do the animation
$('.q_div, .a_div').animate({
left: 0,
}, 1000);
https://jsfiddle.net/a8cq9yj1/1/
I hope it can help you,i just simple using the classList function and some SASS style rule
http://jsbin.com/vosuvam/2/edit?js,output

fade-in an incoming image, fade-out an out going image

I have a logo that I want to fade-in when I hover on the image, and then fade out and be replace by the original when I hover out of the image. I almost got it working but the image double fades-in with this approach and the image does not fade-out. Any changes that can be done here. Here is my html, js and css. Run live example:
$(".opening").hover(function() {
$(".opening img").animate({
opacity: 1
}, "slow");
$(".opening img").css({
"width": 250
});
$(".opening img").attr("src", "http://www.letsgodigital.org/images/producten/3376/pictures/canon-eos-sample-photo.jpg");
}, function() {
$(".opening img").animate({
opacity: 0
}, "slow");
$(".opening img").css({
"width": 150
});
$(".opening img").attr("src", "http://www.cameraegg.org/wp-content/uploads/2015/06/canon-powershot-g3-x-sample-images-3-620x413.jpg");
$(".opening img").animate({
opacity: 1
}, "slow");
});
.opening {
padding: 0 4.2%;
display: inline;
}
.opening img {
width: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="opening">
<img src="http://www.cameraegg.org/wp-content/uploads/2015/06/canon-powershot-g3-x-sample-images-3-620x413.jpg" />
</div>
You don't need JS for such simple :hover → fade tasks.
CSS is quite enough
.opening {
position: relative; /* add this */
display: inline-block; /* change */
}
.opening img {
width: 150px;
}
.opening img + img{ /* the second image */
position:absolute;
top:0;
transition: 0.8s; -webkit-transition: 0.8s;
visibility:hidden;
opacity:0;
}
.opening:hover img + img{
visibility:visible;
opacity:1;
width: 250px;
}
<div class="opening">
<img src="http://www.cameraegg.org/wp-content/uploads/2015/06/canon-powershot-g3-x-sample-images-3-620x413.jpg" />
<img src="http://www.letsgodigital.org/images/producten/3376/pictures/canon-eos-sample-photo.jpg" />
</div>
Also, if you change src using JS that means that your animation will always junk the first time since the image needs to be pulled from the server at the time you're trying to actually animate it.
try to use stop() to stop the currently-running animation
Why not this?
$(".opening").mouseenter(function(){
$(".opening img").fadeIn("slow", function () {
$(this).css({"width":250}).attr("src","http://www.letsgodigital.org/images/producten/3376/pictures/canon-eos-sample-photo.jpg");
});
}).mouseleave(function () {
$(".opening img").fadeOut("slow", function () {
$(this).css({"width":150}).attr("src","http://www.cameraegg.org/wp-content/uploads/2015/06/canon-powershot-g3-x-sample-images-3-620x413.jpg").fadeIn("slow");
});
});

Hovering over one div changes another's img

I need to change an image of one div while hovering over another. So far i have this
$('#button').on({
'hover': function(){
$('#ekranasStatic').attr('src', 'http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranas_zpsczoquizc.png');
}
});
DEMO
But it doesn't work..
EDIT While it works in fiddle, the solution does not work in my local file.
Hover is deperecated with latest versions of jQuery. it is divided into two events mouseenter and mouserleave. use those event it will be helpful
As of 1.9, the event name string "hover" is no longer supported as a
synonym for "mouseenter mouseleave". This allows applications to
attach and trigger a custom "hover" event. Changing existing code is a
simple find/replace, and the "hover" pseudo-event is also supported in
the jQuery Migrate plugin to simplify migration. Reference
$('#button').on({
'mouseenter': function(){
$('#ekranasStatic').attr('src', 'http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranas_zpsczoquizc.png');
}
});
$('#button').on({
'mouseleave': function(){
$('#ekranasStatic').attr('src', 'http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/some_other.png');
}
});
If you still want to use hover events then there is direct hover function provided by jQuery, with reference
$( "td" ).hover(
function() {
$('#ekranasStatic').attr('src', 'http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranas_zpsczoquizc.png');
}, function() {
// change to default on hover out
}
);
Looks like you need to change it on mouseover and reset on mouseout. If you use data-* attribute it will be easier.
$('#button').hover(function() {
var img = $('#ekranasStatic').data('toggle-src');
$('#ekranasStatic').attr('src', img);
}, function() {
var img = $('#ekranasStatic').data('original-src');
$('#ekranasStatic').attr('src', img);
});
.img {
/*** TURI BUT 850 PX **/
position: absolute;
margin-left: 520px;
top: 110px;
z-index: 99;
}
#button {
width: 50px;
height: 70px;
display: block;
position: absolute;
top: 296px;
left: 1120px;
background: url("http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/knopkes_zpsp3qr4xyn.png") no-repeat;
z-index: 2200;
cursor: pointer;
}
#button:focus {
outline: none;
}
#button:hover {
animation: knopke 0.1s steps(2);
animation-fill-mode: forwards;
background-position: 0 0;
}
#keyframes knopke {
to {
background-position: -100px;
opacity: 1;
}
}
#ekranasStatic {
width: 735px;
height: 602px;
display: block;
position: absolute;
top: 120px;
left: 375px;
z-index: 10000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<img class="img" src="http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/galerija3_zpszlnkhebp.png">
<div id="button"></div>
<div id="ekranai">
<img id="ekranasStatic" src="http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranasStatic_zpswrnrw7f8.png" data-original-src="http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranasStatic_zpswrnrw7f8.png" data-toggle-src="http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranas_zpsczoquizc.png"
/>
</div>
Updated Fiddle
change this
$('#button').on({
'hover': function(){
to :
$('#button').hover({ function(){ });
try this :
$('#button').on('hover', function () {
$('#ekranasStatic').attr('src', 'http://i1064.photobucket.com/albums/u378/Benas_Lengvinas/ekranas_zpsczoquizc.png');
}
);
Js Fiddle Updated

Categories

Resources