I am using iScroll for providing iPhone style scrolling. But, when clicking on the textboxes, the keyboard does not show up.
While trying to find the possible cause, I found that removing the iScroll script, makes it work normal, but in that case I miss the scrolling functionality.
Is this a bug in iScroll. If yes, is there a tested work-around? Or is there any alternative for iScroll?
Thanks in advance.
At least in iScroll 4, you can add this code to enable clicking of input fields. See the demo on Form-fields in the examples folder.
<script type="text/javascript">
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper', {
useTransform: false,
onBeforeScrollStart: function (e) {
var target = e.target;
while (target.nodeType != 1) target = target.parentNode;
if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA')
e.preventDefault();
}
});
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', loaded, false);
</script>
I was able to solve the error. The problem was with the CSS.
I thought may be the CSS is somehow creating the problem. I concluded this on the basis that when I commented the CSS for wrapper and scroller, the keyboard showed up... but keeping them, the keyboard didn't work. I was using bottom: 0px;, which seemed to be somehow preventing the keyboard from showing.
Removing bottom: 0px; solved my problem.
Hope this helps others.
I added the following code to _start in iScroll 4.2 to solve this problem:
if (e && e.target && e.target.tagName) {
var bFocusField = ('|INPUT|TEXTAREA|BUTTON|SELECT|'
.indexOf('|' + e.target.tagName + '|') >= 0);
if (bFocusField || that.focusField) {
if (bFocusField) {
that.focusField = e.target;
} else {
that.focusField.blur();
that.focusField = null;
}
e.defaultPrevented = false;
e.returnValue = true;
return true;
}
}
Code is inserted below the initialization part of the function (that.moved = false; ... that.dirY = 0;).
Tested it on iPad 1 (iOS 5.1) and iPad 3 (iOS 6). The onscreen keyboard does not seem to interfere with iScroll (I do an iScroll.refresh() every 5 seconds).
I believe this solution is optimal
Tweak the code in iscroll.js, ( as follows )
onBeforeScrollStart: function (e) {
//e.preventDefault();
if (e.target.nodeName.toLowerCase() == "select" || e.target.tagName.toLowerCase() == 'input' || e.target.tagName.toLowerCase() == 'textarea'){
return;
}
},
Related
My app has a static header. Meaning it remains the same in all views.
The problem is that when I use the <ion-nav-bar> directive the header is animated every time the view changes.
On IOS it's not that bad because the entire is sliding in, but on Android it looks like it flickers.
How can I disable the animation entirely?
I already tried using $ionicConfigProvider.navBar.transition('none'); in the app.config section, but it actually made it worse (also flickers on IOS).
I created a simple codepen (the default transition appears to that of IOS, but if you open the developer console on chrome and change to an android device you can see the flickering).
if you really no idea to how solve this.
you can modify the transition function
First, in app.config section
$ionicConfigProvider.navBar.transition('android');
then, modify ionic transition function
$ionicConfigProvider.transitions.navBar.android = function(enteringHeaderBar, leavingHeaderBar, direction, shouldAnimate) {
function setStyles(ctrl, opacity) {
if (!ctrl) return;
var css = {};
// ionic original
// css.opacity = opacity === 1 ? '' : opacity;
// modify
if (opacity === 1) {
css.opacity = '';
css.display = '';
} else {
css.opacity = opacity;
css.display = 'none'; // let leavingHeaderBar immediately disappear
}
ctrl.setCss('buttons-left', css);
ctrl.setCss('buttons-right', css);
ctrl.setCss('back-button', css);
ctrl.setCss('back-text', css);
ctrl.setCss('title', css);
}
return {
run: function(step) {
setStyles(enteringHeaderBar.controller(), step);
setStyles(leavingHeaderBar && leavingHeaderBar.controller(), 1 - step);
},
shouldAnimate: shouldAnimate && (direction == 'forward' || direction == 'back')
};
};
If you are using Ionic 2 or higher, use the following CSS only:
.toolbar{
.title, button{
opacity: 1!important;
transform: none!important;
}
}
I wrote this script for a navigation menu on the phone. If an item has drop downs, it prevents the link, then displays the drpdown.
$(document).ready(function() {
var bodyWidth = window.screen.availWidth;
if(bodyWidth <= 600) {
$('ul.dropdowns li > a').click(function(event) {
var parent = $(this).closest('li');
var nester = $(this).closest('li').closest('ul').closest('li');
var type = parent.attr("class");
if(parent.hasClass('dropdown') || parent.hasClass('flyout')) {
event.preventDefault();
$(parent).siblings().attr("id", "");
var isActive = (parent.attr("id") == "active" ? true : false);
(isActive ? $(parent).attr("id", "") : $(parent).attr("id", "active"));
}
});
};
});
This works fine with the iPhone, but on Android it gets screwed. I'm at a total loss, any ideas?
By, "gets screwed" I mean nothing happens on Android when you try to click a link.
I found the problem. I was using a CSS transition that for some reason Android wasn't keeping up with.
I need help with a little problem I can't seem to get a grip to:
I have spans that show up on the bottom of the screen when I touch a character (a lot of characters -> a lot of spans). In the span are some information about the character - as I want to make it mobilefriendly I want the user to scroll throught that information.
So far I found a little bit code that helped me a little:
<body onload="touchScroll('test')">
<script>
function isTouchDevice(){
try{
document.createEvent("TouchEvent");
return true;
}catch(e){
return false;
}
}
function touchScroll(id){
if(isTouchDevice()){ //if touch events exist...
var el=document.getElementById(id);
var scrollStartPos=0;
document.getElementById(id).addEventListener("touchstart", function(event) {
scrollStartPos=this.scrollTop+event.touches[0].pageY;
event.preventDefault();
},false);
document.getElementById(id).addEventListener("touchmove", function(event) {
this.scrollTop=scrollStartPos-event.touches[0].pageY;
event.preventDefault();
},false);
}
}
And the span with the id "test" becomes scrollable. Great. But as I have hundreds of span I can't assign an id to every single one. So I was wondering if you could help come up with a way to make every class "tt" scrollable.
I tried reassigning the "test"-id to the next element upon touch. But that didn't work. I tried adding the "test"-id to every class "tt" - didn't work either.
If you want to make yourself a picture of the situation: Here's my testsite!
I found a solution on this site in the comments:
<script type='text/javascript'>
// Determine if this is a touch device
var hasTouch = 'ontouchstart' in document.documentElement,
startEvent = hasTouch ? 'touchstart' : 'mouseover',
moveEvent = hasTouch ? 'touchmove' : 'mousemove',
endEvent = hasTouch ? 'touchend' : 'mouseup';
var Last;
$(".tttw").live(startEvent, function() {
if (Last) Last.removeClass('ttth');
$(this).addClass("ttth");
Last=$(this);
});
function isTouchDevice(){
try{
document.createEvent("TouchEvent");
return true;
}catch(e){
return false;
}
}
function touchScroll(selector) {
if (isTouchDevice()) {
var scrollStartPosY=0;
var scrollStartPosX=0;
$('body').delegate(selector, 'touchstart', function(e) {
scrollStartPosY=this.scrollTop+e.originalEvent.touches[0].pageY;
scrollStartPosX=this.scrollLeft+e.originalEvent.touches[0].pageX;
});
$('body').delegate(selector, 'touchmove', function(e) {
if ((this.scrollTop < this.scrollHeight-this.offsetHeight &&
this.scrollTop+e.originalEvent.touches[0].pageY < scrollStartPosY-5) ||
(this.scrollTop != 0 && this.scrollTop+e.originalEvent.touches[0].pageY > scrollStartPosY+5))
e.preventDefault();
if ((this.scrollLeft < this.scrollWidth-this.offsetWidth &&
this.scrollLeft+e.originalEvent.touches[0].pageX < scrollStartPosX-5) ||
(this.scrollLeft != 0 && this.scrollLeft+e.originalEvent.touches[0].pageX > scrollStartPosX+5))
e.preventDefault();
this.scrollTop=scrollStartPosY-e.originalEvent.touches[0].pageY;
this.scrollLeft=scrollStartPosX-e.originalEvent.touches[0].pageX;
});
}
}
$(document).ready(function(){
touchScroll('.tt');
});
</script>
Working like a charm now ;-)
I have developed android phonegap app.I have a appended the dynamic form contains 'input' and 'select' in the div.I need to get scrollbar for that div.So i used iScroll.js but its not working properly.While typing in the textbox suddenly scrollbar disappears.This problem occurring often.
Here is my code:
function loaded()
{
var myScroll = new iScroll('wrapper',
{
scrollbarClass: 'myScrollbar',
useTransform: false,
vScroll: true,
onBeforeScrollStart: function (e)
{
var target = e.target;
while (target.nodeType != 1) target = target.parentNode;
if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA')
e.preventDefault();
}
});
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', loaded, false);
Please kindly guide me.Thanks in Advance
so a couple of things that will be helpful -
define your myScroll variable outside of your loaded function that way you can access it anywhere.
also after your content has loaded call myScroll.refresh() and have at least a 1ms delay on it. little hack that goes a long way.
Here is a chunk of text inside a scrollable div.
I can scroll it with two fingers in Chrome for Mac. I can scroll it with one finger on my iPad. However, I can't find any way to scroll it in Chrome for Android.
Perhaps there's a work-around using the touch API?
Another quick fix for Chrome for Android (http://chris-barr.com/index.php/entry/scrolling_a_overflowauto_element_on_a_touch_screen_device/)
First create a function to check whether the it is a touch device...
function isTouchDevice(){
try {
document.createEvent("TouchEvent");
return true;
} catch(e) {
return false;
}
}
then function to make div scrollable
function touchScroll(id){
if( isTouchDevice() ){ //if touch events exist...
var el = document.getElementById(id);
var scrollStartPos = 0;
document.getElementById(id).addEventListener("touchstart", function(event){
scrollStartPos = this.scrollTop + event.touches[0].pageY;
event.preventDefault();
}, false);
document.getElementById(id).addEventListener("touchmove", function(event){
this.scrollTop = scrollStartPos - event.touches[0].pageY;
event.preventDefault();
},false);
}
}
... call the function passing the element id
touchScroll("divIdName");
While browsing through the bug reports on this issue, I found this JavaScript library that solves the problem using touch events. Also it is reportedly fixed in Honeycomb, so hopefully the fix will hit people as soon as they push builds of Ice Cream Sandwich.
All android versions before 3.0 are bugged with overflow:scroll or auto (bug info).
For thoses using jQuery here is a quick fix :
function touchScroll(selector){
var scrollStartPos = 0;
$(selector).live('touchstart', function(event) {
scrollStartPos = this.scrollTop + event.originalEvent.touches[0].pageY;
});
$(selector).live('touchmove', function(event) {
this.scrollTop = scrollStartPos - event.originalEvent.touches[0].pageY;
});
}
and then if using modernizr :
if (Modernizr.touch) {
touchScroll($('.myScrollableContent'))
}
but it's not ideal because all touch-able devices will have this.
If you use Phonegap you can do (somewhere after phonegap inited):
if (window.device && device.platform=="Android" && parseInt(device.version) < 3){
touchScroll($('.myScrollableContent'))
}