Disable scrolling when changing focus form elements ipad web app
I've found that in UIWebView, document.body is also sometimes moved. So I use:
input.onfocus = function () {
window.scrollTo(0, 0);
document.body.scrollTop = 0;
}
How to programmatically disable page scrolling with jQuery
The only way I've found to do this is similar to what you described:
- Grab current scroll position (don't forget horizontal axis!).
- Set overflow to hidden (probably want to retain previous overflow value).
- Scroll document to stored scroll position with scrollTo().
Then when you're ready to allow scrolling again, undo all that.
Edit: no reason I can't give you the code since I went to the trouble to dig it up...
// lock scroll position, but retain settings for later
var scrollPosition = [
self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);
// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])
Is it possible to avoid page scrolling when changing focus on HTML elements? (Using JavaScript)
You can simply add prevent default:
function tabnav(event){
event.preventDefault();
.
Of course insert it into the 'case arrow down/up' otherwise you won't have any input at all
How do I stop a web page from scrolling to the top when a link is clicked that triggers JavaScript?
You need to prevent the default action for the click event (i.e. navigating to the link target) from occurring.
There are two ways to do this.
Option 1:event.preventDefault()
Call the .preventDefault()
method of the event object passed to your handler. If you're using jQuery to bind your handlers, that event will be an instance of jQuery.Event
and it will be the jQuery version of .preventDefault()
. If you're using addEventListener
to bind your handlers, it will be an Event
and the raw DOM version of .preventDefault()
. Either way will do what you need.
Examples:
$('#ma_link').click(function($e) {
$e.preventDefault();
doSomething();
});
document.getElementById('#ma_link').addEventListener('click', function (e) {
e.preventDefault();
doSomething();
})
Option 2: return false;
In jQuery:
Returning false from an event handler will automatically call event.stopPropagation() and event.preventDefault()
So, with jQuery, you can alternatively use this approach to prevent the default link behaviour:
$('#ma_link').click(function(e) {
doSomething();
return false;
});
If you're using raw DOM events, this will also work on modern browsers, since the HTML 5 spec dictates this behaviour. However, older versions of the spec did not, so if you need maximum compatibility with older browsers, you should call .preventDefault()
explicitly. See event.preventDefault() vs. return false (no jQuery) for the spec detail.
Prevent body scrolling but allow overlay scrolling
Theory
Looking at current implementation of the pinterest site (it might change in the future), when you open the overlay a noscroll
class is applied to the body
element and overflow: hidden
is set, thus body
is no longer scrollable.
The overlay (created on-the-fly or already inside the page and made visible via display: block
, it makes no difference) has position : fixed
and overflow-y: scroll
, with top
, left
, right
and bottom
properties set to 0
: this style makes the overlay fill the whole viewport.
The div
inside the overlay is instead just in position: static
then the vertical scrollbar you see is related to that element. As a result the content is scrollable but overlay remains fixed.
When you close the zoom you hide the overlay (via display: none
) and then you could also entirely remove it via javascript (or just the content inside, it's up to you how to inject it).
As a final step you have to also remove the noscroll
class to the body
(so the overflow property returns to its initial value)
Code
Codepen Example
(it works by changing the aria-hidden
attribute of the overlay in order to show and hide it and to increase its accessibility).
Markup
(open button)
<button type="button" class="open-overlay">OPEN LAYER</button>
(overlay and close button)
<section class="overlay" aria-hidden="true">
<div>
<h2>Hello, I'm the overlayer</h2>
...
<button type="button" class="close-overlay">CLOSE LAYER</button>
</div>
</section>
CSS
.noscroll {
overflow: hidden;
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; right: 0; bottom: 0; left: 0; }
[aria-hidden="true"] { display: none; }
[aria-hidden="false"] { display: block; }
Javascript (vanilla-JS)
var body = document.body,
overlay = document.querySelector('.overlay'),
overlayBtts = document.querySelectorAll('button[class$="overlay"]');
[].forEach.call(overlayBtts, function(btt) {
btt.addEventListener('click', function() {
/* Detect the button class name */
var overlayOpen = this.className === 'open-overlay';
/* Toggle the aria-hidden state on the overlay and the
no-scroll class on the body */
overlay.setAttribute('aria-hidden', !overlayOpen);
body.classList.toggle('noscroll', overlayOpen);
/* On some mobile browser when the overlay was previously
opened and scrolled, if you open it again it doesn't
reset its scrollTop property */
overlay.scrollTop = 0;
}, false);
});
Finally, here's another example in which the overlay opens with a fade-in effect by a CSS transition
applied to the opacity
property. Also a padding-right
is applied to avoid a reflow on the underlying text when the scrollbar disappears.
Codepen Example (fade)
CSS
.noscroll { overflow: hidden; }
@media (min-device-width: 1025px) {
/* not strictly necessary, just an experiment for
this specific example and couldn't be necessary
at all on some browser */
.noscroll {
padding-right: 15px;
}
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; left: 0; right: 0; bottom: 0;
}
[aria-hidden="true"] {
transition: opacity 1s, z-index 0s 1s;
width: 100vw;
z-index: -1;
opacity: 0;
}
[aria-hidden="false"] {
transition: opacity 1s;
width: 100%;
z-index: 1;
opacity: 1;
}
Prevent iOS from handling focus event on an <input>
This has been quite a hack, but it seems to work:
body, html {
margin: 0;
overflow: auto;
height: 100%;
-webkit-overflow-scrolling: touch;
}
Just add this to your CSS. I needed to remove the margin, not sure if that will affect your design. If so, you might try to add padding instead, but I haven't tried.
The idea is to prevent the html element to scroll, tricking Safari as it seems that it is only attempting to do it in the outer most element.
If the html doesn't scroll, I need to add the scroll back, so I apply it to the body. That makes the scroll to lose the momentum, and to add it back you need that -webkit-overflow-scrolling: touch
thing.
So, to be more clear of what is going on, the code should be like this - but I haven't tried it:
html {
margin: 0;
overflow: hidden;
height: 100%
}
body {
margin: 0;
overflow: auto;
height: 100%;
-webkit-overflow-scrolling: touch;
}
Related Topics
How to Format Numbers by Prepending 0 to Single-Digit Numbers
How to Tell Chrome Web Debugger to Show the Current Mouse Position in Page Coordinates
Uncheck a Checkbox and Another Checkbox Will Untick
Use Localstorage Across Subdomains
How to Take Screenshot of a Div With JavaScript
Detect If String Contains Any Spaces
One Time Page Refresh After First Page Load
How to Unmute Html5 Video With a Muted Prop
Handle File Download from Ajax Post
Add and Remove Values Inside Array in Change Event of Checkbox
How to Redirect to Another Page Using Angularjs
How to Use Zindex in React-Native
How to Format Numbers in Vuejs
Trying to Add Image to Pdf Using Jspdf
Making a JavaScript Function That Finds the First Word in a String/Sentence
How to Remove Captcha Verification from Firebase Phone Auth Using JavaScript
How to Download a File With Node.Js (Without Using Third-Party Libraries)