=]
Here's the thing:
We're developing a webapplication with HTML5/CSS3/JavaScript/jQuery technologies. When I test it in my desktop PC's browser, everything is cool and fully functional. That's not the problem. =]
But... And here's the problem where I'm stuck with currently...
When I'm trying to test it on mobile (or tablet) the divs don't want to scroll. I know that mobiles (and tablets) handle events differently, they have (sometimes, somewhat) different events getting
We don't have too much time to get over with this (as usual -_- ), but still, we have to bring a solution. We don't want to create another UI for NOT dekstop hardwares, so I'm looking for a solution which can be triggered by "chaining" the mobile event handlers together with the basic events.
We're using div's and CSS properties overflow-x, overflow-y which need to be scrolling on mobile (and also tablet) devices. What would you recommend? how would you do it? Which would be the perfect and time-effitient method?
Thank you in advance for answering! =]
Best for everybody,
Ben
Thanks for the helps guys, but I've already found the way of doing this. =) I'm gonna share it with you, so you'll know.
First of all, Android 3.x tablets do have scrolling divs.
But to make it work on 2.2 and ipad: Here's the code I've been using (click on me!)
So you just pass the id of the div you want to scroll for the touchScroll() method (after of corse including on your html's head) et voilá! =)
I've also extended the code (copy > paste code) with another function which accepts an element:
function touchScrollElement(element){
if(isTouchDevice()){
var scrollStartPosY=0;
var scrollStartPosX=0;
element.addEventListener("touchstart", function(event) {
scrollStartPosY=this.scrollTop+event.touches[0].pageY;
scrollStartPosX=this.scrollLeft+event.touches[0].pageX;
},false);
element.addEventListener("touchmove", function(event) {
if ((this.scrollTop < this.scrollHeight-this.offsetHeight &&
this.scrollTop+event.touches[0].pageY < scrollStartPosY-5) ||
(this.scrollTop != 0 && this.scrollTop+event.touches[0].pageY > scrollStartPosY+5))
event.preventDefault();
if ((this.scrollLeft < this.scrollWidth-this.offsetWidth &&
this.scrollLeft+event.touches[0].pageX < scrollStartPosX-5) ||
(this.scrollLeft != 0 && this.scrollLeft+event.touches[0].pageX > scrollStartPosX+5))
event.preventDefault();
this.scrollTop=scrollStartPosY-event.touches[0].pageY;
this.scrollLeft=scrollStartPosX-event.touches[0].pageX;
},false);
}
}
So that'S the current solution... =)
iOS 5 has support for overflow:scroll and overflow:auto. You just have to add this CSS rule and the scroll should work:
-webkit-overflow-scrolling: touch;
When I'm trying to test it on mobile (or tablet) the divs don't want to scroll.
What are you trying in order to make them scroll? If you‘re trying to make them scroll from your code, we’ll need to see the code.
(If on the other hand you’re trying to make them scroll via user-interaction, on iOS you can scroll individual scrollable elements on the page by dragging with two fingers instead of one.)
Mobile implementation of overflow: scroll is horrible...
You can use two fingers on an iOS device but users generally don't know that, and pre-Honeycomb Android operating systems don't have any implementation for overflow: scroll and just clip the overflow like overflow: hidden. Even the Honeycomb implementation is apparently choppy and not a good user experience.
You can use one of a few pre-made JavaScript based packages that try to implement cross-platform scrolling but they generally fall short of a "stellar user experience."
jQuery Mobile has an experiement called "Scrollview" and iScroll is one that comes to mind.
--EDIT--
I just came across a JavaScript Library named Wink that has a nice scrollable area plugin. Check-out Wink Toolkit.
Related
Before you say this isn't possible, I know it is. Here's an example: http://victoriabeckham.landrover.com/INT
The main problem is that iOS freezes DOM manipulation on scroll, so you have to use some sort of technique to overcome the problem. The parallax plugin I was hoping to use is stellar.js, but the issue I am running into is that the "iOS demo" for that plugin isn't really usable on a desktop. I fiddled with it for 3 hours this morning, and couldn't get a setup that works correctly on both iOS and desktop.
I need some ideas, either a technique to configure stellar.js to work the same way on both (I'm not sure if that's possible), or another library that works on both, or maybe some insight on how I could program a workaround myself.
Any help is appreciated.
Step 1: Create and object like this
{
startFrameNumber: {
//first obj
id: idOfElement
duration: howeverManyFrames
startLeft: whatever
endLeft: whatever
startTop: stillWhatever
endTop: whateverAgain
},
nextStartFrameNumber: {
}
}
Step 2: Make the page unscrollable via CSS, ie 100% height and width with and overflow: hidden
Step 3: When the user scrolls (via custom scrollbar, keyboard action, or touch events) advance the animation x frames based on how far they scrolled or whatever. If your animation object you created has a key [frame] then add that to the queue of things that are visible and moving, and move all those things in the queue to their appropriate places and/or remove them from the queue of active objects
That's it. The function for moving things around should be pretty straight forward, except getting the animations smooth will take a little playing around with.
Simply scroll each layer of parallax effect manually and control them yourself without relying on browser's page scrolling.
I've successfully implemented cross device/browser parallax scrolling with the help of the Zynga Scroller js library.
It takes care of one of your main concerns which is the interoperability of click and touch events and scrolling on mobile webkit devices – this allows you to manipulate the DOM as you scroll.
Then, to create the parallax effect you have three options:
Simulating a real-world 3d parallax by using 3d transforms (with a parent/wrapper element that controls perspective and transform origin).
Using a 2d parallax library such as stellar.js or skrollr
Building your own parallax scrolling algorithm.
Here's a quick demo (using existing sample code) of option 1 showing how smooth parallax scrolling would work across desktop and mobile devices. Of course, you're limited to devices that have support for 3d transforms. Note that the Zynga Scroller works via click/touch and drag – it should probably not be used as a dekstop solution as the only thing that would be required is overflow: scroll in CSS.
Have a look at the jQuery-Plugin "Scroll Path" http://joelb.me/scrollpath and combine this with different layers and speeds. You will have recognized that the scrolling of the example page is not just a vertical parallax stage but also moves layers horizontally while you scroll up and down. This is possible with Scroll Path.
Try using http://cubiq.org/iscroll-4 and stellar.js together.
Do your parallax stuff for desktop normally and then add a 'touchmove' Event Listener to fire the scroll event:
document.body.addEventListener('touchmove', function(){$window.scroll()}, true);
Tested and working on iPad 2 with iOs 5.1.1
I'm looking for a non-jquery solution to add a persistent footer overlay to my mobile site. It is similar to a popup ad that is on top of content but anchored to the bottom of the page.
I've been using a javascript approach to this:
window.addEventListener(
'scroll',
function() {
//if scrolled and offsets are the same (iphone)
if(_self.initOffsetY == window.pageYOffset)
{
document.getElementById(_self.id).style.bottom = _self.initWindowHeight - window.innerHeight+"px";
}
else
{
document.getElementById(_self.id).style.bottom = _self.initWindowHeight - window.innerHeight - window.pageYOffset+"px";
}
},
false
);
where initPage Height is the initial page height and initOffsetY is the initial offset of the page. This takes care of the case with the browser menu bar.
But it doesn't really work too well on android. The positioning is off. Can someone explain why? Thanks
You should probably use either of these standalone scrolling helpers:
http://joehewitt.github.com/scrollability/
or http://cubiq.org/iscroll
Wouldn't it be better to have two separate elements, a main wrapper and a footer div perhaps, and enable scrolling in just the wrapper (overflow:auto;)? This would avoid most browser inconsistencies, or even cases where JS is turned off.
There's a drawback though. You will need to program a method for scrolling inner elements for some mobile devices. There are libraries for this (gasp!), but frankly it isn't too hard to program yourself (as I've done with my site).
If you're attached to this approach of floating an element to where you want it / approximating position:fixed, you're going to have a number of things to check, one being html code that you've got to make sure there aren't any margins or padding interfering with the above script. The quick hack solution would be to just measure the heigh difference and calibrate your script according to that. The number you get from the calibration might be helpful in determining the source of the problem. There are probably some additional tricks to make this work smoothly, but I would go with a library thats being used already, and it looks like there are a number of them: http://bradfrostweb.com/blog/mobile/fixed-position/
btw - the iscroll4 library will fix the scrolling issue with overflow:auto on ios < 5, android < 4
I am designing a code snippet which will allow the user to scroll the items inside a div. Its more of a spinning wheel / slot machine. I know an existing solution for iPhone / iPod, but I wanted to have a simple stripped down code.
I have not used any images, and I believe this would involve CSS3 animations.
So far here is my code in jsbin. I have tried binding the touchmove event using jquery, but the alert is not popping up?
My main aim is to enable the user to scroll / swipe Up & down the items inside the div, without making the page scroll up and down. Any suggestion / edits to the code are appreciated.
My intended use for this is for mobile devices (iPhone / Android)
Thanks in advance.
you've almost been on the right side:
http://cubiq.org/iscroll-4
try iScroll.
only limitation that i encountered during my test was that you have to wrap your code in a list (ul) - though that could have been my bad
I think what you are looking for can be achieved by simply using the deafult behavior on IOS Safari (iPhone/iPad)
Just give some fixed height to the container div with overflow
e.g.
<div id="container" style="height:400px;overflow:auto">
Your content
</div>
It would scroll using 2-fingers on versions prior to IOS5 and with a single-finger move for IOS5 and later..
On iOS safari, one-finger panning doesn’t generate any events until the user stops panning. An onscroll event is only generated when the page stops moving and redrawn.
I need a way to detect real time scrolling. Specifically, I want to make a sticky menu that will also work on iOS safari. On non-mobile browsers, sticky menu can be done by switching between "position relative" to "position fixed" on the element while listening to the onscroll events. This method won't work on mobile browser because onscroll events are not continuously fired. What can I do?
Answering my own question. iOS7 now support position:sticky
Demo: http://html5-demos.appspot.com/static/css/sticky.html
I've recently spent many hours trying to come up with a practical solution for the same problem. There's no right way to do this, although there are a few decent hacks (most of them mentioned already). The problem is that JavaScript is paused while the user is scrolling. It makes sense when you consider the implications, but it makes it damn hard to implement fixed positioned element.
The best thing that I've been able to find is this wonderful post by the folks at Google. You can check out http://gmail.com in mobile safari to see it in action.
https://developers.google.com/mobile/articles/webapp_fixed_ui
Hope this helps.
I had a similar issue and bound handlers to touchstart/touchmove/touchend using jquery to detect the single finger scrolling and it worked perfectly. In my case I needed to move another element the same amount as the attempted move of another element and it updated nicely as the scroll was attempted so it ought to be suitable for your requirement.
If all you want is a sticky menu, you can save yourself some headaches by using an existing library. I've had success with iScroll:
http://cubiq.org/iscroll
At the very least, you can take a look at how this works and base your solution around that.
Happy hacking!
Old topic for sure, but I can see alot of visits here. If all you want, is a sticky menu, you can use fixed positioning. No need for iScroll there.
I need to make a product slider like this ( see red area ) swipe slider with momentum.
It should work on Desktop, iPad and Mobile browser. Do you know any jquery/jquery mobile plugin to achieve this.
The effect I want is almost similar to this http://manos.malihu.gr/tuts/jquery_thumbnail_scroller.html (but it's not touch compatible)
and exactly like "Top 25" section in Apple's iPad app named "Trailers"
In my opinion iosSlider is amazing. It works in almost any device and it is well documented. It's free for personal usage, but for commercial sites license costs $20.
Also a great option is touchCarousel or RoyalSlider from same author. These two have everything you'll need, but also not free and have a price of $10-12
I would also recommend http://cubiq.org/iscroll-4
BUT if you're not digging on that try this plugin
http://www.zackgrossbart.com/hackito/touchslider/
it works very well and defaults to a horizontal slide bar on desktop -- it's not as elegant on desktop as iscroll-4 is, but it works very well on touch devices
GOOD LUCK!
If I was you, I would implement my own solution based on the event specs. Basically, what swipe is - it's handling of touch down, touch move, touch up events. here is excerpt of my own lib for handling iPhone touch events:
touch_object.prototype.handle_touchstart = function(e){
if (e.targetTouches.length != 1){
return false;
}
this.obj.style.zIndex = 100;
e.preventDefault();
this.startX = e.targetTouches[0].pageX - this.geometry.x;
this.startY = e.targetTouches[0].pageY - this.geometry.y;
/* adjust for left /top */
this.bind_handler('touchmove');
this.bind_handler('touchend');
}
touch_object.prototype.handle_touchmove = function(e) {
e.preventDefault();
if (e.targetTouches.length != 1){
return false;
}
var x=e.targetTouches[0].pageX - this.startX;
var y=e.targetTouches[0].pageY - this.startY;
this.move(x,y);
}
touch_object.prototype.handle_touchend = function(e){
this.obj.style.zIndex = 10;
this.unbind_handler('touchmove');
this.unbind_handler('touchend');
}
I used that code to "move things around". But, instead of moving, you can create your own algorithm for e.g. triggering redirect to some other location, or you can use that move to "move/swipe" the element, on which the swipe is on to other location.
so, it really helps to understand basics of how things work and then create more complicated solutions. this might help as well.
I used this, to create my solution:
http://developer.apple.com/library/IOs/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html
Have you tried iosSlider? It can do exactly what you need.
http://iosscripts.com/iosslider-jquery-horizontal-slider-for-iphone-ipad-safari/
Take a look at iScroll v4 here: http://cubiq.org/iscroll-4
It may not be jQuery, but it works on Desktop Mobile, and iPad quite well; I've used it on many projects and combined it with jQuery.
Good Luck!
This one could fit your need:
http://caroufredsel.frebsite.nl/
Add jquery Touchwipe for touch support
Then in the configuration add
scroll : {
wipe: true
}
Have you seen FlexSlider from WooThemes? I've used it on several recent projects with great success. It's touch enabled too so it will work on both mouse-based browsers as well as touch-based browsers in iOS and Android.
I found this, hope it helps
http://www.zackgrossbart.com/hackito/touchslider/
Ive found another: http://swipejs.com/
seems to work nicely however I encounter an issue with it when paired with bootstrap on the OS X version of Chrome. If total cross-browser compatibility isn't an issue, then you're golden.
I have made somthink like this for one of my website accualy in developpement.
I have used StepCarousel for the caroussel because it's the only one I found that can accept different image size in the same carrousel.
In addition to this to add the touch swipe effect, I have used jquery.touchswipe plugin;
And stepcarousel move panel rigth or left with a fonction so I can make :
$("#slider-actu").touchwipe({
wipeLeft: function() {stepcarousel.stepBy('slider-actu', 3);},
wipeRight: function() {stepcarousel.stepBy('slider-actu', -3);},
min_move_x: 20
});
You can view the actual render at this page
Hope that help you.
This looks similar and uses jQuery mobile http://www.irinavelychko.com/tutorials/jquery-mobile-gallery
And, the demo of it http://demo.irinavelychko.com/tuts/jqm-dialog-gallery.html
Have a look at jQuery scroll view (demo here). Here is the git hub repository for that experimental project. Look at their html to see what files need to be included and what attributes to add to the elements you want to be scrollable.
I have used this to be able to scroll div elements horizontally on touch devices.
You might be interested in the following:
jQuery Mobile Carousel (github)
jQuery Mobile
I realize this is not a jQuery solution, but Sencha Touch framework is pretty good for building your target UI. Example (click the Carousel sidebar link):
http://dev.sencha.com/deploy/touch/examples/kitchensink/
Checkout Portfoliojs jQuery plugin: http://portfoliojs.com
This plugin supports Touch Devices, Desktops and Mobile Browsers. Also, It has pre-loading feature.
With my experiance the best open source option will be UIKIT with its uikit slider component.
and it is very easy to implement for example in your case you could do something like this.
<div data-uk-slider>
<div class="uk-slider-container">
<ul class="uk-slider uk-grid-width-medium-1-4"> // width of the elements
<li>...</li> //slide elements
...
</ul>
</div>