i have some problems with my script. So, i want to detect end of my scrolling action. I have my alert when i'm scrolling but not if i'm ending it. Can you help me? This is my code:
var animatable = $('body, html');
var animating = false;
animatable.animate( {scrollTop: $('#foo').offset()})
$(window).scroll(function(e) {
if(!animating){
animatable.stop(false, true);
alert('stop scrolling');
}
animating = false;
});
and some fiddle: http://jsfiddle.net/yhnKR/
is this what you're trying to achieve:
$('body').animate( {scrollTop: $('#foo').offset().top},1000,function(){
alert('stop scrolling');
});
http://jsfiddle.net/yhnKR/2/
You don't have to watch the scroll event if you animate the scroll with jquery.
Ok, if you want to detect when the user stopped scrolling, you'll have to use a timeout to check if the user stopped. Otherwise you'll get the event for each scroll step.
Like this:
var delay = 1000;
var timeout = null;
$(window).bind('scroll',function(){
clearTimeout(timeout);
timeout = setTimeout(function(){
alert('scrolling stopped');
},delay);
});
http://jsfiddle.net/yhnKR/4/
maybe adding new events like this:
http://james.padolsey.com/javascript/special-scroll-events-for-jquery/
would help
Related
How can you synchronize scrollbars between two elements without recursively calling each event?
Usually you would expect the following code:
$div1.scroll(function() {
$div2.scrollTop($div1.scrollTop());
});
$div2.scroll(function(){
$div1.scrollTop($div2.scrollTop());
});
But in this case, if you scroll $div1 1px, it will scroll $div2 1px as well, which will prompt the $div2 scroll event to fire and re-apply the scroll position to $div1. While this might not seem like an issue, when this code is applied to a page and you naturally scroll with a mouse, it scrolls in 1px increments because the handlers call eachother and don't allow the scroll to flow.
So, how would you solve this issue?
Example: https://jsfiddle.net/axtn/a91fsar3/2
Found out a good solution. Debouncing does the trick.
You can use a combination of timers and bools to make sure the element is being scrolled by the user. Thus, when the scroll event is rapidly and consecutively fired (like when a user scrolls down), it prevents the handlers from recursively calling eachother. The following code does the trick:
var userScroll1 = true;
var userScroll2 = true;
var timer;
$div1.scroll(function() {
if(userScroll2) {
userScroll1 = false;
clearTimeout(timer);
$div2.scrollTop($div1.scrollTop());
timer = setTimeout(function() {
userScroll1 = true;
}, 100);
}
});
$div2.scroll(function(){
if(userScroll1) {
userScroll2 = false;
clearTimeout(timer);
$div1.scrollTop($div2.scrollTop());
timer = setTimeout(function() {
userScroll2 = true;
}, 100);
}
});
Check out the properly functioning jsbin: https://jsfiddle.net/axtn/a91fsar3
Ok so when someone scrolls to the video it starts and when someone scrolls away from the video it stops using load restarting the video and showing the poster.
The problem I have is that I don't want this function to run when someone clicks to pause the video. It would be pretty annoying for the scroll handler to take control.
jQuery(window).load(function(){
jQuery(window).scroll(function(){
playvideo();
});
});
var playvideo = function(){
var scrollTop = jQuery(window).scrollTop()+jQuery(window).height();
var elem='.video';
var video = document.getElementById('video-background');
var elheight = jQuery(elem).height();
if(scrollTop >= jQuery(elem).offset().top+elheight){
//fade out the video play button and start the video
$j('.video-caption-wrapper').fadeOut("Fast",function() {video.play();});
}else{
// fade in the play button and reload the video
$j('.video-caption-wrapper').fadeIn("Fast",function() {video.load()});
}
}
$j('#video-background').click(function(event) {
//when the video is clicked pause it and unbind scrolling
if (this.paused == false) {
this.pause();
$j(window).off("scroll",playvideo);
} else {
this.play();
}
});
This:
jQuery(window).load(function(){
jQuery(window).scroll(function(){
playvideo();
});
});
Should be:
jQuery(window).load(function(){
jQuery(window).scroll(playvideo);
});
That will allow you to refer to the playvideo function when removing the scroll listener. Right now you try to remove playvideo as a listener when you have never added it. You added an anonymous function which calls playvideo.
I want to simulate a scroll down with the "Page Down" button in a page. I have the call to a function every 2 seconds, but dont know how to connect it with the keyboard buttons (how to simulate a keyboard button press?).
var interval = null;
jQuery(function(){
interval = setInterval(callFunc, 2000);
});
function callFunc(){
jQuery('.link1, .link2, .link3').trigger('click');
}
This seems to work, meaning that when inserted in the console it call the callFunc function every 500ms, but I cant fix the part inside the function to simulate the button press. (keycode for "page down" button is 34)
var interval = null;
$(function(){
interval = setInterval(callFunc, 500);
});
function callFunc(){
var event = $.Event('keypress');
event.which = 34;
event.keyCode = 34;
$(this).trigger(event);
}
Anyone?
Finally managed to achieve what I wanted. Instead of simulating a keypress of "Page down", which for some unknown reason for me didn't work (I think I got the keycode wrong), I simulate a scrolldown:
var interval = null;
$(function(){
interval = setInterval(callFunc, 500);
});
function callFunc(){
var scroll = $(window).scrollTop();
var scrollto = scroll + 500;
$("html, body").animate({scrollTop: scrollto});
}
This is a way to scroll down automatically in any page and trigger the infinite scroller of the page. My example is for retrieving a big list of facebook page likers:
https://www.facebook.com/search/[PADE_ID]/likers
i'm looking for another way to execute this code :
$.each($("#gallery > img"), function(index,curImg) {
setTimeout(function() {
clearCanvas();
cvsCtx.drawImage(curImg,0,0);
} , index*animationMs);
});
This code draw an image from my gallery to my canvas every animationMs .
But i would like to make it possible to stop the animation, with a "Play/stop" button, I can't do it this way...
Any idea or workaround ?? thank you !!
I can't test it. But you can stop animation by using a variable to hold the setTimeout function as following:
var x; // public var
....
x = setTimeout(......);
// To stop it use:
clearTimeout(x);
Hope this works for you
I find that creating timeouts in a loop is usually too hard to manage - you don't want to have to cancel multiple timeouts. Better to have the function doing the work call itself (indirectly) by setting a timeout just before it completes, because then you can put in a simple if test to decide whether to set the next timeout and continue your animation.
Perhaps a little something like this:
<input id="playPause" type="button" value="Play">
<script>
function initAnimation(animationMs, autoRepeat, waitForPlayButton) {
var currentFrame = 0,
$imgList = $("#gallery > img"),
paused = waitForPlayButton;
function drawNext() {
clearCanvas();
cvsCtx.drawImage($imgList[currentFrame++],0,0);
if (currentFrame >= $imgList.length) {
currentFrame = 0;
if (!autoRepeat) {
paused = true;
$("playPause").prop("value", "Play");
}
}
if (!paused)
setTimeout(drawNext, animationMs);
}
$("playPause").prop("value", waitForPlayButton ? "Play" : "Pause")
.click(function() {
this.value = (paused = !paused) ? "Play" : "Pause";
if (!paused)
drawNext();
});
if (!waitForPlayButton)
drawNext();
}
initAnimation(100, true, false);
</script>
If autoRepeat param is false the animation will run once and stop, but can be restarted via the button, otherwise (obviously) it just keeps repeating.
If waitForPlayButton is false the animation will start immediately, otherwise (obviously) it will start when the button is pressed.
Pressing the button will pause at the current frame.
(Not tested since I don't have a bunch of images handy, but I'm sure you get the idea and can fix any problems yourself. Or let me know if you get errors...)
var images = $("#gallery > img").clone(), interval;
function startLoop() {
interval = setInterval(function(){
var image = images[0];
clearCanvas();
cvsCtx.drawImage(image,0,0);
images.append(image);
}, animationMs);
}
$(".stop").click(function() {clearInterval(interval);});
$(".start").click(startLoop);
setTimeout return a timeoutID which can be given to clearTimeout as a parameter to stop the timeout from happening.
You can read more about this at: https://developer.mozilla.org/en/DOM/window.setTimeout
Good luck
It's not really an animation... but still:
$("#gallery > img").each(function(index,curImg) {
$(this).delay(index*animationMs).queue(function(next) {
clearCanvas();
cvsCtx.drawImage(curImg,0,0);
if (next) next();
});
});
Using jQuery queues like I did allows you to do .stop(true), on $("#gallery > img") or a single image and stop their "animation".
First you could add images to a javascript array variable (eventually global) and then call a function cycle() on that array for all its length.
You should put your setTimeout() call inside that function, assigning it to a variable: var t=setTimeout("cycle()",animationMs); and execute clearTimeout(t); when you want to stop the animation.
Of course you could also save in a variable the frame where you were when stopping the animation and restart exactly from that frame when pressing "play" button.
I have this page: http://www.yasyf.com/services.html, in which a video autoplays. I would like to have it so that once the video finishes playing (a set amount of time), the page automatically scrolls down to the text, using a jQuery scrollto with timed delay, but only if the page has not yet been scrolled. Is this possible?
See here the example I made for you.
MORE INFO
Depending on the player you're using, a video finished event could be available. You can then attach the scrollTo function to it. You can read more about this event here:
YOUTUBE
FLOWPLAYER
ADOBE
If you can, give also a look to this incredibly useful resource and this spec about video in HTML5.
About vid.ly :
It seems to me that they use an HTML5 with Flash fallback player. See here the "how can I use vid.ly" section.
JS code :
// add a scrollTo method to jQuery
$.fn.scrollTo = function(duration){
if(duration == null){ duration = 1000; }
var offset = $(this).offset().top - $(window).height()/2 + $(this).height();
$('html,body').animate({ scrollTop: offset}, duration);
}
// Then when the dom is loaded
$("document").ready(function() {
//for HTML5 (for flash please see the ADOBE link above.)
$("video").bind("ended", function() {
// Log on console just for debug
console.log("autoplay ended! About to scroll to...");
// scroll to a div with id="scroll_to_here"
$('#scroll_to_here').scrollTo();
});
});
var scrolled = false;
$(window).scroll(function(){
scrolled = true;
});
var scroll_timer = setTimeout(function(){
if(scrolled !== true)
{
// scroll to whatever
}
},10000);
This is a simple script to do that. I assume scroll / keydown / mouse click to say "the user has interacted with the page, don't auto-scroll."
(function() {
var scrollPage = function() {
$.scrollTo(xyz);
};
var c = setTimeout(scrollPage, 35000);
$(document.body).bind('scroll mousedown keydown', function() {
clearTimeout(c);
});
})();
Let me know if this helps.