I have this code to scroll the viewport height section-by-section when clicked on a fixed button until the end is reached. Then I want to fadeOut the button.
The HTML
<a class="cd-go">
<img class="scroll-swipe" src="<?php bloginfo('template_directory'); ?>/img/scroll_down_arrow.svg">
</a><!-- scroll btn -->
The js:
$(document).on('click', '.cd-go', function(event){
event.preventDefault();
var viewportHeight = $(window).height();
$('html, body').animate({
scrollTop: viewportHeight,
complete: function () {
$('.cd-go').fadeOut(300);
}
}, 500);
});
The problem is it is only scrollin from first to second section. How could this be section by section until the bottom?
EDIT:
Here's a fiddle: http://jsfiddle.net/cyt57dsj/7/
simply place $(document).height() instead of $(window).height() :)
You can keep track of the current section, and multiply viewportHeight by the current section. That way you can scroll section by section.
var currentSection = 0;
var totalSections = document.querySelectorAll("section").length;
$(document).on('click', '.cd-go', function(event){
event.preventDefault();
var viewportHeight = $(window).height();
currentSection++;
if (currentSection > totalSections - 1) currentSection = totalSections - 1;
$('html, body').animate({
scrollTop: viewportHeight * currentSection,
complete: function () {
$('.cd-swipe').slideDown(300);
}
}, 500);
});
.cd-go {
width: 209px;
background: rgba(0,0,0, 0.17);
height: 212px;
border-radius: 212px;
color: #fff;
position: fixed;
bottom: -106px;
text-align: center;
left: 0;
right: 0;
margin: 0 auto;
}
.w-sec {
height:100vh;
}
.w-sec:first-of-type {
background:#fff;
}
.w-sec:nth-of-type(2) {
background:#ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cd-go">
DOWN
</a><!-- scroll btn -->
<section id="section1" class="w-sec cd-section">
content
</section><!-- section 2 -->
<section id="section2" class="w-sec cd-section">
content
</section><!-- section 2 -->
<section id="section3" class="w-sec cd-section">
content
</section><!-- section 2 -->
Try this,
$(document).on('click', '.cd-go', function(event){
event.preventDefault();
var viewportHeight = $(document).height();
$("html, body").animate({
scrollTop: viewportHeight,
}, {
duration: 500,
complete: function () {
$('.cd-swipe').slideDown(300);
}
});
});
you are scrolling window instead of document
Related
I want to set top:0(offset:0) when image come in viewport on single scroll (like on every single scroll next image set to top 0 of image position or offset 0 of image) after completing scrolling all image, continue scrolling the page. Any one have any idea, JavaScript code for this?
Here is link for try out JsFiddle
<div class="main-div">
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb-
1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb-
1.2.1&auto=format&fit=crop&w=700&q=80">
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb-
1.2.1&auto=format&fit=crop&w=634&q=80">
</div>
</div>
.main-div {
box-sizing: border-box;
}
.sticky-div {
position: sticky;
top:0;
height:100vh;
}
if($(window).width() >= 1024){
(function($) {
var selector = ".home-product-slider .product-item";
var $slides = $(selector);
var currentSlide = 0;
var isAnimating = false;
var stopAnimation = function() {
setTimeout(function() {
isAnimating = false;
}, );
};
var bottomIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.bottom <= $(window).height();
};
var topIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.top >= 0;
};
document.addEventListener(
"wheel",
function(event) {
var $currentSlide = $($slides[currentSlide]);
if (isAnimating) {
event.preventDefault();
return;
}
var direction = -event.deltaY;
if (direction < 0) {
// next
if (currentSlide + 1 >= $slides.length) return;
if (!bottomIsReached($currentSlide)) return;
event.preventDefault();
currentSlide++;
var $slide = $($slides[currentSlide]);
var offsetTop = $slide.offset().top;
isAnimating = false;
$("html, body").animate(
{
scrollTop: offsetTop,
behavior: 'smooth'
},
stopAnimation
);
} else {
// back
if (currentSlide - 1 < 0) return;
if (!topIsReached($currentSlide)) return;
event.preventDefault();
currentSlide--;
var $slide = $($slides[currentSlide]);
var offsetTop = $slide.offset().top;
isAnimating = false;
$("html, body").animate(
{
// scrollTop: offsetTop
},
stopAnimation
);
}
{ passive: false }
},
);
})(jQuery);
//home page slider script end here
}
You're looking for scroll snapping. On the container that controls the scrolling set the scroll-snap-type: y mandatory rule. Here you say that there should be snapped in the y axis and that the snap should be honored without exceptions.
On the elements that you want snapped, use the scroll-snap-align property. Set this to start indicating that the start of the element that scrolls into view should fall on the snap grid.
Do beware, the combination of position: sticky and scroll snapping could lead to buggy behavior on Safari iOS. source
html,
body {
margin: 0;
overflow: hidden;
}
.main-div {
box-sizing: border-box;
width: 1000px;
height: 100vh;
max-width: 100%;
overflow-y: auto;
scroll-snap-type: y mandatory;
}
.sticky-div {
position: sticky;
top: 0px;
width: 100%;
max-height: 100%;
height: 750px;
scroll-snap-align: start;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="main-div">
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80">
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80">
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1601140958046-ce3c75269438?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80" />
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1559642147-97be7782c7b3?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80">
</div>
<div class="sticky-div">
<img src="https://images.unsplash.com/photo-1527435292159-ba44021581fa?ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80">
</div>
</div>
After getting my last problems solved properly I've got a second problem.
I've got a div which is fixed. Inside of the fixed div is another div which is scrollable. I want to achieve that if I scroll anywhere on the page, even out of the scrollable div, that the scroll action only applies to the scrollable div, not the fixed div.
I made an example of the problem. I want to achieve that if I am scrolling anywhere, even in the red part, that the scroll action is in the red div.
Demo:
$(window).scroll(function () {
var s = $(this).scrollTop();
var row1 = $('#row1');
if(s>500){
row1.css({
'position': 'relative'
});
}
});
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
overflow: scroll;
height: 100vh;
}
#row1 {
width: 100vw;
height:100vh;
position: fixed;
background-color:red;
}
.col-sm-6{width:50%;float:left;height:100px;}
#test{background-color:green;overflow-x:scroll;}
body{height:1000px}
<div class="row" id="row1">
<div class="col-sm-6"></div>
<div class="col-sm-6" id="test">scrollable div<br>test1<br>test2<br>test3<br>test4<br>test5<br>test6<br>test7<br>test8<br>test9<br>test10<br>test11</div>
</div>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
$(function () {
var myCounter = 0,
myOtherCounter = 0;
var scroll = 0;
$("#test").scroll(function () {
myCounter = myCounter + 1;
$("#log").html("<div>Handler for .scroll() called " + myCounter + " times.</div>");
});
//Firefox
$('#row1').bind('DOMMouseScroll', function (e) {
if (e.originalEvent.detail > 0) {
scrollDown();
} else {
scrollUp();
}
//prevent page fom scrolling
return false;
});
//IE, Opera, Safari
$('#row1').bind('mousewheel', function (e) {
if (e.originalEvent.wheelDelta < 0) {
scrollDown();
} else {
scrollUp();
}
//prevent page fom scrolling
return false;
});
function scrollDown() {
//scroll down
console.log('Down ' + scroll);
if (scroll < $('#test').find('div').height() - $('#test').height() + 20) {
scroll = $('#test').scrollTop() + 5;
$('#test').scrollTop(scroll);
}
};
function scrollUp() {
//scroll up
console.log('Up ' + scroll);
if (scroll > 0) {
scroll = $('#test').scrollTop() - 5;
$('#test').scrollTop(scroll);
}
};
});
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
overflow: scroll;
height: 100vh;
}
#row1 {
width: 100vw;
height:50vh;
position: fixed;
background-color:red;
}
.col-sm-6{width:50%;float:left;height:100px;}
#test{background-color:green;overflow-x:scroll;}
body{height:1000px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row" id="row1">
<div class="col-sm-6" id="test"><div>scrollable div<br>test1<br>test2<br>test3<br>test4<br>test5<br>test6<br>test7<br>test8<br>test9<br>test10<br>test11</div></div>
<div id="log"></div>
<div id="log2"></div>
</div>
I have a problem with jQuery.
I want to add the fixed-top class (Bootstrap 4) when scrolling the page, but this is not the case.
jQuery(document).ready(function($){
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
Can you see what I'm doing wrong?
Your scroll variable is never being updated. You need to add your code into a scroll event like so:
jQuery(document).ready(function($) {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 130) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
});
body {
margin: 0;
}
.foo {
height: 140vh;
background: black;
}
.robig {
width: 100%;
height: 10vh;
background: lime;
}
.fixed-top {
position: fixed;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo"></div>
<div class="robig"></div>
<div class="foo"></div>
However, if you are trying to recreate a sticking effect, I suggest you use position: sticky as jquery isn't needed for this:
body {
margin: 0;
}
.foo {
height: 140vh;
background: black;
}
.robig {
width: 100%;
height: 10vh;
background: lime;
position: sticky;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo"></div>
<div class="robig">Stop at top</div>
<div class="foo"></div>
Your code run on page load only but you need to run your code in scroll event of window
$(window).scroll(function(){
var scroll = $(window).scrollTop();
if (scroll >= 500)
$(".robig").addClass("fixed-top");
else
$(".robig").removeClass("fixed-top");
});
Also you can simplify the code and use .toggleClass() instead
$(window).scroll(function(){
$(".robig").toggleClass("fixed-top", $(window).scrollTop() >= 500);
});
$(window).scroll(function(){
$(".robig").toggleClass("fixed-top", $(window).scrollTop() >= 500);
});
p {height: 500px}
.robig {
width: 100%;
background: red;
}
.fixed-top {
position: fixed;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>content</p>
<div class="robig">robig</div>
<p>content</p>
<p>content</p>
$(document).ready(function(){
var scroll = 0;
$(document).scroll(function() {
scroll = $(this).scrollTop();
if(scroll > 500) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
});
You need to window scroll event. You can try below code
$(document).ready(function(){
$(window).scroll(function(){
if ($(this).scrollTop() >= 130)
{
$(".robig").addClass("fixed-top");
}
else
{
$(".robig").removeClass("fixed-top");
}
});
});
I added a link into my page to scroll down:
<div class="scroll">
<a onclick="scroll_down()" href="#" id="'scroll_id">
click me
</a>
</div>
<script>
function scroll_down() {
var y = $(window).scrollTop(); //current position
$("html, body").animate({scrollTop: y + $(window).height()}, 600);
}
function scroll_top() {
window.scrollTo(0, 0);
}
</script>
I want to set onclick attribute when bottom is reached to scroll_top.
scroll down is working but when bottom is reached , the attribute of theonclick of <a> tag is not changed.
<script>
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= $(document).height()) {
console.log('bootom')
$('#scroll_id').attr('onClick', '');
$('#scroll_id').attr('onClick', 'scroll_top()');
}
}
</script>
do some body tell me where is the error ? why it's not working?
Using the on* event attributes is considered bad practice - and amending them at runtime is worse.
A much better solution is to use a single unobtrusive event handler which determines the current scroll position of the page and moves up/down as necessary, like this:
$(function() {
$('#scroll_id').click(function(e) {
e.preventDefault();
var $win = $(window);
var scrollTarget = $win.height() + $win.scrollTop() >= $(document).height() ? 0 : $win.scrollTop() + $win.height()
$("html, body").animate({
scrollTop: scrollTarget
}, 600);
});
});
.scroll {
position: fixed;
top: 0;
left: 0;
z-index: 10;
}
#content {
height: 1000px;
position: relative;
}
#content div {
position: absolute;
}
#content .top {
top: 20px;
}
#content .middle {
top: 500px;
}
#content .bottom {
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroll">
click me
</div>
<div id="content">
<div class="top">top</div>
<div class="middle">middle</div>
<div class="bottom">bottom</div>
</div>
Syntax Error:
<a onclick="scroll_down()" href="#" id="'scroll_id">
it should be
id="scroll_id">
(removed extra ')
I have a function where I want to move the scroll down if it is at the top. But nothing happens, before and after the function value is still 0.
This is the code:
scrollDrawer = function () {
if (drawerIsUp) {
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
$('html, body').animate({
scrollTop: $(".middle").offset().top
}, 2000);
}
});
console.log($(window).scrollTop());
function winScroll() {
drawerDiv.style.top = (drawerDiv.offset + window.pageYOffset) + "px";
}
}
}
Updated
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $("html,body").scrollTop() < 92 && $("html,body").scrollTop() > 0) {
$("html,body").scrollTop(800)
}
});
console.log($(window).scrollTop());
I have updated the code and modifed it by applying suggestions from the answers, but still the scroll doesn't get relocated. I wonder if that is maybe since when the page opens it is already at top 0, and I need to relocate it immediately without scrolling from the user in the first place.
Html:
<div id="app">
<div id="bg">
</div>
#section('topBar')
#include('customer.layouts.partials.top-bar')
#show
<div id="main-section">
#section('header')
#include('customer.layouts.partials.header')
#show
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'drawer', 'carouselPadding' => ''])
#show
</div>
<div id="drawer">
<div id="magazine-detail">
</div>
<div id="magazine-detail-carousel">
#section('magazine-detail-carousel')
#include('customer.layouts.partials.carousel', ['function' => 'magazineDetail', 'carouselPadding' => 'carouselPadding'])
#show
</div>
</div>
</div>
CSS:
#main-section {
height: calc(100vh - 92px);
overflow-y: scroll;
width: 100%;
position: fixed;
overflow-y: scroll;
top:77px;
}
#drawer {
z-index: 5;
position: fixed;
top: 100vh;
height: calc(100vh - 92px);
max-height: 100%;
overflow-y: scroll;
width: 100%;
background-color: $white;
padding-left: 15px;
padding-right: 15px;
}
.top-bar {
position: fixed;
top: 0;
}
On click div drawer that is first not visible since it is below the vh, goes over the top of the main-section all the way up to where the top-bar starts. This is the animation:
$('#drawer').animate({
top: 92
}, 500);
And then after that animation I want the scroll to start from the bottom so that I can when the user starts scrolling move the drawer back down again by the amount of pixels a user has scrolled up.
Try this
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
// if want to animate scroll
$('html, body').animate({
scrollTop: $("body, html").offset(800)
}, 2000);
// otherwise
$("body, html").offset(800)
}
});
I think you make a mistake,you should addEventListener to window,and when the page init, window's scrollTop() eval 0,so your second example can't work.and the last,when the browser inited the page,all of console.log had excuted,so you would see two same result by console.log,you can try to move on into scroll function,so you can see the scrollTop of window when mouse scroll.
there are some example for you:
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 && $(window).scrollTop() > -1) {
$(window).scrollTop(800);
}
console.log($(window).scrollTop());
});
the other one:
scrollDrawer = function () {
if (1) {
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
$(window).scrollTop(800);
}
});
console.log($(window).scrollTop());
}
}
scrollDrawer();
This may not be exactly what you're looking for, but it is something that can work with a little css.
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 800) {
wrap.addClass("new");
} else {
wrap.removeClass("new");
}
});