JQuery if hovering on either element - javascript

So I have 2 divs. One is "top" and one is "menu." I got "menu" to fade in when you hover on "top" in JQuery, as shown:
$(".top").mouseover(function(){
$(".menu").fadeIn(200);
});
$(".top").mouseout(function(){
$(".menu").fadeOut(200);
});
But I want to make it so if I'm also hovering on "menu," "menu" will stay faded in. How would I do this?

I believe this will do it for you. It waits half a second before hiding the menu. If the user hovers over the menu in that time, then it cancels the hide operation.
var timer;
$(".top").mouseover(function(){
clearTimeout(timer);
$(".menu").fadeIn(200);
});
$(".top, .menu").mouseout(function(){
timer = setTimeout(function() {
$(".menu").fadeOut(200);
}, 500);
});
$(".menu").mouseover(function() {
clearTimeout(timer);
});

Add a variable that remembers if you are hovering on the menu:
var isHoveringMenu;
$(".menu").mouseover(function(){
isHoveringMenu = true;
});
$(".menu").mouseout(function(){
isHoveringMenu = false;
$(".menu").fadeOut(200); // you probably want this here
});
$(".top").mouseover(function(){
$(".menu").fadeIn(200);
isHoveringMenu = true; // not necessary, but sounds good
});
$(".top").mouseout(function(){
if (!isHoveringMenu) {
$(".menu").fadeOut(200);
}
});
You may want to tweak this slightly -- the best solution depends on the spatial relationship between the two divs, so we 'd need to see the layout first.

Related

How to save the last hovered state on an HTML element?

I am working on a Wordpress shortcode for generating dynamically circles.
At my current version I have a problem with saving my current and my last hover state.
Here is a fiddle
I have a problem displaying the text under the circles. The text should be displayed from the last hovered circle until I hover over a new one.
Is there maybe a better solution to my problem?
I think my problem is in the hover end.
[...] ,function () {
$contentBoxPrevious = $contentBoxCurrent;
$contentBoxCurrent.removeClass('active-text');
$(this).removeClass('hover active');
}
Move this line
$contentBoxPrevious.removeClass('active-text');
from the handleOut function to the middle of handleIn function like this https://jsfiddle.net/eu0jcmh0/
What you were doing wrong was that you were removing the "active-text" class every time you moused out of the element instead of removed it when you moused on another element, hope I helped!
Your code looked way too complicated...
So I just rewrote it my way to achieve what I think you want as a result.
Here's the code:
$(document).ready(function() {
// Set all texts invisible
$(".text-content").css({
"opacity": 0
});
// Declare previous and active indexes vars
var previous_index;
var active_index;
$(".icon-circle").hover(function() {
// On mouseenter, getting this index.
active_index = $(this).data("index");
// Show associated text.
$(this).parent().find(".text-content").css({
"opacity": 1
});
// Hide previous associated text.
if (active_index != previous_index) {
$("[data-index='" + previous_index + "']").parent().find(".text-content").css({
"opacity": 0
});
}
}, function() {
// On mouseout, just keeping previous index...
previous_index = active_index;
});
});
Working Fiddle.

Cycle through classes on Jquery to animate

