I'm essentially hiding a form until the user hovers over the call to action piece of the UI, and then sliding the form in while simultaneously sliding the CTA out. Then if the user clicks on the form it stays on the screen until focus is left. Otherwise the elements return to their original state on mouseleave. The animations are all handled with CSS transitions and transforms via adding classes with the js. I've got it working fine, but the js feels a little wet to me so I was curious if there might be a cleaner way to write this?
function fireNewsletter(){
$('.newsletter-container').bind("mouseenter focus", function() {
$(".newsletter-cta").addClass('hiding');
$(".newsletter-form").addClass('showing');
});
$(".newsletter-container").bind("mouseleave", function(){
if ( ! $(".newsletter-input").is(":focus")) {
$(".newsletter-cta").removeClass('hiding');
$(".newsletter-form").removeClass('showing');
}
});
$(".newsletter-input").focusout(function(){
$(".newsletter-cta").removeClass('hiding');
$(".newsletter-form").removeClass('showing');
});
}
I would probably just go with moving the show/hide logic into descriptively named functions and caching the references to the elements. It doesn't make it much shorter but it will perform better and it reads easier.
function fireNewsletter(){
var cta = $(".newsletter-cta"),
form = $(".newsletter-form"),
input = $(".newsletter-input"),
container = $(".newsletter-container");
function show () {
cta.addClass('hiding');
form.addClass('showing');
}
function hide () {
if (!input.is(":focus")) {
cta.removeClass('hiding');
form.removeClass('showing');
}
}
container.bind("mouseenter", show);
container.bind("focus", show);
container.bind("mouseleave", hide);
input.bind("focusout", hide)
}
Related
So I am creating this button that expands when clicked and hides data when clicked again. I have made it work, but it was working only one time before refresh, then I figured I need to take a different approach, by toggling class on the button itself, not the div where data appears. And my problem is, that to do so I need to toggle only one of two classes the button has with javascript. How do I do that?
const expandMovies = document.querySelector("#btnMovies");
expandMovies.addEventListener("click", toggleMovies)
function toggleMovies() {
if (expandMovies.classList.contains("inactive")) {
getMovies();
expandMovies.classList.toggle("active");
} else {
parentMovies.style.display="none";
expandMovies.classList.toggle("inactive");
}
};
You can use second property of toggle method which forces to remove or add class forcibly. Following is the code snippet which can helpful for you.
const expandMovies = document.querySelector("#btnMovies");
expandMovies.addEventListener("click", toggleMovies)
function toggleMovies() {
if (expandMovies.classList.contains("inactive")) {
getMovies();
expandMovies.classList.toggle("inactive",false);
expandMovies.classList.toggle("active",true);
} else {
parentMovies.style.display="none";
expandMovies.classList.toggle("active",false);
expandMovies.classList.toggle("inactive",true);
}
};
So i'm wondering how you can make a div apear at a certain point of the page and stay in the exact same spot untill you reach a specific point of the page
kinda like they have on http://www.squarespace.com where you see a imac screen which stays on the screen until you reach a specific point
can this be done without using js
either way can someone let me know how?
I'm going to assume you mean making a div show up when the user has scrolled to a certain point in the page and then disappear when they scroll to another point.
This isn't technically possible with CSS. There might be a way to make it look like this with other elements covering it up, but I'll focus on doing it with JS for now.
Essentially, you want to
// set up limits for show/hide
var SHOW_Y = 100,
HIDE_Y = 800;
// function to be called every time
// the page is scrolled
function scrolled() {
if(window.scrollTop < SHOW_Y) {
hide(this);
} else if(window.scrollTop < HIDE_Y) {
show(this);
} else {
hide(this);
}
}
// helper function which hides an element
function hide(element) {
element.style.display = 'none';
}
// helper function which shows an element
function show(element) {
element.style.display = 'block';
}
window.addEventListener('load', function() {
var element = document.getElementById('your-element');
window.addEventListener('scroll', scrolled.bind(element));
});
I would probably do this using CSS classes rather than display properties, in order to control the way that the element disappears and reappears, but this should give you some idea.
You could also use a script like Skrollr or ScrollMagic.
I've managed to get this working with:
<!--
function resettoggle() {
document.getElementById('imagecarousel').style.display = 'none';
}
function displayImages() {
document.getElementById$('#imagecarousel').style.display="block";
}
$('#imagecarousel').fadeIn("slow", function() {
// Animation complete
$('#portfolio').click(function () {
$("#imagecarousel").toggle();
});
});
-->
and adding onLoad="resettoggle()" to the body tag
I now only need help with 2 things:
I have the div set to fadeIn, but it seems to be flying in at the speed of light.
When the page loads, you see a flicker of the slideshow before it disappears. Not sure how to implement the resettoggle function in a way that keeps the hidden div completely out of view?
you can use fadeToggle():
Display or hide the matched elements by animating their opacity.
$("#portfolio").click(function () {
$("#imagecarousel").fadeToggle("slow");
});
I have the following html code:
<div id="gridStage">
<div id="point1" class="point rounded-corners">
</div>
</div>
#gridStage is a larger div inside which a smaller div #point is contained.
I want to call a correct function if a user clicks on #point and another wrong function if the user clicks anywhere on #gridStage but not on #point.
The problem is that when the user clicks on #point, jQuery also detects click on #gridStage as a result of which both the functions are called, which is not required.
Currently I am able to do it with the following code:
var pointClick=0;
$(".point").click(function() {
var pointClick=1;
correct();
setTimeout(function() {
pointClick=0;
},1000);
});
$("#gridStage").click(function() {
setTimeout(function() {
if(pointClick===0) {
wrong();
}
}, 500);
});
But I know this is an inefficient way, so is there any other good solution possible??
Note: All I want to do is that I have a grid as an image, then I overlay a div over it & I want to detect if a user has clicked a correct point or not for which I place a div on the correct point on top of the overlay grid, now I have to detect whether his click is on correct point or noyt. So if you have a better layout for this except the above which I am using, you are free to suggest so.
You need to stop the propagation.
$(".point").click(function(e) {
correct();
e.stopPropagation();
});
$("#gridStage").click(function() {
wrong();
});
(note the e parameter on the line $(".point").click(function(e) { and the e.stopPropagation();)
Simply put I'm trying to sync two slideshows created using widgetkit lib in a joomla website, eg. when user clicks next slide on one, the other one also runs nextSlide() function in the slideshow.js. Same for previous. The problems I'm having is widgetkit uses anonymous functions for creating those slideshows and I dont have global references to them after they are created. With my limited programming knowledge I cant seem to trigger the nextSlide function for other slideshows once inside click handler.
If anyone can take a look it would be most welcome.
EDIT:
Of course I forgot to link the example webpage
http://www.yootheme.com/widgetkit/examples/slideshow
Mine is similar with only 2 slideshows, but is still only on local server.
Taking a brief look at widgetkit here is one possible solution. Using jquery you can search for any objects that have a class of slides with a child of next and click all others. The code provided below isn't tested but should point you in the right direction. As long as you don't call stop propagation or prevent default then the original click handlers should still fire.
var slideshow_count = $('.slides .next').length;
var cascade_countdown = 0;
$('.slides .next').each(function() {
$(this).click(function() {
// stop an infinite loop if we're already cascading till we've done it for all the elements.
if(cascade_countdown != 0) {
cascade_countdown--;
return true;
}
// we don't include the slideshow we're clicking in this count
cascade_countdown = slideshow_count - 1;
var clicked_el = this;
$('.slides .next').each(function() {
// only click elements that aren't the initiator
if(this !== clicked_el) {
$(this).click();
}
});
});
});