Overriding JavaScript smooth scroll - javascript

I have this code that works fine to smoothly scroll to an anchor point on a page.
$('a[href^="#"]').click(function () {
$('html, body').animate({
scrollTop: $('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top
}, 800);
return false;
});
That works whenever I want to the smooth scrolling functionality. The problem I have is that I want to link to an anchor point without a smooth scroll for one particular link. How could I do that?

Add a property for the links that you want to have smooth scroll and make the condition below.
You can also make the inverse and add a property for the link that you don't want to have smooth scroll.
$('a[href^="#"]').click(function () {
if($.attr(this, 'behaviour') === "smooth") {
$('html, body').animate({
scrollTop: $('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top
}, 800);
} else {
$('html, body').scrollTop($('[name="' + $.attr(this, 'href').substr(1) + '"]').offset().top);
}
return false;
});
.section1 {
height: 700px;
background-color: pink;
}
.section2 {
height: 600px;
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<h1>Smooth Scroll</h1>
<div class="main section1" name="section1">
<h2>Section 1</h2>
<p>Click on the link to see the "smooth" scrolling effect.</p>
<a behaviour="smooth" href="#section2">Click Me to Smooth Scroll to Section 2 Below</a>
</div>
<div class="main section2" name="section2">
<h2>Section 2</h2>
Click Me to Scroll Instantaneously to Section 1 Above
</div>
</body>

Related

How to autoscroll with percentage or pixels in Javascript?

I have this code to auto scroll to a specific id.
My question is if there is the possibility of autoscroll not to an id but to a certain part of the page with pixels or percentage.
Thanks for the help.
This is the code I have
scrollTop: jQuery("#id").offset().top
}, 2000);
As per documentation of scrollTop it expects a numeric value. The same applies for the usage within animate.
So for a set pixel value just omit the function of getting the offset of an element and put in the value directly. Same goes for the percentage value but with a bit of math involved.
$(document).ready(function(){
// Add smooth scrolling to all links
$(".pixel").on('click', function(event) {
event.preventDefault();
$('html, body').animate({
scrollTop: 200 //set a numeric value to scroll a set amount of pixel
}, 800, function(){
});
});
$(".percent").on('click', function(event) {
event.preventDefault();
var windowHeight = window.innerHeight;
var percent = 90;
var percentPixel = windowHeight * (percent / 100); // calculate the amount of pixel off a percentage
$('html, body').animate({
scrollTop: percentPixel
}, 800, function(){
});
});
});
body, html, .main {
height: 100%;
}
section {
min-height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="pixel" href="#section2">Click Me to Smooth Scroll 200px</a>
<a class="percent" href="#section2">Click Me to Smooth Scroll 90%</a>
<div class="main">
<section></section>
</div>
<div class="main" id="section2">
<section style="background-color:blue"></section>
</div>
Source:https://www.w3schools.com/jquery/css_scrolltop.asp

On scroll take to specific location with jquery or javascript?

I'm not too sure how to describe this with words; but what I am planning to do is something like what this website has achieved: http://sapia.com.pe/
When you scroll down, it takes you to a specific point of the page, as well as when you scroll up. How could I do this using Jquery? Would any plugins be needed?
Check the SNIPPET below it will give you basic idea how it can be achieved
or you can use plugins like fullpage
var arr = ['_a','_b','_c'];
var i=0;
var doing=false;
$(window).bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
if(i==-1) i=2;
if(!doing){
$('html, body').animate({
scrollTop: $("#"+arr[i--]).offset().top
}, 600,function(){doing=false;});
doing=true;
}
}
else{
if(i==3) i=0;
if(!doing){
$('html, body').animate({
scrollTop: $("#"+arr[i++]).offset().top
}, 600,function(){doing=false;});
doing=true;
}
}
});
body{
overflow: hidden;
}
.section,html,body{
width:100%;
height:100%;
}
.a{ background-color:red; }
.b{ background-color:yellow; }
.c{ background-color:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="_a" class="section a"></div>
<div id="_b" class="section b"></div>
<div id="_c" class="section c"></div>

Href scroll to page with offset

How can I make the page scroll to my id
I am using the code below to make the pages croll to where I want it, but it only is triggered on page load
$('html,body').animate({
scrollTop: $(id).offset().top - 64
}, 'slow');
On the links that are clickable, only
href="page#a"
is used. This scrolls to the div but not to where I desire. Is there a way where I can also offset by 64pixels on href? Thanks
The id's css are as follows:
#a, #b {
margin-bottom: 64 px;
visibility: hidden;
position: absolute;
left: -999em;
}
var top_val = $('.test');
$('html, body').stop().animate({
scrollTop: top_val.offset().top
}, 'slow');
$(document).ready(function() {
function scroll (id) {
$(id).bind('click', function(event) {
event.preventDefault();
var $anchor = $(this).attr('href');
$('html, body').stop().animate({
scrollTop: ($anchor).offset().top - 64
}, 'slow');
});
}
scroll('#page1');
scroll('#page2');
});
<a href="" id="page1" >Visit W3Schools</a>
<a href="" id="page2" >Visit W3Schools</a>

