force stop scrolling on reaching the end of a scrollspy section - javascript

here is a fiddle to know where I am starting from
The problem I am looking to solve involves "paginating" content of a single html file, in such a way that locks them into a single section at a time. I want it so that when users scroll to the bottom of a section, it will slide up a prompt to move to the next page, which will fire a transition, such as different easing/from bottom and put them "in" the next section.
This would be repeated in the next section; when they scroll to the top, they will get a "previous" button but be unable to move unless they click "previous". If they hit the bottom, they will be unable to move to the next page without clicking "next". If they click a section tab, it would do the transition and bring them to that page from their current
I know that this will stop scrolling, but how do I modify it such that it will prevent scrolling in this way?
$('body').on({
'mousewheel': function(e) {
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
})

You can just have the window continue to scroll back to the element by using window.scrollTo.
I get the top bottom position and the height of the element, and then when the element is in view of the window I scollTo the difference between the window innerHeight and the elements position.
var el = document.querySelector('.stop');
window.addEventListener('scroll', function (e) {
var elementPos = el.getBoundingClientRect(),
elBot = elementPos.bottom,
elHeight = elementPos.height,
curTop = window.pageYOffset || document.documentElement.scrollTop;
if(elBot <= window.innerHeight-elHeight){
window.scrollTo(0,curTop-(window.innerHeight - elBot));
}
});
Live Demo
And a more complete example with clicking to move on, just to illustrate further.

Related

How to detect if the user is still trying to scroll when the bottom of the page is already reached?

At the bottom of the page I have three <div>s, each representing a step.
As they become completely visible when the user scrolls all the way to the bottom of the page, I want to advance a CSS animation whenever the user tries to further scroll(beyond the bottom of the page),and highlight a different one of the three steps as the user scrolls. The animation will consist of a rocket ship icon that will move from the left to the right of as the user keeps trying to scroll, and the current step being highlighted with a lighter color- functioning as a progress bar, indicating the current step.
However, the dilemma is that I can't seem to detect scroll events after the scroll bar has already reached the bottom of the page. How do I do I get an event handler to pick up these scroll attempts?
Here's the event handler I have set up that isn't called after the bottom of the page has already been reached:
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("You're at the bottom of the page");
}
};
Here's the three steps I want to advance through:
Use onwheel event:
window.onwheel = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("You're at the bottom of the page");
}
};

Media Element Player Exit Full Screen Scrolling Issue

I have long web page that scrolls vertically with several videos. Using Media Element Player, the videos play, but if you enter full screen mode and then exit full screen mode, the page returns to the very top, regardless of where the video is on the page. I want it to return to the same place. Here is the code I'm using:
var topPosition;
MediaElementPlayer.prototype.enterFullScreen_org =
MediaElementPlayer.prototype.enterFullScreen;
MediaElementPlayer.prototype.enterFullScreen = function() {
console.log('enter full screen');
this.enterFullScreen_org();
topPosition = window.pageYOffset;
console.log(topPosition);
}
MediaElementPlayer.prototype.exitFullScreen_org =
MediaElementPlayer.prototype.exitFullScreen;
MediaElementPlayer.prototype.exitFullScreen = function() {
console.log('exit full screen')
this.exitFullScreen_org();
ResetFullScreen();
}
function ResetFullScreen() {
console.log('top pos:', topPosition);
setTimeout(function () { window.scrollTo(0, topPosition) }, 500);
}
The console.log shows the correct value for "topPosition" but the window.scrollTo method doesn't appear to work.
Looking through your code, it appears that it should work. I do, however, have one more method to setting the scroll that may work. This will be useful if the element you're trying to scroll is not at the top level.
When storing the scroll position:
topPosition = document.body.scrollTop;
When setting the scroll position:
document.body.scrollTop = topPosition;
If what you're trying to scroll is an element within the body, and not the body itself, just replace document.body with the element you need to scroll.
Also, I found a little thing in your code:
MediaElementPlayer.prototype.enterFullScreen;'
There's a random quote at the end of that line.
EDIT:
If that method does not work, I have one more idea for you. When they click on the video they view, store the element that they clicked on in a variable. After leaving fullscreen, scroll the element into view. That way, you will be, more or less, where the screen was when it entered fullscreen.
Each video has an onclick containing the following; this stores the element they clicked on.
lastVideoClicked = event.target;
When leaving fullscreen, this code will attempt to scroll that element back into view.
lastVideoClicked.scrollIntoView();
You can try it out on the Stack Overflow site right here - scroll to the bottom of the page, open your javascript console, and enter the code document.getElementById('hlogo').scrollIntoView(). This scrolls the Stack Overflow logo into view.

jQuery resetting scroll of window after scrollTop() call

