I'm using FullPage with scrollOverflow: true and I need to scroll to a certain position in a scrollable section. FullPage uses forked version of iScroll plugin for those overflow sections.
So what I'm doing is:
fire FullPage scroll to section
find instance of iScroll in that section and fire it's scrollTo() event
reBuild() FullPage
The scroll positions of both plugins change correctly, but the problem seems to be that FullPage doesn't register iScroll's scrollTo() event and behaves like the active section is scrolled to the top, so basically scrolling up gets you to previous section and scrolling down gets you under the content eventually.
document.querySelector('.button').addEventListener('click', e => {
fullpage_api.moveTo(3)
fullpage_api.getActiveSection().item.querySelector('.fp-scrollable').scrollTo(0, 1000, 1000)
fullpage_api.reBuild()
})
Here is a simplified version of my code with the bug reproduced: https://jsfiddle.net/5bojtrmd/13/
after clicking the button, you can't get to the section 3 title anymore and you can scroll to red zone which shouldn't be seen
Few things:
You need to use a negative value for the iscroll scrollTo y position.
You won't have to call the refresh function of fullPage.js but the one from iScroll.
Code here:
document.querySelector('.button').addEventListener('click', e => {
fullpage_api.moveTo(3)
var instance = fullpage_api.getActiveSection().item.querySelector('.fp-scrollable').fp_iscrollInstance;
instance.scrollTo(0, -1050, 1000);
setTimeout(function () {
instance.refresh();
}, 1000 + 150);
});
Reproduction online.
Related
I'm adding a back to top button fixed to bottom of the browser window. When clicked, it scrolls to top in desktop and Android, but not iPhone. On the iPhone, the scrollTo event reveals the address bar and the bottom mobile button bar, but does not return the user to the top of the page.
EDIT: The address bar and button bar on the iPhone appears when a touch event occurs within 20-30px of the bottom of the screen. This is why this back to top button doesn't work. Moving it 40px up stops the address/button bars from appearing.
I've attempted to just place it raw:
$('#scroll-to-top-button').on('click', function() {
window.scrollTo(0,0);
});
And with a timer:
$('#scroll-to-top-button').on('click', function() {
window.setTimeout(function() {
window.scrollTo(0,0);
}, 500);
});
I tried using scrollTop, which had the same results: browser button bar and address bar appear, but no scroll.
I also tried initiating the scrollTo and at the same time setting a timeOut with another scrollTo. The timeout never fires.
I did also try scrolling html or body, or a combination of the two:
$('#scroll-to-top-button').on('click', function() {
$('html,body').animate({
scrollTop: 0,
}, 200);
});
Only html
$('#scroll-to-top-button').on('click', function() {
$('body').animate({
scrollTop: 0,
}, 200);
});
only body
$('#scroll-to-top-button').on('click', function() {
$('html').animate({
scrollTop: 0,
}, 200);
});
I've tried resetting the button to an anchor tag and trying to get it to link within the page. This doesn't work with just basic html anchor functionality:
<div id="main-body"> ... lots of content forcing scrollbars to appear ... </div>
<a id="scroll-to-top-button" class="btn btn-default" href="#main-body">Back to Top</a>
And tried preventing default and animating the link to the anchor:
$('#scroll-to-top-button').on('click', function(e) {
e.preventDefault();
$('html,body').animate({
scrollTop: 0,
}, 200);
});
Here's a link demonstrating the problem. In this link, the code is using one of my last examples down this question, where it's purely an anchor tag trying to link to top of page.
http://willanni.com/dev/iphone-scroll/
I thought maybe missing the viewport tag might be causing it, so I added the following: <meta name="viewport" content="width=device-width, initial-scale=1">. However. When I add that in, it still does not make it work.
Besides forcing the address bar and button bar to always be visible in iPhone, is there a way to get this to scroll to top of window in iPhone? (Note: iPad doesn't have this issue, though it had a different weird issue that required the timeout to fix. Different story though)
Try using jQuery animate on body and html:
$("BODY,HTML").animate({
scrollTop: 0
}, 100);
// second parameter is time so adjust it if you please
The answer is that there really is no way to do this without forcing the address/buttons bar to be always visible.
The iPhone captures any touch event within about 20-30px of the bottom of the screen, and displays the address and bottom buttons bar. No page script, button, or links are triggered or registered as touched until the bar is revealed. A position: fixed, bottom: 0; button then is not able to be activated until the second touch:
First touch reveals the bottom button bar (and address bar)
Second touch activates whatever button/script/anchor functionality is in place
Adding an event listener to the window doesn't capture a touch event in that area of the screen while the button bar is hidden. For example, in order to test I set a timeout to allow myself a bit of time to scroll down and hide the bottom bar. In all areas of the screen except the bottom, this worked:
window.addEventListener('touchstart', function() {
setTimeout(function() {
alert('touchstart');
}, 500);
});
In that bottom region, nothing.
So, in effect, to have a button attached to the bottom of the screen work on first click, you'll need to apply some hacky css to the body and html tags to force the address and button bars to always appear:
html,body {
-webkit-overflow-scrolling: touch !important;
overflow: auto !important;
height: 100% !important;
}
I am trying to implement a document navigation, similar to that on the Bootstrap site for their documentation. I've got it working on the whole, but there is one little aspect of it which is bugging me.
Like on Bootstrap, I am using a combination of the affix.js and scrollSpy.js, and this is working. See the following
JSFiddle.
$('#doc_nav').on( "click", "a", function( e ){
// e.preventDefault();
var target = this.hash;
var $target = $(target);
var offset = $target.offset().top;
console.log(offset);
offset = offset - 100;
console.log(offset);
$('html, body').scrollTop( offset );
});
With the e.preventDefault() commented out, the behavior of the navigation menu is as expected. Scrolling down the window results in the displayed div being highlighted on the menu. Clicking on an item in the menu list, takes you directly to corresponding div on the page and when you then scroll away from that section on the page, the menu updates accordingly.
On my 'real' page, I have a fixed header of height 100px. So currently, when I click on a menu link, the pages jumps to the required section and places it at the top of the page where the header obscures it slightly. The scrollTop part of the code above doesn't seem to work unless I use e.preventDefault(). If you uncomment this line in the fiddle and run it again, click on 'Heading 3' link on the menu, and you will see that it now puts the Heading 3 content in the page offset by 100px from the top. Perfect.
However, now scroll back up the page towards the top. You will see that the 'Heading 3' list item, remains in its :hover state, even when the mouse is no where near it. Its as though the e.preventDefault() has prevented the browser from detecting that the mouse is no longer hovering on the item.
Mouseclicking anywhere outside the browser window, corrects the problem.
Can anyone shed any light on what I'm doing wrong here? How can I prevent the default behavior of the anchor click so I can control the page scroll placement, without stopping the correct CSS painting in the process?
The problem arises because I am preventing the browsers default behavior, using e.preventDefault(), as I want to control the scroll to the anchored element.
I've tested this in Firefox and IE10.
The issue is not the :hover state, but the :focus state.
When you click on a link, that link gains focus so you apply the :focus styling (that is the same as the :hover styling in your code). By preventing the default behavior, that link stays active and doesn't lose the focus.
One quick solution would be to unfocus/blur the element by using: $(this).blur().
In your code it would look like this:
$('#doc_nav').on( "click", "a", function( e ){
e.preventDefault();
var target = this.hash;
var $target = $(target);
var offset = $target.offset().top;
console.log(offset);
offset = offset - 100;
console.log(offset);
$(this).blur();
$('html, body').scrollTop( offset );
});
You can see a demo here: https://jsfiddle.net/z32rpe3b/30/
Why did it work fine with e.preventDefault() but incorrectly without it?
The answer to this has to do with the order of execution. The onclick event happens before the href redirection happens in the browser:
Without the e.preventDefault(), the code is executed, and the browser scrolled correctly to the target offset - 100 position (in the onclick), but then it executed the link href and scrolled to the target offset. It just happens so fast that it seems that it goes directly to the target position.
With e.preventDefault(), the code is executed (scrolling to offset - 100), and the browser doesn't execute the href action (so it stays at offset - 100).
First, how to make this function run ONLY on scroll? Second, how to loop/repeat this function ONLY on window scroll infinitely?
$(function(){
$(".media-nav2").transition(
{ y: -600 }, 1500,
'cubic-bezier(.69,.19,.35,.83)');
});
I'm using the above function with this plugin https://github.com/rstacruz/jquery.transit.
Here is my webiste http://dev1.envisionwebdesign.co/johnreid/campaign.html. It's a one page parallax with no scroll bars. You navigate using the top menu and mouse/touch scroll. If you check this link http://dev1.envisionwebdesign.co/johnreid/campaign.html, you can see that the div .media-nav2 immediately transitions when the page loads.
Basically I'm trying to create a parallax effect where when you scroll down to the next page/section, the div .media-nav2 scrolls up. Here's a link to the fiddle http://jsfiddle.net/newmedia85/92YgR/. I have included a link to the onepage parallax jquery for the entire site. The way the one page parallax works is making it really hard for me to solve this. Any help appreciated!
use jquery scroll function
$(window).scroll(function () {
$(".media-nav2").transition({
y: -600
}, 1500, 'cubic-bezier(.69,.19,.35,.83)');
});
This question already has answers here:
Prevent scrolling of parent element when inner element scroll position reaches top/bottom?
(32 answers)
Closed 9 years ago.
I have a div that is scrollable, but whenever you reach the bottom/top of it, it begins to scroll the entire page. That could be annoying for users who scroll fast, and then the entire page starts scrolling unexpectedly.
I need something where if you are hovering over the div, the page is not scrollable.
I have tried this by adding CSS when I hover the div...
body {
overflow:hidden;
}
...It works but there is one problem. The scrollbar disappears and that looks kind of stupid to have it disappearing/reappearing. Any way to achieve the same effect but keep the scrollbar visible? I have seen it done with Facebook chat.
Here is a very simple way to stop the propagation with no plugins, just jQuery.
Update: The code has been updated to work correctly in IE9+. Have not tested in previous versions.
First, create a class on your <div> to mark it as having this behavior. In my example, I use the class .Scrollable.
<div class="Scrollable">
<!-- A bunch of HTML here which will create scrolling -->
</div>
The jQuery to disable is:
$('.Scrollable').on('DOMMouseScroll mousewheel', function(ev) {
var $this = $(this),
scrollTop = this.scrollTop,
scrollHeight = this.scrollHeight,
height = $this.height(),
delta = (ev.type == 'DOMMouseScroll' ?
ev.originalEvent.detail * -40 :
ev.originalEvent.wheelDelta),
up = delta > 0;
var prevent = function() {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
}
if (!up && -delta > scrollHeight - height - scrollTop) {
// Scrolling down, but this will take us past the bottom.
$this.scrollTop(scrollHeight);
return prevent();
} else if (up && delta > scrollTop) {
// Scrolling up, but this will take us past the top.
$this.scrollTop(0);
return prevent();
}
});
In essence, what this does is to detect which direction the scrolling is being requested in (based on the originalEvent.wheelDelta: positive = up, negative = down). If the requested delta of the mousewheel event would move scrolling past the top or bottom of the <div>, cancel the event.
In IE, especially, scrolling events which go past a child element's scrollable area then roll up to parent elements, and the scrolling continues regardless of the event being canceled. Because we cancel the event in any case, and then control the scrolling on the child through jQuery, this is prevented.
This is loosely based on the way that this question solves the problem, but does not require the plugin, and is cross-browser compliant with IE9+.
Here is a working jsFiddle demonstrating the code in-action.
Here is a working jsFiddle demonstrating the code in-action, and updated to work with IE.
Here is a working jsFiddle demonstrating the code in-action, and updated to work with IE and FireFox. See this post for more details about the necessity of the changes.
maybe have a look to
How to disable scrolling temporarily?
This is a sample to stop and activate scroll
I am trying to make a horizontally scrolling Web Page. This template uses J Query and CSS to control width, but the User still has to drag the scroll bar across the bottom - how would I add arrows or something that the User could just click on and it would go over to the next section?
http://css-tricks.com/how-to-create-a-horizontally-scrolling-site/
Check out this JQuery plugin http://plugins.jquery.com/project/ScrollTo
You can use scrollLeft and offset() to determine what to scroll to:
A next button might look like this (Based very closely on a sample in Chapter 7 of jQuery Enlightenment):
$(".next").click(function(e){
$('html, body').animate({
scrollLeft: $(this).closest('td').next().offset().left
}, 1000);
e.preventDefault();
});
I am assuming you followed the CSS-Tricks article closely, which means you have a table on the page.
If you didn't want the animation you could do it this way:
$(".next").click(function(e){
$('html, body').scrollLeft($(this).closest('td').next().offset().left );
e.preventDefault();
});