Horizontal scrolling upon button click (viewport + scrollLeft)

I am pretty sure it's a very very easy question, but even after several hours of reading through Stackoverflow/Google.. still no luck.
I have a horizontal scrolling website, works great. Now i've added two buttons at the bottom of the screen (left/right).
If a visitor clicks on the 'right' button, i want the whole page to scroll to the next 'section', which is exactly $(window).width() pixels to the right.
My idea was to add so jquery that upon clicking the button ScrollLeft: $(window).width() + $(window).ScrollLeft().
Theoretically this would start with the first click scrolling rightwards exactly the width of the viewport. the 2/3/4 click it would start at the current ScrollLeft() position and once more add the viewport width.
the jquery that i use for this is the following (most likely it's somewhat bloated, jquery is not my strongsuit)
I've tried defining variables, break it down further etc. All to no avail.
$(".right a").on("click", function(event) {
event.preventDefault();
$("html, body").animate({
scrollLeft: $(window).scrollLeft() + $(window).width()
}, "slow"); //Animates the scroll
});
$(".left a").on("click", function(event) {
event.preventDefault();
$("html, body").animate({
scrollLeft: $(window).scrollLeft() - $(window).width()
}, "slow"); //Animates the scroll
});
-edit-
as requested here the HTML markup.
The articles inside #horz-wrap are actually scrolling.
<div class="sitewrap">
<div class="portfolio-wrapper">
<section id="horz-wrap">
<article class="post">
<!--section here-->
</article>
<article class="post">
<!--section here-->
</article>
</section>
</div>
<ul class="horz-nav">
<li class="left"><</li>
<li class="right">></li>
</ul>
--edit 2--
Upon request I just uploaded the page, live version: http://lauretf35.thirtyfive.axc.nl/laurens/test.html
Thanks!
Here's the change you need, you may still need some fix but this will help with scrolling.
JavaScript
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('table').animate({
scrollTop: target.offset().top - 100
}, 1000);
return false;
}
}
});
});
CSS:
table {
border-collapse: collapse;
border-spacing: 0;
position: absolute;
top: 200px;
width: 100%;
display: inline-block;
}

Having trouble getting the scroll animation to not trigger the scroll event

