I'm having some difficulties in one of the jQ features I've implemented. The problem is that slide animation is hiding/showing multiple times for some of the attempts. I want it to be showing only once after hovering an element.
All is working fine but sometimes is fading few times when mouse is hovering element, so if you move a mouse but you're still hover it shouldn't happened. I want it to fade every time you hover but it should animate only once per hover but sometimes is fading few extra times per one hover. Try to move a mouse between title and the content when hovering.
$(document).ready(function() {
$('.latest_module').hover(function(){
var front = $(this).children('.cb-article-meta');
var back = $(this).children('.cb-article-meta-hover');
var backh2 = $(this).children('.cb-article-meta-hover').children('h2');
var backp = $(this).children('.cb-article-meta-hover').children('p');
var img = $(this).children('.cb-grid-img');
$(front).css('display','none');
$(back).css('display','block');
$(img).addClass('latest_module_hover');
$(backh2).hide().show("slide", { direction: 'right' },800).css('padding','0 20px');
$(backp).hide().show("slide", { direction: 'left' }, 800).css('padding','0 20px');
},function(){
var front = $(this).children('.cb-article-meta');
var back = $(this).children('.cb-article-meta-hover');
var img = $(this).children('.cb-grid-img');
$(front).css('display','block');
$(back).css('display','none');
$(img).removeClass('latest_module_hover');
});
});
Testing on jsfiddle
Thanks,
If your problem is that you only want hover to run the first time you can just unbind it when it enters with this $(this).unbind('mouseenter mouseleave')
$(document).ready(function() {
$('.latest_module').hover(function(){
$(this).unbind('mouseenter mouseleave')
...
http://jsfiddle.net/bgsx23nc/12/
EDIT:
or as suggested by Guruprasad Rao only on leave
...
$(img).removeClass('latest_module_hover');
$(this).unbind('mouseenter mouseleave')
});
});
http://jsfiddle.net/Guruprasad_Rao/bgsx23nc/13/
Just add a class to the sliding element and then from next time check if it has class already and if yes don't do anything like one below:
DEMO
$(document).ready(function() {
$('.latest_module').hover(function(){
if(!$(this).hasClass('hoverDone')) //check if it has class and if no then
{
$(this).addClass('hoverDone'); //add class once hover done
var front = $(this).children('.cb-article-meta');
var back = $(this).children('.cb-article-meta-hover');
var backh2 = $(this).children('.cb-article-meta-hover').children('h2');
var backp = $(this).children('.cb-article-meta-hover').children('p');
var img = $(this).children('.cb-grid-img');
$(front).css('display','none');
$(back).css('display','block');
$(img).addClass('latest_module_hover');
$(backh2).hide().show("slide", { direction: 'right' },800).css('padding','0 20px');
$(backp).hide().show("slide", { direction: 'left' }, 800).css('padding','0 20px');
}
},function(){
var front = $(this).children('.cb-article-meta');
var back = $(this).children('.cb-article-meta-hover');
var img = $(this).children('.cb-grid-img');
$(front).css('display','block');
$(back).css('display','none');
$(img).removeClass('latest_module_hover');
});
});
Related
As the title suggests I want to detect the start and end of a scrollable element built using overflow.
The following code works:
var scrollAmount = 150;
var scrollBox = $('.js-compare_scroll');
var arrowLeft = $('.js-compare_scroll_left');
var arrowRight = $('.js-compare_scroll_right');
var inactive = 'm-inactive';
$(arrowLeft).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '-='+scrollAmount
}, function() {
arrowRight.removeClass(inactive);
if(scrollBox.scrollLeft() === 0) {
arrowLeft.addClass(inactive);
}
});
});
$(arrowRight).on('click', function () {
$(this).parent().find(scrollBox).stop().animate({
scrollLeft: '+='+scrollAmount
}, function() {
arrowLeft.removeClass(inactive);
if(scrollBox.scrollLeft() + scrollBox.innerWidth() >= scrollBox[0].scrollWidth) {
arrowRight.addClass(inactive);
}
});
});
However the class to style the inactive colour of the arrows only appears once the animation completes. I need to add the class before the animation completes because it has a delay. I believe by default it is 400.
Is there anyway to detect this and apply the arrow classes where needed?
Thanks.
Came back from a break and realised I should take the checking if its at the end off the click event and onto a scroll event. This works a lot better now.
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>
I try to animate menu-panel. It should slide to the left. But it doesn't work right. And I can't understand why.
There are a few issues with the current code (e.g. you were missing a . on one panel selector and not referencing panel1 after changing the panel class. I also switched to absolute positioning with the arrow inside the panel.
I did a little cleanup to make the changes obvious (you should not repeat jQuery selectors - use temp vars instead):
JSFiddle: http://jsfiddle.net/TrueBlueAussie/2x3uT/8/
$(function () {
$('.slider-arrow').click(function () {
var $this = $(this);
var $panel = $(".panel, .panel1");
var left = -53;
var text = '»';
if ($this.hasClass('hide')) {
text = '«';
left = 0;
}
$panel.animate({
left: left
}, 700, function () {
// Animation complete.
$this.html(text).toggleClass('hide').toggleClass('show');
$panel.toggleClass('panel').toggleClass('panel1');
});
});
});
You can tweak the position numbers to make it match what you wanted.
I want a nav to highlight (or something similar) once a user clicks on it AND when a user scrolls to the corresponding section.
However, on my computer when one clicks on any of the nav events after3, only nav event 3 changes. I'm guessing this is because after one clicks on 4 or 5, the scroll bar is already at the bottom of the page, so 4 and 5 never reach the top. The only div at the top is post 3, so my code highlights nav event 3 and ignores the click.
Is there any way I can fix this? Ive tried if statements (only highlight nav event if it's at the top AND the scrollbar isn't at the bottom or the top isn't the last item).
Here is a more accurate fiddle, using a fix below showing what I am talking about. The fix now highlights on scroll, but if you click option 5, it will not highlight.
$('.option').children('a').click(function() {
$('.option').css('background-color', '#CCCCCC;');
$(this).css('background-color', 'red');
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$(window).scrollTop(postLocation);
});
$(window).scroll(function() {
var scrollBar = $(this).scrollTop();
var allPosts = [];
var post = $('.content').offset();
var lastPost = allPosts.legnth-1
var windowHeight = $(window).height();
var bottomScroll = windowHeight-scrollBar;
$(".content").each(function(){
allPosts.push($(this).attr('id'));
});
i = 0;
for(i in allPosts){
var currentPost = "#"+allPosts[i];
var postPosition = $(currentPost).offset().top;
if (scrollBar >= postPosition){
$('.option').css('background-color', '#CCCCCC');
$('#nav'+allPosts[i]).css('background-color', 'red');
};
};
});
I think you've overdone your scroll() handler, to keep it simple you just needs to check if the scrollbar/scrollTop reaches the '.contents' offset top value but should not be greater than its offset().top plus its height().
$(window).scroll(function () {
var scrollBar = $(this).scrollTop();
$(".content").each(function (index) {
var elTop = $(this).offset().top;
var elHeight = $(this).height();
if (scrollBar >= elTop - 5 && scrollBar < elTop + elHeight) {
/* $(this) '.content' is the active on the vewport,
get its index to target the corresponding navigation '.option',
like this - $('.Nav li').eq(index)
*/
}
});
});
And you actually don't need to set $(window).scrollTop(postLocation); because of the default <a> tag anchoring on click, you can omit that one and it will work fine. However if you are looking to animate you need first to prevent this default behavior:
$('.option').children('a').click(function (e) {
e.preventDefault();
var postId = $($(this).attr('href'));
var postLocation = postId.offset().top;
$('html, body').animate({scrollTop:postLocation},'slow');
});
See the demo.
What you are trying to implement from scratch, although commendable, has already been done by the nice folks at Bootstrap. It is called a Scrollspy and all you need to do to implement it is include Bootstrap js and css (you also need jquery but you already have that) and make some minor changes to your html.
Scrollspy implementation steps.
And here is a demonstration. Notice only one line of js. :D
$('body').scrollspy({ target: '.navbar-example' });
So I am very very new to JavaScript and unfortunately I don't know the basics too well also.
I was working on a code to make an element hidden after clicking it and again reversing back the effect by clicking the same button but I am unable to do so. Please help me here is the code:
$(function() {
$('#boxclose').click(function(){
$('#md-share-window').animate({'bottom':'-90px'},500,function(){});
});
});
You can use a class to identify the state of the element you are animating.
Here's an example: http://jsfiddle.net/FgDaq/
$('#boxclose').click(function() {
var c = 'on',
el = '#md-share-window',
duration = 500;
if ($(el).hasClass(c)) {
$(el).animate({'bottom': 0}, duration)
.removeClass(c);
} else {
$(el).animate({'bottom': '-90px'}, duration)
.addClass(c);
}
});
You'll need to get the initial position (or hard code it) and keep track of whether you are in the initial or updated position:
$(function() {
var shareWindow = $('#md-share-window');
var initialPosition = shareWindow.css('bottom'); //get initial position
var atInitialPos = true; //whether this is the initial or updated position
$('#boxclose').on('click', function(){
var newPosition = atInitialPos ? '-90px' : initialPosition; //determines new position
shareWindow.animate({'bottom': newPosition}, 500);
atInitialPos = !atInitialPos; //toggle initial position boolean
});
});