I'm using the mousewheel and waypoints plugin to scroll sections of my page; The problem I am having is when I scroll using the apple mighty mouse the scrolling is too sensitive and the function gets triggered more then once when the animation is complete. I tried to set a timeout function and variable to check if the animation is complete but neither of these worked.
I would like to replicate an effect similar to the one on this website.
JQUERY
$('body').mousewheel(function(event, delta, deltaX, deltaY) {
clearTimeout(interval);
console.log('test');
$('section').waypoint(function(direction){
thisID = $(this);
},{ offset: '350' });
indexPos = thisID.index('section');
if (completed == true) {
completed = false;
var interval = "";
if (delta > 0) {
interval = setTimeout(function(){
if ($(this).not(":first-child")) {
//$(this).animate(function(){
$('html, body').stop().animate({
scrollTop: thisID.prev().offset().top - 200
}, 1000, 'swing' , function() { completed = true; });
//});
}else {
$('html, body').stop().animate({
scrollTop: thisID.offset().top - 200
}, 1000, 'swing' , function() { completed = true; });
}
},400);
}
else if (delta < 0) {
interval = setTimeout(function(){
if ($(this).not(":first-child")) {
$('html, body').stop().animate({
scrollTop: thisID.next().offset().top - 200
}, 1000, 'swing' , function() { completed = true; });
}
else {
$('html, body').stop().animate({
scrollTop: thisID.offset().top - 200
}, 1000, 'swing' , function() { completed = true; });
}
},400);
}
};
return false; // prevent default
});
I don't know what this is doing: indexPos = thisID.index('section'); but before doing anything, I would check if ins't anything in progress already:
$('body').mousewheel(function(event, delta, deltaX, deltaY) {
if($('html').is(':animated') || $('body').is(':animated')) return false;
// else, do your stuff...
});
You can use underscore js http://underscorejs.org/
and do something like this:
$('body').mousewheel(_.debounce(function() {
//handle the mouse wheel event in here
}, 30)
This will wait for 30 ms from the last mousewheel event before firing the callback
This website doesn't seem to use scrolling. It merely moves to a new anchor (watch the url when scrolling) which is triggered by moving (scrolling) your mouse up or down as a trigger which feels like lagged scrolling (but in fact, you don't have any control over the direction once it moves). You can use jquery animate to do that.
Related
i'd like to limit scrolling on my webpage to divs/sections whatever.
Like limiting the scroll step to the screen-height.
If a user scrolls whether it is with a mouse-wheel or a mac 2-finger-scroll.
He should scroll automatically to the next section or the previous one.
Example pages: Jenny Example FLPNY Example
I have already found a function here, to limit listening to the scroll event (debounce). I just can't figure out how no to get a random scroll behaviour.
function debounce(func, interval) {
var lastCall = -1;
return function () {
clearTimeout(lastCall);
var args = arguments;
lastCall = setTimeout(function () {
func.apply(this, args);
}, interval);
};
}
$(window).on('wheel', debounce(function (e) {
currentScrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
var delta = e.originalEvent.deltaY;
if (delta > 0) {
console.log("down");
$("html, body").animate({
scrollTop: nextSection
}, 500);
}
else {
console.log("up");
// this will search within the section
$("html, body").animate({
scrollTop: prevSection
}, 500);
}
Not quite sure what you mean by:
I just can't figure out how no to get a random scroll behaviour.
But the site you link is making use of fullPage.js.
I would like to scroll up or down the window while the mouse is over a specific element.
What I have so far basically works but it's not "smooth". It starts and stops on and on, not looking nice. Do you have any idea how to make a more constant smooth scrolling?
This is my code:
doScroll = 0;
$(".helperDown").mouseenter(function() {
scrollHandler = setInterval( function() {
console.log('scrolling down...');
if(doScroll == 0) {
doScroll = 1;
$("html, body").animate({scrollTop: fromTop+50}, 200, 'linear', function() {
doScroll = 0;
});
}
}, 200);
});
$(".helperDown").mouseleave(function() {
clearInterval(scrollHandler);
});
.helperDown is the area where the mouse has to be in to start scrolling. fromTop is always recalculated after a scroll event.
You can not start a series of animation and expect a smooth scrolling. What you need is to start one animation only by pre-calculating the distance this animation will cover. Also, jQuery has a nice wrapper for mouseenter and mouseleave -combined. It's the hover() function with two functions as its parameter. The following code block will solve your issue.
Also, this plnkr has both the up and down scroll feature:
https://plnkr.co/edit/WoneJ8?p=preview
$(function () {
// change this value as per your need
var distancePerSec = 1000;
$(".helperDown").hover(function () {
var h = $("body").height();
var targetScrollTop = h - $(window).height();
var distanceToTravel = targetScrollTop - $(window).scrollTop();
var animationDuration = (distanceToTravel / distancePerSec) * 1000;
$("html, body").animate({
scrollTop: targetScrollTop
}, animationDuration, 'linear');
}, function () {
// stop the animation
$("html, body").stop();
});
})
ScrollTop is a jquery plugin (go to top of page), trying to make slow Scroll Speed, but not working. I have changed scrollSpeed : 'fast', to scrollSpeed : 'slow', but it still fast, nothing change.
JS:
$.fn.extend({
addScrollTop: function(options) {
var defaults = {
useObjWindow : false,
scrollSpeed : 'fast',
zIndex: '99'
}
var options = $.extend(defaults, options);
if($('body').find('.scrollTop-btn').length == 0) {
$('body').append('<div class="scrollTop-btn" style="display:none;"><i class="fa fa-chevron-up"></i></div>');
}
if(options.useObjWindow) {
var parentWindow = this;
var scrollWindow = this;
}
else {
var parentWindow = window;
var scrollWindow = 'html, body';
}
$(document).ready(function() {
$('.scrollTop-btn').on('click', function() {
$(scrollWindow).animate({scrollTop:0}, options.scrollSpeed);
});
$(parentWindow).scroll(function() {
$('.scrollTop-btn').hide();
var aTop = $('.scrollTop-btn').height() + 20;
if($(this).scrollTop() >= (aTop + 20)) {
$('.scrollTop-btn').css('z-index', options.zIndex);
$('.scrollTop-btn').show();
}
else {
if($('.scrollTop-btn').is(":visible")) {
$('.scrollTop-btn').hide();
}
}
});
});
}
});
Call:
jQuery(document).ready(function() {
jQuery("body").addScrollTop();
});
How to make it slower or smoother, when it go to top?
use jquery animate()
$('html,body').animate({ scrollTop: 0 }, 'slow');
refer this stack overflow question
Only with CSS:
html {
scroll-behavior: smooth;
}
Using jQuery
If you want you can customize how much time you would like the "scrolling" to last. Or do something else when scroll effect is finished.
I have a: <a href="#" class="scrollToTop">
And want to scroll to an element with class "beginning"
$('.scrollToTop').on('click', function(event){
event.preventDefault();
$('html, body').stop().animate({scrollTop: $('.beginning').offset().top}, 500);
});
The last part where you have the 500. You can set there how much time you want the effect to last. In milliseconds.
http://api.jquery.com/animate/
Replace 'slow' with - Ex. 1000, 5000, 10000
$('html,body').animate({ scrollTop: 0 }, <milliseconds>);
// Scroll 2 sec
$('html,body').animate({ scrollTop: 0 }, 2000);
// Scroll 5 sec
$('html,body').animate({ scrollTop: 0 }, 5000);
I am experiencing extreme lag issues with my javascript code. Especially parallaxing is very slow. I expect that this results from multiple executions of the functions. Here is my code:
function tada() {
$(".arrow").addClass("tada");
setTimeout(function () {
$(".arrow").removeClass("tada");
}, 1000);
}
var j = 0;
function thumb() {
if(j < 18) {
setInterval(function () {
$('.equip-thumb').eq(j).css('opacity', '1');
j++;
}, 100);
}
}
$(document).ready(function(){
for (var i = 0; i < 18; i++) {
var color = "#1b1f25";
if ((i%3) === 0) {
color = "#1b222c";
}
if ((i%3) === 1) {
color = "#171c23";
}
if ((i%3) === 2) {
color = "#2a313b";
}
$('.equip-thumb').eq(i).css("background-color", color);
}
});
var fired = 0;
$(window).scroll(function(){
var wScroll = $(this).scrollTop();
var wHeight = $(this).height();
$(".arrow").css({
'opacity' : 1-wScroll/wHeight/0.5
});
$("#splash").css({
'transform' : 'translate(-'+ wScroll /10 +'% , 0px)',
'opacity' : 1-wScroll/wHeight/0.5
});
if(wScroll > ($('.section-equipment').offset().top - 0.6*wHeight)) {
if (fired === 0) {
fired = 1;
thumb();
}
}
});
$(function() {
setInterval(function () {
tada();
}, 4000);
$('.equip-thumb').on({
mouseover: function(){
$(this).children().css('transform', 'translate(0px, 0px)');
},
mouseleave: function() {
$(this).children().css('transform', 'translate(0px, 100%)');
},
click: function(){
$(this).siblings().children().css('transform', 'translate(0px, 100%)');
$(this).children().css('transform', 'translate(0px, 0px)');
}
});
$('#portfolio-a').click(function (){
$('html, body').animate({
scrollTop: $('.section-portfolio').offset().top - 65
}, 1000);
});
$('#equipment-a').click(function (){
$('html, body').animate({
scrollTop: $('.section-equipment').offset().top - 65
}, 1000);
});
$('#contact-a').click(function (){
$('html, body').animate({
scrollTop: $('.section-contact').offset().top - 65
}, 1000);
});
});
How could I improve it?
You should contemplate using requestAnimationFrame for animation, as the browser will invoke your callback before each repaint, thus it's a better guarantee that animations will be in sync with your monitor's refresh rate, Also, some browsers will make optimisations which ultimately result in more performant code.
Aside from the answers surrounding your use of setInterval, your scroll event callback could be wrapped in an invocation of requestAnimationFrame:
$(window).scroll(function () {
requestAnimationFrame(function (lastUpdate) {
var wScroll = $(this).scrollTop();
var wHeight = $(this).height();
$(".arrow").css({
'opacity' : 1-wScroll/wHeight/0.5
});
});
});
The lastUpdate parameter is a timestamp representing when queued callbacks begin to fire, so you could even use this to throttle your logic.
The code below will run forever. Because j < 18 initially, it will execute the setInterval function. However, there is nothing that is stopping the function from ending. Therefore, you are executing $('.equip-thumb').eq(j).css('opacity', '1') 10 times a second forever!
setInterval(function () {
$('.equip-thumb').eq(j).css('opacity', '1');
j++;
}, 100);
In order to fix this, you should create a for loop instead (to keep things simple) and use setTimeout instead of setInterval. I hope this helps!
I have this script were i want it to make an offset for 15% top of the id its scrolling to. I have try many things, so im kinda curious what approach you guys would take. I have stripped it down to what works, since all of my own attempts failed. Hope someone can help me out.
$('a[href*=#]').bind('click', function (e) {
e.preventDefault();
var target = $(this).attr("href");
$('html, body').stop().animate({ scrollTop: $(target).offset().top }, 800, function () {
location.hash = target;
});
return false;
});
i made a fiddle here: http://jsfiddle.net/77rFz/
I didn't try it, but I would say something like this could work:
$('a[href*=#]').bind('click', function (e) {
e.preventDefault();
var target = $(this).attr("href");
var offset = $(target).offset().top - $(target).height * 0.15;
$('html, body').stop().animate({ scrollTop: offset }, 800, function () {
location.hash = target;
});
return false;
});
Try something like this
Math.round(parseInt($(target).offset().top) * 0.15)
This worked!
$('a[href*=#]').bind('click', function (e) {
e.preventDefault();
var target = $(this).attr("href");
var parentDiv = $(this).parent(".wrap1");
var offset = Math.round(parseInt($(target).offset().top) - (0.15 * parentDiv.height()));
$('html, body').stop().animate({ scrollTop: offset }, 800, function () {
//location.hash = target;
});
return false;
});