I currently have a number of div tags that can be seen below that are each the height of the viewport.
<!-- .current represents the div the user is currently viewing -->
<div class="full-height current" id="id1">
<div class="container">
</div>
</div>
<div class="full-height" id="id2">
<div class="container">
</div>
</div>
<div class="full-height" id="id3">
<div class="container">
</div>
</div>
<div class="full-height" id="id4">
<div class="container">
</div>
</div>
<div class="full-height" id="id5">
<div class="container">
</div>
</div>
I am attempting to implement a feature where upon a user scrolling, the window will scroll to the next div tag, always having only one div in view at a time. The way I implemented it works great, except for the fact that the animation triggers the scroll event again, resulting in an endless loop of the page scrolling once the user scrolls at all. I attempted to fix this by having a variable that will stop the event from triggering if the animation is in progress, but it does not seem to work. I am aware that I didn't do it for the scroll up, but I just wanted to see if it worked for the down first.
$(window).scroll(function(event) {
var scrollTop = $(this).scrollTop();
// If user scrolls down
if ((scrollTop > lastScrollTop) && $(".current").next("div").length > 0) {
if (animating == false) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000, function() {animating = false});
}
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").animate({
scrollTop: $(".current").offset().top
}, 1000);
}
}
lastScrollTop = scrollTop;
});
CSS included just in case. The 100vh - 111px is due to a fixed navbar at the top that is 111px high
/* Makes the element take up the entire height of the screen */
.full-height{
height: -o-calc(100vh - 111px); /* opera */
height: -webkit-calc(100vh - 111px); /* google, safari */
height: -moz-calc(100vh - 111px); /* firefox */
}
#id1 {
background-color: red;
}
#id2 {
background-color: blue;
}
#id3 {
background-color: yellow;
}
#id4 {
background-color: green;
}
#id5 {
background-color: purple;
}
If anyone could give me any ideas for fixing my problem, that would be great.
You'll want to stop the event and preventDefault. Here is some code from a current landing page:
$(document).ready(function () {
$('a.page-scroll').on('click', function(event) {
var link = $(this);
$('html, body').stop().animate({
scrollTop: $(link.attr('href')).offset().top - 50
}, 500);
event.preventDefault();
});
$('body').scrollspy({
target: '.navbar-fixed-top',
offset: 80
});
});
It uses bootstrap scrollspy so just ignore that. But notice that it stops any scroll animation that could be running and then also calls event.preventDefault() to stop the scroll event from bubbling and thus becoming recursive.
EDIT:
O.k. so I've a better look and the basic problem re: infinite scrolling is the code doesn't check if the scrollTop is already at 'where it needs to be'. You need an additional check to short circuit the scroll:
if (animating == false) {
if ($(this).scrollTop() == lastScrollTop) return;
if (($(this).scrollTop() > lastScrollTop) && $(".current").next("div")) {
console.log("down");
$(".current").next("div").addClass("current");
$(".current").first().removeClass("current");
animating = true;
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000,
function () { lastScrollTop = $(this).scrollTop(); animating = false; });
// If user scrolls up
} else {
if ($(".current").prev("div").length > 0) {
console.log("up");
$(".current").prev("div").addClass("current");
$(".current").last().removeClass("current");
$("html, body").stop().animate({
scrollTop: $(".current").offset().top
}, 1000, function () { lastScrollTop = $(this).scrollTop(); animating = false; });
}
}
}
Otherwise as it stands it will always either scroll up or down and never settle. That said with that "working" it's a terrible user experience. It will jump about since your scroll to code will fight the user on current scrollTop if they keep scrolling. i.e. your code will make it jump back to a previous position.
Try defining scroll event handler as named function ; defining lastScrollTop outside of scroll handler ; substituting .one() for .on() to allow animation to complete before re-attaching scroll event ; use .promise() which should be called at most once to avoid .animate() complete callback being called twice with selector "html, body" ; substituting single if to check for next or previous element .length and .animate() call for multiple if..else conditions and statements, animation function calls ; re-attach scroll event at .then() following animation completion .promise()
var lastScrollTop = 0;
function scroller(event) {
var scrollTop = $(this).scrollTop();
var direction = scrollTop > lastScrollTop ? "next" : "prev";
var el = $(".current")[direction](".full-height");
console.log(direction === "next" ? "down" : "up");
if (el.is("*")) {
$("html, body").animate({
scrollTop: el.offset().top
}, 1000).promise().then(function() {
console.log(this)
lastScrollTop = $(window).scrollTop();
$(".current")
.removeClass("current")[direction]("div")
.addClass("current")
setTimeout(function() {
$(window).one("scroll", scroller)
})
});
} else {
lastScrollTop = scrollTop;
$(window).one("scroll", scroller)
}
}
$(window).one("scroll", scroller);
/* Makes the element take up the entire height of the screen */
.full-height {
height: -o-calc(100vh - 111px);
/* opera */
height: -webkit-calc(100vh - 111px);
/* google, safari */
height: -moz-calc(100vh - 111px);
/* firefox */
}
#id1 {
background-color: red;
}
#id2 {
background-color: blue;
}
#id3 {
background-color: yellow;
}
#id4 {
background-color: green;
}
#id5 {
background-color: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- .current represents the div the user is currently viewing -->
<div class="full-height current" id="id1">
<div class="container">
</div>
</div>
<div class="full-height" id="id2">
<div class="container">
</div>
</div>
<div class="full-height" id="id3">
<div class="container">
</div>
</div>
<div class="full-height" id="id4">
<div class="container">
</div>
</div>
<div class="full-height" id="id5">
<div class="container">
</div>
</div>
If you define height 100vh ,scroll event wont trigger

Categories

Resources