enter image description here
I'm trying to create an animation where if you click the button the circles animate around the path and changes size. I'm not sure how i would cycle the classes on the next click ?
http://bluemoontesting.co.uk/bluemoon2016/people.html
I'm using an svg and have targeted the elements with this so far:
<script>
$(".animate-slider").click(function() {
$('.st7').toggleClass("top-left");
$('#XMLID_292_').toggleClass("left");
$('#XMLID_293_').toggleClass("center-right");
$('#XMLID_297_').toggleClass("top-right");
$('#XMLID_301_').toggleClass("top");
$('#XMLID_283_').toggleClass("top-center");
});
</script>
If anyone could help me i'd be very grateful :)
Thanks
I would take a little different approach. Instead of toggling classes, to get it to move to more than two positions, you will need to cycle the classes assigned to each element instead. Storing the class names in an array would allow you to move them in the array to cycle the position that each element moves to next. I created a simplified example.
$(document).ready(function () {
var steps = ['right', 'bottom-right', 'bottom-left', 'left', 'top'],
allClasses = steps.join(' ');
$('#go').click(function() {
$('#a').removeClass(allClasses).addClass(steps[0]);
$('#b').removeClass(allClasses).addClass(steps[1]);
$('#c').removeClass(allClasses).addClass(steps[2]);
$('#d').removeClass(allClasses).addClass(steps[3]);
$('#e').removeClass(allClasses).addClass(steps[4]);
steps.push(steps.shift()); // move first element to the end
// to cycle in the other direction you would pop and unshift instead
// steps.unshift(steps.pop()); // move last element to the beginning
});
});
You could just use setInterval like so:
var $st7 = $('.st7'); //class selectors can be expensive, so cache them
function rotate() {
$st7.toggleClass("top-left");
$('#XMLID_292_').toggleClass("left");
$('#XMLID_293_').toggleClass("center-right");
$('#XMLID_297_').toggleClass("top-right");
$('#XMLID_301_').toggleClass("top");
$('#XMLID_283_').toggleClass("top-center");
}
//2000 is milliseconds, so that's two seconds
var rotateIntervalId = setInterval(rotate, 2000);
//optionally consider stopping/starting the effect on mouse hover/exit
$('#Layer_1').on('hover', function() {
clearInterval(rotateIntervalId);
}).on('blur', function() {
rotateIntervalId = setInterval(rotate, 2000);
});

How to fire a unique ID modal when multiple divs with class is clicked using jQuery?

Forgive the strangely worded question, my first StackOverflow post, and I'm a novice to jQuery/JS. I've used the search feature a lot and haven't found exactly what I'm looking for:
I am having an issue essentially, where I have dynamically added divs by the end-user (they pick how many content blocks they want to use), with the same class, that need to hide and show specific divs (with unique IDs) when they are clicked. I finally figured out how to give each div a unique ID, but I'm not sure how to get the child divs of the particular div what was clicked, to fire properly on click. Hope that makes sense.
Here is the HTML I have:
<div class="resource-video">
//Unique thumbnail
</div>
<div class="overlay-container hide" style="width: 50px; height: 50px;">
<div class="video-player hide">
//Included unique video
</div>
</div>
This will end up being duplicated based on how many videos are added.
Here is the JavaScript I am using:
//Generates unique IDs for each of the divs on the page with those classes
var i = 0;
$(".resource-video").each(function(i){
$(this).attr("id","video_"+ (i+ 1) );
});
$(".overlay-container").each(function(i){
$(this).attr("id","container_"+ (i+ 1) );
});
$(".video-player").each(function(i){
$(this).attr("id","player_"+ (i+ 1) );
});
//Currently opens all of them
$(".resource-video").on("click", function(){
openModal(".overlay-container", false, true);
alert($(this).attr("id")); //Alerts the right div clicked
if ($(".video-player").hasClass("hide")){
$(".video-player").removeClass("hide").addClass("show");
$(".overlay-container").animate({ height:'300px', width: '500px' }, "slow");
}
$("#overlay").on("click", function(){
$(".video-player").removeClass("show").addClass("hide");
$(".overlay-container").css({ "height":"50px", "width":"50px",
"display":"none"});
$(this).hide();
});
return false;
});
// Probably not totally necessary, but just in case
function closeModals(){
$("body").find(".modal").hide();
$("#overlay").hide();
$("body, html").removeClass("no-scroll");
};
function openModal(divID, allowScroll, blockScreen){
closeModals();
$(divID).show();
if ( blockScreen == true ){ $("#overlay").show(); };
if ( allowScroll == false ){ $("body, html").addClass("no-scroll"); };
};
As it stands now, all of the overlays open because I am targeting the class not the IDs. Basically, I need to find out a way to have the specific overlay associated with the specific div clicked on to display without hardcoding that, since the number of divs will change all the time. I would think I could use something like $(this) or event.target, but things I tried didn't work.
Hopefully I was clear enough with my issue and made it general enough for other people to use too. Thanks for any help in advance!
This uses DOM traversal functions to find the corresponding DIVs to the one that was clicked.
$(".resource-video").on("click", function(){
var overlayContainer = $(this).next();
var videoPlayer = overlayContainer.children(".video-player");
openModal(overlayContainer, false, true);
if (videoPlayer.hasClass("hide")){
videoPlayer.removeClass("hide").addClass("show");
overlayContainer.animate({ height:'300px', width: '500px' }, "slow");
}
return false;
});
// Only need to bind this once, not every time .resource-video is clicked.
$("#overlay").on("click", function(){
$(".video-player").removeClass("show").addClass("hide");
$(".overlay-container").css({ "height":"50px", "width":"50px",
"display":"none"});
$(this).hide();
});
// Probably not totally necessary, but just in case
function closeModals(){
$(".modal").hide();
$("#overlay").hide();
$("body, html").removeClass("no-scroll");
};
function openModal(div, allowScroll, blockScreen){
closeModals();
div.show();
if ( blockScreen == true ){ $("#overlay").show(); };
if ( allowScroll == false ){ $("body, html").addClass("no-scroll"); };
};

