Create Jquery Drop down using Divs and maintaing dual hover - javascript

What I'm trying to do is to fade in a div by rolling over a link. Once your mouse is over the link, you're able to mouse around the div that just faded in and you can click links inside the div.
Currently I have four links and each have a div with links and images in. On hover of the link the div fades in below the link then you can move your mouse over the div and use the images + links within. On roll out of the link or the div, it should fade out. Also, if you move your mouse to another main navigation link it should fade out the previous and fade in the new div.
The problem seems to be that the previous DIV will sometimes not fade out if you rapidly move to next link. I'm drawing a blank, any ideas?
Problem solved, answer is here: http://jsfiddle.net/UkneJ/3/
This is what I'm working with: http://jsfiddle.net/DemhU/17/
$('#div1, #div2, #div3, #div4').hide();
var is_over;
var hide_dropnav = function(a) {
setTimeout(function() {
if (is_over) {
return;
} else {
var a_name = $(a).attr('data-name');
$('#' + a_name).fadeTo(250, 0);
$('#nav li a').removeClass('active');
}
}, 10);
}
$('#nav li a').hover(function() {
var elem_name = $(this).attr('data-name');
$('#' + elem_name).stop(true,true).fadeTo(150, 1);
is_over = true;
$('#nav li a').removeClass('active');
$(this).addClass('active');
var that = this;
hide_dropnav(that);
}, function(){
is_over = false;
hide_dropnav(this);
});
$('#div1, #div2, #div3, #div4').hover(function() {
is_over = true;
}, function() {
is_over = false;
});

There are a lot of ways to do this, but I threw together a quick working example of the method I've used before:
http://jsfiddle.net/UkneJ/
In this example, I'm binding hover to both the A and the DIV, and using a slight delay to check is "is either element hovered?" state.
You can also just bind hover to the wrapping LI, which makes things much simple. This only works if both your link and your div are contained in each LI, though:
http://jsfiddle.net/UkneJ/1/

possible without javascript: http://jsfiddle.net/XENww/

Related

Changing background image referred to each menu item only by scrolling

I'm developing a wordpress theme that has a function of changing background image by hovering menu item(each menu item is attached different image). On mobile, I'd like to change background image just by scrolling so that viewers don't need to click each menu to change the background image.
This is the method I implemented to change background by hovering.
http://codepen.io/nummelin/pen/kzaso
// When any of the a's inside of sidebarContainer are hovered
$( ".sidebarContainer a" ).hover(function() {
// Removes all previous classes but keeps sidebar1
$('.sidebar1').removeClass().addClass('sidebar1');
// Splits up the URL on the current href
var URI = $(this).attr('href').split('/');
console.log(URI[2]);
// Applies the last part of the URL to sidebar1
$('.sidebar1').addClass(URI[2]);
});
Achieving with scrolling, I think I need a function that hovering menu item by its position like the image below.
Does anyone have any ideas how to achieve this? I've been exploring a plugin or sample code similar to this, but haven't found any...
Any advices would be appreciated.
Okay, so this is the code I wrote. Hope it helps. I've worked on cross-fading effect but it wasn't that easy. If someone tried please teach me how to do it.
Demo on Codepen:
http://codepen.io/bavavava/pen/rrNpaY
jQuery(function($){
'use strict';
$(document).ready(function(){
var elem = $('li.list-item'),
$listPosition = $.map(elem, function(el, i) { return $(el).offset().top; }),
$listURL = $.map(elem, function(el,i) { return $(el).find('a').attr('href'); }),
$bg = $('.container');
console.log($listPosition);
console.log($listURL);
//PRELOAD IMAGES
$.fn.preload = function() {
this.each(function(){
$('<img/>')[0].src = this;
});
}
$($listURL).preload();
//SCROLL CHANGE
$(window).on('scroll', function () {
var windowScroll = $(this).scrollTop();
$.each($listPosition, function (i, pos) {
if (windowScroll >= pos) {
$bg.css('background', 'url(' + $listURL[i] + '), black no-repeat center center fixed');
}
});
});
});
});

