How to make an element scroll when scrolling body - javascript

When the mousewheel is scrolled on the body of a page this event can be captured. I'd like this event to trigger a target element to scroll.
#target is a scrollable element that is never the height of the page. I'd like to capture the mousescroll event anywhere on the page so even if the cursor is not over the element the element still scrolls.
$( 'body' ).on( 'DOMMouseScroll mousewheel', function () {
// Scroll #target instead of body
});
Thanks to this post for showing me how to capture scroll wheel events: Capturing Scroll Wheel Events

You can have a look at this.
http://jsfiddle.net/ZtGva/7/
JS
$(function () {
var myCounter = 0,
myOtherCounter = 0;
var scroll = 0;
$("#target").scroll(function () {
myCounter = myCounter + 1;
$("#log").html("<div>Handler for .scroll() called " + myCounter + " times.</div>");
});
//Firefox
// $(document).bind(...) this works as well
$('#body').bind('DOMMouseScroll', function (e) {
if (e.originalEvent.detail > 0) {
scrollDown();
} else {
scrollUp();
}
//prevent page fom scrolling
return false;
});
//IE, Opera, Safari
$('#body').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 < $('#target').find('div').height() - $('#target').height() + 20) {
scroll = $('#target').scrollTop() + 5;
$('#target').scrollTop(scroll);
}
};
function scrollUp() {
//scroll up
console.log('Up ' + scroll);
if (scroll > 0) {
scroll = $('#target').scrollTop() - 5;
$('#target').scrollTop(scroll);
}
};
});
Note I added a div for height calculation
<div id="target"><div>.... </div></div>
You can clean up this code a bit by caching some jquery variables but the idea is there

Related

About "paragraph sliding" in html