How do I show or hide div, based on position of another div

I have the following jquery that slides a div horizontally:
$('.nextcol').click(function() {
$('.innerslide').animate({'left': '-=711px'}, 1000);
});
$('.prevcol').click(function() {
$('.innerslide').animate({'left': '+=711px'}, 1000);
});
What I want to happen is this... if the div.innerslide has a position that is left: 0px then I want to hide div.backarrow. If the position is not left: 0px, then it shows it.
Any help would be greatly appreciated.
EDIT (added HTML Markup)
<div class="backarrow prevcol">
<div id="mainleft" class="overflowhidden">
<div class="innerslide">
<div class="col">my content including next</div>
<div class="col">my content including next</div>
<div class="col">my content including next</div>
</div>
</div>
Try this:
if ($('.innerslide').css("left") == 0) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
Fix for Double-Click Issue:
From what you described in your comment about the issue when the visitor double-clicks, it sounds like the double-click is causing two of the animation events to fire. To keep this from happening, you can either disable the click handler while the animation is running and re-enable it once it is finished, or you can try to write a new thread to continually check the element's position. One of these solutions is not a good idea - I'll let you figure out which one :) - but the other actually has a very simple solution that requires little change to your existing code (and may actually reduce your overhead by a teeny weeny amount):
$('.nextcol').on("click.next", function() {
$('.innerslide').animate({'left': '-=711px'}, 1000, showHideBack());
$(this).off("click.next");
});
$('.prevcol').on("click.prev", function() {
$('.innerslide').animate({'left': '+=711px'}, 1000, showHideForward());
$(this).off("click.prev");
});
Then add this this line to showHideBack() (and a complementary one to showHideForward() if you are using that):
$('.nextcol').on("click.next".....
I suggest that you write a function to set each click handler and another to remove each one. This will make your live very easy and the whole solution should reduce overhead by removing unnecessary click handlers while the animation is running.
Note: the animation method often calls its callback before the animation finishes. As such, you may wish to use a delay before calling the showHide... method(s).
Let me know if you have any questions. Good luck! :)
UPDATE:
Here is the updated version of the fiddle you gave me with all bugs ironed out. It looks like I misunderstood part of your goal in my original solution, but I straightened it out here. I have also included the updated jQuery, here:
var speed = 1000;
var back = $("div.backarrow");
var next = $(".nextcol");
var prev = $(".prevcol");
var inner = $(".innerslide");
function clickNext(index) {
next.off("click.next");
inner.animate({
'left': '-=711px'
}, speed, function() {
back.show(); //this line will only be hit if there is a previous column to show
next.delay(speed).on("click.next", function() {
clickNext();
});
});
}
function clickPrev() {
prev.off("click.prev");
inner.animate({
'left': '+=711px'
}, speed, function() {
if (inner.css("left") == "0px") {
back.delay(speed).hide();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
} else {
back.delay(speed).show();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
}
});
}
next.on("click.next", function() {
clickNext();
});
prev.on("click.prev", function() {
clickPrev();
});​
I was going to also include a condition to check if you were viewing the last column, but, as I don't know what your final implementation will be, I didn't know if it would be applicable. As always, let me know if you need help or clarification on any of this. :)
You could try the step option — a callback function that is fired at each step of the animation:
$('.prevcol').click(function() {
$('.innerslide').animate({ left: '+=711px' },
{
duration: 1000,
step: function(now, fx) {
if (now === 0 ) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
}
});
});
More examples of usage in this article The jQuery animate() step callback function

