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;
}
Related
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
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>
Smooth scrolling effect in JQuery not working in IE & Mozila Browsers, its fine in Chrome browser can any one help on this. iam using this code. some times working in mozila but in IE. please ignore stickit() function.
Thanks in Advance.
< script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js" > < /script> <
script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" > < /script> <
script src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" > < /script> <
script src = "scroll_110.js" > < /script>
$(document).ready(function() {
// Add scrollspy to <body>
$('a').scrollspy({
target: "a",
offset: 50
});
// Add smooth scrolling on all links inside the navbar
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('body').animate({
scrollTop: $(hash).offset().top
}, 1200, function() {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
// Create a clone of the menu, right next to original.
jquery('.menu').addClass('original').clone().insertAfter('.menu').addClass('cloned').css('position', 'fixed').css('top', '0').css('margin-top', '0').css('z-index', '500').removeClass('original').hide();
scrollIntervalID = setInterval(stickIt, 10);
function stickIt() {
var orgElementPos = jquery('.original').offset();
orgElementTop = orgElementPos.top;
if (jquery(window).scrollTop() >= (orgElementTop)) {
// scrolled past the original position; now only show the cloned, sticky element.
// Cloned element should always have same left position and width as original element.
orgElement = jquery('.original');
coordsOrgElement = orgElement.offset();
leftOrgElement = coordsOrgElement.left;
widthOrgElement = orgElement.css('width');
jquery('.cloned').css('left', leftOrgElement + 'px').css('top', 0).css('width', widthOrgElement).show();
jquery('.original').css('visibility', 'hidden');
} else {
// not scrolled past the menu; only show the original menu.
jquery('.cloned').hide();
jquery('.original').css('visibility', 'visible');
}
}
#top,
#middle,
#bottom {
height: 1600px;
width: 900px;
background: green;
}
.menu {
background: #fffff;
color: #333;
height: 40px;
line-height: 40px;
letter-spacing: 1px;
width: 100%;
}
<div class="menu">
Top
Middle
Bottom
</div>
<div id="top">
Top</div>
<div id="middle">
Middle</div>
<div id="bottom">
Bottom</div>
the solution would be to use both html and body in JQ -> $('html,body').animate
see below ( i removed the scrollspy code as it's not relevant to this question, but you should keep it )
$(document).ready(function() {
// Add scrollspy to <body>
// Add smooth scrolling on all links inside the navbar
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('html,body').animate({
scrollTop: $(hash).offset().top
}, 1200, function() {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
div {
height: 500px;
width: 100%;
background: red;
border-top: 10px solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>Section1</li>
<li>Section2</li>
<li>Section3</li>
</ul>
<div id ="section1">
</div>
<div id ="section2">
</div>
<div id ="section3">
</div>
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
In this example I am trying to slideToggel a part of the footer and also scroll to the bottom of the page and change the img to up.png. How do I add those 2 added funcationality to the slideToggle.
HTML
<li id="show_footer"><a><img src="images/footer/down.png" /></a></li>
<nav id="sub">
</nav>
CSS
nav#sub {
display: none;
}
SCRIPT
$("#show_footer").click(function() {
$("#sub").slideToggle("slow");
});
Try this code,
$("#show_footer").click(function() {
$("#sub").slideToggle("slow");
$("html, body").animate({ scrollTop: $(document).height() }, "slow");
if($('#sub:visible').length > 0){
$('#show_footer > a > img').attr('src', 'new/src/file/up.png');
}else{
$('#show_footer > a > img').attr('src', 'new/src/file/down.png');
}
});
This should do the trick. Edited because smooth scroll. THIS IS NOT TESTED.