I have an off canvas menu that slides in from the right and sits on top of the page. To prevent a scroll bar I am setting the content section's position to fixed while the menu is open. Problem is, when I close the menu the scroll position on the page is lost, the user is returned to the top of the page.
I am trying to store the scroll position of the page and then set the scroll when the window is closed, but its not working. If I debug the code I can see the scrollTop() functioning as expected, but then it goes into the jQuery.js script and after several function calls it resets the scroll to the top of the page.
What am I doing wrong?
var scrollPos;
function openMenu() {
$('body').addClass('open');
}
function closeMenu(compat) {
$('body').removeClass('open');
}
/*** Event Handlers ***/
$('#js-menu-toggle').on('click', function() {
scrollPos = $(window).scrollTop();
openMenu();
});
$('#js-menu-close').on('click', function() {
closeMenu();
$(window).scrollTop(scrollPos);
});
My apologies for not providing enough of an MCVE.
It turns out the problem was the events were bound to an <a> link with a "#" href, so adding in
return false;
as the last line of the .on events solved my problem.

Switch tabs based on mouse scroll

I would like to have a widget on a webpage containing a number of tabs. When the user scrolls the page and the widget comes in to view and he keeps scrolling down, the tabs should be activated one by one (without the page scrolling further down). Once the last tab is showing, the page should resume scrolling as usual. Is this doable using JS/jQuery?
UPDATE:
Since this seems too broad a question:
The problem is, I don't know how to use the scroll offset and prevent the page from scrolling down until I decide it can resume its normal behavior
UPDATE 2
I created This fiddle,
$(document).ready(function(){
$('#tabbed').mouseover(function(){
$(this).focus();
}).scroll(function(){
console.log("scrolling tabs");
});
$(window).scroll(function(evt){
var scrollPos = $(this).scrollTop()
console.log(scrollPos);
// BULLETPROOF WAY TO DETECT IF THE MOUSE IS OVER THE
// SCROLLABLE DIV AND GIVE IT FOCUS HERE?
});
});
it contains a long page and a scrollable div among its contents. The only problem is that the div starts catching scroll events only if I move my mouse. If I could find a bulletproof way to activate the scrolling div whenever the mouse is over it I'm there. Any ideas?
You can't prevent scrolling with javascript. Using iframes and divs with scroll will only work if the mouse is over them.
You can cancel the mouse wheel and keys events related to the scrolling, however the user will be able to scroll using the scrollbar (more here).
Another approach is leaving an empty area and fixing your widget inside this area, like in this working example
$(window).bind('scroll', function()
{
var scroll = $(window).scrollTop(),
innerHeight = window.innerHeight || $(window).height(),
fooScroll = $('#fooScroll'),
emptyArea = $('#emptyArea'),
offset = emptyArea.offset(),
fixedClass = 'fixed';
if(scroll > offset.top)
{
if(scroll < offset.top + emptyArea.height() - fooScroll.height())
{
fooScroll.addClass(fixedClass);
fooScroll.css("top", 0);
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", emptyArea.height() - fooScroll.height());
}
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", 0);
}
});
Then you can change the tabs while the page is scrolling.
You should be able to do this. You can use the jQuery scroll event to run your own code whenever the user scrolls up or down. Also, so long as you call e.preventDefault() whenever the scroll event is fired, you can prevent the whole window from scrolling up or down.

How would I scroll horizontally to the next article in a page (or #, etc.)?

I'm trying to work with a jQuery script I found at http://marcgrabanski.com/articles/scrollto-next-article-button-jquery that allows me to set up "next" and "previous" buttons that scroll the user through a page from one article to the next (or previous). The idea is that the button would stay in a fixed position and clicking the button multiple times would keep the user scrolling on to the next article (or other element).
I have a page that scrolls horizontally, so I want to adapt the code so that instead of finding the top of each h2 in the container, it finds the left side of each h2 and scrolls the user horizontally and not vertically. Here is the code I'm using:
jQuery(function($){
$('<div id="next_arrow">Next</div>')
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollTop = $(window).scrollTop();
$('#container h2').each(function(i, h2){ // loop through article headings
h2top = $(h2).offset().top; // get article heading top
if (scrollTop<h2top) { // compare if document is below heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});
Any help is greatly appreciated in advance. Thank you.
jP
#paulGraffix, #ShankarSangoli, and #esses thank you for your responses.
As a follow-up to my last question, how would I go about limiting the scroll to scroll horizontally only?
If you click on the arrows at the top of http://174.121.134.126/~methfree/ the window will scroll vertically (as well as horizontally) if the browser window is small enough to scroll vertically. Is there any way to add a scroll-x (or something like that) to the script to limit the scroll to horizontal only?
Thanks,
jP
Basically you should just be able to switch out all the vertical references to horizontal ones and it should work. Try something like this:
jQuery(function($){
$('<div id="next_arrow">Next</div>')
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollLeft = $(window).scrollLeft();
$('#container h2').each(function(i, h2){ // loop through article headings
h2Left = $(h2).offset().left; // get article heading left
if (scrollLeft<h2Left) { // compare if document is left of heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});
you may be able to modify your code using offsetLeft (or offsetRight) instead of using (window).scrollTop.
this link may be helpful: http://unknownerror.net/2011-04/top-clienttop-scrolltop-offsettop-the-difference-between-memo-4017
Try this
jQuery(function($){
$('<div id="next_arrow">Next</div>') //item to be added
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollLeft = $(window).scrollLeft();
$('#container h2').each(function(i, h2){ // loop through article headings
h2left = $(h2).offset().left; // get article heading left
if (scrollLeft < h2Left) { // compare if document is below heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});

Categories