Problem
Simple thing as scrolling a div with overflow:auto is currently not possible on the Android platform.
Due to my application requirement I really needed this functionality so here is what I come up with
Challenges
Currently when we call node.offsetHeight
we will not get the full height of the div only the content visible
to fix that I change the positioning to absolute and height 100% to get the true height of the div.
Android project with scrollable div can be download here
Code
Code consist of three parts
- CSS
- JavaScript
- HTML markup
.scroller_container{ position:relative; border:1px solid #CCC; overflow:hidden; top:0;left:0 } .scroller{ position:relative; float:left; } .scroller_navigator{ float:right;border:1px solid #CCC; height:150px; width:45px; } .scroll_down, .scroll_up{ clear:left;padding:8px } .scroller_navigator_spacer{ width:10px; height:48px; clear:left; } |
/** * WebKit Div Scroller class * @author:Greg Bugaj * Initial release */ //Namespace var GB=GB || {}; GB.Scroller= { SCROLL_INREMENT:5,//Amount to scroll per update SCROLL_TIME:75,//Time between update Intervals in MS getElementsByClassName:function(classname, node) { if (!node) { node = document.getElementsByTagName('BODY')[0]; } var a = []; var re = new RegExp('\\b' + classname + '\\b'); var els = node.getElementsByTagName("*"); for(var i=0,j=els.length; i<j; i++){ if(re.test(els[i].className))a.push(els[i]); } return a; }, //Attached event to the scrollable components init:function(){ var root = document.getElementsByTagName('BODY')[0]; var containers=GB.Scroller.getElementsByClassName("scroller_container", root); for(var i=0;i<containers.length;i++){ var scroller_container = containers[i]; //Copy old properties var old={ position:scroller_container.style.position, height:scroller_container.style.height, overflow:scroller_container.style.overflow }; //Set new props*/ scroller_container.style.position="absolute"; scroller_container.style.height="100%"; scroller_container.style.overflow="none"; var scroller = GB.Scroller.getElementsByClassName("scroller", scroller_container); if(scroller==null){ alert("There is no DIV with class 'scroller'"); } scroller=scroller[0];//There should be only 1 element in the array var contentHeight = scroller.offsetHeight; //Move the element back to it original positon with its original values scroller_container.style.position=old.position; scroller_container.style.height=old.height; scroller_container.style.overflow=old.overflow; var visibleContentHeight = scroller_container.offsetHeight ; var iTimer=0; /** * Scroll content layer up/down * @param {Object} e * @param {Object} direction to scroll */ var scrollContent=function(e, direction){ var t=parseInt(scroller.style.top); var cancelTimer=false; /*Scroll text up*/ if(direction == -1 && ((contentHeight+scroller.offsetTop) < visibleContentHeight)){ cancelTimer=true; }/*Scroll text down*/ else if(direction == 1/*DOWN*/ && ((contentHeight+scroller.offsetTop) >= contentHeight)){ cancelTimer=true; } if(cancelTimer){ clearInterval(iTimer); return; } t+=GB.Scroller.SCROLL_INREMENT*direction; scroller.style.top=t+"px"; }; //Attach events to navigation var tapUP = GB.Scroller.getElementsByClassName("scroll_up", scroller_container); if(tapUP==null){ alert("There is no DIV with class 'scroll_up'"); } tapUP=tapUP[0];//There should be only 1 element in the array var tapDOWN = GB.Scroller.getElementsByClassName("scroll_down", scroller_container); if(tapDOWN==null){ alert("There is no DIV with class 'scroll_down'"); } tapDOWN=tapDOWN[0];//There should be only 1 element in the array tapUP.addEventListener('touchstart', function(e){ iTimer=setInterval(function(){ scrollContent(e, -1);}, GB.Scroller.SCROLL_TIME); }, false); tapUP.addEventListener('touchend', function(e){ clearInterval(iTimer); }, false); tapDOWN.addEventListener('touchstart', function(e){ iTimer=setInterval(function(){scrollContent(e, 1);}, GB.Scroller.SCROLL_TIME); }, false); tapDOWN.addEventListener('touchend', function(e){ clearInterval(iTimer); }, false); }//for }//function }; //Initialize all the scrollable components on the page window.addEventListener('load', function(){ GB.Scroller.init(); }, true); |
<div class="scroller_container" style="width:318px; height:150px;"> <div class="scroller" style="width:205px; top:0;left:0;"> Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec dapibus ipsum in nulla rhoncus a blandit enim lobortis. Mauris scelerisque justo eu purus molestie ut sodales diam laoreet. Integer id volutpat urna. Sed lacinia risus id magna pharetra scelerisque. Proin venenatis blandit sapien vitae pulvinar. Nulla et urna in erat venenatis posuere eu id ipsum. Proin magna mi, congue ultrices malesuada id, sollicitudin a urna. Praesent id lorem leo. Phasellus vestibulum dapibus mattis. Fusce et faucibus risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec dapibus ipsum in nulla rhoncus a blandit enim lobortis. Mauris scelerisque justo eu purus molestie ut sodales diam laoreet. Integer id volutpat urna. Sed lacinia risus id magna pharetra scelerisque. Proin venenatis blandit sapien vitae pulvinar. Nulla et urna in erat venenatis posuere eu id ipsum. Proin magna mi, congue ultrices malesuada id, sollicitudin a urna. Praesent id lorem leo. Phasellus vestibulum dapibus mattis. Fusce et faucibus risus. </div><!--//scroller--> <div class="scroller_navigator"><!-- Navigation --> <div class="scroll_down" > <img src="arrow_up.png" width="32" height="32" alt="Scroll content down" / > </div> <!-- Spacer between scroll icons --> <div class="scroller_navigator_spacer"> </div> <div class="scroll_up"> <img src="arrow_down.png" width="32" height="32" alt="Scroll content up" /> </div> </div> </div><!--//scroller_container--> |
Feature request/updates
I will add features as I need them or upon request.
Hi,
I want to convert an .docx/.doc file to html and displaying in emulator with help of Web- view. But i am displaying entire data into webview as Single page(we need to scroll many times). So, i want to match the content of .docx file with webview as pages or put some buttons or gestures to get next page.But i unable to display text as pages in Web-View.
is there any solution or suggestion to get as pages?
How to get the height and width of webview?
Thanks
To get the height and width of the webiview you could simply call
mRenderView.getHeight();
mRenderView.getWidth();
This is rather quite complicated requirement, I would probably try to convert each page of .docx to an image and use that image as my source for webview. You could also try to go from docx -> pdf -> image, this way you have control over the width and height of the component. Hope this helps.
how can i just do scrolling without controls to one div alone.
You could simply invoke the method that is responsible for scrolling up/down manually.
This solution is just great. However due to the requirements of my project, I need to be able to scroll and do the same thing. I was wondering if you have a solution for that too? In another words, like what Elon asked above, How can we just do scrolling without those buttons? Could you share your code Greg please?
Thank you
Pingback: Touchstart Android | android Skill
I have tried Android webview. Div scrolling is working fine. But scrollbar not visible . what changes I have to do. I’m testing in Samsung Galaxy . could you please help me on that
Hello
It have been a long time since I worked on this, do you have a sample project I could take a look at?