I want to achieve such a function as paragraph sliding (I don't know how to explain paragraph sliding)
So I just put it on the website for you to see
(It may take a while to enter)
https://grayraven.tw/
Like this one after another
I tried to write it myself, but there was no response after I wrote it
Below is my code
var mousewheel = (/Firefox/i.test(navigator.userAgent)) ?
"DOMMouseScroll" : "mousewheel";
var IDK = 1
slide.addEventListener(mousewheel,
function (e) {
if (e.wheelDelta > 0 || e.detail < 0) {
IDK + 1
$("html,body").animate({scrollTop: $("#" + IDK ).offset().top}, 1000);
} else {
if(IDK=1){
console.log("NO")
}else{
IDK - 1
$("html,body").animate({scrollTop: $("#" + IDK ).offset().top}, 1000);
}
}
}, false);
If you can tell me how to write, thank you very much
My English is not very good, please forgive me
Did you mean this?
//Set each section's height equals to the window height
$('section').height($(window).height());
/*set the class 'active' to the first element
this will serve as our indicator*/
$('section').first().addClass('active');
/* handle the mousewheel event together with
DOMMouseScroll to work on cross browser */
$(document).on('mousewheel DOMMouseScroll', function (e) {
e.preventDefault();//prevent the default mousewheel scrolling
var active = $('section.active');
//get the delta to determine the mousewheel scrol UP and DOWN
var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
//if the delta value is negative, the user is scrolling down
if (delta < 0) {
//mousewheel down handler
next = active.next();
//check if the next section exist and animate the anchoring
if (next.length) {
/*setTimeout is here to prevent the scrolling animation
to jump to the topmost or bottom when
the user scrolled very fast.*/
var timer = setTimeout(function () {
/* animate the scrollTop by passing
the elements offset top value */
$('body, html').animate({
scrollTop: next.offset().top
}, 'slow');
// move the indicator 'active' class
next.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 800);
}
} else {
//mousewheel up handler
/*similar logic to the mousewheel down handler
except that we are animate the anchoring
to the previous sibling element*/
prev = active.prev();
if (prev.length) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: prev.offset().top
}, 'slow');
prev.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 800);
}
}
});
body, html {
margin:0;
padding:0;
overflow:hidden;
}
section {
height:100vh!important;
font-size:30px;
display:flex;
justify-content:center;
align-items:center;
color:white;
}
.bg1{background-color:#FAAD80;}
.bg2{background-color:#FF6767;}
.bg3{background-color:#FF3D68;}
.bg4{background-color:#A73489;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="bg1">First</section>
<section class="bg2">Second</section>
<section class="bg3">Third</section>
<section class="bg4">Fourth</section>

Scroll to bottom of page using Javascript or jquery with these conditions

I am trying to stimulate a web chat room for which the page needs to be:
Scrolled to bottom of the page after some interval if the user hasn't scrolled.
Stop scrolling if the user has scrolled.
Starts scrolling to bottom of page if user reaches a div #end
<script>
var scroll = 1;
function autoScrolling(scroll) {
if(scroll==1){
window.scrollTo(0,document.body.scrollHeight);
}
}
window.onscroll = function() {
setInterval(autoScrolling(0), 1000);
}
window.addEventListener("scroll", function() {
var elementTarget = document.getElementById("end");
if (window.scrollY > (elementTarget.offsetTop + elementTarget.offsetHeight)) {
scroll=1;
setInterval(autoScrolling(0), 1000);
}
});
</script>
I am applying this logic but it isn't working.
Try this,
var scrolled = false;
$(document).ready(function(){
//First requirement
window.setInterval(function(){
checkScroll();
}, 5000);
//Second requirement
window.onscroll = function() { setScroll()};
//Third requirement
$('#end').on('scroll', function() {
if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
autoScroll();
}
})
})
function autoScroll(){
window.scrollTo(0,document.body.scrollHeight);
}
function setScroll(){
if (window.scrollY > (elementTarget.offsetTop + elementTarget.offsetHeight)) {
scroll=true;
}
}
}
function checkScroll(){
if(!scrolled)
autoScroll();
scrolled = false;
}

jQuery scrollTop() returns wrong offset on scroll-direction change

I'm trying to get the correct scroll direction via jQuery's "scroll" event.
For this, I'm using the solution here: https://stackoverflow.com/a/4326907/8407840
However, if I change the direction of my scroll, the offset returned by scrollTop is incorrect on the first time. This results in the following behavior:
Wheel down -> down
Wheel down -> down
Wheel up -> down
Wheel up -> up
Wheel down -> up
Wheel down -> down
... and so on, I think you get it.
var ACTIVE_SECTION = null;
var ANIMATION_DURATION = 700;
$(document).ready(function() {
ACTIVE_SECTION = $("section:first-of-type").get(0);
var prevPosition = $(window).scrollTop();
$(window).on("scroll", function() {
doScrollingStuff(prevPosition);
});
});
function doScrollingStuff(prevPosition) {
var ctPosition = $(window).scrollTop();
var nextSection = ACTIVE_SECTION;
// Remove and re-append event, to prevent it from firing too often.
$(window).off("scroll");
setTimeout(function() {
$(window).on("scroll", function() {
doScrollingStuff(prevPosition);
});
}, ANIMATION_DURATION + 100);
// Determine scroll direction and target the next section
if(ctPosition < prevPosition) {
console.log("up");
nextSection = $(ACTIVE_SECTION).prev("section").get(0);
} else if(ctPosition > prevPosition) {
console.log("down");
nextSection = $(ACTIVE_SECTION).next("section").get(0);
}
// If a next section exists: Scroll to it!
if(typeof nextSection != 'undefined') {
var offset = $(nextSection).offset();
$("body, html").animate({
scrollTop: offset.top
}, ANIMATION_DURATION);
ACTIVE_SECTION = nextSection;
} else {
nextSection = ACTIVE_SECTION;
}
console.log(ACTIVE_SECTION);
prevPosition = ctPosition;
}
section {
width:100%;
height:100vh;
padding:60px;
box-sizing:border-box;
}
section:nth-child(1) { background:#13F399; }
section:nth-child(2) { background:#14FD43; }
section:nth-child(3) { background:#4EE61E; }
section:nth-child(4) { background:#BEFD14; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="sect1">Section 1</section>
<section id="sect2">Section 2</section>
<section id="sect3">Section 3</section>
<section id="sect4">Section 4</section>
Here's a pen, where you can see my implementation: https://codepen.io/EigenDerArtige/pen/aVEyxd
I am trying to accomplish an autoscroll to the next or previous section, whenever the user scrolls or swipes up/down... Therefore I only fire the "scroll"-event once every second, to prevent multiple scrolljacks all happening at once... However the above behavior seems to result in the user being scrolled to the wrong section.
I've been trying for a couple of hours now to get it working, but to no avail. Help is greatly appreciated!
The problem lies in the assignment prevPosition = ctPosition.
Each time the scroll handler runs, var ctPosition = $(window).scrollTop(); is good for determining scroll direction, however it's not the value that should be rememberad as prevPosition.
prevPosition needs to be $(window).scrollTop() as measured after the animation has completed.
Try this :
$(document).ready(function() {
var ANIMATION_DURATION = 700;
var ACTIVE_SECTION = $("section:first-of-type").eq(0);
var prevPosition = $(window).scrollTop();
$(window).on("scroll", doScrollingStuff);
function doScrollingStuff(e) {
$(window).off("scroll");
var ctPosition = $(window).scrollTop();
var nextSection = (ctPosition < prevPosition) ? ACTIVE_SECTION.prev("section") : (ctPosition > prevPosition) ? ACTIVE_SECTION.next("section") : ACTIVE_SECTION; // Determine scroll direction and target the next section
// If next section exists and is not current section: Scroll to it!
if(nextSection.length > 0 && nextSection !== ACTIVE_SECTION) {
$("body, html").animate({
'scrollTop': nextSection.offset().top
}, ANIMATION_DURATION).promise().then(function() {
// when animation is complete
prevPosition = $(window).scrollTop(); // remember remeasured .scrollTop()
ACTIVE_SECTION = nextSection; // remember active section
$(window).on("scroll", doScrollingStuff); // no need for additional delay after animation
});
} else {
setTimeout(function() {
$(window).on("scroll", doScrollingStuff);
}, 100); // Debounce
}
}
});

Turning jQuery event listener on after off

So I want to turn off a jQuery event under a certain condition (if the user scrolls down) but if they do the opposite (scroll up) then I want the event turned to on so that it will fire.
This is my code but as I am new to jQuery, I am pretty sure I'm missing something in the handler - I just don't know what it should be.
Here is the code:
function myFunction() {
var handler = function(e){
//code here
}
var position = $(window).scrollTop();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if(scroll > position) {
// scrolling downwards
$(window).off("scroll", handler);
}
if(scroll < position) {
//scrolling upwards
$(window).on("scroll", handler);
hypeDocument.showPreviousScene(hypeDocument.kSceneTransitionPushTopToBottom, 1.1)
}
position = scroll;
});
}
try using an if-else statement instead of two ifs
$(function()
{
var handler = function(e){
// hypeDocument.showPreviousScene(hypeDocument.kSceneTransitionPushTopToBottom, 1.1)
console.log('handler');
}
var position = $(window).scrollTop();
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > position) {
// scrolling downwards
// NOTHING
}
if(scroll < position) {
//scrolling upwards
handler();
}
position = scroll;
});
});
Open console and you'll see "handler" in output each time you scroll up.
You need to add scroll handler after document.ready event:
$(function() {
/* YOUR CODE HERE */
});
I think you doing wrong trying to subscribe and unsubscribe your handler.
You should just determine the direction of scroll as you do.
Then if it is right direction – call your handler:
if (scroll < position) {
//scrolling upwards
handler();
}
Update 3: in future you could do this instead.
var nT = $(window).scrollTop, pos = nT(), func = function(e){ /*code here*/ };
$(window).scroll(()=>(nT()<pos)&&(pos=nT(),func())); //make people hate you.
Update 2: and to make it even smaller..
var newTop = $(window).scrollTop, position = newTop(),
handler = function(e){ /*code here*/ };
$(window).scroll(function() {
(newTop()<position)&&(position=newTop(),handler());
});
Update: Or you could make it even better
var newTop = $(window).scrollTop, position = newTop();
var handler = function(e){
//code here
};
$(window).scroll(function() {
var scroll = newTop();
if(scroll < position) handler();
position = scroll;
});
Use Boolean variable instead of attaching/detaching event.
var disabled= false,
newTop = $(window).scrollTop,
position = newTop();
var handler = function(e){
if (disabled) return;
//code here
};
$(window).scroll(function() {
var scroll = newTop();
if(scroll > position) disabled=true;
else disabled=false;
position = scroll;
});

Force "overscrolling" at Chrome/Mac with javascript

When you get to the limit of document, you can keep scrolling and can see an background behing the document before it bounces back (overscrolling).
How can I force the window to overscroll like this with javascript?
This is not the ultimate solution since I think the animation is imperfect and it's really only for desktops, but it can at least get you started. What I have done is increase the height of the body for animation on scroll.
$(document).on('scroll mousewheel', function (e) {
//Check for mousewheel scrolling down (or not used at all)
if (!e.originalEvent || !e.originalEvent.wheelDeltaY
|| e.originalEvent.wheelDeltaY < 0) {
if ($(window).height() + $(this).scrollTop() == $(this).height()) {
//Prevent simultaneous triggering of the animation
if (!$("body").data('bouncing')) {
$("body").height(function (_, h) { return h + 15; })
.data('bouncing', true);
$("body, html").animate({
'scrollTop': '+=15'
}, 125).animate({
'scrollTop': '-=15'
}, {duration: 125, complete: function () {
$(this).height(function (_, h) { return h - 15; })
.data('bouncing', false);
}});
}
}
}
}).on('keydown', function (e) {
//The "down" arrow; still bounces when pressed at the bottom of the page
if (e.which == '40') {
$(this).trigger('scroll');
}
});
I've been playing with this version that imitates the effect using a div, that slides in and out of view at the bottom of the page. If you have a high res monitor, you may need to increase the height of the main div to test it.
<div id="main" style="background:#f5f5f5;height:1000px"></div>
<div id="overscroll" style="background:#666666;height:120px"></div>
<script type="text/javascript">
var $doc = $(document);
$doc.ready(function () {
var $wnd = $(window),
$oscroll = $('#overscroll'),
block = false;
$wnd.bind('scroll', function () {
if (!block) {
block = true;
var scrollTop = $wnd.scrollTop(),
wndHeight = $wnd.height(),
docHeight = $doc.height();
try {
if (scrollTop + (wndHeight + 120) > docHeight) {
$oscroll.slideUp('slow');
}
else if ($oscroll.css('display') === 'none'
&& (scrollTop + (wndHeight + 120) < docHeight)) {
$oscroll.slideDown();
}
} finally {
block = false;
}
}
});
});
</script>

Categories

Resources