Menu & Submenu Hover Both With Separate Divs

I think I've been overthinking this all day long. It shouldn't be this hard...
I have a div with the main menu it's child with the submenu. My initial problem was wanting to show the submenu horizontal instead of vertial with absolute positioning on the screen so I could put it where I want it. Now I have this mess, and I think overthinking the situation has lost me on it.
I just want to separate the submenu from the parent after hovering over parent, then keep it up as long as you're on the parent or submenu, and fade it out when you leave either, putting the submenu appended back to the parent. The logo gets faded out when hovering over a parent that has a submenu, and faded back in when the submenu fades out. What its doing now is fading back in the logo pretty much no matter what, and its really buggy when hovering on submenu, along with it just plain not staying when hovering over it sometimes.
If there's a better way to position this so I don't have to go through this mess, or just a better way overall, please point it out.
<script type="text/javascript">
jQuery(document).ready(function($){
var inEle = false;
var hideTimer;
$('.sub-menu li a').css('display', 'inline-block');
// do hover on main menu
$('.uk-navbar-nav li a').hover(
function() {
// reset everything on new hover
clearTimeout(hideTimer);
// fade in the spire logo
$('.logoimgcontainer img').stop(true, true).fadeIn(2000);
inEle = true;
// save the id if there is one to hide
var subID = $('body').children('ul[class*="sub-menu"]').attr('id');
// find the ul submenu and put it back on the div in the main menu, remove the placeholder id
$('body').children('ul[class*="sub-menu"]').appendTo($(this).parent().parent().find('div[id*="'+subID+'"]')).removeAttr('id');
// fade out the ul submenu
$(this).parent().parent().find('div[id*="'+subID+'"]').find('ul').fadeOut(100);
// find the div holding the ul submenu and take out its placeholder id
$(this).parent().parent().find('div[id*="'+subID+'"]').removeAttr('id');
//show submenu
if ($(this).parent().find('div').hasClass('uk-dropdown')) {
$('.logoimgcontainer img').stop(true, true).fadeOut(150);
$(this).parent().find('div').find('ul').appendTo('body').css({
'display' : 'inline-block',
'position' : 'absolute',
'left' : '0',
'right' : '0',
'top' : '90px',
'margin' : 'auto',
'width' : '300px',
'text-align' : 'center',
'z-index' : '150'
}).attr('id', $(this).text());
$(this).parent().find('div').attr('id', $(this).text());
$(this).parent().find('div').find('ul').fadeIn(1000);
}
}, function() {
// do nothing here mkay
}
);
// do hover out on main menu
$('.uk-navbar-nav li').hover(
function() {
// do nothing here k
},function() {
// check if this item has a submenu
if ($(this).find('div').hasClass('uk-dropdown')) {
// clear out the timer
clearTimeout(hideTimer);
var aID = $(this).find('a').text();
// go ahead and set it not in sub since it hovered out here
inEle = false;
// reset the timer
hideTimer = setTimeout(function() {
// make sure its not in the submenu
if (!inEle) {
//var checkUL = $('ul[id*="'+aID+'"]');
//if (!checkUL.is(":hover")) {
// hideTimer = setTimeout(function() {
// fade in the spire logo
$('.logoimgcontainer img').stop(true, true).fadeIn(2000);
// find the ul submenu and put it back on the div in the main menu, remove the placeholder id
$('ul[id*="'+aID+'"]').appendTo('div[id*="'+aID+'"]').removeAttr('id');
// fade out the ul submenu
$(this).find('div[id*="'+aID+'"]').find('ul').fadeOut(500);
// find the div holding the ul submenu and take out its placeholder id
$(this).find('div[id*="'+aID+'"]').removeAttr('id');
//}, 1000);
}else clearTimeout(hideTimer); // still in the sub menu, clear the timer, handle in submenu
}, 1000);
}
}
);
// do hover in the submenu
$('.sub-menu').hover(
function() {
// set were in the submenu now
inEle = true;
// take out the timer for the main menu
clearTimeout(hideTimer);
}, function() {
// dont need the timeout anymore, not in submenu or main menu item
clearTimeout(hideTimer);
var ulID = $(this).attr('id');
// set were out of the submenu
inEle = false;
hideTimer = setTimeout(function() {
//var checkUL = $('.uk-navbar-nav li a:contains("'+ulID+'")');
//if (!checkUL.is(":hover")) {
if (!inEle) {
// fade in the spire logo
$('.logoimgcontainer img').stop(true, true).fadeIn(3000);
// find the ul submenu and put it back on the div in the main menu, remove the placeholder id
$('body').find('ul[id*="'+ulID+'"]').appendTo($('.uk-navbar-nav li').find('div[id*="'+ulID+'"]')).removeAttr('id');
// fade out the ul submenu
$('.uk-navbar-nav li').find('div[id*="'+ulID+'"]').find('ul').fadeOut(500);
// find the div holding the ul submenu and take out its placeholder id
$('body').find('div[id*="'+ulID+'"]').removeAttr('id');
}else clearTimeout(hideTimer); // still in the sub menu, clear the timer, handle in submenu
}, 1000);
}
);
});
</script>
I recommend going with clicks instead of hovers, because hovers don't work on mobile devices (aka touch screens). Rolling your own menu is kind of like reinventing the wheel these days. I can recommend some good bootstrap based templates that already have menus built in and they even "magically" change into hamburgers on mobile devices. However, maybe you are trying to learn and I have written some menus myself and one piece of advice on can give you is that you should use jquery and use mouseLeave instead of mouseOut. mouseOut won't even let you get to your drop down list.

