I am building an ios web app. I want to disable scrolling, so I used:
$(document).bind('touchmove', function(e) {
e.preventDefault();
});
and it works perfectly. However, now if the user taps on an input, it is not focused. "No big deal", I thought. This half fixes the problem:
$("div#searchBarView input").hammer().on("tap", function(){ //I'm using the hammer.js touch library.
this.focus();
});
So now the keyboard comes up, but no cursor or blue focus-haze appear. If I type, then no text appears. Any ideas how to get the focus, but keep the scrolling off?
Thanks!
-Sean
Rather than using JavaScript to prevent the scrolling, you might want to look at an alternative method, you should be able to prevent scrolling with pure CSS
html, body {
overflow: hidden;
height: 100%;
padding: 0;
margin: 0;
}
Then you can disable bounce with - How to prevent app running in phone-gap from scrolling vertically?
Related
I have a hard to debug issue where a click on an input element behaves completely different on my Samsung S10 than in my desktop Chrome browser (also when using device testing tools).
Here's how to test:
on a small mobile design (max-width: 56em) a blue filter bar appears at the bottom of the screen
Click it to show all filters, a popup menu appears (you can go back to results by clicking button "Bekijk resultaten")
Click "+ Specificeer" at the bottom of that screen
In the small range specification popup that appears click the first input element (placeholder="van")
In Chrome on desktop the user can now enter a number. Also when I use Chrome device debugging tools and set it to iPhoneX, Galaxy S5, Galaxy Fold rendering etcetera it works just fine.
But when I load my live site on my Galaxy S10 in the Chrome browser, the moment the user clicks the input element to enter a number, the rest of the filter popup menu is hidden, and it only shows part of the range specification popup. Scrolling of the page is completely disabled. I'm thinking that certain events are handled differently, but I can't figure out which ones and why.
I tried monitoring events using monitorEvents(window,"click");, but no click events show
Logged events via Performance tab, but could not find the culprit
I have no idea why anymore and I can't reproduce it in Chrome desktop browser to actually debug it.
UPDATE 1
The issue was the mobile virtual keyboard that trigger the resize method.
Fixed it by checking for width change:
var initialWidth = $(window).width(), initialHeight = $(window).height();
window.addEventListener('resize', function () {
if ($(window).width() != initialWidth) {//the width was changed
}
})
Well, I've played around. illusion is totally right.
I've copied some styles from .filters .mobile class to .filters_TEST
.filters_TEST{
&.active{
height: auto;
flex-grow:1;
overflow: auto;
opacity: 1;
z-index: 100;
padding: 0;
background-color: #FFF!important;
min-height: 100vh;
.modal_container{
background-color: #fff;
overflow: auto;
overflow-x: hidden;
position: relative;
width: 100%;
height: 100vh;
overflow-y: hidden;
#mobilefilters{
display:block;
}
}
}
}
added test button:
<span class="js-callmodal display-mobile-only">CALL MODAL</span>
and on button click added new class to .
$('.js-callmodal').on('click',function(){
$('.filters_TEST').addClass('active');
});
now when you click:
CALL MODAL -> Specificeer -> input
modal stays in place;
to truly fix your problem you should search what removes .mobile class when input is triggered.
I guess the code should be somewhere in file: _genfuncs.min.js?v=90
While debugging, I found that when the input is in focus and the keyboard pops up, that instant .mobile class is removed from section.filters. You'll have to see for any event handler that removes the .mobile class on any event. Secondly, after the bug was encountered I again added the removed .mobile class manually to section.filters and the modal was back in place working properly. After clicking "Specificeer" it gives rise to another bug, where the main page becomes unscrollable. Also at the same instant there is another error TypeError which could possibly be the cause of the other bug...
I use jQuery Selectric plugin for customize select's.
$('select').selectric({
disableOnMobile: false
});
If i open select on iPad device my left column move up
.left-column {
position: fixed;
left: 0;
top: 0;
width: 200px;
height: 100vh;
background: #F00;
z-index: 100;
}
Please, help with it. Demo here: http://output.jsbin.com/seleyi
UPD: test at browserstack iOS < 7 - no problem, iOS 8.3 - have some problem, iOS 9.1 have this bug
It's bug iOS 9, include in iOS 8, but in 9 version include partly.
Bug with input, with attribute readonly="readonly". Selectric use hide input:
What happen:
If click on selectric-wrapper start method _open.
Method _open set focus on hide input.selectric-input. It make selectric plugin and i don't know why. May be, more simple add listeners for keystrokes on a hidden element. And handle such events when an item has focus. Why input? If you use another element, then pressing the arrow keys, we will also scroll the document itself. Because, use input , although I could be wrong. Maybe better input for e-readers, ie, used it to enhance accessibility.
And when focus comes to input , despite the fact that it is readonly, iOS (I think so) tries to allocate space for the keyboard. I can advise a simple workaround:
$(".selectric-input[readonly]").on("focus", function(evt) {
this.blur();
});
Ie when the focus input immediately rid of him, because on iPads impossible to move through the list using the keyboard, the functionality should not be compromised.
This question already has answers here:
ipad safari: disable scrolling, and bounce effect?
(22 answers)
Closed 5 years ago.
In reviewing the many questions and answers on this topic on StackOverflow, none of the solutions provided worked reliably. All CSS, JavaScript, jQuery and hybrid solutions had at least one deficiency that prevented the scroll from disabling and/or toggling effectively.
I've also searched the web high and wide and have not found a good answer.
So far I have this function:
function toggleScroll(btn, item) {
$(btn).click(function() {
$(item).toggleClass("noscroll");
});
}
...which will add a overflow: hidden; to any class I want onclick, and remove it on second click.
The thing is, this code doesn't work with iOS devices.
How could I make this work with iOS devices?
Ideally, I would prefer a pure CSS solution. But I understand that this may not be possible, especially the toggle component.
Any JavaScript or jQuery solution would be fine, as well.
Thanks in advance!
Disable Scroll / Scrolling on iOS Devices (iPad, iPhone, Mac) with jQuery
I think this gets you close to what you want. The only issue may be the toggle, which is two buttons (Enable and Disable). If you want to make the toggle a single button, maybe you can post a separate question or somebody else can improve upon this answer. (I'm mostly an HTML / CSS / PHP guy. I'm somewhat new to JS).
var disableScroll = false;
var scrollPos = 0;
function stopScroll() {
disableScroll = true;
scrollPos = $(window).scrollTop();
}
function enableScroll() {
disableScroll = false;
}
$(function(){
$(window).bind('scroll', function(){
if(disableScroll) $(window).scrollTop(scrollPos);
});
$(window).bind('touchmove', function(){
$(window).trigger('scroll');
});
});
credit: https://stackoverflow.com/a/17597303/3597276
Disable Scroll / Scrolling on iOS Devices (iPad, iPhone, Mac) with CSS
For a pure CSS solution to disable scrolling on iOS devices try these options:(Of course, these have no toggle.)
html, body {
position: fixed;
}
html, body {
position: relative;
overflow: hidden;
}
body {
position: fixed;
overflow: hidden;
}
body {
position: fixed;
height: 100%;
overflow: hidden;
width: 100%;
}
Here are some of the posts and articles I read on this issue.
Disable scrolling in an iPhone web application?
Disable all scrolling on webpage
iPhone Web App - Stop body bounce/scrolling in iOS8
ipad safari: disable scrolling, and bounce effect?
iPhone Web App - Stop body scrolling
iOS Safari – How to disable overscroll but allow scrollable divs to scroll normally?
Enable/Disable Scrolling in iPhone/iPad’s Safari
iOS prevent scrolling on body
I'm making a single-page application with HTML, CSS and Javascript (no jQuery or similar). This application is made of many UI pages that can change via Javascript. The user experience is fine using the mouse on computers, but not so nice with touchscreens (mobile, etc.).
There are many buttons with a CSS hover graphic effect. If I change page tapping one button on a touch screen, the pointer stays there triggering the CSS hover of next elements appearing in the same position when the page is "changed". This effect is very annoying, but I can't figure out how to fix it.
The code is very simple:
CSS
button {
background-color: #XXXXXX;
}
button:hover {
background-color: #ZZZZZZ;
}
HTML
<button onclick="changepage()"></button>
You can use modernizr with Touch Events detection, than use
html.no-touch button:hover {
background-color: #ZZZZZZ;
}
Without modernizr you can add this simple code to append no-touch/touch class to html tag
<script type="text/javascript">
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Windows Phone/i.test(navigator.userAgent)) {
document.getElementsByTagName('html')[0].className += ' touch';
}else{
document.getElementsByTagName('html')[0].className += ' no-touch';
}
</script>
Thank you anyway! Finally I made a very simple script that works perfectly...it is good even for touch computers that have a mouse too (like mine), and of course for mobile phones. There is no need to detect devices! The solution is to add a very small div under the cursor pointer after the page changes, by calling the function refresh_hover(). This div 1px x 1px is removed as soon as the user clicks on it or the cursor goes out from it. In this way the hover effect is removed when the content changes behind the pointer, but then restored when the user does something! You will probably think that is very stupid, but is simple and works very well!
Here it is:
function refresh_hover(){
if(!event){
return false;
}
var x = event.clientX;
var y = event.clientY;
var div = document.getElementById('mouse_div');
if(!div){
document.body.innerHTML=document.body.innerHTML
+'<div style="position: fixed; z-index: 1000; height: 1px; width: 1px; display: block;" id="mouse_div" onmouseout="this.style.display=\'none\'" onclick="this.style.display=\'none\'"></div>';
div = document.getElementById('mouse_div');
}
div.style.display='block';
div.style.top=y+'px';
div.style.left=x+'px'
}
I have a <div> with some content. I gave this div an id attribute, oDIV, and bound a function to the onscroll event via this small script:
window.onload = {
document.getElementById("oDiv").onscroll = function() {
document.getElementById("tooltip").className = "sTooltip";
this.onscroll = null;
};
}
I added some simple CSS to the div, so that a vertical scroll bar would appear. Content stretches down quite a bit and there's a lot to scroll.
#oDiv {
border: 1px solid black;
float: left;
height: 300px;
overflow: auto;
overflow-x: hidden;
padding: 0;
padding-right: 40px;
clear: left;
}
Anyways, if the user tries to scroll I want a tooltip to appear to remind the user that there's a filter option to hide some of the stuff they have to scroll, through.
In Firefox and more current browsers it worked just fine.
The problem I have, is I have to support IE6, and this approach does work in IE6 but there's a slight issue. If you "grab" the scroll bar by left clicking and holding and continue to drag when the event is fired the scroll bar is prematurely released. Forcing the user to again click on the drag bar. It's a minor issue, but I want to know why?
I only intend to fire this event once ever, only when scrolling has initiated.
If a library or framework has solved this odd behavior, could you please show their source to which they address this?
Also, I think timing libraries etc. al for determining the "point at which they stopped scrolling" is way overkill for this.
It could be because IE is pausing to render the "tooltip". Instead of using display:none on your tooltip try to use visibility:hidden and then toggle to visibility:visible.