jquery: bookmarking Paragraph function, is checking for class on every single Paragraph hover efficient? is there a better way?

Im creating a feature using jquery on my site that allows people to place a bookmark on a paragraph when they're viewing an article, so if they want to come back later, they'll know where they stopped.
When the user clicks on "PLACE A BOOKMARK", it adds the class .placing to that link. When the user hovers over a paragraph, the script checks to see if the link has the .placing class, if it does, it fades in a div on hover that says "bookmark this paragraph", on hover off it fades that div back out.
Right now my code is placed within a $('P').click(function... that is within the hover function, it's caused links on the page to not fire their hover animation. So links inside paragraphs wont animate on hover because when i hover over a paragraph it's checking for the .placing class and doing the bookmark hover function.
How would i get the hover animation to work again on links that exist within paragraphs?
and is this the best way to do it? to check for the .placing class every single time i hover over a paragraph? There's gotta be a better way to do this, like a switch that only allows the bookmark paragraph hovering function to work when the switch is on, and not checking with every single paragraph hover.
$('#placeBookmark').click(function () {
$(this).toggleClass('placing')
})
$('p').hoverIntent(function () {
// HOVER ON
if ($('#placeBookmark').hasClass('placing')) {
$(this).append('<span id="bookmarkThis">BOOKMARK THIS</span>')
$(this).find('#bookmarkThis').stop().animate({opacity: 1.0}, 400)
$('p').click(function (e) {
var newbm = $('#bookmark').offset().top
var offset = $(this).offset();
var top = offset.top
var phrases = ["SUCCESS", "SWEEEEEEET MANNN", "AWESOMELY AWESOME", "NEAT-OH!", "EXCELLENT, BOOKMARK PLACED", "BOOKMARK SAVED", "YOU DID IT KID!", "WOOOHOOO", "YOU ARE WONDERFUL"];
if ($('#placeBookmark').hasClass('placing')) {
//$('#placeBookmark').trigger('click')
$('#placeBookmark').removeClass('placing')
if (top == newbm) {
// bookmarkColorDelay = 2000
$('#bookmarkThis').html('<span>ITS ALREADY BOOKMARKED</span> SILLY PERSON').delay(2000).fadeOut(400, function () {
$(this).remove()//html('BOOKMARK THIS')
})
} else {
// bookmarkColorDelay = 1000
var selectedPhrase = phrases[Math.floor(Math.random() * phrases.length)];
$('#bookmarkThis').html(selectedPhrase).delay(1000).fadeOut(400, function () {
$(this).remove()//html('BOOKMARK THIS')
})
$('#bookmark').fadeOut(300, function () {
$(this).css({
left: offset.left - 30,
top: top
}).fadeIn(300);
})
}
$(this).stop().delay(bookmarkColorDelay).animate({
color: "#333",
backgroundColor: "#fff"
}, 200)
}
});
}
}, function () {
// HOVER OFF
if ($('#placeBookmark').hasClass('placing')) {
$(this).find('#bookmarkThis').stop().fadeOut(400, function(){
$(this).remove()
})
}
});
Use a class selector! :-)
$('.placing').live('click', function(event) {
// Whatever you want to do
});
$('.placing').live('hover', function(event) {
// Whatever you want to do
});
It will work even though the class .placing is added later.
I would take the code by Andrea and optimise it slightly as
$('p.placing').live('click', function(event) {
// Whatever you want to do
});
$('p.placing').live('hover', function(event) {
// Whatever you want to do
});

Categories