Wow.js repeat animation every time you scroll up or down

I'm pretty new with Jquery. I would like that my animations with Wow.js could run more than once time. For instance: i scroll to the bottom of my page and see all the animations, and if i scroll back to the top i see again the animations like when you scroll down. I hope that I explained myself. I have already seen many websites that repeats the animations on theirs pages but unfortunately I don't remember them and I can't provide a link.
I have already tried this:
$(window).scroll(function(){
new WOW().init();
}
But it repeat the animations also if you scroll a little and it's pretty ugly to see. I try to explain me better: I have a with my animation and if it is focused the animation is triggered, then i scroll down to another div and the previous div is no more visible(not in the window viewport), then again i scroll back to my div with animation and the animation is triggered again.
I'm sorry for this messy question but I really don't know how to explain it.
Thanks in advance!
This example by BenoƮt Boucart shows how the animation can be "reset" when the user scrolls out of view and back in. The key here is the second function that removes the animation css class when the element scrolls out of view. I wish WOW.js would implement this, but they've indicated that they don't plan to.
http://codepen.io/benske/pen/yJoqz
Snippet:
// Showed...
$(".revealOnScroll:not(.animated)").each(function () {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded > offsetTop) {
if ($this.data('timeout')) {
window.setTimeout(function(){
$this.addClass('animated ' + $this.data('animation'));
}, parseInt($this.data('timeout'),10));
} else {
$this.addClass('animated ' + $this.data('animation'));
}
}
});
// Hidden...
$(".revealOnScroll.animated").each(function (index) {
var $this = $(this),
offsetTop = $this.offset().top;
if (scrolled + win_height_padded < offsetTop) {
$(this).removeClass('animated fadeInUp flipInX lightSpeedIn')
}
});
If a user wants to repeat the animation on both the events i.e.
onScrollUp
onScrollDown
then this will be a good solution for it:
First create an addBox function, it will help to push new elements into the WOW boxes array.
WOW.prototype.addBox = function(element){
this.boxes.push(element);
};
Then use jQuery and scrollspy plugin that helps to detect which element is out of the view and then push WOW as:
$('.wow').on('scrollSpy:exit',function(){
var element = $(this);
element.css({
'visibility' : 'hidden',
'animation-name' : 'none'
}).removeClass('animated');
wow.addBox(this);
});
Solution Courtesy: ugurerkan
Answer by #vivekk is correct I m just adding a working example so that people can easily get this
see the Demo fiddle
<script>
// Repeat demo content
var $body = $('body');
var $box = $('.box');
for (var i = 0; i < 20; i++) {
$box.clone().appendTo($body);
}
// Helper function for add element box list in WOW
WOW.prototype.addBox = function(element) {
this.boxes.push(element);
};
// Init WOW.js and get instance
var wow = new WOW();
wow.init();
// Attach scrollSpy to .wow elements for detect view exit events,
// then reset elements and add again for animation
$('.wow').on('scrollSpy:exit', function() {
$(this).css({
'visibility': 'hidden',
'animation-name': 'none'
}).removeClass('animated');
wow.addBox(this);
}).scrollSpy();
</script>

