I've been trying to figure out how to trigger animations on scroll, and I can't quite get it. Basically, I want to have a class that I can add to my titles that will trigger an animation any time the element with the class is scrolled into view.
I tried using the jQuery Inview plugin, but I couldn't get it to do what I wanted. Then I switched to Waypoints.js and I kind of have it working, but it's not perfect. Right now, the elements animate when I scroll to them for the first time but they do nothing when I scroll up and back down the page. The animations only fire once.
Below is my current code. If anyone can help me figure out a way to get the animations triggering every time the user scrolls past them—and also a way to condense the code so that it fires based on class and not ID—that would be really excellent. (Right now, I have separate function for each element.)
PS: I'm using animate.css, wow.js, textillate.js for the animations.
HTML
<h1 class="lettering wow fadeInDown" id="l1" data-in-effect="flipInY">Yo. Check it out.</h1>
jQuery
$(function () {
var l1 = $("#l1");
var waypoint = new Waypoint({
element: document.getElementById('l1'),
handler: function() {
l1.textillate({ in: { effect: 'flipInY' } });
},
offset: 'bottom-in-view',
});
});
Thanks for your help!
EDIT: I have found a partial solution that triggers the animations every time you scroll past them. However, I can only seem to get it to work with ids. I'd rather be able to target a class than have to write a separate function for each new title. Any ideas on how to modify the following code so that it works for a class of .lettering?
// Animate #l1
$(function () {
var animatel1 = $('#l1').textillate({
autoStart: false,
in: { effect: 'flipInY' },
out: { effect: 'fadeOut', sync: true, }
});
var l1 = $("#l1");
var inview = new Waypoint.Inview({
element: $('#l1'),
enter: function(direction) {
},
entered: function(direction) {
animatel1.textillate('in')
},
exit: function(direction) {
animatel1.textillate('out')
},
exited: function(direction) {
}
})
});
Having it work with a class is a matter of looping through your array of elements. I see you're using jQuery, so it can help you with a bit of the boilerplate:
$(function () {
$('.your-class').textillate({
autoStart: false,
in: { effect: 'flipInY' },
out: { effect: 'fadeOut', sync: true, }
});
$('.your-class').each(function() {
new Waypoint.Inview({
element: this,
entered: function(direction) {
$(this.element).textillate('in')
},
exit: function(direction) {
$(this.element).textillate('out')
}
});
});
});
This is what worked for me. Needed to wrap everything in an .each() function. Replace lettering with your class name and you should be good to go.
$('.lettering').each(function() {
var animatelettering = $('.lettering').each(function(){
$(this).textillate({
autoStart: false,
in: { effect: 'flipInY' },
out: { effect: 'fadeOut', sync: true, }
});
});
new Waypoint.Inview({
element: this,
enter: function(direction) {
},
entered: function(direction) {
animatelettering.textillate('in')
},
exit: function(direction) {
animatelettering.textillate('out')
},
exited: function(direction) {
}
});
});
Related
Using a jquery plugin for Youtube backgrounds (https://github.com/pupunzi/jquery.mb.YTPlayer/wiki)
I am trying to pause all the background videos with a single pause button, not sure for which reason it only pauses the first video, no matter the length of divs with background video.
I set up a jsfiddle explaining what I am trying to achieve.
The codes are as follow:
$('.vid').each(function() {
var vid = $(this).data('video');
$(this).YTPlayer({
videoURL: vid,
stopMovieOnBlur: false,
mute: true,
ratio: 'auto',
quality: 'default',
loop: true,
showYTLogo: false,
showControls: false,
containment: 'self'
});
});
$('.pauseit').on('click', function() {
$('.vid').YTPPause()
});
Thanks for any help on this.
Converting comment to answer.
Make sure the button is a button: type="button"
use .each again to pause the videos:
Like this:
$('.pauseit').on('click', function() {
$('.vid').each(function() { $(this).YTPPause(); });
});
https://jsfiddle.net/mplungjan/swnj2bcg/
Take a look here. I modified the jsfiddle:
update
Chnage it like this:
$('.pauseit').on('click', function() {
$('.vid').each(function() {
$( this ).YTPPause();
})
});
Thank for the recomendations, I have updated my ask.
I have the next code:
https://jsfiddle.net/btq7mm0h/3/
Is a simply counter starts when the document is ready. I would like that it will start when the div id="testimonios" is visible on screen because when I do scroll to down for to see the effect is already can't see.
What I have made, I find several plugin js like
https://www.customd.com/articles/13/checking-if-an-element-is-visible-on-screen-using-jquery
Add script in my document and modified the code:
if $('#testimonios').visible( true ) {
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 9000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
}
Please any suggestion.
There's a few ways to go about this such as using a timer, pure javascript and jquery has a few variations. Here's one way to go about this.
$("#testimonios").bind("DOMSubtreeModified", function() {
// do whatever here, you can even add an if statement for css such as
var cssCheck = $(this).css('display');
if (cssCheck == "block") {
// Div Display is Visible
alert("isVisible");
} else {
// Div Display is not Visible
alert("isNotVisible");
}
});
You can see the result at codebin: http://codebins.com/bin/4ldqoyk
I'm trying to use Masonry and smoothState together using SmoothState animations between pages.
The code below makes smoothState animations work both forwards and in reverse:
$(function(){
'use strict';
var $page = $('#main'),
options = {
debug: true,
prefetch: true,
cacheLength: 2,
onStart: {
duration: 500, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
}
},
smoothState = $page.smoothState(options).data('smoothState');
});
I can make Masonry work by invoking
$(document).ready(function() {
var $container = $('#portfolio');
$container.imagesLoaded( function() {
$container.masonry({
itemSelector : '.p-item',
});
});
});
But they don't play nicely together. Masonry works, but smoothState doesn't (the forward animations are still fine, because they're pure CSS, but the JS doesn't seem to work). If I get rid of the Masonry code, smoothState works fine, which seems odd because they ought to be unrelated.
Is there a way to have both?
According to the FAQ, the $(document).ready functions must be re-initialised in the onAfter. After looking at lots of articles in the issues section and here, the developer has created a gist here that re-runs any $(document).ready functions.
I still can't get it working though (I'm not using masonry but using imagesLoaded from desandro and some other plugins), seems $.readyFn.execute(); is supposed to run on option.callback but the FAQs say to run onAfter callback. I have tried both and it's not worked for me, I've also tried removing all other plugins and just doing some menial task on ready but that didn't work, seems onAfter just doesn't fire for me.
So even though this doesn't work for me, according to other posts this should fix it for you.
Paste in the following right after including jQuery
;(function($){
var $doc = $(document);
/** create mod exec controller */
$.readyFn = {
list: [],
register: function(fn) {
$.readyFn.list.push(fn);
},
execute: function() {
for (var i = 0; i < $.readyFn.list.length; i++) {
try {
$.readyFn.list[i].apply(document, [$]);
}
catch (e) {
throw e;
}
};
}
};
/** run all functions */
$doc.ready(function(){
$.readyFn.execute();
});
/** register function */
$.fn.ready = function(fn) {
$.readyFn.register(fn);
};
})(jQuery);
Then add the following, make sure the original masonry call is inside a $(document).ready function
$(function(){
'use strict';
var $page = $('#main'),
options = {
debug: true,
prefetch: true,
cacheLength: 2,
onStart: {
duration: 500, // Duration of our animation
render: function ($container) {
// Add your CSS animation reversing class
$container.addClass('is-exiting');
// Restart your animation
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function ($container, $newContent) {
// Remove your CSS animation reversing class
$container.removeClass('is-exiting');
// Inject the new content
$container.html($newContent);
}
},
// over a year ago, this was simply callback: function(){}
onAfter: function($container, $newContent){
$.readyFn.execute();
}
},
smoothState = $page.smoothState(options).data('smoothState');
});
I need to start scroll when user hover. I take a function reference from the question this and this. I notice that even the callback function is not working with initCallback option. Am I missing something or I forgot something to put in the code. Here is example of code fiddle
function mycarousel_initCallback(carousel)
{
carousel.clip.hover(function() {
carousel.startAuto();
}, function() {
carousel.stopAuto();
});
};
You should use jcarouselAutoscroll plugin for that
Check this updated fiddle
INIT CODE
A(".example").jcarousel({
auto: 1,
wrap: "last"
}).jcarouselAutoscroll({
interval: 1000,
target: '+=1',
autostart: false
});
Code for hovering
$(".example li").hover(function () {
$(".example").jcarouselAutoscroll('start');
},function () {
$(".example").jcarouselAutoscroll('stop');
})
I am currently using the following code to initialize a lazy initialization version of Bootstrap tooltip. After the first hover everything works fine in regards to the delay, but on the initial hover it shows right away. I know this is because of the $(this).tooltip('show'); method, but I dont know how to use the delay and show at the same time. I have to use the $(this).tooltip('show'); because once hovered the element doesnt show the tooltip unless I move out and back in.
$(element).on('hover', '.item', function () {
matchup = ko.dataFor(this).Matchup;
if (matchup) {
if ($(this).attr('data-original-title') != '') {
$(this).tooltip({ title: matchup.Title, html: true, delay: 1000 });
$(this).tooltip('show');
}
}
});
Updated Answer
$(element).on('mouseenter', '.item', function (e) {
matchup = ko.dataFor(this).Matchup;
if (matchup) {
if ($(this).attr('data-original-title') != '') {
$(this)
.addClass('tooltip-init')
.tooltip({ title: matchup.Title, html: true, delay: { show: 1000, hide: 0 } })
.trigger(e.type);
}
});
try use trigger
try the following code
$(this).tooltip({
title: matchup.Title,
html: true,
trigger: 'hover',
delay: delay: { show: 2000, hide: 3000 }
}).trigger('hover');
I found Holmes answer using delay to work, but not reliably. When moving through a series of items, the hover seemed to stop showing. With the help of another stackoverflow answer leading to this jsfiddle by Sherbrow, I simplified the code and got it working in this jsfiddle. Simplified code below:
var enterTimeout = false;
$('[rel="tooltip"]').tooltip({trigger:'manual'}).on('mouseenter', function() {
var show = function(n) {
enterTimeout = setTimeout(function(n) {
var isHovered = n.is(":hover");
if (isHovered) n.tooltip('show');
enterTimeout = false;
}, 750);
};
if(enterTimeout) clearTimeout(enterTimeout);
show( $(this) );
});
$('[rel="tooltip"]').on('mouseout click',function() {
$(this).tooltip('hide');
});