lack of smooth expand collapse of li elements using jQuery

I am trying to slide down li elements on mouseenter of ul and on mouseleave it will slideup its li elements. When I have varying number of li elements, when one slides up it automatically causes mouseenter on other ul
How can this be prevented to ensure a smooth expand/collapse experience?
This is what i have tried so far, i am using hovering variable to have a flag so that for next 2 seconds the mouseenter doesnt cause collapsing/expanding
var hovering=0;
$("ul").mouseenter(function (e) {
console.log(hovering + " " + Math.random());
setTimeout(function(){
clearHover();
}, 1000);
if (hovering == 0) {
hovering = 1;
$(this).children("li").slideDown();
$(".nav").not(this).find("li").slideUp();
}
});
$("ul").mouseleave(function (e) {
$(this).children("li").slideUp();
hovering = 0;
});
function clearHover(){
hovering = 0;
console.log(hovering + " " + Math.random());
};
This is the fiddle
Your problem is not that it automatically opens another ul, all your ul's are 100% width. No wonder you will hover over one of them when leaving another. Try adding this in the css:
ul {width: 50px;}
If you display the ul as a table, you'll get a width that flexes with the content of the header text (where you have "1st", "2nd", etc.)
ul {display: table;}

jQuery FadeIn, FadeOut spamming bug

I have typed some code to fade in and out some divs including a navigator.
I've noticed a bug when you click the navigator fast and try to change between divs very fast by spamming the buttons, the div's will be bugged and if you will inspect the code, you will see that the divs are fading in up to 0.5 opacity, or sometimes even 0.12 and fades out to 0.0 up to 0.09 or something like that.
This is my code:
$(document).ready(function(){
var currentDiv = $("#fading_divs div:first");
currentDiv.css("display","block");
var divN = $("#fading_divs div").length;
var fadeInterval;
for(i=0; i<divN; i++){
$('<span />').text(i+1).appendTo('#fade_nav');
}
$('#fade_nav span').eq(0).addClass('active');
$('#fade_nav span').click(function(){
clearInterval(fadeInterval);
$('#fade_nav span').removeClass('active').eq( $(this).index() ).addClass('active');
currentDiv.fadeOut({duration:1000,queue:false});
currentDiv = $("#fading_divs div").eq( $(this).index() );
currentDiv.fadeIn({duration:1000,queue:false});
anim();
});
function anim() {
fadeInterval = setInterval(function(){
currentDiv.fadeOut({duration:1000,queue:false});
if(currentDiv.next().length)
currentDiv = currentDiv.next();
else
currentDiv = currentDiv.siblings().first();
$('#fade_nav span').removeClass('active').eq( currentDiv.index() ).addClass('active');
currentDiv.fadeIn({duration:1000,queue:false});
}, 4000);
}
anim();
});
Here is a fiddle: http://jsfiddle.net/b5PfE/
try to spam the nav buttons until you will see that the divs are barely fading in or out.
Any suggestion about how to fix it?
This is how I usually solve issues like that:
Add a class to your #fade_nav span of "activated"
Use $('.activated').live('click', function (event) { // }); to start your function
Within that function, first remove the activated class from #fade_nav. This will prevent the buttons from being clickable during your animation.
At the end of the function, add the .activated class back on so the buttons are clickable once more.

Categories

Resources